summaryrefslogtreecommitdiff
path: root/arch/arm/mach-k3
diff options
context:
space:
mode:
authorMarkus Schneider-Pargmann <msp@baylibre.com>2023-11-27 18:00:29 +0100
committerPraneeth Bajjuri <praneeth@ti.com>2023-11-28 12:34:52 -0600
commit4fda02e747cadf57b9d6fa02ae9fe333de792df1 (patch)
treeb988d11d30759dc0bba6051dafbd1e7cc452efec /arch/arm/mach-k3
parent77053f97e011df8fa2d3f098f43bda3c2d7facd6 (diff)
arm: mach-k3: Remove CANUART IO isolation
After leaving the Partial-IO mode or other deep sleep states, the IO isolation needs to be removed. This routine is shared by at least am62, am62a and am62p. The original function for testing was developed by Akashdeep Kaur <a-kaur@ti.com> Signed-off-by: Markus Schneider-Pargmann <msp@baylibre.com> Reviewed-by: Dhruva Gole <d-gole@ti.com>
Diffstat (limited to 'arch/arm/mach-k3')
-rw-r--r--arch/arm/mach-k3/am625_init.c2
-rw-r--r--arch/arm/mach-k3/am62a7_init.c2
-rw-r--r--arch/arm/mach-k3/am62p5_init.c2
-rw-r--r--arch/arm/mach-k3/common.c56
-rw-r--r--arch/arm/mach-k3/common.h1
-rw-r--r--arch/arm/mach-k3/include/mach/hardware.h29
6 files changed, 92 insertions, 0 deletions
diff --git a/arch/arm/mach-k3/am625_init.c b/arch/arm/mach-k3/am625_init.c
index d5d741cb93..ccbfad29d7 100644
--- a/arch/arm/mach-k3/am625_init.c
+++ b/arch/arm/mach-k3/am625_init.c
@@ -135,6 +135,8 @@ void board_init_f(ulong dummy)
/* Init DM early */
spl_early_init();
+ wkup_ctrl_remove_can_io_isolation_if_set();
+
/*
* Process pinctrl for the serial0 and serial3, aka WKUP_UART0 and
* MAIN_UART1 modules and continue regardless of the result of pinctrl.
diff --git a/arch/arm/mach-k3/am62a7_init.c b/arch/arm/mach-k3/am62a7_init.c
index 0b044bf037..5a96683c53 100644
--- a/arch/arm/mach-k3/am62a7_init.c
+++ b/arch/arm/mach-k3/am62a7_init.c
@@ -103,6 +103,8 @@ void board_init_f(ulong dummy)
/* Init DM early */
spl_early_init();
+ wkup_ctrl_remove_can_io_isolation_if_set();
+
/*
* Process pinctrl for the serial0 and serial3, aka WKUP_UART0 and
* MAIN_UART1 modules and continue regardless of the result of pinctrl.
diff --git a/arch/arm/mach-k3/am62p5_init.c b/arch/arm/mach-k3/am62p5_init.c
index 55535a3ff9..ac1b01bd84 100644
--- a/arch/arm/mach-k3/am62p5_init.c
+++ b/arch/arm/mach-k3/am62p5_init.c
@@ -88,6 +88,8 @@ void board_init_f(ulong dummy)
if (ret)
panic("spl_early_init() failed: %d\n", ret);
+ wkup_ctrl_remove_can_io_isolation_if_set();
+
/*
* Process pinctrl for the serial0 and serial3, aka WKUP_UART0 and
* MAIN_UART1 modules and continue regardless of the result of pinctrl.
diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c
index 0d070a8c95..a64f7e3cba 100644
--- a/arch/arm/mach-k3/common.c
+++ b/arch/arm/mach-k3/common.c
@@ -27,6 +27,9 @@
#include <env.h>
#include <elf.h>
#include <soc.h>
+#include <wait_bit.h>
+
+#define CLKSTOP_TRANSITION_TIMEOUT_MS 10
#if IS_ENABLED(CONFIG_SYS_K3_SPL_ATF)
enum {
@@ -100,6 +103,59 @@ void mmr_unlock(phys_addr_t base, u32 partition)
writel(CTRLMMR_LOCK_KICK1_UNLOCK_VAL, part_base + CTRLMMR_LOCK_KICK1);
}
+static void wkup_ctrl_remove_can_io_isolation(void)
+{
+ const void *wait_reg = (const void *)(WKUP_CTRL_MMR0_BASE +
+ WKUP_CTRL_MMR_CANUART_WAKE_STAT1);
+ int ret;
+ u32 reg = 0;
+
+ /* Program magic word */
+ reg = readl(WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_CANUART_WAKE_CTRL);
+ reg |= WKUP_CTRL_MMR_CANUART_WAKE_CTRL_MW << WKUP_CTRL_MMR_CANUART_WAKE_CTRL_MW_SHIFT;
+ writel(reg, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_CANUART_WAKE_CTRL);
+
+ /* Set enable bit. */
+ reg |= WKUP_CTRL_MMR_CANUART_WAKE_CTRL_MW_LOAD_EN;
+ writel(reg, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_CANUART_WAKE_CTRL);
+
+ /* Clear enable bit. */
+ reg &= ~WKUP_CTRL_MMR_CANUART_WAKE_CTRL_MW_LOAD_EN;
+ writel(reg, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_CANUART_WAKE_CTRL);
+
+ /* wait for CAN_ONLY_IO signal to be 0 */
+ ret = wait_for_bit_32(wait_reg,
+ WKUP_CTRL_MMR_CANUART_WAKE_STAT1_CANUART_IO_MODE,
+ false,
+ CLKSTOP_TRANSITION_TIMEOUT_MS,
+ false);
+ if (ret < 0)
+ return;
+
+ /* Reset magic word */
+ writel(0, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_CANUART_WAKE_CTRL);
+
+ /* Remove WKUP IO isolation */
+ reg = readl(WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_PMCTRL_IO_0);
+ reg = reg & WKUP_CTRL_MMR_PMCTRL_IO_0_WRITE_MASK & ~WKUP_CTRL_MMR_PMCTRL_IO_0_GLOBAL_WUEN_0;
+ writel(reg, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_PMCTRL_IO_0);
+
+ /* clear global IO isolation */
+ reg = readl(WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_PMCTRL_IO_0);
+ reg = reg & WKUP_CTRL_MMR_PMCTRL_IO_0_WRITE_MASK & ~WKUP_CTRL_MMR_PMCTRL_IO_0_IO_ISO_CTRL_0;
+ writel(reg, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_PMCTRL_IO_0);
+
+ writel(0, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_DEEPSLEEP_CTRL);
+ writel(0, WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_PMCTRL_IO_GLB);
+}
+
+void wkup_ctrl_remove_can_io_isolation_if_set(void)
+{
+ if (readl(WKUP_CTRL_MMR0_BASE + WKUP_CTRL_MMR_CANUART_WAKE_STAT1) &
+ WKUP_CTRL_MMR_CANUART_WAKE_STAT1_CANUART_IO_MODE)
+ wkup_ctrl_remove_can_io_isolation();
+}
+
bool is_rom_loaded_sysfw(struct rom_extended_boot_data *data)
{
if (strncmp(data->header, K3_ROM_BOOT_HEADER_MAGIC, 7))
diff --git a/arch/arm/mach-k3/common.h b/arch/arm/mach-k3/common.h
index e71c7453cb..4c0d4666d7 100644
--- a/arch/arm/mach-k3/common.h
+++ b/arch/arm/mach-k3/common.h
@@ -44,3 +44,4 @@ bool is_rom_loaded_sysfw(struct rom_extended_boot_data *data);
enum k3_device_type get_device_type(void);
void ti_secure_image_post_process(void **p_image, size_t *p_size);
void ti_secure_image_check_binary(void **p_image, size_t *p_size);
+void wkup_ctrl_remove_can_io_isolation_if_set(void);
diff --git a/arch/arm/mach-k3/include/mach/hardware.h b/arch/arm/mach-k3/include/mach/hardware.h
index ca53b43962..20e9634513 100644
--- a/arch/arm/mach-k3/include/mach/hardware.h
+++ b/arch/arm/mach-k3/include/mach/hardware.h
@@ -102,6 +102,35 @@ K3_SOC_ID(am62px, AM62PX)
#define CTRLMMR_LOCK_KICK1 0x100c
#define CTRLMMR_LOCK_KICK1_UNLOCK_VAL 0xd172bc5a
+/*
+ * Shared WKUP_CTRL_MMR0 definitions used to remove IO isolation
+ */
+#define WKUP_CTRL_MMR_CANUART_WAKE_CTRL 0x18300
+#define WKUP_CTRL_MMR_CANUART_WAKE_CTRL_MW 0x2aaaaaaa
+#define WKUP_CTRL_MMR_CANUART_WAKE_CTRL_MW_SHIFT 1
+#define WKUP_CTRL_MMR_CANUART_WAKE_CTRL_MW_LOAD_EN BIT(0)
+
+#define WKUP_CTRL_MMR_CANUART_WAKE_STAT1 0x1830c
+#define WKUP_CTRL_MMR_CANUART_WAKE_STAT1_CANUART_IO_MODE BIT(0)
+
+#define WKUP_CTRL_MMR_PMCTRL_IO_0 0x18084
+#define WKUP_CTRL_MMR_PMCTRL_IO_0_ISOCLK_OVRD_0 BIT(0)
+#define WKUP_CTRL_MMR_PMCTRL_IO_0_ISOOVR_EXTEND_0 BIT(4)
+#define WKUP_CTRL_MMR_PMCTRL_IO_0_ISO_BYPASS_OVR_0 BIT(6)
+#define WKUP_CTRL_MMR_PMCTRL_IO_0_WUCLK_CTRL_0 BIT(8)
+#define WKUP_CTRL_MMR_PMCTRL_IO_0_GLOBAL_WUEN_0 BIT(16)
+#define WKUP_CTRL_MMR_PMCTRL_IO_0_IO_ISO_CTRL_0 BIT(24)
+#define WKUP_CTRL_MMR_PMCTRL_IO_0_WRITE_MASK ( \
+ WKUP_CTRL_MMR_PMCTRL_IO_0_ISOCLK_OVRD_0 | \
+ WKUP_CTRL_MMR_PMCTRL_IO_0_ISOOVR_EXTEND_0 | \
+ WKUP_CTRL_MMR_PMCTRL_IO_0_ISO_BYPASS_OVR_0 | \
+ WKUP_CTRL_MMR_PMCTRL_IO_0_WUCLK_CTRL_0 | \
+ WKUP_CTRL_MMR_PMCTRL_IO_0_GLOBAL_WUEN_0 | \
+ WKUP_CTRL_MMR_PMCTRL_IO_0_IO_ISO_CTRL_0)
+
+#define WKUP_CTRL_MMR_PMCTRL_IO_GLB 0x1809c
+#define WKUP_CTRL_MMR_DEEPSLEEP_CTRL 0x18160
+
#define K3_ROM_BOOT_HEADER_MAGIC "EXTBOOT"
struct rom_extended_boot_data {