[PATCH] ARM: k3: add bootsource detection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Sascha Hauer <s.hauer@xxxxxxxxxxxxxx>
---
 arch/arm/dts/k3-am625.dtsi |   8 ++
 arch/arm/mach-k3/common.c  | 161 +++++++++++++++++++++++++++++++++++++
 include/mach/k3/common.h   |   6 ++
 3 files changed, 175 insertions(+)
 create mode 100644 include/mach/k3/common.h

diff --git a/arch/arm/dts/k3-am625.dtsi b/arch/arm/dts/k3-am625.dtsi
index 2b2d3e1b4d..7d49198aa2 100644
--- a/arch/arm/dts/k3-am625.dtsi
+++ b/arch/arm/dts/k3-am625.dtsi
@@ -1,4 +1,12 @@
 
+/ {
+	chosen {
+		barebox,bootsource-mmc0 = &sdhci0;
+		barebox,bootsource-mmc1 = &sdhci1;
+		barebox,bootsource-mmc2 = &sdhci2;
+	};
+};
+
 &phy_gmii_sel {
 	compatible = "ti,am654-phy-gmii-sel", "syscon";
 };
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index 7c2375d3ec..0da6f76ae4 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -1,8 +1,13 @@
 // SPDX-License-Identifier: GPL-2.0-only
 #include <of.h>
+#include <io.h>
 #include <deep-probe.h>
 #include <init.h>
 #include <pm_domain.h>
