summaryrefslogtreecommitdiff
path: root/arch/arm/mach-imx/pm-imx6.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-imx/pm-imx6.c')
-rw-r--r--arch/arm/mach-imx/pm-imx6.c48
1 files changed, 46 insertions, 2 deletions
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c
index e0f59360bd9e..9d3d0bdee56f 100644
--- a/arch/arm/mach-imx/pm-imx6.c
+++ b/arch/arm/mach-imx/pm-imx6.c
@@ -65,6 +65,7 @@
#define MX6Q_SUSPEND_OCRAM_SIZE 0x1000
#define MX6_MAX_MMDC_IO_NUM 33
+#define MX6_MAX_MMDC_NUM 34
extern unsigned long iram_tlb_base_addr;
extern unsigned long iram_tlb_phys_addr;
@@ -101,6 +102,8 @@ struct imx6_pm_socdata {
const char *pl310_compat;
const u32 mmdc_io_num;
const u32 *mmdc_io_offset;
+ const u32 mmdc_num;
+ const u32 *mmdc_offset;
};
static const u32 imx6q_mmdc_io_offset[] __initconst = {
@@ -150,6 +153,16 @@ static const u32 imx6ul_mmdc_io_offset[] __initconst = {
0x494, 0x4b0, /* MODE_CTL, MODE, */
};
+static const u32 imx6ul_mmdc_offset[] __initconst = {
+ 0x01c, 0x800, 0x80c, 0x83c,
+ 0x848, 0x850, 0x81c, 0x820,
+ 0x82c, 0x830, 0x8c0, 0x8b8,
+ 0x004, 0x008, 0x00c, 0x010,
+ 0x014, 0x018, 0x01c, 0x02c,
+ 0x030, 0x040, 0x000, 0x01c,
+ 0x020, 0x818, 0x01c,
+};
+
static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
.mmdc_compat = "fsl,imx6q-mmdc",
.src_compat = "fsl,imx6q-src",
@@ -158,6 +171,8 @@ static const struct imx6_pm_socdata imx6q_pm_data __initconst = {
.pl310_compat = "arm,pl310-cache",
.mmdc_io_num = ARRAY_SIZE(imx6q_mmdc_io_offset),
.mmdc_io_offset = imx6q_mmdc_io_offset,
+ .mmdc_num = 0,
+ .mmdc_offset = NULL,
};
static const struct imx6_pm_socdata imx6dl_pm_data __initconst = {
@@ -168,6 +183,8 @@ static const struct imx6_pm_socdata imx6dl_pm_data __initconst = {
.pl310_compat = "arm,pl310-cache",
.mmdc_io_num = ARRAY_SIZE(imx6dl_mmdc_io_offset),
.mmdc_io_offset = imx6dl_mmdc_io_offset,
+ .mmdc_num = 0,
+ .mmdc_offset = NULL,
};
static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
@@ -178,6 +195,8 @@ static const struct imx6_pm_socdata imx6sl_pm_data __initconst = {
.pl310_compat = "arm,pl310-cache",
.mmdc_io_num = ARRAY_SIZE(imx6sl_mmdc_io_offset),
.mmdc_io_offset = imx6sl_mmdc_io_offset,
+ .mmdc_num = 0,
+ .mmdc_offset = NULL,
};
static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
@@ -188,6 +207,8 @@ static const struct imx6_pm_socdata imx6sx_pm_data __initconst = {
.pl310_compat = "arm,pl310-cache",
.mmdc_io_num = ARRAY_SIZE(imx6sx_mmdc_io_offset),
.mmdc_io_offset = imx6sx_mmdc_io_offset,
+ .mmdc_num = 0,
+ .mmdc_offset = NULL,
};
static const struct imx6_pm_socdata imx6ul_pm_data __initconst = {
@@ -198,6 +219,8 @@ static const struct imx6_pm_socdata imx6ul_pm_data __initconst = {
.pl310_compat = NULL,
.mmdc_io_num = ARRAY_SIZE(imx6ul_mmdc_io_offset),
.mmdc_io_offset = imx6ul_mmdc_io_offset,
+ .mmdc_num = ARRAY_SIZE(imx6ul_mmdc_offset),
+ .mmdc_offset = imx6ul_mmdc_offset,
};
static struct map_desc iram_tlb_io_desc __initdata = {
@@ -253,6 +276,8 @@ struct imx6_cpu_pm_info {
u32 ttbr1; /* Store TTBR1 */
u32 mmdc_io_num; /* Number of MMDC IOs which need saved/restored. */
u32 mmdc_io_val[MX6_MAX_MMDC_IO_NUM][2]; /* To save offset and value */
+ u32 mmdc_num; /* Number of MMDC registers which need saved/restored. */
+ u32 mmdc_val[MX6_MAX_MMDC_NUM][2];
} __aligned(8);
unsigned long save_ttbr1(void)
@@ -579,6 +604,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
unsigned long iram_paddr;
int i, ret = 0;
const u32 *mmdc_offset_array;
+ const u32 *mmdc_io_offset_array;
suspend_set_ops(&imx6q_pm_ops);
@@ -642,16 +668,34 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata)
pm_info->ddr_type = imx_mmdc_get_ddr_type();
pm_info->mmdc_io_num = socdata->mmdc_io_num;
- mmdc_offset_array = socdata->mmdc_io_offset;
+ mmdc_io_offset_array = socdata->mmdc_io_offset;
+ pm_info->mmdc_num = socdata->mmdc_num;
+ mmdc_offset_array = socdata->mmdc_offset;
for (i = 0; i < pm_info->mmdc_io_num; i++) {
pm_info->mmdc_io_val[i][0] =
- mmdc_offset_array[i];
+ mmdc_io_offset_array[i];
pm_info->mmdc_io_val[i][1] =
readl_relaxed(pm_info->iomuxc_base.vbase +
+ mmdc_io_offset_array[i]);
+ }
+
+ /* initialize MMDC settings */
+ for (i = 0; i < pm_info->mmdc_num; i++) {
+ pm_info->mmdc_val[i][0] =
+ mmdc_offset_array[i];
+ pm_info->mmdc_val[i][1] =
+ readl_relaxed(pm_info->mmdc_base.vbase +
mmdc_offset_array[i]);
}
+ /* need to overwrite the value for some mmdc registers */
+ if (cpu_is_imx6ul()) {
+ pm_info->mmdc_val[20][1] = (pm_info->mmdc_val[20][1]
+ & 0xffff0000) | 0x0202;
+ pm_info->mmdc_val[23][1] = 0x8033;
+ }
+
imx6_suspend_in_ocram_fn = fncpy(
suspend_ocram_base + sizeof(*pm_info),
&imx6_suspend,