From 236609d93c76b9e108d765cd7cf0632063ea8273 Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Thu, 30 Jan 2020 12:50:44 +1300 Subject: ddr: marvell: a38x: Allow boards to specify CK_DELAY parameter For some layouts it is necessary to adjust the CK_DELAY parameter to successfully complete DDR training. Add the ability to specify the CK_DELAY in the mv_ddr_topology_map. Signed-off-by: Chris Packham --- board/alliedtelesis/x530/x530.c | 6 +++++- drivers/ddr/marvell/a38x/ddr3_init.c | 5 +++++ drivers/ddr/marvell/a38x/ddr_topology_def.h | 3 +++ drivers/ddr/marvell/a38x/mv_ddr_topology.c | 10 ++++++++++ drivers/ddr/marvell/a38x/mv_ddr_topology.h | 1 + 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/board/alliedtelesis/x530/x530.c b/board/alliedtelesis/x530/x530.c index e0fa806..04b053d 100644 --- a/board/alliedtelesis/x530/x530.c +++ b/board/alliedtelesis/x530/x530.c @@ -66,7 +66,11 @@ static struct mv_ddr_topology_map board_topology_map = { BUS_MASK_32BIT_ECC, /* subphys mask */ MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ { {0} }, /* raw spd data */ - {0} /* timing parameters */ + {0}, /* timing parameters */ + { {0} }, /* electrical configuration */ + {0}, /* electrical parameters */ + 0, /* Clock enable mask */ + 160 /* Clock delay */ }; struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) diff --git a/drivers/ddr/marvell/a38x/ddr3_init.c b/drivers/ddr/marvell/a38x/ddr3_init.c index 22c8f9c..a971cc1 100644 --- a/drivers/ddr/marvell/a38x/ddr3_init.c +++ b/drivers/ddr/marvell/a38x/ddr3_init.c @@ -106,8 +106,10 @@ static int mv_ddr_training_params_set(u8 dev_num) struct tune_train_params params; int status; u32 cs_num; + int ck_delay; cs_num = mv_ddr_cs_num_get(); + ck_delay = mv_ddr_ck_delay_get(); /* NOTE: do not remove any field initilization */ params.ck_delay = TUNE_TRAINING_PARAMS_CK_DELAY; @@ -131,6 +133,9 @@ static int mv_ddr_training_params_set(u8 dev_num) params.g_odt_config = TUNE_TRAINING_PARAMS_ODT_CONFIG_2CS; } + if (ck_delay > 0) + params.ck_delay = ck_delay; + status = ddr3_tip_tune_training_params(dev_num, ¶ms); if (MV_OK != status) { printf("%s Training Sequence - FAILED\n", ddr_type); diff --git a/drivers/ddr/marvell/a38x/ddr_topology_def.h b/drivers/ddr/marvell/a38x/ddr_topology_def.h index 950f296..34196b1 100644 --- a/drivers/ddr/marvell/a38x/ddr_topology_def.h +++ b/drivers/ddr/marvell/a38x/ddr_topology_def.h @@ -127,6 +127,9 @@ struct mv_ddr_topology_map { /* Clock enable mask */ u32 clk_enable; + + /* Clock delay */ + int ck_delay; }; enum mv_ddr_iface_mode { diff --git a/drivers/ddr/marvell/a38x/mv_ddr_topology.c b/drivers/ddr/marvell/a38x/mv_ddr_topology.c index ef3b658..09840b1 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_topology.c +++ b/drivers/ddr/marvell/a38x/mv_ddr_topology.c @@ -229,6 +229,16 @@ int mv_ddr_is_ecc_ena(void) return 0; } +int mv_ddr_ck_delay_get(void) +{ + struct mv_ddr_topology_map *tm = mv_ddr_topology_map_get(); + + if (tm->ck_delay) + return tm->ck_delay; + + return -1; +} + /* translate topology map definition to real memory size in bits */ static unsigned int mem_size[] = { ADDR_SIZE_512MB, diff --git a/drivers/ddr/marvell/a38x/mv_ddr_topology.h b/drivers/ddr/marvell/a38x/mv_ddr_topology.h index 766f25d..4fca476 100644 --- a/drivers/ddr/marvell/a38x/mv_ddr_topology.h +++ b/drivers/ddr/marvell/a38x/mv_ddr_topology.h @@ -319,6 +319,7 @@ unsigned short mv_ddr_bus_bit_mask_get(void); unsigned int mv_ddr_if_bus_width_get(void); unsigned int mv_ddr_cs_num_get(void); int mv_ddr_is_ecc_ena(void); +int mv_ddr_ck_delay_get(void); unsigned long long mv_ddr_mem_sz_per_cs_get(void); unsigned long long mv_ddr_mem_sz_get(void); unsigned int mv_ddr_rtt_nom_get(void); -- cgit v1.1 From 5e2de83f7115aaad6ea32ae8cb41b08a2c2f7a50 Mon Sep 17 00:00:00 2001 From: Josip Kelecic Date: Thu, 13 Feb 2020 14:38:49 +0100 Subject: arm: mvebu: dts: Sort Armada series dts alphabetically MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sort the Armada series dts in the Makefile alphabetically prior to adding new board support. Signed-off-by: Josip Kelečić Reviewed-by: Luka Kovacic Reviewed-by: Stefan Roese --- arch/arm/dts/Makefile | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 2a89da2..6d1e866 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -191,25 +191,25 @@ dtb-$(CONFIG_ARCH_MVEBU) += \ armada-3720-turris-mox.dtb \ armada-3720-uDPU.dtb \ armada-375-db.dtb \ + armada-385-atl-x530.dtb \ + armada-385-atl-x530DP.dtb \ + armada-385-db-88f6820-amc.dtb \ + armada-385-turris-omnia.dtb \ armada-388-clearfog.dtb \ armada-388-gp.dtb \ armada-388-helios4.dtb \ - armada-385-db-88f6820-amc.dtb \ - armada-385-turris-omnia.dtb \ - armada-7040-db.dtb \ + armada-38x-controlcenterdc.dtb \ armada-7040-db-nand.dtb \ + armada-7040-db.dtb \ + armada-8040-clearfog-gt-8k.dtb \ armada-8040-db.dtb \ armada-8040-mcbin.dtb \ - armada-8040-clearfog-gt-8k.dtb \ + armada-xp-crs305-1g-4s.dtb \ + armada-xp-db-xc3-24g4xg.dtb \ armada-xp-gp.dtb \ armada-xp-maxbcm.dtb \ armada-xp-synology-ds414.dtb \ - armada-xp-theadorable.dtb \ - armada-38x-controlcenterdc.dtb \ - armada-385-atl-x530.dtb \ - armada-385-atl-x530DP.dtb \ - armada-xp-db-xc3-24g4xg.dtb \ - armada-xp-crs305-1g-4s.dtb + armada-xp-theadorable.dtb dtb-$(CONFIG_ARCH_UNIPHIER_LD11) += \ uniphier-ld11-global.dtb \ -- cgit v1.1 From a1dd1fcb6ede14f74d3c7ec1319a6f3f9cd23f6a Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 15 Feb 2020 21:58:31 +0100 Subject: arm: mvebu: drivers/ddr: remove redundant assignment The value of local variable ecc is immediately overwritten. So we can remove the first assignment. Signed-off-by: Heinrich Schuchardt Reviewed-by: Stefan Roese --- drivers/ddr/marvell/axp/ddr3_init.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/ddr/marvell/axp/ddr3_init.c b/drivers/ddr/marvell/axp/ddr3_init.c index 13df912..30ad5d4 100644 --- a/drivers/ddr/marvell/axp/ddr3_init.c +++ b/drivers/ddr/marvell/axp/ddr3_init.c @@ -435,10 +435,6 @@ static u32 ddr3_init_main(void) #endif #if defined(ECC_SUPPORT) && defined(AUTO_DETECTION_SUPPORT) - ecc = DRAM_ECC; -#endif - -#if defined(ECC_SUPPORT) && defined(AUTO_DETECTION_SUPPORT) ecc = 0; if (ddr3_check_config(BUS_WIDTH_ECC_TWSI_ADDR, CONFIG_ECC)) ecc = 1; -- cgit v1.1 From 201a500deccd2375e663d9266f2ae0173d173a81 Mon Sep 17 00:00:00 2001 From: Josua Mayer Date: Mon, 17 Feb 2020 19:37:28 +0100 Subject: arm: mvebu: clearfog: add scsi target to distro-boot Support for sata devices via the scsi command is available and already enabled by default for the Clearfog Base and Pro. This change adds scsi to the list of boot targets used by distro-boot. Signed-off-by: Josua Mayer Cc: Stefan Roese Reviewed-by: Stefan Roese --- include/configs/clearfog.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/configs/clearfog.h b/include/configs/clearfog.h index 633187d..33c71b3 100644 --- a/include/configs/clearfog.h +++ b/include/configs/clearfog.h @@ -104,6 +104,12 @@ #define BOOT_TARGET_DEVICES_MMC(func) #endif +#ifdef CONFIG_SCSI +#define BOOT_TARGET_DEVICES_SCSI(func) func(SCSI, scsi, 0) +#else +#define BOOT_TARGET_DEVICES_SCSI(func) +#endif + #ifdef CONFIG_USB_STORAGE #define BOOT_TARGET_DEVICES_USB(func) func(USB, usb, 0) #else @@ -112,6 +118,7 @@ #define BOOT_TARGET_DEVICES(func) \ BOOT_TARGET_DEVICES_MMC(func) \ + BOOT_TARGET_DEVICES_SCSI(func) \ BOOT_TARGET_DEVICES_USB(func) \ func(PXE, pxe, na) \ func(DHCP, dhcp, na) -- cgit v1.1 From ad91fdfff0bd6ea471afe838e0f6d58ed898694e Mon Sep 17 00:00:00 2001 From: Chris Packham Date: Wed, 26 Feb 2020 19:53:50 +1300 Subject: arm: mvebu: update RTC values for PCIe memory wrappers Update the RTC (Read Timing Control) values for PCIe memory wrappers following an ERRATA (ERRATA# TDB). This means the PCIe accesses will used slower memory Read Timing, to allow more efficient energy consumption, in order to lower the minimum VDD of the memory. Will lead to more robust memory when voltage drop occurs (VDDSEG) The code is based on changes from Marvell's U-Boot, specifically: https://github.com/MarvellEmbeddedProcessors/u-boot-marvell/commit/20cd2704072512de176e048970f2883db901674b https://github.com/MarvellEmbeddedProcessors/u-boot-marvell/commit/eb608a7c8dd0d42b87601a61b9c0cc5615ab94b2 https://github.com/MarvellEmbeddedProcessors/u-boot-marvell/commit/c4af19ae2bf08cf6e450e741ce4f04d402a5cb6b Signed-off-by: Chris Packham Signed-off-by: Chris Packham Reviewed-by: Stefan Roese --- arch/arm/mach-mvebu/include/mach/cpu.h | 2 ++ arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c | 17 +++++++++++++++++ arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h | 13 +++++++++++++ arch/arm/mach-mvebu/spl.c | 3 +++ 4 files changed, 35 insertions(+) diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h index 2e2d72a..fa7c817 100644 --- a/arch/arm/mach-mvebu/include/mach/cpu.h +++ b/arch/arm/mach-mvebu/include/mach/cpu.h @@ -166,8 +166,10 @@ int ddr3_init(void); /* Auto Voltage Scaling */ #if defined(CONFIG_ARMADA_38X) || defined(CONFIG_ARMADA_39X) void mv_avs_init(void); +void mv_rtc_config(void); #else static inline void mv_avs_init(void) {} +static inline void mv_rtc_config(void) {} #endif /* diff --git a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c index e9dd096..3c4c7e0 100644 --- a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c +++ b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.c @@ -257,6 +257,23 @@ u8 sys_env_device_rev_get(void) return (value & (REVISON_ID_MASK)) >> REVISON_ID_OFFS; } +void mv_rtc_config(void) +{ + u32 i, val; + + if (!(IS_ENABLED(CONFIG_ARMADA_38X) || IS_ENABLED(CONFIG_ARMADA_39X))) + return; + + /* Activate pipe0 for read/write transaction, and set XBAR client number #1 */ + val = 0x1 << DFX_PIPE_SELECT_PIPE0_ACTIVE_OFFS | + 0x1 << DFX_PIPE_SELECT_XBAR_CLIENT_SEL_OFFS; + writel(val, MVEBU_DFX_BASE); + + /* Set new RTC value for all memory wrappers */ + for (i = 0; i < RTC_MEMORY_WRAPPER_COUNT; i++) + reg_write(RTC_MEMORY_WRAPPER_REG(i), RTC_MEMORY_WRAPPER_CTRL_VAL); +} + void mv_avs_init(void) { u32 sar_freq; diff --git a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h index 1774a5b..17cd811 100644 --- a/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h +++ b/arch/arm/mach-mvebu/serdes/a38x/sys_env_lib.h @@ -150,6 +150,19 @@ #define MPP_UART1_SET_MASK (~(0xff000)) #define MPP_UART1_SET_DATA (0x66000) +#define DFX_PIPE_SELECT_PIPE0_ACTIVE_OFFS 0 +/* DFX_PIPE_SELECT_XBAR_CLIENT_SEL_OFFS: Since address completion in 14bit + * address mode, and given that [14:8] => [19:13], the 2 lower bits [9:8] => + * [14:13] are dismissed. hence field offset is also shifted to 10 + */ +#define DFX_PIPE_SELECT_XBAR_CLIENT_SEL_OFFS 10 + +#define RTC_MEMORY_CTRL_REG_BASE 0xE6000 +#define RTC_MEMORY_WRAPPER_COUNT 8 +#define RTC_MEMORY_WRAPPER_REG(i) (RTC_MEMORY_CTRL_REG_BASE + ((i) * 0x40)) +#define RTC_MEMORY_CTRL_PDLVMC_FIELD_OFFS 6 +#define RTC_MEMORY_WRAPPER_CTRL_VAL (0x1 << RTC_MEMORY_CTRL_PDLVMC_FIELD_OFFS) + #define AVS_DEBUG_CNTR_REG 0xe4124 #define AVS_DEBUG_CNTR_DEFAULT_VALUE 0x08008073 diff --git a/arch/arm/mach-mvebu/spl.c b/arch/arm/mach-mvebu/spl.c index a99bf16..70fef3b 100644 --- a/arch/arm/mach-mvebu/spl.c +++ b/arch/arm/mach-mvebu/spl.c @@ -130,6 +130,9 @@ void board_init_f(ulong dummy) /* Initialize Auto Voltage Scaling */ mv_avs_init(); + /* Update read timing control for PCIe */ + mv_rtc_config(); + /* * Return to the BootROM to continue the Marvell xmodem * UART boot protocol. As initiated by the kwboot tool. -- cgit v1.1 From bd02fd29f996f90308d54632da767e586f6c1b44 Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Mon, 23 Mar 2020 11:26:31 -0600 Subject: arm: mvebu: clearfog: add SCSI to distro bootcmd Include attempting to boot from SCSI (SATA) devices within generated board distro bootcmd environment. The reasoning for boot ordering is that MMC and USB are external and removable, while when a case is in use, replacing M.2 or mSATA drives requires disassembly. Therefore, to boot SCSI, [bootable] external media must be removed. If SCSI were placed before MMC or USB, then removing a bootable SCSI drive to enable MMC or USB booting would be more difficult. Signed-off-by: Joel Johnson Reviewed-by: Stefan Roese --- include/configs/clearfog.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/configs/clearfog.h b/include/configs/clearfog.h index 33c71b3..eef6983 100644 --- a/include/configs/clearfog.h +++ b/include/configs/clearfog.h @@ -116,10 +116,17 @@ #define BOOT_TARGET_DEVICES_USB(func) #endif +#ifdef CONFIG_SCSI +#define BOOT_TARGET_DEVICES_SCSI(func) func(SCSI, scsi, 0) +#else +#define BOOT_TARGET_DEVICES_SCSI(func) +#endif + #define BOOT_TARGET_DEVICES(func) \ BOOT_TARGET_DEVICES_MMC(func) \ BOOT_TARGET_DEVICES_SCSI(func) \ BOOT_TARGET_DEVICES_USB(func) \ + BOOT_TARGET_DEVICES_SCSI(func) \ func(PXE, pxe, na) \ func(DHCP, dhcp, na) -- cgit v1.1 From cecf38a75581b0d4c4922b9a4ff94a626604830e Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Mon, 23 Mar 2020 11:26:32 -0600 Subject: arm: mvebu: clearfog: support multiple SATA boot Enable distro bootcmd support for additional SATA ports if enabled. Signed-off-by: Joel Johnson Reviewed-by: Stefan Roese --- include/configs/clearfog.h | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/include/configs/clearfog.h b/include/configs/clearfog.h index eef6983..52945d1 100644 --- a/include/configs/clearfog.h +++ b/include/configs/clearfog.h @@ -116,17 +116,47 @@ #define BOOT_TARGET_DEVICES_USB(func) #endif -#ifdef CONFIG_SCSI -#define BOOT_TARGET_DEVICES_SCSI(func) func(SCSI, scsi, 0) +#ifndef CONFIG_SCSI +#define BOOT_TARGET_DEVICES_SCSI_BUS0(func) +#define BOOT_TARGET_DEVICES_SCSI_BUS1(func) +#define BOOT_TARGET_DEVICES_SCSI_BUS2(func) #else -#define BOOT_TARGET_DEVICES_SCSI(func) +/* + * With SCSI enabled, M.2 SATA is always located on bus 0 + */ +#define BOOT_TARGET_DEVICES_SCSI_BUS0(func) func(SCSI, scsi, 0) + +/* + * Either one or both mPCIe slots may be configured as mSATA interfaces. The + * SCSI bus ids are assigned based on sequence of hardware present, not always + * tied to hardware slot ids. As such, use second SCSI bus if either slot is + * set for SATA, and only use third SCSI bus if both slots are SATA enabled. + */ +#if defined (CONFIG_CLEARFOG_CON2_SATA) || defined (CONFIG_CLEARFOG_CON3_SATA) +#define BOOT_TARGET_DEVICES_SCSI_BUS1(func) func(SCSI, scsi, 1) +#else +#define BOOT_TARGET_DEVICES_SCSI_BUS1(func) +#endif + +#if defined (CONFIG_CLEARFOG_CON2_SATA) && defined (CONFIG_CLEARFOG_CON3_SATA) +#define BOOT_TARGET_DEVICES_SCSI_BUS2(func) func(SCSI, scsi, 2) +#else +#define BOOT_TARGET_DEVICES_SCSI_BUS2(func) #endif +#endif /* CONFIG_SCSI */ + +/* + * The SCSI buses are attempted in increasing bus order, there is no current + * mechanism to alter the default bus priority order for booting. + */ #define BOOT_TARGET_DEVICES(func) \ BOOT_TARGET_DEVICES_MMC(func) \ BOOT_TARGET_DEVICES_SCSI(func) \ BOOT_TARGET_DEVICES_USB(func) \ - BOOT_TARGET_DEVICES_SCSI(func) \ + BOOT_TARGET_DEVICES_SCSI_BUS0(func) \ + BOOT_TARGET_DEVICES_SCSI_BUS1(func) \ + BOOT_TARGET_DEVICES_SCSI_BUS2(func) \ func(PXE, pxe, na) \ func(DHCP, dhcp, na) -- cgit v1.1 From 4f7991ee1c34f2f0d80a680146aeff867d688dd9 Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Mon, 23 Mar 2020 14:21:29 -0600 Subject: arm: mvebu: fix SerDes table alignment Tested on Solidrun ClearFog Base. Table alignment was: | Lane # | Speed | Type | -------------------------------- | 0 | 3 | SATA0 | | 1 | 0 | SGMII1 | | 2 | 3 | SATA1 | | 3 | 5 | USB3 HOST1 | | 4 | 5 | USB3 HOST0 | | 5 | 4 | SGMII2 | -------------------------------- After the change, it's correctly aligned as: | Lane # | Speed | Type | -------------------------------- | 0 | 3 | SATA0 | | 1 | 0 | SGMII1 | | 2 | 5 | PCIe1 | | 3 | 5 | USB3 HOST1 | | 4 | 5 | PCIe2 | | 5 | 0 | SGMII2 | -------------------------------- Signed-off-by: Joel Johnson Reviewed-by: Stefan Roese --- arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c index 33e7056..66409a5 100644 --- a/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c +++ b/arch/arm/mach-mvebu/serdes/a38x/high_speed_env_spec.c @@ -1366,16 +1366,16 @@ static void print_topology_details(const struct serdes_map *serdes_map, DEBUG_INIT_S("board SerDes lanes topology details:\n"); - DEBUG_INIT_S(" | Lane # | Speed | Type |\n"); + DEBUG_INIT_S(" | Lane # | Speed | Type |\n"); DEBUG_INIT_S(" --------------------------------\n"); for (lane_num = 0; lane_num < count; lane_num++) { if (serdes_map[lane_num].serdes_type == DEFAULT_SERDES) continue; DEBUG_INIT_S(" | "); DEBUG_INIT_D(hws_get_physical_serdes_num(lane_num), 1); - DEBUG_INIT_S(" | "); + DEBUG_INIT_S(" | "); DEBUG_INIT_D(serdes_map[lane_num].serdes_speed, 2); - DEBUG_INIT_S(" | "); + DEBUG_INIT_S(" | "); DEBUG_INIT_S((char *) serdes_type_to_string[serdes_map[lane_num]. serdes_type]); -- cgit v1.1 From a8d0aa31bd213160bf9cb689df1040db0377cc66 Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Mon, 23 Mar 2020 14:21:30 -0600 Subject: arm: mvebu: solidrun: remove hardcoded DTS MAC address Using a consistent hardcoded MAC address from the DTS file causes issues when using multiple devices on the same network segment. Instead rely on environment configuration or random generation. Signed-off-by: Joel Johnson Reviewed-by: Stefan Roese --- arch/arm/dts/armada-38x-solidrun-microsom.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/dts/armada-38x-solidrun-microsom.dtsi b/arch/arm/dts/armada-38x-solidrun-microsom.dtsi index a322a28..9bbeafc 100644 --- a/arch/arm/dts/armada-38x-solidrun-microsom.dtsi +++ b/arch/arm/dts/armada-38x-solidrun-microsom.dtsi @@ -39,7 +39,6 @@ ð0 { /* ethernet@70000 */ - mac-address = [00 50 43 02 02 01]; pinctrl-0 = <&ge0_rgmii_pins>; pinctrl-names = "default"; phy = <&phy_dedicated>; -- cgit v1.1 From ee26e8539f1f244ae3cdb932fdcae73f1d9b5911 Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Mon, 23 Mar 2020 14:21:31 -0600 Subject: arm: mvebu: clearfog: use Pro name by default Make the board version printed indicate the Pro variant default. Also adjust static name casing to match what is expected for EEPROM product name to share string constants. Signed-off-by: Joel Johnson Reviewed-by: Stefan Roese --- board/solidrun/clearfog/clearfog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c index e268ef5..9b31902 100644 --- a/board/solidrun/clearfog/clearfog.c +++ b/board/solidrun/clearfog/clearfog.c @@ -170,7 +170,7 @@ int board_init(void) int checkboard(void) { - char *board = "ClearFog"; + char *board = "Clearfog Pro"; cf_read_tlv_data(); if (strlen(cf_tlv_data.tlv_product_name[0]) > 0) -- cgit v1.1 From 9f205d658da33bf2462baa1608aed996c48473af Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Mon, 23 Mar 2020 14:21:32 -0600 Subject: arm: mvebu: clearfog: initial ClearFog Base variant Add a unique entry for ClearFog Base variant, reflected in the board name and adjusted SerDes topology. Signed-off-by: Joel Johnson Reviewed-by: Stefan Roese --- arch/arm/mach-mvebu/Kconfig | 2 ++ board/solidrun/clearfog/Kconfig | 18 ++++++++++++++++++ board/solidrun/clearfog/clearfog.c | 38 ++++++++++++++++++++++++++++++++------ 3 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 board/solidrun/clearfog/Kconfig diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index bc5eaa5..161dee9 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -280,4 +280,6 @@ config SECURED_MODE_CSK_INDEX default 0 depends on SECURED_MODE_IMAGE +source "board/solidrun/clearfog/Kconfig" + endif diff --git a/board/solidrun/clearfog/Kconfig b/board/solidrun/clearfog/Kconfig new file mode 100644 index 0000000..936d591 --- /dev/null +++ b/board/solidrun/clearfog/Kconfig @@ -0,0 +1,18 @@ +menu "ClearFog configuration" + depends on TARGET_CLEARFOG + +config TARGET_CLEARFOG_BASE + bool "Use ClearFog Base static configuration" + help + Use the ClearFog Base as the static configuration instead of the + default which uses the ClearFog Pro. + + Runtime board detection is always attempted and used if available. The + static configuration is used as a fallback in cases where runtime + detection is disabled, is not available in hardware, or otherwise fails. + + Only newer revisions of the ClearFog product line support runtime + detection via additional EEPROM hardware. This option enables selecting + the Base variant for older hardware revisions. + +endmenu diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c index 9b31902..11d3a7f 100644 --- a/board/solidrun/clearfog/clearfog.c +++ b/board/solidrun/clearfog/clearfog.c @@ -42,6 +42,7 @@ static void cf_read_tlv_data(void) read_tlv_data(&cf_tlv_data); } +/* The starting board_serdes_map reflects original Clearfog Pro usage */ static struct serdes_map board_serdes_map[] = { {SATA0, SERDES_SPEED_3_GBPS, SERDES_DEFAULT_MODE, 0, 0}, {SGMII1, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0}, @@ -51,6 +52,13 @@ static struct serdes_map board_serdes_map[] = { {SGMII2, SERDES_SPEED_1_25_GBPS, SERDES_DEFAULT_MODE, 0, 0}, }; +void config_cfbase_serdes_map(void) +{ + board_serdes_map[4].serdes_type = USB3_HOST0; + board_serdes_map[4].serdes_speed = SERDES_SPEED_5_GBPS; + board_serdes_map[4].serdes_mode = SERDES_DEFAULT_MODE; +} + int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count) { cf_read_tlv_data(); @@ -59,12 +67,26 @@ int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count) board_serdes_map[0].serdes_type = PEX0; board_serdes_map[0].serdes_speed = SERDES_SPEED_5_GBPS; board_serdes_map[0].serdes_mode = PEX_ROOT_COMPLEX_X1; - } - - if (sr_product_is(&cf_tlv_data, "Clearfog Base")) { - board_serdes_map[4].serdes_type = USB3_HOST0; - board_serdes_map[4].serdes_speed = SERDES_SPEED_5_GBPS; - board_serdes_map[4].serdes_mode = SERDES_DEFAULT_MODE; + } else if (sr_product_is(&cf_tlv_data, "Clearfog Pro")) { + /* handle recognized product as noop, no adjustment required */ + } else if (sr_product_is(&cf_tlv_data, "Clearfog Base")) { + config_cfbase_serdes_map(); + } else { + /* + * Fallback to static default. EEPROM TLV support is not + * enabled, runtime detection failed, hardware support is not + * present, EEPROM is corrupt, or an unrecognized product name + * is present. + */ + if (IS_ENABLED(CONFIG_SPL_CMD_TLV_EEPROM)) + puts("EEPROM TLV detection failed: "); + puts("Using static config for "); + if (IS_ENABLED(CONFIG_TARGET_CLEARFOG_BASE)) { + puts("Clearfog Base.\n"); + config_cfbase_serdes_map(); + } else { + puts("Clearfog Pro.\n"); + } } *serdes_map_array = board_serdes_map; @@ -171,6 +193,8 @@ int board_init(void) int checkboard(void) { char *board = "Clearfog Pro"; + if (IS_ENABLED(CONFIG_TARGET_CLEARFOG_BASE)) + board = "Clearfog Base"; cf_read_tlv_data(); if (strlen(cf_tlv_data.tlv_product_name[0]) > 0) @@ -200,6 +224,8 @@ int board_late_init(void) env_set("fdtfile", "armada-385-clearfog-gtr-s4.dtb"); else if (sr_product_is(&cf_tlv_data, "Clearfog GTR L8")) env_set("fdtfile", "armada-385-clearfog-gtr-l8.dtb"); + else if (IS_ENABLED(CONFIG_TARGET_CLEARFOG_BASE)) + env_set("fdtfile", "armada-388-clearfog-base.dtb"); return 0; } -- cgit v1.1 From 8a86308a87d32b289eff0b6f89de1dea466bae9b Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Mon, 23 Mar 2020 14:21:33 -0600 Subject: arm: mvebu: clearfog: Add option for 2.5 Gbps SFP While newer Linux kernels provide autoconfiguration of SFP, provide an option for setting in U-Boot Kconfig for use prior to booting. Signed-off-by: Joel Johnson Reviewed-by: Stefan Roese --- board/solidrun/clearfog/Kconfig | 7 +++++++ board/solidrun/clearfog/clearfog.c | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/board/solidrun/clearfog/Kconfig b/board/solidrun/clearfog/Kconfig index 936d591..c910e17 100644 --- a/board/solidrun/clearfog/Kconfig +++ b/board/solidrun/clearfog/Kconfig @@ -15,4 +15,11 @@ config TARGET_CLEARFOG_BASE detection via additional EEPROM hardware. This option enables selecting the Base variant for older hardware revisions. +config CLEARFOG_SFP_25GB + bool "Enable 2.5 Gbps mode for SFP" + help + Set the SFP module connection to support 2.5 Gbps transfer speed for the + SGMII connection (requires a supporting SFP). By default, transfer speed + of 1.25 Gbps is used, suitable for a more common 1 Gbps SFP module. + endmenu diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c index 11d3a7f..8f3e5dc 100644 --- a/board/solidrun/clearfog/clearfog.c +++ b/board/solidrun/clearfog/clearfog.c @@ -63,6 +63,11 @@ int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count) { cf_read_tlv_data(); + /* Apply build configuration options before runtime configuration */ + if (IS_ENABLED(CONFIG_CLEARFOG_SFP_25GB)) + board_serdes_map[5].serdes_speed = SERDES_SPEED_3_125_GBPS; + + /* Apply runtime detection changes */ if (sr_product_is(&cf_tlv_data, "Clearfog GTR")) { board_serdes_map[0].serdes_type = PEX0; board_serdes_map[0].serdes_speed = SERDES_SPEED_5_GBPS; -- cgit v1.1 From 009d4cfcf27f9b3bc5fbb2f53731e6c59015aa33 Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Mon, 23 Mar 2020 14:21:34 -0600 Subject: arm: mvebu: clearfog: Add SATA mode flags The mPCIe slots on ClearFog Pro and ClearFog Base may be alternately configured for SATA usage. Signed-off-by: Joel Johnson Reviewed-by: Stefan Roese --- board/solidrun/clearfog/Kconfig | 17 +++++++++++++++++ board/solidrun/clearfog/clearfog.c | 14 ++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/board/solidrun/clearfog/Kconfig b/board/solidrun/clearfog/Kconfig index c910e17..44224d9 100644 --- a/board/solidrun/clearfog/Kconfig +++ b/board/solidrun/clearfog/Kconfig @@ -15,6 +15,23 @@ config TARGET_CLEARFOG_BASE detection via additional EEPROM hardware. This option enables selecting the Base variant for older hardware revisions. +config CLEARFOG_CON3_SATA + bool "Use CON3 slot in SATA mode" + help + Use the CON3 port with SATA protocol instead of the default PCIe. + The ClearFog port allows usage of either mSATA or miniPCIe + modules, but the desired protocol must be configured at build + time since it affects the SerDes topology layout. + +config CLEARFOG_CON2_SATA + bool "Use CON2 slot in SATA mode" + depends on !TARGET_CLEARFOG_BASE + help + Use the CON2 port with SATA protocol instead of the default PCIe. + The ClearFog port allows usage of either mSATA or miniPCIe + modules, but the desired protocol must be configured at build + time since it affects the SerDes topology layout. + config CLEARFOG_SFP_25GB bool "Enable 2.5 Gbps mode for SFP" help diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c index 8f3e5dc..fd9bd95 100644 --- a/board/solidrun/clearfog/clearfog.c +++ b/board/solidrun/clearfog/clearfog.c @@ -67,6 +67,20 @@ int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count) if (IS_ENABLED(CONFIG_CLEARFOG_SFP_25GB)) board_serdes_map[5].serdes_speed = SERDES_SPEED_3_125_GBPS; + if (IS_ENABLED(CONFIG_CLEARFOG_CON2_SATA)) { + board_serdes_map[4].serdes_type = SATA2; + board_serdes_map[4].serdes_speed = SERDES_SPEED_3_GBPS; + board_serdes_map[4].serdes_mode = SERDES_DEFAULT_MODE; + board_serdes_map[4].swap_rx = 1; + } + + if (IS_ENABLED(CONFIG_CLEARFOG_CON3_SATA)) { + board_serdes_map[2].serdes_type = SATA1; + board_serdes_map[2].serdes_speed = SERDES_SPEED_3_GBPS; + board_serdes_map[2].serdes_mode = SERDES_DEFAULT_MODE; + board_serdes_map[2].swap_rx = 1; + } + /* Apply runtime detection changes */ if (sr_product_is(&cf_tlv_data, "Clearfog GTR")) { board_serdes_map[0].serdes_type = PEX0; -- cgit v1.1 From 8eccd0dda0eea1d8ddc922d55d118f8db31715ad Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Mon, 23 Mar 2020 14:21:35 -0600 Subject: arm: mvebu: clearfog: Unify DT selection paths Unify the location of DT selection into board_late_init instead of split between detection and static configuration paths. Signed-off-by: Joel Johnson Reviewed-by: Stefan Roese --- board/solidrun/clearfog/clearfog.c | 2 ++ include/configs/clearfog.h | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c index fd9bd95..249ea46 100644 --- a/board/solidrun/clearfog/clearfog.c +++ b/board/solidrun/clearfog/clearfog.c @@ -245,6 +245,8 @@ int board_late_init(void) env_set("fdtfile", "armada-385-clearfog-gtr-l8.dtb"); else if (IS_ENABLED(CONFIG_TARGET_CLEARFOG_BASE)) env_set("fdtfile", "armada-388-clearfog-base.dtb"); + else + env_set("fdtfile", "armada-388-clearfog.dtb"); return 0; } diff --git a/include/configs/clearfog.h b/include/configs/clearfog.h index 52945d1..8314956 100644 --- a/include/configs/clearfog.h +++ b/include/configs/clearfog.h @@ -178,7 +178,6 @@ #define CONFIG_EXTRA_ENV_SETTINGS \ RELOCATION_LIMITS_ENV_SETTINGS \ LOAD_ADDRESS_ENV_SETTINGS \ - "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \ "console=ttyS0,115200\0" \ BOOTENV -- cgit v1.1 From b16d7c3216fea40545a3ed1784345f3c851b28e8 Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Mon, 23 Mar 2020 14:21:36 -0600 Subject: arm: mvebu: clearfog: add SPI offsets Add reasonable default SPI offsets and ENV size when configured to boot from SPI flash. Signed-off-by: Joel Johnson Reviewed-by: Stefan Roese --- board/solidrun/clearfog/Kconfig | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/board/solidrun/clearfog/Kconfig b/board/solidrun/clearfog/Kconfig index 44224d9..ea9c419 100644 --- a/board/solidrun/clearfog/Kconfig +++ b/board/solidrun/clearfog/Kconfig @@ -39,4 +39,16 @@ config CLEARFOG_SFP_25GB SGMII connection (requires a supporting SFP). By default, transfer speed of 1.25 Gbps is used, suitable for a more common 1 Gbps SFP module. +config ENV_SECT_SIZE + hex "Environment Sector-Size" + # Use SPI flash erase block size of 4 KiB + default 0x1000 if MVEBU_SPL_BOOT_DEVICE_SPI + # Use optimistic 64 KiB erase block, will vary between actual media + default 0x10000 if MVEBU_SPL_BOOT_DEVICE_MMC + +config SYS_SPI_U_BOOT_OFFS + hex "address of u-boot payload in SPI flash" + default 0x20000 + depends on MVEBU_SPL_BOOT_DEVICE_SPI + endmenu -- cgit v1.1 From c5936cc4f8c36bc3deb0335a5f5b38c2bd3cea3c Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Mon, 23 Mar 2020 14:21:38 -0600 Subject: arm: mvebu: clearfog: move ENV params to Kconfig Migrate the values for ENV_SIZE and ENV_OFFSET into board specific Kconfig defaults so they're more accessible for configuration. Signed-off-by: Joel Johnson Reviewed-by: Stefan Roese --- board/solidrun/clearfog/Kconfig | 8 ++++++++ configs/clearfog_defconfig | 2 -- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/board/solidrun/clearfog/Kconfig b/board/solidrun/clearfog/Kconfig index ea9c419..e8c3f53 100644 --- a/board/solidrun/clearfog/Kconfig +++ b/board/solidrun/clearfog/Kconfig @@ -39,6 +39,14 @@ config CLEARFOG_SFP_25GB SGMII connection (requires a supporting SFP). By default, transfer speed of 1.25 Gbps is used, suitable for a more common 1 Gbps SFP module. +config ENV_SIZE + hex "Environment Size" + default 0x10000 + +config ENV_OFFSET + hex "Environment offset" + default 0xF0000 + config ENV_SECT_SIZE hex "Environment Sector-Size" # Use SPI flash erase block size of 4 KiB diff --git a/configs/clearfog_defconfig b/configs/clearfog_defconfig index c938448..6db8b8a 100644 --- a/configs/clearfog_defconfig +++ b/configs/clearfog_defconfig @@ -9,8 +9,6 @@ CONFIG_SPL_LIBGENERIC_SUPPORT=y CONFIG_SYS_MALLOC_F_LEN=0x2000 CONFIG_TARGET_CLEARFOG=y CONFIG_MVEBU_SPL_BOOT_DEVICE_MMC=y -CONFIG_ENV_SIZE=0x10000 -CONFIG_ENV_OFFSET=0xF0000 CONFIG_DM_GPIO=y CONFIG_SPL_MMC_SUPPORT=y CONFIG_SPL_SERIAL_SUPPORT=y -- cgit v1.1 From 27f48f7dc4f57d0109f6333eb5148d0e9c3dbd95 Mon Sep 17 00:00:00 2001 From: Joel Johnson Date: Mon, 23 Mar 2020 14:21:40 -0600 Subject: arm: mvebu: clearfog: Use Pro DT by default Switch to explicitly using the Pro variant DT, which has been available since Linux 4.11. Signed-off-by: Joel Johnson Reviewed-by: Stefan Roese --- board/solidrun/clearfog/clearfog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/board/solidrun/clearfog/clearfog.c b/board/solidrun/clearfog/clearfog.c index 249ea46..443751b 100644 --- a/board/solidrun/clearfog/clearfog.c +++ b/board/solidrun/clearfog/clearfog.c @@ -246,7 +246,7 @@ int board_late_init(void) else if (IS_ENABLED(CONFIG_TARGET_CLEARFOG_BASE)) env_set("fdtfile", "armada-388-clearfog-base.dtb"); else - env_set("fdtfile", "armada-388-clearfog.dtb"); + env_set("fdtfile", "armada-388-clearfog-pro.dtb"); return 0; } -- cgit v1.1 From b80ca8176dc0e78d3fb22b2389c847a5d96ee583 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Wed, 8 Apr 2020 12:02:03 +0200 Subject: arm: mvebu: turris_mox: Fix early SPI communication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SPI clock signal changes value when the SPI configuration register is configured. This can sometimes lead to the device misinterpreting the enablement of the SPI controller as actual clock tick. This can be solved by first setting the SPI CS1 pin from GPIO to SPI mode, and only after that writing the SPI configuration register. Signed-off-by: Marek Behún Reviewed-by: Stefan Roese --- board/CZ.NIC/turris_mox/turris_mox.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/board/CZ.NIC/turris_mox/turris_mox.c b/board/CZ.NIC/turris_mox/turris_mox.c index 377191b..0b13d1d 100644 --- a/board/CZ.NIC/turris_mox/turris_mox.c +++ b/board/CZ.NIC/turris_mox/turris_mox.c @@ -67,9 +67,11 @@ int board_fix_fdt(void *blob) * to read SPI by reading/writing SPI registers directly */ - writel(0x563fa, ARMADA_37XX_NB_GPIO_SEL); writel(0x10df, ARMADA_37XX_SPI_CFG); - writel(0x2005b, ARMADA_37XX_SPI_CTRL); + /* put pin from GPIO to SPI mode */ + clrbits_le32(ARMADA_37XX_NB_GPIO_SEL, BIT(12)); + /* enable SPI CS1 */ + setbits_le32(ARMADA_37XX_SPI_CTRL, BIT(17)); while (!(readl(ARMADA_37XX_SPI_CTRL) & 0x2)) udelay(1); @@ -89,7 +91,8 @@ int board_fix_fdt(void *blob) size = i; - writel(0x5b, ARMADA_37XX_SPI_CTRL); + /* disable SPI CS1 */ + clrbits_le32(ARMADA_37XX_SPI_CTRL, BIT(17)); if (size > 1 && (topology[1] == MOX_MODULE_PCI || topology[1] == MOX_MODULE_USB3 || -- cgit v1.1 From eddd6f90c99a19b3290590c0eb041f95002b4f4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Wed, 8 Apr 2020 12:02:04 +0200 Subject: arm: mvebu: dts: turris_mox: update sdhci properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With recent changes to the mmc subsystem (chip detect code etc) update the sdhci node of the Turris Mox device tree. Signed-off-by: Marek Behún Reviewed-by: Stefan Roese --- arch/arm/dts/armada-3720-turris-mox.dts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/arch/arm/dts/armada-3720-turris-mox.dts b/arch/arm/dts/armada-3720-turris-mox.dts index c36a5b8..4c65c3e 100644 --- a/arch/arm/dts/armada-3720-turris-mox.dts +++ b/arch/arm/dts/armada-3720-turris-mox.dts @@ -45,6 +45,20 @@ regulator-boot-on; }; + vsdc_reg: vsdc-reg { + compatible = "regulator-gpio"; + regulator-name = "vsdc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + + gpios = <&gpiosb 23 GPIO_ACTIVE_HIGH>; + gpios-states = <0>; + states = <1800000 0x1 + 3300000 0x0>; + enable-active-high; + }; + mdio { #address-cells = <1>; #size-cells = <0>; @@ -93,7 +107,11 @@ }; &sdhci1 { + wp-inverted; bus-width = <4>; + cd-gpios = <&gpionb 10 GPIO_ACTIVE_HIGH>; + vqmmc-supply = <&vsdc_reg>; + marvell,pad-type = "sd"; status = "okay"; }; -- cgit v1.1 From 2b3f2dd1ce90410d2edcd67bbef686c3361133c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Wed, 8 Apr 2020 12:02:05 +0200 Subject: arm: mvebu: turris_mox: Setup Linux's device tree before boot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch Linux's device tree according to which Mox modules are connected. Linux's device tree has all possible Mox module nodes preprogrammed, but in disabled state. If MOX B, MOX F or MOX G module is present, this code enables the PCI node. For the network modules (MOX C, MOX D and MOX E) are present, the code enables corresponding ethernet and swtich nodes and DSA connections. For the SFP cage the SFP GPIO controller node and SFP node are also enabled. Signed-off-by: Marek Behún Reviewed-by: Stefan Roese --- board/CZ.NIC/turris_mox/turris_mox.c | 295 ++++++++++++++++++++++++++++++++--- configs/turris_mox_defconfig | 1 + 2 files changed, 278 insertions(+), 18 deletions(-) diff --git a/board/CZ.NIC/turris_mox/turris_mox.c b/board/CZ.NIC/turris_mox/turris_mox.c index 0b13d1d..6e93782 100644 --- a/board/CZ.NIC/turris_mox/turris_mox.c +++ b/board/CZ.NIC/turris_mox/turris_mox.c @@ -34,7 +34,11 @@ #define ARMADA_37XX_SPI_DOUT 0xd0010608 #define ARMADA_37XX_SPI_DIN 0xd001060c +#define ETH1_PATH "/soc/internal-regs@d0000000/ethernet@40000" +#define MDIO_PATH "/soc/internal-regs@d0000000/mdio@32004" +#define SFP_GPIO_PATH "/soc/internal-regs@d0000000/spi@10600/moxtet@1/gpio@0" #define PCIE_PATH "/soc/pcie@d0070000" +#define SFP_PATH "/sfp" DECLARE_GLOBAL_DATA_PTR; @@ -459,24 +463,22 @@ int last_stage_init(void) } break; case MOX_MODULE_PCI: - if (pci) { + if (pci) printf("Error: Only one Mini-PCIe module is supported!\n"); - } else if (usb) { + else if (usb) printf("Error: Mini-PCIe module cannot come after USB 3.0 module!\n"); - } else if (i && (i != 1 || !passpci)) { + else if (i && (i != 1 || !passpci)) printf("Error: Mini-PCIe module should be the first connected module or come right after Passthrough Mini-PCIe module!\n"); - } else { + else ++pci; - } break; case MOX_MODULE_TOPAZ: - if (topaz) { + if (topaz) printf("Error: Only one Topaz module is supported!\n"); - } else if (peridot >= 3) { + else if (peridot >= 3) printf("Error: At most two Peridot modules can come before Topaz module!\n"); - } else { + else ++topaz; - } break; case MOX_MODULE_PERIDOT: if (sfp || topaz) { @@ -489,24 +491,22 @@ int last_stage_init(void) } break; case MOX_MODULE_USB3: - if (pci) { + if (pci) printf("Error: USB 3.0 module cannot come after Mini-PCIe module!\n"); - } else if (usb) { + else if (usb) printf("Error: Only one USB 3.0 module is supported!\n"); - } else if (i && (i != 1 || !passpci)) { + else if (i && (i != 1 || !passpci)) printf("Error: USB 3.0 module should be the first connected module or come right after Passthrough Mini-PCIe module!\n"); - } else { + else ++usb; - } break; case MOX_MODULE_PASSPCI: - if (passpci) { + if (passpci) printf("Error: Only one Passthrough Mini-PCIe module is supported!\n"); - } else if (i != 0) { + else if (i != 0) printf("Error: Passthrough Mini-PCIe module should be the first connected module!\n"); - } else { + else ++passpci; - } } } @@ -551,3 +551,262 @@ int last_stage_init(void) return 0; } + +#if defined(CONFIG_OF_BOARD_SETUP) + +static int vnode_by_path(void *blob, const char *fmt, va_list ap) +{ + char path[128]; + + vsnprintf(path, 128, fmt, ap); + return fdt_path_offset(blob, path); +} + +static int node_by_path(void *blob, const char *fmt, ...) +{ + va_list ap; + int res; + + va_start(ap, fmt); + res = vnode_by_path(blob, fmt, ap); + va_end(ap); + + return res; +} + +static int phandle_by_path(void *blob, const char *fmt, ...) +{ + va_list ap; + int node, phandle, res; + + va_start(ap, fmt); + node = vnode_by_path(blob, fmt, ap); + va_end(ap); + + if (node < 0) + return node; + + phandle = fdt_get_phandle(blob, node); + if (phandle > 0) + return phandle; + + phandle = fdt_get_max_phandle(blob); + if (phandle < 0) + return phandle; + + phandle += 1; + + res = fdt_setprop_u32(blob, node, "linux,phandle", phandle); + if (res < 0) + return res; + + res = fdt_setprop_u32(blob, node, "phandle", phandle); + if (res < 0) + return res; + + return phandle; +} + +static int enable_by_path(void *blob, const char *fmt, ...) +{ + va_list ap; + int node; + + va_start(ap, fmt); + node = vnode_by_path(blob, fmt, ap); + va_end(ap); + + if (node < 0) + return node; + + return fdt_setprop_string(blob, node, "status", "okay"); +} + +static bool is_topaz(int id) +{ + return topaz && id == peridot + topaz - 1; +} + +static int switch_addr(int id) +{ + return is_topaz(id) ? 0x2 : 0x10 + id; +} + +static int setup_switch(void *blob, int id) +{ + int res, addr, i, node, phandle; + + addr = switch_addr(id); + + /* first enable the switch by setting status = "okay" */ + res = enable_by_path(blob, MDIO_PATH "/switch%i@%x", id, addr); + if (res < 0) + return res; + + /* + * now if there are more switches or a SFP module coming after, + * enable corresponding ports + */ + if (id < peridot + topaz - 1) { + res = enable_by_path(blob, + MDIO_PATH "/switch%i@%x/ports/port@a", + id, addr); + } else if (id == peridot - 1 && !topaz && sfp) { + res = enable_by_path(blob, + MDIO_PATH "/switch%i@%x/ports/port-sfp@a", + id, addr); + } else { + res = 0; + } + if (res < 0) + return res; + + if (id >= peridot + topaz - 1) + return 0; + + /* finally change link property if needed */ + node = node_by_path(blob, MDIO_PATH "/switch%i@%x/ports/port@a", id, + addr); + if (node < 0) + return node; + + for (i = id + 1; i < peridot + topaz; ++i) { + phandle = phandle_by_path(blob, + MDIO_PATH "/switch%i@%x/ports/port@%x", + i, switch_addr(i), + is_topaz(i) ? 5 : 9); + if (phandle < 0) + return phandle; + + if (i == id + 1) + res = fdt_setprop_u32(blob, node, "link", phandle); + else + res = fdt_appendprop_u32(blob, node, "link", phandle); + if (res < 0) + return res; + } + + return 0; +} + +static int remove_disabled_nodes(void *blob) +{ + while (1) { + int res, offset; + + offset = fdt_node_offset_by_prop_value(blob, -1, "status", + "disabled", 9); + if (offset < 0) + break; + + res = fdt_del_node(blob, offset); + if (res < 0) + return res; + } + + return 0; +} + +int ft_board_setup(void *blob, bd_t *bd) +{ + int node, phandle, res; + + /* + * If MOX B (PCI), MOX F (USB) or MOX G (Passthrough PCI) modules are + * connected, enable the PCIe node. + */ + if (pci || usb || passpci) { + node = fdt_path_offset(blob, PCIE_PATH); + if (node < 0) + return node; + + res = fdt_setprop_string(blob, node, "status", "okay"); + if (res < 0) + return res; + } + + /* + * If MOX C (Topaz switch) and/or MOX E (Peridot switch) are connected, + * enable the eth1 node and setup the switches. + */ + if (peridot || topaz) { + int i; + + res = enable_by_path(blob, ETH1_PATH); + if (res < 0) + return res; + + for (i = 0; i < peridot + topaz; ++i) { + res = setup_switch(blob, i); + if (res < 0) + return res; + } + } + + /* + * If MOX D (SFP cage module) is connected, enable the SFP node and eth1 + * node. If there is no Peridot switch between MOX A and MOX D, add link + * to the SFP node to eth1 node. + * Also enable and configure SFP GPIO controller node. + */ + if (sfp) { + res = enable_by_path(blob, SFP_PATH); + if (res < 0) + return res; + + res = enable_by_path(blob, ETH1_PATH); + if (res < 0) + return res; + + if (!peridot) { + phandle = phandle_by_path(blob, SFP_PATH); + if (phandle < 0) + return res; + + node = node_by_path(blob, ETH1_PATH); + if (node < 0) + return node; + + res = fdt_setprop_u32(blob, node, "sfp", phandle); + if (res < 0) + return res; + + res = fdt_setprop_string(blob, node, "phy-mode", + "sgmii"); + if (res < 0) + return res; + } + + res = enable_by_path(blob, SFP_GPIO_PATH); + if (res < 0) + return res; + + if (sfp_pos) { + char newname[16]; + + /* moxtet-sfp is on non-zero position, change default */ + node = node_by_path(blob, SFP_GPIO_PATH); + if (node < 0) + return node; + + res = fdt_setprop_u32(blob, node, "reg", sfp_pos); + if (res < 0) + return res; + + sprintf(newname, "gpio@%x", sfp_pos); + + res = fdt_set_name(blob, node, newname); + if (res < 0) + return res; + } + } + + fdt_fixup_ethernet(blob); + + /* Finally remove disabled nodes, as per Rob Herring's request. */ + remove_disabled_nodes(blob); + + return 0; +} + +#endif diff --git a/configs/turris_mox_defconfig b/configs/turris_mox_defconfig index 2e63704..3bc69cd 100644 --- a/configs/turris_mox_defconfig +++ b/configs/turris_mox_defconfig @@ -37,6 +37,7 @@ CONFIG_CMD_BTRFS=y CONFIG_CMD_EXT4_WRITE=y CONFIG_MAC_PARTITION=y CONFIG_OF_BOARD_FIXUP=y +CONFIG_OF_BOARD_SETUP=y CONFIG_DEFAULT_DEVICE_TREE="armada-3720-turris-mox" CONFIG_ENV_IS_IN_SPI_FLASH=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y -- cgit v1.1 From 9e4cdbabac1b38da30838701dca9f70935c7e095 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Wed, 8 Apr 2020 12:02:06 +0200 Subject: arm: mvebu: dts: turris_mox: fix USB3 regulator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit e8e9715df2d4 requires the USB3 regulator node to have the enable-active-high property for the regulator to work properly. The GPIO_ACTIVE_HIGH constant is not enough anymore. Signed-off-by: Marek Behún Fixes: e8e9715df2d4 ("regulator: fixed: Modify enable-active-high...") Reviewed-by: Stefan Roese --- arch/arm/dts/armada-3720-turris-mox.dts | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/dts/armada-3720-turris-mox.dts b/arch/arm/dts/armada-3720-turris-mox.dts index 4c65c3e..a1e0ad5 100644 --- a/arch/arm/dts/armada-3720-turris-mox.dts +++ b/arch/arm/dts/armada-3720-turris-mox.dts @@ -42,6 +42,7 @@ startup-delay-us = <2000000>; shutdown-delay-us = <1000000>; gpio = <&gpiosb 0 GPIO_ACTIVE_HIGH>; + enable-active-high; regulator-boot-on; }; -- cgit v1.1 From 9657841010cae49b1f903adf198ec334cfc92f11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Wed, 8 Apr 2020 12:02:07 +0200 Subject: arm: mvebu: turris_mox: don't use hardcoded addresses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use macro MVEBU_REGISTER to access register addresses instead of hardcoded addresses. Signed-off-by: Marek Behún Reviewed-by: Stefan Roese --- board/CZ.NIC/turris_mox/mox_sp.c | 14 ++++++++------ board/CZ.NIC/turris_mox/turris_mox.c | 11 ++++++----- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/board/CZ.NIC/turris_mox/mox_sp.c b/board/CZ.NIC/turris_mox/mox_sp.c index 0b29ffc..3c23471 100644 --- a/board/CZ.NIC/turris_mox/mox_sp.c +++ b/board/CZ.NIC/turris_mox/mox_sp.c @@ -4,15 +4,17 @@ */ #include +#include #include -#define RWTM_CMD_PARAM(i) (size_t)(0xd00b0000 + (i) * 4) -#define RWTM_CMD 0xd00b0040 -#define RWTM_CMD_RETSTATUS 0xd00b0080 -#define RWTM_CMD_STATUS(i) (size_t)(0xd00b0084 + (i) * 4) +#define RWTM_BASE (MVEBU_REGISTER(0xb0000)) +#define RWTM_CMD_PARAM(i) (size_t)(RWTM_BASE + (i) * 4) +#define RWTM_CMD (RWTM_BASE + 0x40) +#define RWTM_CMD_RETSTATUS (RWTM_BASE + 0x80) +#define RWTM_CMD_STATUS(i) (size_t)(RWTM_BASE + 0x84 + (i) * 4) -#define RWTM_HOST_INT_RESET 0xd00b00c8 -#define RWTM_HOST_INT_MASK 0xd00b00cc +#define RWTM_HOST_INT_RESET (RWTM_BASE + 0xc8) +#define RWTM_HOST_INT_MASK (RWTM_BASE + 0xcc) #define SP_CMD_COMPLETE BIT(0) #define MBOX_STS_SUCCESS (0x0 << 30) diff --git a/board/CZ.NIC/turris_mox/turris_mox.c b/board/CZ.NIC/turris_mox/turris_mox.c index 6e93782..cd39b1c 100644 --- a/board/CZ.NIC/turris_mox/turris_mox.c +++ b/board/CZ.NIC/turris_mox/turris_mox.c @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -28,11 +29,11 @@ #define MOX_MODULE_USB3 0x5 #define MOX_MODULE_PASSPCI 0x6 -#define ARMADA_37XX_NB_GPIO_SEL 0xd0013830 -#define ARMADA_37XX_SPI_CTRL 0xd0010600 -#define ARMADA_37XX_SPI_CFG 0xd0010604 -#define ARMADA_37XX_SPI_DOUT 0xd0010608 -#define ARMADA_37XX_SPI_DIN 0xd001060c +#define ARMADA_37XX_NB_GPIO_SEL (MVEBU_REGISTER(0x13830)) +#define ARMADA_37XX_SPI_CTRL (MVEBU_REGISTER(0x10600)) +#define ARMADA_37XX_SPI_CFG (MVEBU_REGISTER(0x10604)) +#define ARMADA_37XX_SPI_DOUT (MVEBU_REGISTER(0x10608)) +#define ARMADA_37XX_SPI_DIN (MVEBU_REGISTER(0x1060c)) #define ETH1_PATH "/soc/internal-regs@d0000000/ethernet@40000" #define MDIO_PATH "/soc/internal-regs@d0000000/mdio@32004" -- cgit v1.1 From c8a185a823d7aa8fc02df0c064d47e5713eaebc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Wed, 8 Apr 2020 12:02:08 +0200 Subject: arm: mvebu: turris_mox: sort headers alphabetically MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sort #includes alphabetically, the only exception is common.h, which is included first in most parts of U-Boot. Signed-off-by: Marek Behún Reviewed-by: Stefan Roese --- board/CZ.NIC/turris_mox/turris_mox.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/board/CZ.NIC/turris_mox/turris_mox.c b/board/CZ.NIC/turris_mox/turris_mox.c index cd39b1c..5bb53b1 100644 --- a/board/CZ.NIC/turris_mox/turris_mox.c +++ b/board/CZ.NIC/turris_mox/turris_mox.c @@ -4,19 +4,19 @@ */ #include -#include #include -#include #include -#include +#include #include +#include #include -#include -#include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include #include "mox_sp.h" -- cgit v1.1 From f075b425a72c095a1e11ff855c3ba8b060feec20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Wed, 8 Apr 2020 19:25:18 +0200 Subject: arm64: mvebu: armada-8k: move dram init code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move Armada-8k specific DRAM init code into armada-8k specific directory. Signed-off-by: Marek Behún Reviewed-by: Stefan Roese --- arch/arm/mach-mvebu/arm64-common.c | 46 ++---------------------------- arch/arm/mach-mvebu/armada8k/Makefile | 3 +- arch/arm/mach-mvebu/armada8k/dram.c | 52 ++++++++++++++++++++++++++++++++++ arch/arm/mach-mvebu/include/mach/cpu.h | 4 +++ 4 files changed, 59 insertions(+), 46 deletions(-) create mode 100644 arch/arm/mach-mvebu/armada8k/dram.c diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c index 40b98db..244ea49 100644 --- a/arch/arm/mach-mvebu/arm64-common.c +++ b/arch/arm/mach-mvebu/arm64-common.c @@ -45,54 +45,12 @@ const struct mbus_dram_target_info *mvebu_mbus_dram_info(void) return NULL; } -/* DRAM init code ... */ - -#define MV_SIP_DRAM_SIZE 0x82000010 - -static u64 a8k_dram_scan_ap_sz(void) -{ - struct pt_regs pregs; - - pregs.regs[0] = MV_SIP_DRAM_SIZE; - pregs.regs[1] = SOC_REGS_PHY_BASE; - smc_call(&pregs); - - return pregs.regs[0]; -} - -static void a8k_dram_init_banksize(void) -{ - /* - * The firmware (ATF) leaves a 1G whole above the 3G mark for IO - * devices. Higher RAM is mapped at 4G. - * - * Config 2 DRAM banks: - * Bank 0 - max size 4G - 1G - * Bank 1 - ram size - 4G + 1G - */ - phys_size_t max_bank0_size = SZ_4G - SZ_1G; - - gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; - if (gd->ram_size <= max_bank0_size) { - gd->bd->bi_dram[0].size = gd->ram_size; - return; - } - - gd->bd->bi_dram[0].size = max_bank0_size; - if (CONFIG_NR_DRAM_BANKS > 1) { - gd->bd->bi_dram[1].start = SZ_4G; - gd->bd->bi_dram[1].size = gd->ram_size - max_bank0_size; - } -} - __weak int dram_init_banksize(void) { if (CONFIG_IS_ENABLED(ARMADA_8K)) - a8k_dram_init_banksize(); + return a8k_dram_init_banksize(); else - fdtdec_setup_memory_banksize(); - - return 0; + return fdtdec_setup_memory_banksize(); } __weak int dram_init(void) diff --git a/arch/arm/mach-mvebu/armada8k/Makefile b/arch/arm/mach-mvebu/armada8k/Makefile index 82cb25b..0a47567 100644 --- a/arch/arm/mach-mvebu/armada8k/Makefile +++ b/arch/arm/mach-mvebu/armada8k/Makefile @@ -2,5 +2,4 @@ # # Copyright (C) 2016 Stefan Roese -obj-y = cpu.o -obj-y += cache_llc.o +obj-y = cpu.o cache_llc.o dram.o diff --git a/arch/arm/mach-mvebu/armada8k/dram.c b/arch/arm/mach-mvebu/armada8k/dram.c new file mode 100644 index 0000000..265a8b0 --- /dev/null +++ b/arch/arm/mach-mvebu/armada8k/dram.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2016 Stefan Roese + */ + +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define MV_SIP_DRAM_SIZE 0x82000010 + +u64 a8k_dram_scan_ap_sz(void) +{ + struct pt_regs pregs; + + pregs.regs[0] = MV_SIP_DRAM_SIZE; + pregs.regs[1] = SOC_REGS_PHY_BASE; + smc_call(&pregs); + + return pregs.regs[0]; +} + +int a8k_dram_init_banksize(void) +{ + /* + * The firmware (ATF) leaves a 1G whole above the 3G mark for IO + * devices. Higher RAM is mapped at 4G. + * + * Config 2 DRAM banks: + * Bank 0 - max size 4G - 1G + * Bank 1 - ram size - 4G + 1G + */ + phys_size_t max_bank0_size = SZ_4G - SZ_1G; + + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + if (gd->ram_size <= max_bank0_size) { + gd->bd->bi_dram[0].size = gd->ram_size; + return 0; + } + + gd->bd->bi_dram[0].size = max_bank0_size; + if (CONFIG_NR_DRAM_BANKS > 1) { + gd->bd->bi_dram[1].start = SZ_4G; + gd->bd->bi_dram[1].size = gd->ram_size - max_bank0_size; + } + + return 0; +} diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h index fa7c817..16d8252 100644 --- a/arch/arm/mach-mvebu/include/mach/cpu.h +++ b/arch/arm/mach-mvebu/include/mach/cpu.h @@ -172,6 +172,10 @@ static inline void mv_avs_init(void) {} static inline void mv_rtc_config(void) {} #endif +/* A8K dram functions */ +u64 a8k_dram_scan_ap_sz(void); +int a8k_dram_init_banksize(void); + /* * get_ref_clk * -- cgit v1.1 From a129f64fb0f817178955e234c0a4f8b415b38759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Wed, 8 Apr 2020 19:25:19 +0200 Subject: arm64: mvebu: a37xx: improve code determining memory info structures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently on Armada-37xx the mem_map structure is statically defined to map first 2 GB of memory as RAM region, and system registers and PCIe region device region. This is insufficient for when there is more RAM or when for example the PCIe windows is mapped to another address by the CPU Address Decoder. In the case when the board has 4 GB RAM, on some boards the ARM Trusted Firmware can move the PCIe window to another address, in order to maximize possible usable RAM. Also the dram_init and dram_init_banksize looks for information in device-tree, and therefore different device trees are needed for boards with different RAM sizes. Therefore we add code that looks at how the ARM Trusted Firmware has configured the CPU Address Decoder windows, and then we update the mem_map structure and compute gd->ram_size and gd->bd->bi_dram bank base addresses and sizes accordingly. Signed-off-by: Marek Behún Reviewed-by: Stefan Roese --- arch/arm/mach-mvebu/arm64-common.c | 5 + arch/arm/mach-mvebu/armada3700/cpu.c | 252 +++++++++++++++++++++++++++++---- arch/arm/mach-mvebu/include/mach/cpu.h | 4 + 3 files changed, 235 insertions(+), 26 deletions(-) diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c index 244ea49..34cc047 100644 --- a/arch/arm/mach-mvebu/arm64-common.c +++ b/arch/arm/mach-mvebu/arm64-common.c @@ -49,6 +49,8 @@ __weak int dram_init_banksize(void) { if (CONFIG_IS_ENABLED(ARMADA_8K)) return a8k_dram_init_banksize(); + else if (CONFIG_IS_ENABLED(ARMADA_3700)) + return a3700_dram_init_banksize(); else return fdtdec_setup_memory_banksize(); } @@ -61,6 +63,9 @@ __weak int dram_init(void) return 0; } + if (CONFIG_IS_ENABLED(ARMADA_3700)) + return a3700_dram_init(); + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; diff --git a/arch/arm/mach-mvebu/armada3700/cpu.c b/arch/arm/mach-mvebu/armada3700/cpu.c index c832681..959a909 100644 --- a/arch/arm/mach-mvebu/armada3700/cpu.c +++ b/arch/arm/mach-mvebu/armada3700/cpu.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2016 Stefan Roese + * Copyright (C) 2020 Marek Behun */ #include @@ -13,6 +14,7 @@ #include #include #include +#include /* Armada 3700 */ #define MVEBU_GPIO_NB_REG_BASE (MVEBU_REGISTER(0x13800)) @@ -26,39 +28,237 @@ #define MVEBU_NB_WARM_RST_REG (MVEBU_GPIO_NB_REG_BASE + 0x40) #define MVEBU_NB_WARM_RST_MAGIC_NUM 0x1d1e -static struct mm_region mvebu_mem_map[] = { - { - /* RAM */ - .phys = 0x0UL, - .virt = 0x0UL, - .size = 0x80000000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | - PTE_BLOCK_INNER_SHARE - }, +/* Armada 3700 CPU Address Decoder registers */ +#define MVEBU_CPU_DEC_WIN_REG_BASE (size_t)(MVEBU_REGISTER(0xcf00)) +#define MVEBU_CPU_DEC_WIN_CTRL(w) \ + (MVEBU_CPU_DEC_WIN_REG_BASE + ((w) << 4)) +#define MVEBU_CPU_DEC_WIN_CTRL_EN BIT(0) +#define MVEBU_CPU_DEC_WIN_CTRL_TGT_MASK 0xf +#define MVEBU_CPU_DEC_WIN_CTRL_TGT_OFFS 4 +#define MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM 0 +#define MVEBU_CPU_DEC_WIN_CTRL_TGT_PCIE 2 +#define MVEBU_CPU_DEC_WIN_SIZE(w) (MVEBU_CPU_DEC_WIN_CTRL(w) + 0x4) +#define MVEBU_CPU_DEC_WIN_BASE(w) (MVEBU_CPU_DEC_WIN_CTRL(w) + 0x8) +#define MVEBU_CPU_DEC_WIN_REMAP(w) (MVEBU_CPU_DEC_WIN_CTRL(w) + 0xc) +#define MVEBU_CPU_DEC_WIN_GRANULARITY 16 +#define MVEBU_CPU_DEC_WINS 5 + +#define MAX_MEM_MAP_REGIONS (MVEBU_CPU_DEC_WINS + 2) + +#define A3700_PTE_BLOCK_NORMAL \ + (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE) +#define A3700_PTE_BLOCK_DEVICE \ + (PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE) + +DECLARE_GLOBAL_DATA_PTR; + +static struct mm_region mvebu_mem_map[MAX_MEM_MAP_REGIONS] = { { - /* SRAM, MMIO regions */ - .phys = 0xd0000000UL, - .virt = 0xd0000000UL, + /* + * SRAM, MMIO regions + * Don't remove this, a3700_build_mem_map needs it. + */ + .phys = SOC_REGS_PHY_BASE, + .virt = SOC_REGS_PHY_BASE, .size = 0x02000000UL, /* 32MiB internal registers */ - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE - }, - { - /* PCI regions */ - .phys = 0xe8000000UL, - .virt = 0xe8000000UL, - .size = 0x02000000UL, /* 32MiB master PCI space */ - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE + .attrs = A3700_PTE_BLOCK_DEVICE }, - { - /* List terminator */ - 0, - } }; struct mm_region *mem_map = mvebu_mem_map; +static int get_cpu_dec_win(int win, u32 *tgt, u32 *base, u32 *size) +{ + u32 reg; + + reg = readl(MVEBU_CPU_DEC_WIN_CTRL(win)); + if (!(reg & MVEBU_CPU_DEC_WIN_CTRL_EN)) + return -1; + + if (tgt) { + reg >>= MVEBU_CPU_DEC_WIN_CTRL_TGT_OFFS; + reg &= MVEBU_CPU_DEC_WIN_CTRL_TGT_MASK; + *tgt = reg; + } + + if (base) { + reg = readl(MVEBU_CPU_DEC_WIN_BASE(win)); + *base = reg << MVEBU_CPU_DEC_WIN_GRANULARITY; + } + + if (size) { + /* + * Window size is encoded as the number of 1s from LSB to MSB, + * followed by 0s. The number of 1s specifies the size in 64 KiB + * granularity. + */ + reg = readl(MVEBU_CPU_DEC_WIN_SIZE(win)); + *size = ((reg + 1) << MVEBU_CPU_DEC_WIN_GRANULARITY); + } + + return 0; +} + +/* + * Builds mem_map according to CPU Address Decoder settings, which were set by + * the TIMH image on the Cortex-M3 secure processor, or by ARM Trusted Firmware + */ +static void build_mem_map(void) +{ + int win, region; + + region = 1; + for (win = 0; win < MVEBU_CPU_DEC_WINS; ++win) { + u32 base, tgt, size; + u64 attrs; + + /* skip disabled windows */ + if (get_cpu_dec_win(win, &tgt, &base, &size)) + continue; + + if (tgt == MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM) + attrs = A3700_PTE_BLOCK_NORMAL; + else if (tgt == MVEBU_CPU_DEC_WIN_CTRL_TGT_PCIE) + attrs = A3700_PTE_BLOCK_DEVICE; + else + /* skip windows with other targets */ + continue; + + mvebu_mem_map[region].phys = base; + mvebu_mem_map[region].virt = base; + mvebu_mem_map[region].size = size; + mvebu_mem_map[region].attrs = attrs; + ++region; + } + + /* add list terminator */ + mvebu_mem_map[region].size = 0; + mvebu_mem_map[region].attrs = 0; +} + +void enable_caches(void) +{ + build_mem_map(); + + icache_enable(); + dcache_enable(); +} + +int a3700_dram_init(void) +{ + int win; + + gd->ram_size = 0; + for (win = 0; win < MVEBU_CPU_DEC_WINS; ++win) { + u32 base, tgt, size; + + /* skip disabled windows */ + if (get_cpu_dec_win(win, &tgt, &base, &size)) + continue; + + /* skip non-DRAM windows */ + if (tgt != MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM) + continue; + + /* + * It is possible that one image was built for boards with + * different RAM sizes, for example 512 MiB and 1 GiB. + * We therefore try to determine the actual RAM size in the + * window with get_ram_size. + */ + gd->ram_size += get_ram_size((void *)(size_t)base, size); + } + + return 0; +} + +struct a3700_dram_window { + size_t base, size; +}; + +static int dram_win_cmp(const void *a, const void *b) +{ + size_t ab, bb; + + ab = ((const struct a3700_dram_window *)a)->base; + bb = ((const struct a3700_dram_window *)b)->base; + + if (ab < bb) + return -1; + else if (ab > bb) + return 1; + else + return 0; +} + +int a3700_dram_init_banksize(void) +{ + struct a3700_dram_window dram_wins[MVEBU_CPU_DEC_WINS]; + int bank, win, ndram_wins; + u32 last_end; + size_t size; + + ndram_wins = 0; + for (win = 0; win < MVEBU_CPU_DEC_WINS; ++win) { + u32 base, tgt, size; + + /* skip disabled windows */ + if (get_cpu_dec_win(win, &tgt, &base, &size)) + continue; + + /* skip non-DRAM windows */ + if (tgt != MVEBU_CPU_DEC_WIN_CTRL_TGT_DRAM) + continue; + + dram_wins[win].base = base; + dram_wins[win].size = size; + ++ndram_wins; + } + + qsort(dram_wins, ndram_wins, sizeof(dram_wins[0]), dram_win_cmp); + + bank = 0; + last_end = -1; + + for (win = 0; win < ndram_wins; ++win) { + /* again determining actual RAM size as in a3700_dram_init */ + size = get_ram_size((void *)dram_wins[win].base, + dram_wins[win].size); + + /* + * Check if previous window ends as the current starts. If yes, + * merge these windows into one "bank". This is possible by this + * simple check thanks to mem_map regions being qsorted in + * build_mem_map. + */ + if (last_end == dram_wins[win].base) { + gd->bd->bi_dram[bank - 1].size += size; + last_end += size; + } else { + if (bank == CONFIG_NR_DRAM_BANKS) { + printf("Need more CONFIG_NR_DRAM_BANKS\n"); + return -ENOBUFS; + } + + gd->bd->bi_dram[bank].start = dram_wins[win].base; + gd->bd->bi_dram[bank].size = size; + last_end = dram_wins[win].base + size; + ++bank; + } + } + + /* + * If there is more place for DRAM BANKS definitions than needed, fill + * the rest with zeros. + */ + for (; bank < CONFIG_NR_DRAM_BANKS; ++bank) { + gd->bd->bi_dram[bank].start = 0; + gd->bd->bi_dram[bank].size = 0; + } + + return 0; +} + void reset_cpu(ulong ignored) { /* diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h index 16d8252..3bb541b 100644 --- a/arch/arm/mach-mvebu/include/mach/cpu.h +++ b/arch/arm/mach-mvebu/include/mach/cpu.h @@ -176,6 +176,10 @@ static inline void mv_rtc_config(void) {} u64 a8k_dram_scan_ap_sz(void); int a8k_dram_init_banksize(void); +/* A3700 dram functions */ +int a3700_dram_init(void); +int a3700_dram_init_banksize(void); + /* * get_ref_clk * -- cgit v1.1 From 4e9eb04c8d258521f2ec80ad857179f5e362f7fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Wed, 8 Apr 2020 19:25:20 +0200 Subject: arm: mvebu: turris_mox: support devices with RAM > 1 GB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to support MOX boards with 2 GB or 4 GB RAM, we use the new Armada-3700 generic code for memory information structures. This is done by removing dram_init and dram_init_banksize from turris_mox.c, in order for the generic, weak definitions to be used. Also for boards with 4 GB RAM it is needed to increase CONFIG_NR_DRAM_BANKS to 2 in turris_mox_defconfig. Signed-off-by: Marek Behún Reviewed-by: Stefan Roese --- board/CZ.NIC/turris_mox/turris_mox.c | 16 ---------------- configs/turris_mox_defconfig | 2 +- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/board/CZ.NIC/turris_mox/turris_mox.c b/board/CZ.NIC/turris_mox/turris_mox.c index 5bb53b1..8e4c023 100644 --- a/board/CZ.NIC/turris_mox/turris_mox.c +++ b/board/CZ.NIC/turris_mox/turris_mox.c @@ -43,22 +43,6 @@ DECLARE_GLOBAL_DATA_PTR; -int dram_init(void) -{ - gd->ram_base = 0; - gd->ram_size = (phys_size_t)get_ram_size(0, 0x40000000); - - return 0; -} - -int dram_init_banksize(void) -{ - gd->bd->bi_dram[0].start = (phys_addr_t)0; - gd->bd->bi_dram[0].size = gd->ram_size; - - return 0; -} - #if defined(CONFIG_OF_BOARD_FIXUP) int board_fix_fdt(void *blob) { diff --git a/configs/turris_mox_defconfig b/configs/turris_mox_defconfig index 3bc69cd..d786255 100644 --- a/configs/turris_mox_defconfig +++ b/configs/turris_mox_defconfig @@ -8,7 +8,7 @@ CONFIG_ENV_SIZE=0x10000 CONFIG_ENV_SECT_SIZE=0x10000 CONFIG_ENV_OFFSET=0x180000 CONFIG_DM_GPIO=y -CONFIG_NR_DRAM_BANKS=1 +CONFIG_NR_DRAM_BANKS=2 CONFIG_DEBUG_UART_BASE=0xd0012000 CONFIG_DEBUG_UART_CLOCK=25804800 CONFIG_DEBUG_UART=y -- cgit v1.1 From cb2ddb291ee6fcbddd6d8f4ff49089dfe580f5d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Wed, 8 Apr 2020 19:25:21 +0200 Subject: arm64: mvebu: a37xx: add device-tree fixer for PCIe regions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In case when ARM Trusted Firmware changes the default address of PCIe regions (which can be done for devices with 4 GB RAM to maximize the amount of RAM the device can use) we add code that looks at how ATF changed the PCIe windows in the CPU Address Decoder and changes given device-tree blob accordingly. Signed-off-by: Marek Behún Reviewed-by: Stefan Roese --- arch/arm/mach-mvebu/armada3700/cpu.c | 52 ++++++++++++++++++++++++++++++++++ arch/arm/mach-mvebu/include/mach/cpu.h | 3 ++ 2 files changed, 55 insertions(+) diff --git a/arch/arm/mach-mvebu/armada3700/cpu.c b/arch/arm/mach-mvebu/armada3700/cpu.c index 959a909..17d2d43 100644 --- a/arch/arm/mach-mvebu/armada3700/cpu.c +++ b/arch/arm/mach-mvebu/armada3700/cpu.c @@ -50,6 +50,8 @@ #define A3700_PTE_BLOCK_DEVICE \ (PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE) +#define PCIE_PATH "/soc/pcie@d0070000" + DECLARE_GLOBAL_DATA_PTR; static struct mm_region mvebu_mem_map[MAX_MEM_MAP_REGIONS] = { @@ -259,6 +261,56 @@ int a3700_dram_init_banksize(void) return 0; } +static u32 find_pcie_window_base(void) +{ + int win; + + for (win = 0; win < MVEBU_CPU_DEC_WINS; ++win) { + u32 base, tgt; + + /* skip disabled windows */ + if (get_cpu_dec_win(win, &tgt, &base, NULL)) + continue; + + if (tgt == MVEBU_CPU_DEC_WIN_CTRL_TGT_PCIE) + return base; + } + + return -1; +} + +int a3700_fdt_fix_pcie_regions(void *blob) +{ + u32 new_ranges[14], base; + const u32 *ranges; + int node, len; + + node = fdt_path_offset(blob, PCIE_PATH); + if (node < 0) + return node; + + ranges = fdt_getprop(blob, node, "ranges", &len); + if (!ranges) + return -ENOENT; + + if (len != sizeof(new_ranges)) + return -EINVAL; + + memcpy(new_ranges, ranges, len); + + base = find_pcie_window_base(); + if (base == -1) + return -ENOENT; + + new_ranges[2] = cpu_to_fdt32(base); + new_ranges[4] = new_ranges[2]; + + new_ranges[9] = cpu_to_fdt32(base + 0x1000000); + new_ranges[11] = new_ranges[9]; + + return fdt_setprop_inplace(blob, node, "ranges", new_ranges, len); +} + void reset_cpu(ulong ignored) { /* diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h index 3bb541b..c3f8ad8 100644 --- a/arch/arm/mach-mvebu/include/mach/cpu.h +++ b/arch/arm/mach-mvebu/include/mach/cpu.h @@ -180,6 +180,9 @@ int a8k_dram_init_banksize(void); int a3700_dram_init(void); int a3700_dram_init_banksize(void); +/* A3700 PCIe regions fixer for device tree */ +int a3700_fdt_fix_pcie_regions(void *blob); + /* * get_ref_clk * -- cgit v1.1 From c64ac3b3185aeb3846297ad7391fc6df8ecd73bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Beh=C3=BAn?= Date: Wed, 8 Apr 2020 19:25:22 +0200 Subject: arm: mvebu: turris_mox: fix PCIe ranges in device tree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use the new a3700_fdt_fix_pcie_regions function in turris_mox.c so that MOX boards with 4 GB RAM are fully supported. Signed-off-by: Marek Behún Reviewed-by: Stefan Roese --- board/CZ.NIC/turris_mox/turris_mox.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/board/CZ.NIC/turris_mox/turris_mox.c b/board/CZ.NIC/turris_mox/turris_mox.c index 8e4c023..470ea32 100644 --- a/board/CZ.NIC/turris_mox/turris_mox.c +++ b/board/CZ.NIC/turris_mox/turris_mox.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -104,6 +105,11 @@ int board_fix_fdt(void *blob) return 0; } + if (a3700_fdt_fix_pcie_regions(blob) < 0) { + printf("Cannot fix PCIe regions in U-Boot's device tree!\n"); + return 0; + } + return 0; } #endif @@ -708,6 +714,11 @@ int ft_board_setup(void *blob, bd_t *bd) res = fdt_setprop_string(blob, node, "status", "okay"); if (res < 0) return res; + + /* Fix PCIe regions for devices with 4 GB RAM */ + res = a3700_fdt_fix_pcie_regions(blob); + if (res < 0) + return res; } /* -- cgit v1.1