summaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx/imx9/scmi/soc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx/imx9/scmi/soc.c')
-rw-r--r--arch/arm/mach-imx/imx9/scmi/soc.c213
1 files changed, 204 insertions, 9 deletions
diff --git a/arch/arm/mach-imx/imx9/scmi/soc.c b/arch/arm/mach-imx/imx9/scmi/soc.c
index f973652d0cb..dbaa19a9e6e 100644
--- a/arch/arm/mach-imx/imx9/scmi/soc.c
+++ b/arch/arm/mach-imx/imx9/scmi/soc.c
@@ -17,8 +17,11 @@
#include <env_internal.h>
#include <fuse.h>
#include <imx_thermal.h>
+#include <linux/bitfield.h>
#include <linux/iopoll.h>
#include <scmi_agent.h>
+#include <scmi_nxp_protocols.h>
+#include "common.h"
DECLARE_GLOBAL_DATA_PTR;
@@ -174,7 +177,7 @@ u32 get_cpu_rev(void)
{
u32 rev = (gd->arch.soc_rev >> 24) - 0xa0;
- return (MXC_CPU_IMX95 << 12) | (CHIP_REV_1_0 + rev);
+ return (SCMI_CPU << 12) | (CHIP_REV_1_0 + rev);
}
#define UNLOCK_WORD 0xD928C520
@@ -254,6 +257,30 @@ static struct mm_region imx9_mem_map[] = {
PTE_BLOCK_OUTER_SHARE
}, {
#endif
+ /* PCIE2 ECAM */
+ .virt = 0x880000000UL,
+ .phys = 0x880000000UL,
+ .size = 0x10000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* PCIE1 Outbound */
+ .virt = 0x900000000UL,
+ .phys = 0x900000000UL,
+ .size = 0x100000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
+ /* PCIE2 Outbound */
+ .virt = 0xA00000000UL,
+ .phys = 0xA00000000UL,
+ .size = 0x100000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN
+ }, {
/* empty entry to split table entry 5 if needed when TEEs are used */
0,
}, {
@@ -435,12 +462,16 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
{
u32 val[2] = {};
int ret, num_of_macs;
+ u32 bank = 40;
+
+ if (is_imx94())
+ bank = 66;
- ret = fuse_read(40, 5, &val[0]);
+ ret = fuse_read(bank, 5, &val[0]);
if (ret)
goto err;
- ret = fuse_read(40, 6, &val[1]);
+ ret = fuse_read(bank, 6, &val[1]);
if (ret)
goto err;
@@ -456,10 +487,32 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
mac[3] = (val[0] >> 24) & 0xff;
mac[4] = val[1] & 0xff;
mac[5] = (val[1] >> 8) & 0xff;
- if (dev_id == 1)
- mac[5] = mac[5] + 3;
- if (dev_id == 2)
- mac[5] = mac[5] + 6;
+
+ if (is_imx94()) {
+ /*
+ * i.MX94 uses the following mac address offset list:
+ * | No. | Module | Mac address user |
+ * |--------|-------------|---------------------------|
+ * | 0 ~ 1 | ethercat | port0/port1 |
+ * | 2 | netc switch | internal enetc3 mac/swp0 |
+ * | 3 ~ 6 | | enetc3 vf1~3/swp1 |
+ * | 7 | enetc mac | enetc0 pf |
+ * | 8 | | enetc1 pf |
+ * | 9 | | enetc2 pf |
+ * | 10 | netc switch | swp2 |
+ */
+ if (dev_id == 0)
+ mac[5] = mac[5] + 2; /* enetc3 mac/swp0 */
+ if (dev_id == 1)
+ mac[5] = mac[5] + 8; /* enetc1 */
+ if (dev_id == 2)
+ mac[5] = mac[5] + 9; /* enetc2 */
+ } else {
+ if (dev_id == 1)
+ mac[5] = mac[5] + 3;
+ if (dev_id == 2)
+ mac[5] = mac[5] + 6;
+ }
debug("%s: MAC%d: %pM\n", __func__, dev_id, mac);
return;
@@ -468,11 +521,149 @@ err:
printf("%s: fuse read err: %d\n", __func__, ret);
}
+static char *rst_string[32] = {
+ "cm33_lockup",
+ "cm33_swreq",
+ "cm7_lockup",
+ "cm7_swreq",
+ "fccu",
+ "jtag_sw",
+ "ele",
+ "tempsense",
+ "wdog1",
+ "wdog2",
+ "wdog3",
+ "wdog4",
+ "wdog5",
+ "jtag",
+ "cm33_exc",
+ "bbm",
+ "sw",
+ "sm_err", "fusa_sreco", "pmic", "unused", "unused", "unused",
+ "unused", "unused", "unused", "unused", "unused", "unused",
+ "unused", "unused",
+ "por"
+};
+
+static char *rst_string_imx94[32] = {
+ "cm33_lockup",
+ "cm33_swreq",
+ "cm70_lockup",
+ "cm70_swreq",
+ "fccu",
+ "jtag_sw",
+ "ele",
+ "tempsense",
+ "wdog1",
+ "wdog2",
+ "wdog3",
+ "wdog4",
+ "wdog5",
+ "jtag",
+ "wdog6",
+ "wdog7",
+ "wdog8",
+ "wo_netc", "cm33s_lockup", "cm33s_swreq", "cm71_lockup", "cm71_swreq", "cm33_exc",
+ "bbm", "sw", "sm_err", "fusa_sreco", "pmic", "unused",
+ "unused", "unused",
+ "por"
+};
+
+int get_reset_reason(bool sys, bool lm)
+{
+ struct scmi_imx_misc_reset_reason_in in = {
+ .flags = MISC_REASON_FLAG_SYSTEM,
+ };
+
+ struct scmi_imx_misc_reset_reason_out out = { 0 };
+ struct scmi_msg msg = {
+ .protocol_id = SCMI_PROTOCOL_ID_IMX_MISC,
+ .message_id = SCMI_IMX_MISC_RESET_REASON,
+ .in_msg = (u8 *)&in,
+ .in_msg_sz = sizeof(in),
+ .out_msg = (u8 *)&out,
+ .out_msg_sz = sizeof(out),
+ };
+ int ret;
+
+ struct udevice *dev;
+ char **rst;
+
+ if (is_imx94())
+ rst = rst_string_imx94;
+ else
+ rst = rst_string;
+
+ ret = uclass_get_device_by_name(UCLASS_CLK, "protocol@14", &dev);
+ if (ret)
+ return ret;
+
+ if (sys) {
+ ret = devm_scmi_process_msg(dev, &msg);
+ if (out.status) {
+ printf("%s:%d for SYS\n", __func__, out.status);
+ return ret;
+ }
+
+ if (out.bootflags & MISC_BOOT_FLAG_VLD) {
+ printf("SYS Boot reason: %s, origin: %ld, errid: %ld\n",
+ rst[out.bootflags & MISC_BOOT_FLAG_REASON],
+ out.bootflags & MISC_BOOT_FLAG_ORG_VLD ?
+ FIELD_GET(MISC_BOOT_FLAG_ORIGIN, out.bootflags) : -1,
+ out.bootflags & MISC_BOOT_FLAG_ERR_VLD ?
+ FIELD_GET(MISC_BOOT_FLAG_ERR_ID, out.bootflags) : -1
+ );
+ }
+ if (out.shutdownflags & MISC_SHUTDOWN_FLAG_VLD) {
+ printf("SYS shutdown reason: %s, origin: %ld, errid: %ld\n",
+ rst[out.bootflags & MISC_SHUTDOWN_FLAG_REASON],
+ out.bootflags & MISC_SHUTDOWN_FLAG_ORG_VLD ?
+ FIELD_GET(MISC_SHUTDOWN_FLAG_ORIGIN, out.bootflags) : -1,
+ out.bootflags & MISC_SHUTDOWN_FLAG_ERR_VLD ?
+ FIELD_GET(MISC_SHUTDOWN_FLAG_ERR_ID, out.bootflags) : -1
+ );
+ }
+ }
+
+ if (lm) {
+ in.flags = 0;
+ memset(&out, 0, sizeof(struct scmi_imx_misc_reset_reason_out));
+
+ ret = devm_scmi_process_msg(dev, &msg);
+ if (out.status) {
+ printf("%s:%d for LM\n", __func__, out.status);
+ return ret;
+ }
+
+ if (out.bootflags & MISC_BOOT_FLAG_VLD) {
+ printf("LM Boot reason: %s, origin: %ld, errid: %ld\n",
+ rst[out.bootflags & MISC_BOOT_FLAG_REASON],
+ out.bootflags & MISC_BOOT_FLAG_ORG_VLD ?
+ FIELD_GET(MISC_BOOT_FLAG_ORIGIN, out.bootflags) : -1,
+ out.bootflags & MISC_BOOT_FLAG_ERR_VLD ?
+ FIELD_GET(MISC_BOOT_FLAG_ERR_ID, out.bootflags) : -1
+ );
+ }
+
+ if (out.shutdownflags & MISC_SHUTDOWN_FLAG_VLD) {
+ printf("LM shutdown reason: %s, origin: %ld, errid: %ld\n",
+ rst[out.bootflags & MISC_SHUTDOWN_FLAG_REASON],
+ out.bootflags & MISC_SHUTDOWN_FLAG_ORG_VLD ?
+ FIELD_GET(MISC_SHUTDOWN_FLAG_ORIGIN, out.bootflags) : -1,
+ out.bootflags & MISC_SHUTDOWN_FLAG_ERR_VLD ?
+ FIELD_GET(MISC_SHUTDOWN_FLAG_ERR_ID, out.bootflags) : -1
+ );
+ }
+ }
+
+ return 0;
+}
+
const char *get_imx_type(u32 imxtype)
{
switch (imxtype) {
- case MXC_CPU_IMX95:
- return "95";/* iMX95 FULL */
+ case SCMI_CPU:
+ return IMX_PLAT_STR;
default:
return "??";
}
@@ -553,6 +744,10 @@ int arch_cpu_init(void)
gpio_reset(GPIO3_BASE_ADDR);
gpio_reset(GPIO4_BASE_ADDR);
gpio_reset(GPIO5_BASE_ADDR);
+#ifdef CONFIG_IMX94
+ gpio_reset(GPIO6_BASE_ADDR);
+ gpio_reset(GPIO7_BASE_ADDR);
+#endif
}
return 0;