Commit bf51c393 authored by Anson Huang's avatar Anson Huang Committed by Jason Liu

ENGR00209501 [MX6]Support different platforms DDR IO setting in DSM

As Mx6 dq, dl and sl have different DDR IO address, so
we need to do the DDR IO low power setting according
to different CPU type.

Also, Mx6sl has some different config in DSM, need to
separate it from other platforms.

Change mx6q_suspend to mx6_suspend, as it is a common
thing for all mx6 platforms.

Add rtc driver for mxsl platform to support suspend/resume test.
Signed-off-by: default avatarAnson Huang <b20788@freescale.com>
parent 256e6e5d
......@@ -7,7 +7,7 @@ obj-y := cpu.o mm.o system.o devices.o dummy_gpio.o irq.o bus_freq.o usb_dr.o
pm.o cpu_op-mx6.o mx6_wfi.o mx6_fec.o mx6_anatop_regulator.o cpu_regulator-mx6.o \
mx6_mmdc.o mx6_ddr_freq.o
obj-$(CONFIG_ARCH_MX6) += clock.o mx6q_suspend.o clock_mx6sl.o
obj-$(CONFIG_ARCH_MX6) += clock.o mx6_suspend.o clock_mx6sl.o
obj-$(CONFIG_MACH_MX6Q_ARM2) += board-mx6q_arm2.o
obj-$(CONFIG_MACH_MX6SL_ARM2) += board-mx6sl_arm2.o mx6sl_arm2_pmic_pfuze100.o
obj-$(CONFIG_MACH_MX6Q_SABRELITE) += board-mx6q_sabrelite.o
......
......@@ -713,6 +713,8 @@ static void __init mx6_arm2_init(void)
gp_reg_id = "cpu_vddgp";
mx6_cpu_regulator_init();
imx6q_add_imx_snvs_rtc();
imx6q_add_imx_i2c(0, &mx6_arm2_i2c0_data);
imx6q_add_imx_i2c(1, &mx6_arm2_i2c1_data);
i2c_register_board_info(0, mxc_i2c0_board_info,
......
......@@ -35,7 +35,7 @@
#define IRAM_SUSPEND_SIZE (1 << 12)
/*************************************************************
mx6q_suspend:
mx6_suspend:
Suspend the processor (eg, wait for interrupt).
Set the DDR into Self Refresh
......@@ -50,6 +50,123 @@ see define in include/linux/suspend.h
r1: iram_paddr
r2: suspend_iram_base
*************************************************************/
.macro sl_ddr_io_save
ldr r4, [r1, #0x30c] /* DRAM_DQM0 */
ldr r5, [r1, #0x310] /* DRAM_DQM1 */
ldr r6, [r1, #0x314] /* DRAM_DQM2 */
ldr r7, [r1, #0x318] /* DRAM_DQM3 */
stmfd r0!, {r4-r7}
ldr r4, [r1, #0x344] /* DRAM_SDQS0 */
ldr r5, [r1, #0x348] /* DRAM_SDQS1 */
ldr r6, [r1, #0x34c] /* DRAM_SDQS2 */
ldr r7, [r1, #0x350] /* DRAM_SDQS3 */
stmfd r0!, {r4-r7}
ldr r4, [r1, #0x5c4] /* GPR_B0DS */
ldr r5, [r1, #0x5cc] /* GPR_B1DS */
ldr r6, [r1, #0x5d4] /* GPR_B2DS */
ldr r7, [r1, #0x5d8] /* GPR_B3DS */
stmfd r0!, {r4-r7}
ldr r4, [r1, #0x300] /* DRAM_CAS */
ldr r5, [r1, #0x31c] /* DRAM_RAS */
ldr r6, [r1, #0x338] /* DRAM_SDCLK_0 */
ldr r7, [r1, #0x5ac] /* GPR_ADDS*/
stmfd r0!, {r4-r7}
ldr r4, [r1, #0x5b0] /* DDRMODE_CTL */
ldr r5, [r1, #0x5c0] /* DDRMODE */
ldr r6, [r1, #0x33c] /* DRAM_SODT0*/
ldr r7, [r1, #0x340] /* DRAM_SODT1*/
stmfd r0!, {r4-r7}
ldr r4, [r1, #0x330] /* DRAM_SDCKE0 */
ldr r5, [r1, #0x334] /* DRAM_SDCKE1 */
ldr r6, [r1, #0x320] /* DRAM_RESET */
ldr r7, [r1, #0x5c8] /* GPR_CTLDS */
stmfd r0!, {r4-r7}
.endm
.macro sl_ddr_io_restore
ldmea r0!, {r4-r7}
str r4, [r1, #0x30c] /* DRAM_DQM0 */
str r5, [r1, #0x310] /* DRAM_DQM1 */
str r6, [r1, #0x314] /* DRAM_DQM2 */
str r7, [r1, #0x318] /* DRAM_DQM3 */
ldmea r0!, {r4-r7}
str r4, [r1, #0x344] /* DRAM_SDQS0 */
str r5, [r1, #0x348] /* DRAM_SDQS1 */
str r6, [r1, #0x34c] /* DRAM_SDQS2 */
str r7, [r1, #0x350] /* DRAM_SDQS3 */
ldmea r0!, {r4-r7}
str r4, [r1, #0x5c4] /* GPR_B0DS */
str r5, [r1, #0x5cc] /* GPR_B1DS */
str r6, [r1, #0x5d4] /* GPR_B2DS */
str r7, [r1, #0x5d8] /* GPR_B3DS */
ldmea r0!, {r4-r7}
str r4, [r1, #0x300] /* DRAM_CAS */
str r5, [r1, #0x31c] /* DRAM_RAS */
str r6, [r1, #0x338] /* DRAM_SDCLK_0 */
str r7, [r1, #0x5ac] /* GPR_ADDS*/
ldmea r0!, {r4-r7}
str r4, [r1, #0x5b0] /* DDRMODE_CTL */
str r5, [r1, #0x5c0] /* DDRMODE */
str r6, [r1, #0x33c] /* DRAM_SODT0*/
str r7, [r1, #0x340] /* DRAM_SODT1*/
ldmea r0!, {r4-r7}
str r4, [r1, #0x330] /* DRAM_SDCKE0 */
str r5, [r1, #0x334] /* DRAM_SDCKE1 */
str r6, [r1, #0x320] /* DRAM_RESET */
str r7, [r1, #0x5c8] /* GPR_CTLDS */
.endm
.macro sl_ddr_io_set_lpm
mov r0, #0
str r0, [r1, #0x30c] /* DRAM_DQM0 */
str r0, [r1, #0x310] /* DRAM_DQM1 */
str r0, [r1, #0x314] /* DRAM_DQM2 */
str r0, [r1, #0x318] /* DRAM_DQM3 */
str r0, [r1, #0x344] /* DRAM_SDQS0 */
str r0, [r1, #0x348] /* DRAM_SDQS1 */
str r0, [r1, #0x34c] /* DRAM_SDQS2 */
str r0, [r1, #0x350] /* DRAM_SDQS3 */
str r0, [r1, #0x5c4] /* GPR_B0DS */
str r0, [r1, #0x5cc] /* GPR_B1DS */
str r0, [r1, #0x5d4] /* GPR_B2DS */
str r0, [r1, #0x5d8] /* GPR_B3DS */
str r0, [r1, #0x300] /* DRAM_CAS */
str r0, [r1, #0x31c] /* DRAM_RAS */
str r0, [r1, #0x338] /* DRAM_SDCLK_0 */
str r0, [r1, #0x5ac] /* GPR_ADDS*/
str r0, [r1, #0x5b0] /* DDRMODE_CTL */
str r0, [r1, #0x5c0] /* DDRMODE */
str r0, [r1, #0x33c] /* DRAM_SODT0*/
str r0, [r1, #0x340] /* DRAM_SODT1*/
str r0, [r1, #0x5c8] /* GPR_CTLDS */
mov r0, #0x80000
str r0, [r1, #0x320] /* DRAM_RESET */
mov r0, #0x1000
str r0, [r1, #0x330] /* DRAM_SDCKE0 */
str r0, [r1, #0x334] /* DRAM_SDCKE1 */
.endm
.macro dl_ddr_io_save
ldr r4, [r1, #0x470] /* DRAM_DQM0 */
......@@ -455,11 +572,12 @@ Flush and disable L1 dcache
.endm
ENTRY(mx6q_suspend)
ENTRY(mx6_suspend)
stmfd sp!, {r0-r12} @ Save registers
/*************************************************************
suspend mode entry
*************************************************************/
mov r12, r3 /* Save CPU type to r12*/
cmp r0, #0x1
bne dormant /* dormant mode */
......@@ -537,21 +655,34 @@ saved register and context as below:
CPSR
SCTLR
************************************************************/
ddr_iomux_save:
/* save mmdc iomux setting, stack is from the tail of
iram_suspend base */
mov r0, r2 /* get suspend_iram_base */
add r0, r0, #IRAM_SUSPEND_SIZE /* 4K */
mov r4, sp @ Store sp
mrs r5, spsr @ Store spsr
mov r6, lr @ Store lr
mov r7, r12 @ Store cpu type
stmfd r0!, {r4-r7}
ldr r1, =MX6Q_IOMUXC_BASE_ADDR
add r1, r1, #PERIPBASE_VIRT
cmp r12, #MXC_CPU_MX6Q
bne dl_io_save
dq_ddr_io_save
b ddr_io_save_done
dl_io_save:
cmp r12, #MXC_CPU_MX6DL
bne sl_io_save
dl_ddr_io_save
b ddr_io_save_done
sl_io_save:
sl_ddr_io_save
mov r4, sp @ Store sp
mrs r5, spsr @ Store spsr
mov r6, lr @ Store lr
stmfd r0!, {r4-r6}
ddr_io_save_done:
/* c1 and c2 registers */
mrc p15, 0, r4, c1, c0, 2 @ CPACR
......@@ -614,11 +745,24 @@ refresh:
ldr r1, =MX6Q_IOMUXC_BASE_ADDR
add r1, r1, #PERIPBASE_VIRT
cmp r12, #MXC_CPU_MX6Q
bne dl_io_set_lpm
dq_ddr_io_set_lpm
b ddr_io_set_lpm_done
dl_io_set_lpm:
cmp r12, #MXC_CPU_MX6DL
bne sl_io_set_lpm
dl_ddr_io_set_lpm
b ddr_io_set_lpm_done
sl_io_set_lpm:
sl_ddr_io_set_lpm
ddr_io_set_lpm_done:
/****************************************************************
save resume pointer into SRC_GPR1
****************************************************************/
ldr r0, =mx6q_suspend
ldr r0, =mx6_suspend
ldr r1, =resume
sub r1, r1, r0
add r3, r3, r1
......@@ -645,7 +789,19 @@ system immediately.
ldr r1, =MX6Q_IOMUXC_BASE_ADDR
add r1, r1, #PERIPBASE_VIRT
cmp r12, #MXC_CPU_MX6Q
bne dl_io_restore
dq_ddr_io_restore
b ddr_io_restore_done
dl_io_restore:
cmp r12, #MXC_CPU_MX6DL
bne sl_io_restore
dl_ddr_io_restore
b ddr_io_restore_done
sl_io_restore:
sl_ddr_io_restore
ddr_io_restore_done:
mrc p15, 0, r1, c1, c0, 0
orr r1, r1, #(1 << 2) @ Enable the C bit
......@@ -665,14 +821,29 @@ resume:
str r1, [r0, #SRC_GPR1_OFFSET] /* clear SRC_GPR1 */
ldr r0, [r0, #SRC_GPR2_OFFSET]
/* Restore cp15 registers and cpu type */
ldmea r0!, {r4-r7}
mov sp, r4 @ Restore sp
msr spsr_cxsf, r5 @ Restore spsr
mov lr, r6 @ Restore lr
mov r12, r7 @ Restore cpu type
/* Restore DDR IO */
ldr r1, =MX6Q_IOMUXC_BASE_ADDR
cmp r12, #MXC_CPU_MX6Q
bne dl_io_dsm_restore
dq_ddr_io_restore
b ddr_io_restore_dsm_done
dl_io_dsm_restore:
cmp r12, #MXC_CPU_MX6DL
bne sl_io_dsm_restore
dl_ddr_io_restore
b ddr_io_restore_dsm_done
sl_io_dsm_restore:
sl_ddr_io_restore
/* Restore cp15 registers */
ldmea r0!, {r4-r6}
mov sp, r4
msr spsr_cxsf, r5 @ Restore spsr
mov lr, r6 @ Restore lr
ddr_io_restore_dsm_done:
/* c1 and c2 registers */
ldmea r0!, {r4-r7}
......@@ -798,7 +969,15 @@ restore control register to enable cache
* enabling MMU.
*/
ldr r4, =PAGE_OFFSET
cmp r12, #MXC_CPU_MX6SL
bne dq_dl_phy_offset
ldr r5, =MX6SL_PHYS_OFFSET
b get_phy_offset_done
dq_dl_phy_offset:
ldr r5, =MX6_PHYS_OFFSET
get_phy_offset_done:
sub r4, r4, r5
add r4, r4, r10
str r9, [r4]
......@@ -825,8 +1004,7 @@ out:
ldmfd sp!, {r0-r12}
mov pc, lr
.equ va2pa_offset, (PAGE_OFFSET - MX6_PHYS_OFFSET)
.type mx6q_do_suspend, #object
ENTRY(mx6q_do_suspend)
.word mx6q_suspend
.size mx6q_suspend, . - mx6q_suspend
.type mx6_do_suspend, #object
ENTRY(mx6_do_suspend)
.word mx6_suspend
.size mx6_suspend, . - mx6_suspend
......@@ -49,6 +49,7 @@
#define GPC_ISR3_OFFSET 0x20
#define GPC_ISR4_OFFSET 0x24
#define GPC_CNTR_OFFSET 0x0
#define GPC_PGC_DISP_PGCR_OFFSET 0x240
#define GPC_PGC_GPU_PGCR_OFFSET 0x260
#define GPC_PGC_CPU_PDN_OFFSET 0x2a0
#define GPC_PGC_CPU_PUPSCR_OFFSET 0x2a4
......@@ -70,7 +71,7 @@ static struct pm_platform_data *pm_data;
#if defined(CONFIG_CPU_FREQ)
extern int set_cpu_freq(int wp);
#endif
extern void mx6q_suspend(suspend_state_t state);
extern void mx6_suspend(suspend_state_t state);
extern void mx6_init_irq(void);
extern unsigned int gpc_wake_irq[4];
......@@ -86,11 +87,11 @@ static void __iomem *anatop_base;
static void *suspend_iram_base;
static void (*suspend_in_iram)(suspend_state_t state,
unsigned long iram_paddr, unsigned long suspend_iram_base) = NULL;
unsigned long iram_paddr, unsigned long suspend_iram_base, unsigned int cpu_type) = NULL;
static unsigned long iram_paddr, cpaddr;
static u32 ccm_ccr, ccm_clpcr, scu_ctrl;
static u32 gpc_imr[4], gpc_cpu_pup, gpc_cpu_pdn, gpc_cpu, gpc_ctr;
static u32 gpc_imr[4], gpc_cpu_pup, gpc_cpu_pdn, gpc_cpu, gpc_ctr, gpc_disp;
static u32 anatop[2], ccgr1, ccgr2, ccgr3, ccgr6;
static u32 ccm_analog_pfd528;
static bool usb_vbus_wakeup_enabled;
......@@ -236,6 +237,8 @@ static void mx6_suspend_store(void)
gpc_cpu_pdn = __raw_readl(gpc_base + GPC_PGC_CPU_PDNSCR_OFFSET);
gpc_cpu = __raw_readl(gpc_base + GPC_PGC_CPU_PDN_OFFSET);
gpc_ctr = __raw_readl(gpc_base + GPC_CNTR_OFFSET);
if (cpu_is_mx6sl())
gpc_disp = __raw_readl(gpc_base + GPC_PGC_DISP_PGCR_OFFSET);
anatop[0] = __raw_readl(anatop_base + ANATOP_REG_2P5_OFFSET);
anatop[1] = __raw_readl(anatop_base + ANATOP_REG_CORE_OFFSET);
}
......@@ -261,7 +264,8 @@ static void mx6_suspend_restore(void)
__raw_writel(gpc_cpu_pup, gpc_base + GPC_PGC_CPU_PUPSCR_OFFSET);
__raw_writel(gpc_cpu_pdn, gpc_base + GPC_PGC_CPU_PDNSCR_OFFSET);
__raw_writel(gpc_cpu, gpc_base + GPC_PGC_CPU_PDN_OFFSET);
if (cpu_is_mx6sl())
__raw_writel(gpc_disp, gpc_base + GPC_PGC_DISP_PGCR_OFFSET);
__raw_writel(ccgr1, MXC_CCM_CCGR1);
__raw_writel(ccgr2, MXC_CCM_CCGR2);
__raw_writel(ccgr3, MXC_CCM_CCGR3);
......@@ -272,9 +276,17 @@ static void mx6_suspend_restore(void)
static int mx6_suspend_enter(suspend_state_t state)
{
unsigned int wake_irq_isr[4];
unsigned int cpu_type;
struct gic_dist_state gds;
struct gic_cpu_state gcs;
if (cpu_is_mx6q())
cpu_type = MXC_CPU_MX6Q;
else if (cpu_is_mx6dl())
cpu_type = MXC_CPU_MX6DL;
else
cpu_type = MXC_CPU_MX6SL;
wake_irq_isr[0] = __raw_readl(gpc_base +
GPC_ISR1_OFFSET) & gpc_wake_irq[0];
wake_irq_isr[1] = __raw_readl(gpc_base +
......@@ -326,7 +338,7 @@ static int mx6_suspend_enter(suspend_state_t state)
}
suspend_in_iram(state, (unsigned long)iram_paddr,
(unsigned long)suspend_iram_base);
(unsigned long)suspend_iram_base, cpu_type);
if (state == PM_SUSPEND_MEM) {
/* restore gic registers */
......@@ -428,7 +440,7 @@ static int __init pm_init(void)
* Need to run the suspend code from IRAM as the DDR needs
* to be put into low power mode manually.
*/
memcpy((void *)cpaddr, mx6q_suspend, SZ_4K);
memcpy((void *)cpaddr, mx6_suspend, SZ_4K);
suspend_in_iram = (void *)suspend_iram_base;
......
......@@ -37,6 +37,7 @@
#define SCU_INVALIDATE 0x0c
#define SCU_FPGA_REVISION 0x10
#define GPC_CNTR_OFFSET 0x0
#define GPC_PGC_DISP_PGCR_OFFSET 0x240
#define GPC_PGC_GPU_PGCR_OFFSET 0x260
#define GPC_PGC_CPU_PDN_OFFSET 0x2a0
#define GPC_PGC_CPU_PUPSCR_OFFSET 0x2a4
......@@ -79,7 +80,7 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
int stop_mode = 0;
void __iomem *anatop_base = IO_ADDRESS(ANATOP_BASE_ADDR);
u32 ccm_clpcr, anatop_val;
u32 ccm_clpcr, anatop_val, reg;
ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK);
......@@ -96,21 +97,33 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY;
ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS;
if (cpu_is_mx6sl()) {
ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH0_LPM_HS;
ccm_clpcr |= MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY;
} else
ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS;
stop_mode = 0;
} else if (mode == STOP_POWER_OFF) {
ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET;
ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS;
if (cpu_is_mx6sl()) {
ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH0_LPM_HS;
ccm_clpcr |= MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY;
} else
ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS;
stop_mode = 1;
} else {
ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET;
ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS;
if (cpu_is_mx6sl()) {
ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH0_LPM_HS;
ccm_clpcr |= MXC_CCM_CLPCR_BYPASS_PMIC_VFUNC_READY;
} else
ccm_clpcr |= MXC_CCM_CLPCR_BYP_MMDC_CH1_LPM_HS;
stop_mode = 2;
}
break;
......@@ -134,7 +147,11 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
__raw_writel(0x1, gpc_base + GPC_PGC_CPU_PDN_OFFSET);
__raw_writel(0x1, gpc_base + GPC_PGC_GPU_PGCR_OFFSET);
__raw_writel(0x1, gpc_base + GPC_CNTR_OFFSET);
if (cpu_is_mx6q()) {
if (cpu_is_mx6sl()) {
__raw_writel(0x1, gpc_base + GPC_PGC_DISP_PGCR_OFFSET);
__raw_writel(0x10, gpc_base + GPC_CNTR_OFFSET);
}
if (cpu_is_mx6q() || cpu_is_mx6dl()) {
/* Enable weak 2P5 linear regulator */
anatop_val = __raw_readl(anatop_base +
HW_ANADIG_REG_2P5);
......@@ -149,8 +166,24 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
__raw_writel(anatop_val, anatop_base +
HW_ANADIG_REG_CORE);
}
} else {
/* Disable VDDHIGH_IN to VDDSNVS_IN power path,
* only used when VDDSNVS_IN is powered by dedicated
* power rail */
anatop_val = __raw_readl(anatop_base +
HW_ANADIG_ANA_MISC0);
anatop_val |= BM_ANADIG_ANA_MISC0_RTC_RINGOSC_EN;
__raw_writel(anatop_val, anatop_base +
HW_ANADIG_ANA_MISC0);
/* We need to allow the memories to be clock gated
* in STOP mode, else the power consumption will
* be very high. */
reg = __raw_readl(MXC_CCM_CGPR);
reg |= MXC_CCM_CGPR_MEM_IPG_STOP_MASK;
__raw_writel(reg, MXC_CCM_CGPR);
}
if (cpu_is_mx6q())
if (!cpu_is_mx6dl())
__raw_writel(__raw_readl(MXC_CCM_CCR) |
MXC_CCM_CCR_RBC_EN, MXC_CCM_CCR);
/* Make sure we clear WB_COUNT and re-config it */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment