diff options
author | Anson Huang <Anson.Huang@nxp.com> | 2016-10-09 18:32:32 +0800 |
---|---|---|
committer | Jason Liu <jason.hui.liu@nxp.com> | 2019-02-12 10:24:59 +0800 |
commit | 8413b078297c3a04a4e09124408f7339e754bdea (patch) | |
tree | 23635c28f32d8bac999fdb7cb6485e019a4bae6a | |
parent | e205e58fe59e88edc9df44f7875060ca41816950 (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.c | 13 | ||||
-rw-r--r-- | arch/arm/mach-imx/gpc.c | 15 | ||||
-rw-r--r-- | arch/arm/mach-imx/pm-imx6.c | 67 |
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); } |