summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnson Huang <Anson.Huang@nxp.com>2016-10-09 18:32:32 +0800
committerJason Liu <jason.hui.liu@nxp.com>2019-02-12 10:24:59 +0800
commit8413b078297c3a04a4e09124408f7339e754bdea (patch)
tree23635c28f32d8bac999fdb7cb6485e019a4bae6a
parente205e58fe59e88edc9df44f7875060ca41816950 (diff)
MLK-13303-10 ARM: imx: add DSM mode support for i.mx6sll
Add DSM mode support for i.MX6SLL, Mega/Fast mix can be off now. Signed-off-by: Anson Huang <Anson.Huang@nxp.com>
-rw-r--r--arch/arm/mach-imx/anatop.c13
-rw-r--r--arch/arm/mach-imx/gpc.c15
-rw-r--r--arch/arm/mach-imx/pm-imx6.c67
3 files changed, 79 insertions, 16 deletions
diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c
index f5e5492f8b7c..abdc3c53554d 100644
--- a/arch/arm/mach-imx/anatop.c
+++ b/arch/arm/mach-imx/anatop.c
@@ -146,7 +146,8 @@ void imx_anatop_pre_suspend(void)
if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_2_0)
imx_anatop_disable_pu(true);
- if ((imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2) &&
+ if ((imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2 ||
+ imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR3) &&
!imx_gpc_usb_wakeup_enabled())
imx_anatop_enable_2p5_pulldown(true);
else
@@ -154,7 +155,8 @@ void imx_anatop_pre_suspend(void)
imx_anatop_enable_fet_odrive(true);
- if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull())
+ if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
+ cpu_is_imx6ull() || cpu_is_imx6sll())
imx_anatop_disconnect_high_snvs(true);
}
@@ -174,7 +176,8 @@ void imx_anatop_post_resume(void)
if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_2_0)
imx_anatop_disable_pu(false);
- if ((imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2) &&
+ if ((imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2 ||
+ imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR3) &&
!imx_gpc_usb_wakeup_enabled())
imx_anatop_enable_2p5_pulldown(false);
else
@@ -182,9 +185,9 @@ void imx_anatop_post_resume(void)
imx_anatop_enable_fet_odrive(false);
- if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull())
+ if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
+ cpu_is_imx6ull() || cpu_is_imx6sll())
imx_anatop_disconnect_high_snvs(false);
-
}
static void imx_anatop_usb_chrg_detect_disable(void)
diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c
index 86eac3100511..78c0a5a1430e 100644
--- a/arch/arm/mach-imx/gpc.c
+++ b/arch/arm/mach-imx/gpc.c
@@ -119,7 +119,8 @@ unsigned int imx_gpc_is_m4_sleeping(void)
bool imx_gpc_usb_wakeup_enabled(void)
{
- if (!(cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull()))
+ if (!(cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull()
+ || cpu_is_imx6sll()))
return false;
/*
@@ -180,7 +181,8 @@ void imx_gpc_pre_suspend(bool arm_power_off)
_imx6_pm_pu_power_off();
/* power down the mega-fast power domain */
- if ((cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull()) && arm_power_off)
+ if ((cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull()
+ || cpu_is_imx6sll()) && arm_power_off)
imx_gpc_mf_mix_off();
/* Tell GPC to power off ARM core when suspend */
@@ -204,7 +206,8 @@ void imx_gpc_post_resume(void)
/* Keep ARM core powered on for other low-power modes */
imx_gpc_set_arm_power_in_lpm(false);
/* Keep M/F mix powered on for other low-power modes */
- if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull())
+ if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull()
+ || cpu_is_imx6sll())
writel_relaxed(0x0, gpc_base + GPC_PGC_MF_PDN);
for (i = 0; i < IMR_NUM; i++)
@@ -371,7 +374,8 @@ int imx_gpc_mf_power_on(unsigned int irq, unsigned int on)
int imx_gpc_mf_request_on(unsigned int irq, unsigned int on)
{
- if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull())
+ if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull()
+ || cpu_is_imx6sll())
return imx_gpc_mf_power_on(irq, on);
else if (cpu_is_imx7d())
return imx_gpcv2_mf_power_on(irq, on);
@@ -453,7 +457,8 @@ static int __init imx_gpc_init(struct device_node *node,
writel_relaxed(~0, gpc_base + GPC_IMR1 + i * 4);
/* Read supported wakeup source in M/F domain */
- if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull()) {
+ if (cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull()
+ || cpu_is_imx6sll()) {
of_property_read_u32_index(node, "fsl,mf-mix-wakeup-irq", 0,
&gpc_mf_irqs[0]);
of_property_read_u32_index(node, "fsl,mf-mix-wakeup-irq", 1,
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index 208790bebcbe..aa506cbe9985 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -422,6 +422,25 @@ static const u32 imx6ul_mmdc_lpddr2_offset[] __initconst = {
0x800, 0x004, 0x01c,
};
+static const u32 imx6sll_mmdc_io_offset[] __initconst = {
+ 0x30c, 0x310, 0x314, 0x318, /* DQM0 ~ DQM3 */
+ 0x5c4, 0x5cc, 0x5d4, 0x5d8, /* GPR_B0DS ~ GPR_B3DS */
+ 0x300, 0x31c, 0x338, 0x5ac, /* CAS, RAS, SDCLK_0, GPR_ADDS */
+ 0x33c, 0x340, 0x5b0, 0x5c0, /* SODT0, SODT1, MODE_CTL, MODE */
+ 0x330, 0x334, 0x320, /* SDCKE0, SDCKE1, RESET */
+};
+
+static const u32 imx6sll_mmdc_lpddr3_offset[] __initconst = {
+ 0x01c, 0x85c, 0x800, 0x890,
+ 0x8b8, 0x81c, 0x820, 0x82c,
+ 0x830, 0x83c, 0x848, 0x850,
+ 0x8c0, 0x8b8, 0x004, 0x008,
+ 0x00c, 0x010, 0x038, 0x014,
+ 0x018, 0x01c, 0x02c, 0x030,
+ 0x040, 0x000, 0x020, 0x818,
+ 0x800, 0x004, 0x01c,
+};
+
static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
.mmdc_compat = "fsl,imx6q-mmdc",
.src_compat = "fsl,imx6q-src",
@@ -515,6 +534,17 @@ static const struct imx6_pm_socdata imx6ul_lpddr2_pm_data __initconst = {
.mmdc_offset = imx6ul_mmdc_lpddr2_offset,
};
+static const struct imx6_pm_socdata imx6sll_pm_data __initconst = {
+ .mmdc_compat = "fsl,imx6sll-mmdc",
+ .src_compat = "fsl,imx6sll-src",
+ .iomuxc_compat = "fsl,imx6sll-iomuxc",
+ .gpc_compat = "fsl,imx6sll-gpc",
+ .mmdc_io_num = ARRAY_SIZE(imx6sll_mmdc_io_offset),
+ .mmdc_io_offset = imx6sll_mmdc_io_offset,
+ .mmdc_num = ARRAY_SIZE(imx6sll_mmdc_lpddr3_offset),
+ .mmdc_offset = imx6sll_mmdc_lpddr3_offset,
+};
+
static struct map_desc iram_tlb_io_desc __initdata = {
/* .virtual and .pfn are run-time assigned */
.length = SZ_1M,
@@ -649,10 +679,10 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
val |= 0x2 << BP_CLPCR_LPM;
val &= ~BM_CLPCR_VSTBY;
val &= ~BM_CLPCR_SBYOS;
- if (cpu_is_imx6sl() || cpu_is_imx6sx())
+ if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6sll())
val |= BM_CLPCR_BYPASS_PMIC_READY;
if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
- cpu_is_imx6ull())
+ cpu_is_imx6ull() || cpu_is_imx6sll())
val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
else
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
@@ -667,10 +697,10 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
val |= 0x3 << BP_CLPCR_STBY_COUNT;
val |= BM_CLPCR_VSTBY;
val |= BM_CLPCR_SBYOS;
- if (cpu_is_imx6sl() || cpu_is_imx6sx())
+ if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6sll())
val |= BM_CLPCR_BYPASS_PMIC_READY;
if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() ||
- cpu_is_imx6ull())
+ cpu_is_imx6ull() || cpu_is_imx6sll())
val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
else
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
@@ -835,7 +865,8 @@ static int imx6q_pm_enter(suspend_state_t state)
imx6_enable_rbc(true);
imx_gpc_pre_suspend(true);
imx_anatop_pre_suspend();
- if (cpu_is_imx6ull() && imx_gpc_is_mf_mix_off())
+ if ((cpu_is_imx6ull() || cpu_is_imx6sll()) &&
+ imx_gpc_is_mf_mix_off())
imx6_console_save(console_saved_reg);
if (cpu_is_imx6sx() && imx_gpc_is_mf_mix_off()) {
ccm_ccgr4 = readl_relaxed(ccm_base + CCGR4);
@@ -875,7 +906,8 @@ static int imx6q_pm_enter(suspend_state_t state)
sizeof(qspi_regs_imx6sx) /
sizeof(struct qspi_regs));
}
- if (cpu_is_imx6ull() && imx_gpc_is_mf_mix_off())
+ if ((cpu_is_imx6ull() || cpu_is_imx6sll()) &&
+ imx_gpc_is_mf_mix_off())
imx6_console_restore(console_saved_reg);
if (cpu_is_imx6q() || cpu_is_imx6dl())
imx_smp_prepare();
@@ -1101,6 +1133,18 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
mmdc_offset_array[i]);
}
+ if (cpu_is_imx6sll() && pm_info->ddr_type == IMX_DDR_TYPE_LPDDR3) {
+ pm_info->mmdc_val[0][1] = 0x8000;
+ pm_info->mmdc_val[2][1] = 0xa1390003;
+ pm_info->mmdc_val[3][1] = 0x470000;
+ pm_info->mmdc_val[4][1] = 0x800;
+ pm_info->mmdc_val[13][1] = 0x800;
+ pm_info->mmdc_val[14][1] = 0x20012;
+ pm_info->mmdc_val[20][1] = 0x1748;
+ pm_info->mmdc_val[21][1] = 0x8000;
+ pm_info->mmdc_val[28][1] = 0xa1310003;
+ }
+
/* need to overwrite the value for some mmdc registers */
if ((cpu_is_imx6sx() || cpu_is_imx6ul() || cpu_is_imx6ull()) &&
pm_info->ddr_type != IMX_DDR_TYPE_LPDDR2) {
@@ -1208,6 +1252,17 @@ void __init imx6dl_pm_init(void)
void __init imx6sl_pm_init(void)
{
+ struct device_node *np;
+
+ if (cpu_is_imx6sll()) {
+ imx6_pm_common_init(&imx6sll_pm_data);
+ np = of_find_node_by_path(
+ "/soc/aips-bus@02000000/spba-bus@02000000/serial@02020000");
+ if (np)
+ console_base = of_iomap(np, 0);
+ return;
+ }
+
imx6_pm_common_init(&imx6sl_pm_data);
}