diff options
author | Ranjani Vaidyanathan <ra5478@freescale.com> | 2013-07-12 17:24:11 -0500 |
---|---|---|
committer | Terry Lv <r65388@freescale.com> | 2013-07-25 12:46:28 +0800 |
commit | 7b60e285b7b019185389326c2d989f5e42d9736e (patch) | |
tree | 9027d1a9b401018c8c8c81827529b855ad94c8bd | |
parent | 5b402809af785fdd61f1597ac7eda930f1477d6a (diff) |
ENGR00270573-1 [MX6SL]Add support for dynamic Power Gating of the display MIX
The display MIX can be power gated when EPDC, PXP and LCDIF are all inactive.
This will save around 1.5mW-1.8mW of power in system IDLE mode.
Signed-off-by: Ranjani Vaidyanathan <ra5478@freescale.com>
-rwxr-xr-x | arch/arm/mach-mx6/board-mx6sl_arm2.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-mx6/board-mx6sl_evk.c | 2 | ||||
-rwxr-xr-x | arch/arm/mach-mx6/clock_mx6sl.c | 37 | ||||
-rw-r--r-- | arch/arm/mach-mx6/pm.c | 53 | ||||
-rw-r--r-- | arch/arm/plat-mxc/include/mach/epdc.h | 3 |
5 files changed, 45 insertions, 52 deletions
diff --git a/arch/arm/mach-mx6/board-mx6sl_arm2.c b/arch/arm/mach-mx6/board-mx6sl_arm2.c index 63fd57960cb8..9d4b3e37799b 100755 --- a/arch/arm/mach-mx6/board-mx6sl_arm2.c +++ b/arch/arm/mach-mx6/board-mx6sl_arm2.c @@ -877,6 +877,7 @@ static struct imx_epdc_fb_platform_data epdc_data = { .put_pins = epdc_put_pins, .enable_pins = epdc_enable_pins, .disable_pins = epdc_disable_pins, + .pg_display_mix = true, }; static int spdc_get_pins(void) @@ -1104,6 +1105,7 @@ static struct mxc_fb_platform_data fb_data[] = { .mode_str = "SEIKO-WVGA", .mode = video_modes, .num_modes = ARRAY_SIZE(video_modes), + .pg_display_mix = true, }, }; diff --git a/arch/arm/mach-mx6/board-mx6sl_evk.c b/arch/arm/mach-mx6/board-mx6sl_evk.c index 082845ba22a3..ef92719ef79d 100644 --- a/arch/arm/mach-mx6/board-mx6sl_evk.c +++ b/arch/arm/mach-mx6/board-mx6sl_evk.c @@ -1084,6 +1084,7 @@ static struct imx_epdc_fb_platform_data epdc_data = { .put_pins = epdc_put_pins, .enable_pins = epdc_enable_pins, .disable_pins = epdc_disable_pins, + .pg_display_mix = true, }; static int spdc_get_pins(void) @@ -1316,6 +1317,7 @@ static struct mxc_fb_platform_data wvga_fb_data[] = { .mode_str = "SEIKO-WVGA", .mode = wvga_video_modes, .num_modes = ARRAY_SIZE(wvga_video_modes), + .pg_display_mix = true, }, }; diff --git a/arch/arm/mach-mx6/clock_mx6sl.c b/arch/arm/mach-mx6/clock_mx6sl.c index f375b4ac9dd4..e95c45484362 100755 --- a/arch/arm/mach-mx6/clock_mx6sl.c +++ b/arch/arm/mach-mx6/clock_mx6sl.c @@ -89,6 +89,11 @@ DEFINE_SPINLOCK(mx6sl_clk_lock); #define MXC_TPRER 0x04 #define V2_TPRER_PRE24M_OFFSET 12 #define V2_TPRER_PRE24M_MASK 0xF +#define GPC_CNTR_OFFSET 0x0 +#define GPC_PGC_DISP_PGCR_OFFSET 0x240 +#define GPC_PGC_DISP_PUPSCR_OFFSET 0x244 +#define GPC_PGC_DISP_PDNSCR_OFFSET 0x248 +#define GPC_PGC_DISP_SR_OFFSET 0x24c /* We need to check the exp status again after timer expiration, * as there might be interrupt coming between the first time exp @@ -1899,6 +1904,33 @@ static struct clk i2c_clk[] = { }, }; +static int _display_mix_enable(struct clk *clk) +{ + if (cpu_is_mx6sl() && (mx6sl_revision() >= IMX_CHIP_REVISION_1_2)) { + __raw_writel(0x0, gpc_base + GPC_PGC_DISP_PGCR_OFFSET); + __raw_writel(0x20, gpc_base + GPC_CNTR_OFFSET); + __raw_writel(0x1, gpc_base + GPC_PGC_DISP_SR_OFFSET); + } + return 0; +} + +static void _display_mix_disable(struct clk *clk) +{ + if (cpu_is_mx6sl() && (mx6sl_revision() >= IMX_CHIP_REVISION_1_2)) { + __raw_writel(0x101, gpc_base + GPC_PGC_DISP_PUPSCR_OFFSET); + __raw_writel(0x101, gpc_base + GPC_PGC_DISP_PDNSCR_OFFSET); + + __raw_writel(0x1, gpc_base + GPC_PGC_DISP_PGCR_OFFSET); + __raw_writel(0x10, gpc_base + GPC_CNTR_OFFSET); + } +} + +static struct clk display_mix = { + __INIT_CLK_DEBUG(display_mix) + .enable = _display_mix_enable, + .disable = _display_mix_disable, +}; + static int _clk_ipu1_set_parent(struct clk *clk, struct clk *parent) { int mux; @@ -2037,6 +2069,7 @@ static struct clk ipu2_clk = { .set_rate = _clk_ipu2_set_rate, .get_rate = _clk_ipu2_get_rate, .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, + .secondary = &display_mix, }; static struct clk usdhc_dep_clk = { @@ -2803,6 +2836,7 @@ static struct clk pxp_axi_clk = { .round_rate = _clk_pxp_epdc_axi_round_rate, .get_rate = _clk_pxp_axi_get_rate, .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, + .secondary = &display_mix, }; static struct clk epdc_axi_clk = { @@ -2818,6 +2852,7 @@ static struct clk epdc_axi_clk = { .round_rate = _clk_pxp_epdc_axi_round_rate, .get_rate = _clk_epdc_axi_get_rate, .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, + .secondary = &display_mix, }; static unsigned long _clk_lcdif_pix_get_rate(struct clk *clk) @@ -2967,6 +3002,7 @@ static struct clk lcdif_pix_clk = { .round_rate = _clk_epdc_lcdif_pix_round_rate, .get_rate = _clk_lcdif_pix_get_rate, .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, + .secondary = &display_mix, }; static struct clk epdc_pix_clk = { @@ -2982,6 +3018,7 @@ static struct clk epdc_pix_clk = { .round_rate = _clk_epdc_lcdif_pix_round_rate, .get_rate = _clk_epdc_pix_get_rate, .flags = AHB_HIGH_SET_POINT | CPU_FREQ_TRIG_UPDATE, + .secondary = &display_mix, }; static unsigned long _clk_spdif_round_rate(struct clk *clk, unsigned long rate) diff --git a/arch/arm/mach-mx6/pm.c b/arch/arm/mach-mx6/pm.c index d9c04e11bed0..f2efa00efb47 100644 --- a/arch/arm/mach-mx6/pm.c +++ b/arch/arm/mach-mx6/pm.c @@ -50,11 +50,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_DISP_PUPSCR_OFFSET 0x244 -#define GPC_PGC_DISP_PDNSCR_OFFSET 0x248 -#define GPC_PGC_DISP_SR_OFFSET 0x24c -#define GPC_PGC_GPU_PGCR_OFFSET 0x260 +#define GPC_PGC_DISP_PGCR_OFFSET 0x240 #define GPC_PGC_CPU_PDN_OFFSET 0x2a0 #define GPC_PGC_CPU_PUPSCR_OFFSET 0x2a4 #define GPC_PGC_CPU_PDNSCR_OFFSET 0x2a8 @@ -174,47 +170,6 @@ static void usb_power_up_handler(void) } -static void disp_power_down(void) -{ - if (cpu_is_mx6sl() && (mx6sl_revision() >= IMX_CHIP_REVISION_1_2)) { - - __raw_writel(0xFFFFFFFF, gpc_base + GPC_PGC_DISP_PUPSCR_OFFSET); - __raw_writel(0xFFFFFFFF, gpc_base + GPC_PGC_DISP_PDNSCR_OFFSET); - - __raw_writel(0x1, gpc_base + GPC_PGC_DISP_PGCR_OFFSET); - __raw_writel(0x10, gpc_base + GPC_CNTR_OFFSET); - - /* Disable EPDC/LCDIF pix clock, and EPDC/LCDIF/PXP axi clock */ - __raw_writel(ccgr3 & - ~MXC_CCM_CCGRx_CG5_MASK & - ~MXC_CCM_CCGRx_CG4_MASK & - ~MXC_CCM_CCGRx_CG3_MASK & - ~MXC_CCM_CCGRx_CG2_MASK & - ~MXC_CCM_CCGRx_CG1_MASK, MXC_CCM_CCGR3); - - } -} - -static void disp_power_up(void) -{ - if (cpu_is_mx6sl() && (mx6sl_revision() >= IMX_CHIP_REVISION_1_2)) { - /* - * Need to enable EPDC/LCDIF pix clock, and - * EPDC/LCDIF/PXP axi clock before power up. - */ - __raw_writel(ccgr3 | - MXC_CCM_CCGRx_CG5_MASK | - MXC_CCM_CCGRx_CG4_MASK | - MXC_CCM_CCGRx_CG3_MASK | - MXC_CCM_CCGRx_CG2_MASK | - MXC_CCM_CCGRx_CG1_MASK, MXC_CCM_CCGR3); - - __raw_writel(0x0, gpc_base + GPC_PGC_DISP_PGCR_OFFSET); - __raw_writel(0x20, gpc_base + GPC_CNTR_OFFSET); - __raw_writel(0x1, gpc_base + GPC_PGC_DISP_SR_OFFSET); - } -} - static void mx6_suspend_store(void) { /* save some settings before suspend */ @@ -319,14 +274,12 @@ static int mx6_suspend_enter(suspend_state_t state) switch (state) { case PM_SUSPEND_MEM: - disp_power_down(); usb_power_down_handler(); mxc_cpu_lp_set(ARM_POWER_OFF); arm_pg = true; break; case PM_SUSPEND_STANDBY: if (cpu_is_mx6sl()) { - disp_power_down(); usb_power_down_handler(); mxc_cpu_lp_set(STOP_XTAL_ON); arm_pg = true; @@ -394,10 +347,8 @@ static int mx6_suspend_enter(suspend_state_t state) restore_gic_dist_state(0, &gds); restore_gic_cpu_state(0, &gcs); } - if (state == PM_SUSPEND_MEM || (cpu_is_mx6sl())) { + if (state == PM_SUSPEND_MEM || (cpu_is_mx6sl())) usb_power_up_handler(); - disp_power_up(); - } mx6_suspend_restore(); diff --git a/arch/arm/plat-mxc/include/mach/epdc.h b/arch/arm/plat-mxc/include/mach/epdc.h index 36aac88230c8..08fef76148f3 100644 --- a/arch/arm/plat-mxc/include/mach/epdc.h +++ b/arch/arm/plat-mxc/include/mach/epdc.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. + * Copyright (C) 2011-2013 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -36,6 +36,7 @@ struct imx_epdc_fb_platform_data { void (*put_pins) (void); void (*enable_pins) (void); void (*disable_pins) (void); + bool pg_display_mix; }; struct imx_spdc_panel_init_set { |