+#include <bootsource.h>
+#include <linux/bits.h>
+#include <linux/bitfield.h>
+#include <mach/k3/common.h>
 
 static const struct of_device_id k3_of_match[] = {
 	{
@@ -12,11 +17,167 @@ static const struct of_device_id k3_of_match[] = {
 };
 BAREBOX_DEEP_PROBE_ENABLE(k3_of_match);
 
+/* Primary BootMode devices */
+#define BOOT_DEVICE_RAM                 0x00
+#define BOOT_DEVICE_OSPI                0x01
+#define BOOT_DEVICE_QSPI                0x02
+#define BOOT_DEVICE_SPI                 0x03
+#define BOOT_DEVICE_CPGMAC              0x04
+#define BOOT_DEVICE_ETHERNET_RGMII      0x04
+#define BOOT_DEVICE_ETHERNET_RMII       0x05
+#define BOOT_DEVICE_I2C                 0x06
+#define BOOT_DEVICE_UART                0x07
+#define BOOT_DEVICE_MMC                 0x08
+#define BOOT_DEVICE_EMMC                0x09
+
+#define BOOT_DEVICE_USB                 0x2A
+#define BOOT_DEVICE_DFU                 0x0A
+#define BOOT_DEVICE_GPMC_NAND           0x0B
+#define BOOT_DEVICE_GPMC_NOR            0x0C
+#define BOOT_DEVICE_XSPI                0x0E
+#define BOOT_DEVICE_NOBOOT              0x0F
+
+/* Backup BootMode devices */
+#define BACKUP_BOOT_DEVICE_DFU          0x01
+#define BACKUP_BOOT_DEVICE_UART         0x03
+#define BACKUP_BOOT_DEVICE_ETHERNET     0x04
+#define BACKUP_BOOT_DEVICE_MMC          0x05
+#define BACKUP_BOOT_DEVICE_SPI          0x06
+#define BACKUP_BOOT_DEVICE_I2C          0x07
+#define BACKUP_BOOT_DEVICE_USB          0x09
+
+#define K3_PRIMARY_BOOTMODE             0x0
+
+#define MAIN_DEVSTAT_BACKUP_BOOTMODE		GENMASK(12, 10)
+#define MAIN_DEVSTAT_BACKUP_BOOTMODE_CFG	BIT(13)
+#define MAIN_DEVSTAT_BACKUP_USB_MODE		BIT(0)
+
+static void k3_get_backup_bootsource(u32 devstat, enum bootsource *src, int *instance)
+{
+	u32 bkup_bootmode = FIELD_GET(MAIN_DEVSTAT_BACKUP_BOOTMODE, devstat);
+	u32 bkup_bootmode_cfg = FIELD_GET(MAIN_DEVSTAT_BACKUP_BOOTMODE_CFG, devstat);
+
+	*src = BOOTSOURCE_UNKNOWN;
+
+	switch (bkup_bootmode) {
+	case BACKUP_BOOT_DEVICE_UART:
+		*src = BOOTSOURCE_SERIAL;
+		return;
+	case BACKUP_BOOT_DEVICE_USB:
+		*src = BOOTSOURCE_USB;
+		return;
+	case BACKUP_BOOT_DEVICE_ETHERNET:
+		*src = BOOTSOURCE_NET;
+		return;
+	case BACKUP_BOOT_DEVICE_MMC:
+		if (bkup_bootmode_cfg) {
+			*src = BOOTSOURCE_MMC;
+			*instance = 1;
+		} else {
+			*src = BOOTSOURCE_MMC;
+			*instance = 0;
+		}
+		return;
+	case BACKUP_BOOT_DEVICE_SPI:
+		*src = BOOTSOURCE_SPI;
+		return;
+	case BACKUP_BOOT_DEVICE_I2C:
+		*src = BOOTSOURCE_I2C;
+		return;
+	case BACKUP_BOOT_DEVICE_DFU:
+		if (bkup_bootmode_cfg & MAIN_DEVSTAT_BACKUP_USB_MODE)
+			*src = BOOTSOURCE_USB;
+		else
+			*src = BOOT_DEVICE_DFU;
+		return;
+	};
+}
+
+#define MAIN_DEVSTAT_PRIMARY_BOOTMODE		GENMASK(6, 3)
+#define MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG	GENMASK(9, 7)
+#define MAIN_DEVSTAT_PRIMARY_USB_MODE		BIT(1)
+#define MAIN_DEVSTAT_PRIMARY_MMC_PORT		BIT(2)
+
+static void k3_get_primary_bootsource(u32 devstat, enum bootsource *src, int *instance)
+{
+	u32 bootmode = FIELD_GET(MAIN_DEVSTAT_PRIMARY_BOOTMODE, devstat);
+	u32 bootmode_cfg = FIELD_GET(MAIN_DEVSTAT_PRIMARY_BOOTMODE_CFG, devstat);
+
+	switch (bootmode) {
+	case BOOT_DEVICE_OSPI:
+		fallthrough;
+	case BOOT_DEVICE_QSPI:
+		fallthrough;
+	case BOOT_DEVICE_XSPI:
+		fallthrough;
+	case BOOT_DEVICE_SPI:
+		*src = BOOTSOURCE_SPI;
+		return;
+	case BOOT_DEVICE_ETHERNET_RGMII:
+		fallthrough;
+	case BOOT_DEVICE_ETHERNET_RMII:
+		*src = BOOTSOURCE_NET;
+		return;
+	case BOOT_DEVICE_EMMC:
+		*src = BOOTSOURCE_MMC;
+		*instance = 0;
+		return;
+	case BOOT_DEVICE_MMC:
+		if (bootmode_cfg & MAIN_DEVSTAT_PRIMARY_MMC_PORT) {
+			*src = BOOTSOURCE_MMC;
+			*instance = 1;
+		} else {
+			*src = BOOTSOURCE_MMC;
+			*instance = 0;
+		}
+		return;
+	case BOOT_DEVICE_DFU:
+		if (bootmode_cfg & MAIN_DEVSTAT_PRIMARY_USB_MODE)
+			*src = BOOTSOURCE_USB;
+		else
+			*src = BOOT_DEVICE_DFU;
+		return;
+	case BOOT_DEVICE_NOBOOT:
+		*src = BOOTSOURCE_UNKNOWN;
+		return;
+	}
+}
+
+#define K3_BOOT_PARAM_TABLE_INDEX_OCRAM		0x7000F290
+
+static void k3_get_bootsource(u32 devstat, enum bootsource *src, int *instance)
+{
+	u32 bootmode = *(u32 *)(K3_BOOT_PARAM_TABLE_INDEX_OCRAM);
+
+	if (bootmode == K3_PRIMARY_BOOTMODE)
+		k3_get_primary_bootsource(devstat, src, instance);
+	else
+		k3_get_backup_bootsource(devstat, src, instance);
+}
+
+#define AM625_WKUP_CTRL_MMR0_BASE		0x43000000
+#define AM625_CTRLMMR_MAIN_DEVSTAT		(AM625_WKUP_CTRL_MMR0_BASE + 0x30)
+
+void am625_get_bootsource(enum bootsource *src, int *instance)
+{
+	u32 devstat;
+
+	devstat = readl(AM625_CTRLMMR_MAIN_DEVSTAT);
+
+	k3_get_bootsource(devstat, src, instance);
+}
+
 static int am625_init(void)
 {
+	enum bootsource src = BOOTSOURCE_UNKNOWN;
+	int instance = 0;
+
 	if (!of_machine_is_compatible("ti,am625"))
 		return 0;
 
+	am625_get_bootsource(&src, &instance);
+	bootsource_set(src, instance);
+
 	genpd_activate();
 
 	return 0;
diff --git a/include/mach/k3/common.h b/include/mach/k3/common.h
new file mode 100644
index 0000000000..448ec1343c
--- /dev/null
+++ b/include/mach/k3/common.h
@@ -0,0 +1,6 @@
+#ifndef __MACH_K3_COMMON_H
+#define __MACH_K3_COMMON_H
+
+void am625_get_bootsource(enum bootsource *src, int *instance);
+
+#endif /* __MACH_K3_COMMON_H */
-- 
2.39.5





[Index of Archives]     [Linux Embedded]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux