summaryrefslogtreecommitdiff
path: root/arch/arm/mach-omap2/control.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/control.c')
-rw-r--r--arch/arm/mach-omap2/control.c230
1 files changed, 141 insertions, 89 deletions
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index bd8089ff929f..79860b23030d 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* OMAP2/3 System Control Module register access
*
@@ -5,10 +6,6 @@
* Copyright (C) 2007 Nokia Corporation
*
* Written by Paul Walmsley
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
*/
#undef DEBUG
@@ -17,6 +14,7 @@
#include <linux/of_address.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
+#include <linux/cpu_pm.h>
#include "soc.h"
#include "iomap.h"
@@ -138,11 +136,6 @@ struct omap3_control_regs {
static struct omap3_control_regs control_context;
#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
-void __init omap2_set_globals_control(void __iomem *ctrl)
-{
- omap2_ctrl_base = ctrl;
-}
-
u8 omap_ctrl_readb(u16 offset)
{
u32 val;
@@ -233,68 +226,7 @@ void omap3_ctrl_write_boot_mode(u8 bootmode)
#endif
-/**
- * omap_ctrl_write_dsp_boot_addr - set boot address for a remote processor
- * @bootaddr: physical address of the boot loader
- *
- * Set boot address for the boot loader of a supported processor
- * when a power ON sequence occurs.
- */
-void omap_ctrl_write_dsp_boot_addr(u32 bootaddr)
-{
- u32 offset = cpu_is_omap243x() ? OMAP243X_CONTROL_IVA2_BOOTADDR :
- cpu_is_omap34xx() ? OMAP343X_CONTROL_IVA2_BOOTADDR :
- cpu_is_omap44xx() ? OMAP4_CTRL_MODULE_CORE_DSP_BOOTADDR :
- soc_is_omap54xx() ? OMAP4_CTRL_MODULE_CORE_DSP_BOOTADDR :
- 0;
-
- if (!offset) {
- pr_err("%s: unsupported omap type\n", __func__);
- return;
- }
-
- omap_ctrl_writel(bootaddr, offset);
-}
-
-/**
- * omap_ctrl_write_dsp_boot_mode - set boot mode for a remote processor
- * @bootmode: 8-bit value to pass to some boot code
- *
- * Sets boot mode for the boot loader of a supported processor
- * when a power ON sequence occurs.
- */
-void omap_ctrl_write_dsp_boot_mode(u8 bootmode)
-{
- u32 offset = cpu_is_omap243x() ? OMAP243X_CONTROL_IVA2_BOOTMOD :
- cpu_is_omap34xx() ? OMAP343X_CONTROL_IVA2_BOOTMOD :
- 0;
-
- if (!offset) {
- pr_err("%s: unsupported omap type\n", __func__);
- return;
- }
-
- omap_ctrl_writel(bootmode, offset);
-}
-
#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
-/*
- * Clears the scratchpad contents in case of cold boot-
- * called during bootup
- */
-void omap3_clear_scratchpad_contents(void)
-{
- u32 max_offset = OMAP343X_SCRATCHPAD_ROM_OFFSET;
- void __iomem *v_addr;
- u32 offset = 0;
-
- v_addr = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD_ROM);
- if (omap3xxx_prm_clear_global_cold_reset()) {
- for ( ; offset <= max_offset; offset += 0x4)
- writel_relaxed(0x0, (v_addr + offset));
- }
-}
-
/* Populate the scratchpad structure with restore structure */
void omap3_save_scratchpad_contents(void)
{
@@ -621,8 +553,113 @@ void __init omap3_ctrl_init(void)
}
#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
+static unsigned long am43xx_control_reg_offsets[] = {
+ AM33XX_CONTROL_SYSCONFIG_OFFSET,
+ AM33XX_CONTROL_STATUS_OFFSET,
+ AM43XX_CONTROL_MPU_L2_CTRL_OFFSET,
+ AM33XX_CONTROL_CORE_SLDO_CTRL_OFFSET,
+ AM33XX_CONTROL_MPU_SLDO_CTRL_OFFSET,
+ AM33XX_CONTROL_CLK32KDIVRATIO_CTRL_OFFSET,
+ AM33XX_CONTROL_BANDGAP_CTRL_OFFSET,
+ AM33XX_CONTROL_BANDGAP_TRIM_OFFSET,
+ AM33XX_CONTROL_PLL_CLKINPULOW_CTRL_OFFSET,
+ AM33XX_CONTROL_MOSC_CTRL_OFFSET,
+ AM33XX_CONTROL_DEEPSLEEP_CTRL_OFFSET,
+ AM43XX_CONTROL_DISPLAY_PLL_SEL_OFFSET,
+ AM33XX_CONTROL_INIT_PRIORITY_0_OFFSET,
+ AM33XX_CONTROL_INIT_PRIORITY_1_OFFSET,
+ AM33XX_CONTROL_TPTC_CFG_OFFSET,
+ AM33XX_CONTROL_USB_CTRL0_OFFSET,
+ AM33XX_CONTROL_USB_CTRL1_OFFSET,
+ AM43XX_CONTROL_USB_CTRL2_OFFSET,
+ AM43XX_CONTROL_GMII_SEL_OFFSET,
+ AM43XX_CONTROL_MPUSS_CTRL_OFFSET,
+ AM43XX_CONTROL_TIMER_CASCADE_CTRL_OFFSET,
+ AM43XX_CONTROL_PWMSS_CTRL_OFFSET,
+ AM33XX_CONTROL_MREQPRIO_0_OFFSET,
+ AM33XX_CONTROL_MREQPRIO_1_OFFSET,
+ AM33XX_CONTROL_HW_EVENT_SEL_GRP1_OFFSET,
+ AM33XX_CONTROL_HW_EVENT_SEL_GRP2_OFFSET,
+ AM33XX_CONTROL_HW_EVENT_SEL_GRP3_OFFSET,
+ AM33XX_CONTROL_HW_EVENT_SEL_GRP4_OFFSET,
+ AM33XX_CONTROL_SMRT_CTRL_OFFSET,
+ AM33XX_CONTROL_MPUSS_HW_DEBUG_SEL_OFFSET,
+ AM43XX_CONTROL_CQDETECT_STS_OFFSET,
+ AM43XX_CONTROL_CQDETECT_STS2_OFFSET,
+ AM43XX_CONTROL_VTP_CTRL_OFFSET,
+ AM33XX_CONTROL_VREF_CTRL_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_0_3_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_4_7_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_8_11_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_12_15_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_16_19_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_20_23_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_24_27_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_28_31_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_32_35_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_36_39_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_40_43_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_44_47_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_48_51_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_52_55_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_56_59_OFFSET,
+ AM33XX_CONTROL_TPCC_EVT_MUX_60_63_OFFSET,
+ AM33XX_CONTROL_TIMER_EVT_CAPT_OFFSET,
+ AM33XX_CONTROL_ECAP_EVT_CAPT_OFFSET,
+ AM33XX_CONTROL_ADC_EVT_CAPT_OFFSET,
+ AM43XX_CONTROL_ADC1_EVT_CAPT_OFFSET,
+ AM33XX_CONTROL_RESET_ISO_OFFSET,
+};
+
+static u32 am33xx_control_vals[ARRAY_SIZE(am43xx_control_reg_offsets)];
+
+/**
+ * am43xx_control_save_context - Save the wakeup domain registers
+ *
+ * Save the wkup domain registers
+ */
+static void am43xx_control_save_context(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(am43xx_control_reg_offsets); i++)
+ am33xx_control_vals[i] =
+ omap_ctrl_readl(am43xx_control_reg_offsets[i]);
+}
+
+/**
+ * am43xx_control_restore_context - Restore the wakeup domain registers
+ *
+ * Restore the wkup domain registers
+ */
+static void am43xx_control_restore_context(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(am43xx_control_reg_offsets); i++)
+ omap_ctrl_writel(am33xx_control_vals[i],
+ am43xx_control_reg_offsets[i]);
+}
+
+static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v)
+{
+ switch (cmd) {
+ case CPU_CLUSTER_PM_ENTER:
+ if (enable_off_mode)
+ am43xx_control_save_context();
+ break;
+ case CPU_CLUSTER_PM_EXIT:
+ if (enable_off_mode)
+ am43xx_control_restore_context();
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
struct control_init_data {
int index;
+ void __iomem *mem;
s16 offset;
};
@@ -635,6 +672,10 @@ static const struct control_init_data omap2_ctrl_data = {
.offset = -OMAP2_CONTROL_GENERAL,
};
+static const struct control_init_data ctrl_aux_data = {
+ .index = TI_CLKM_CTRL_AUX,
+};
+
static const struct of_device_id omap_scrm_dt_match_table[] = {
{ .compatible = "ti,am3-scm", .data = &ctrl_data },
{ .compatible = "ti,am4-scm", .data = &ctrl_data },
@@ -644,6 +685,7 @@ static const struct of_device_id omap_scrm_dt_match_table[] = {
{ .compatible = "ti,dm816-scrm", .data = &ctrl_data },
{ .compatible = "ti,omap4-scm-core", .data = &ctrl_data },
{ .compatible = "ti,omap5-scm-core", .data = &ctrl_data },
+ { .compatible = "ti,omap5-scm-wkup-pad-conf", .data = &ctrl_aux_data },
{ .compatible = "ti,dra7-scm-core", .data = &ctrl_data },
{ }
};
@@ -660,15 +702,23 @@ int __init omap2_control_base_init(void)
struct device_node *np;
const struct of_device_id *match;
struct control_init_data *data;
+ void __iomem *mem;
for_each_matching_node_and_match(np, omap_scrm_dt_match_table, &match) {
data = (struct control_init_data *)match->data;
- omap2_ctrl_base = of_iomap(np, 0);
- if (!omap2_ctrl_base)
+ mem = of_iomap(np, 0);
+ if (!mem) {
+ of_node_put(np);
return -ENOMEM;
+ }
+
+ if (data->index == TI_CLKM_CTRL) {
+ omap2_ctrl_base = mem;
+ omap2_ctrl_offset = data->offset;
+ }
- omap2_ctrl_offset = data->offset;
+ data->mem = mem;
}
return 0;
@@ -687,6 +737,7 @@ int __init omap_control_init(void)
const struct omap_prcm_init_data *data;
int ret;
struct regmap *syscon;
+ static struct notifier_block nb;
for_each_matching_node_and_match(np, omap_scrm_dt_match_table, &match) {
data = match->data;
@@ -700,36 +751,37 @@ int __init omap_control_init(void)
if (scm_conf) {
syscon = syscon_node_to_regmap(scm_conf);
- if (IS_ERR(syscon))
- return PTR_ERR(syscon);
+ if (IS_ERR(syscon)) {
+ ret = PTR_ERR(syscon);
+ goto of_node_put;
+ }
if (of_get_child_by_name(scm_conf, "clocks")) {
ret = omap2_clk_provider_init(scm_conf,
data->index,
syscon, NULL);
if (ret)
- return ret;
+ goto of_node_put;
}
} else {
/* No scm_conf found, direct access */
ret = omap2_clk_provider_init(np, data->index, NULL,
- omap2_ctrl_base);
+ data->mem);
if (ret)
- return ret;
+ goto of_node_put;
}
}
+ /* Only AM43XX can lose ctrl registers context during rtc-ddr suspend */
+ if (soc_is_am43xx()) {
+ nb.notifier_call = cpu_notifier;
+ cpu_pm_register_notifier(&nb);
+ }
+
return 0;
-}
-/**
- * omap3_control_legacy_iomap_init - legacy iomap init for clock providers
- *
- * Legacy iomap init for clock provider. Needed only by legacy boot mode,
- * where the base addresses are not parsed from DT, but still required
- * by the clock driver to be setup properly.
- */
-void __init omap3_control_legacy_iomap_init(void)
-{
- omap2_clk_legacy_provider_init(TI_CLKM_SCRM, omap2_ctrl_base);
+of_node_put:
+ of_node_put(np);
+ return ret;
+
}