diff options
author | Colin Cross <ccross@android.com> | 2011-11-03 22:09:11 -0700 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2011-11-03 22:09:11 -0700 |
commit | f1e5f49f2f2ed46e5356e091de1e86dc08b20d85 (patch) | |
tree | bfc8970948e006af8069a5f732bbd59c0f18bf34 /arch/arm/mach-omap2 | |
parent | 70c7a98bb28405787cf7aaf9d8a216b559bd4a35 (diff) | |
parent | 90672f17369273aba3fb402d5c41752686c65d53 (diff) | |
download | kernel_samsung_tuna-f1e5f49f2f2ed46e5356e091de1e86dc08b20d85.zip kernel_samsung_tuna-f1e5f49f2f2ed46e5356e091de1e86dc08b20d85.tar.gz kernel_samsung_tuna-f1e5f49f2f2ed46e5356e091de1e86dc08b20d85.tar.bz2 |
Merge branch 'android-omap-3.0' into android-omap-tuna-3.0
Conflicts:
arch/arm/mach-omap2/dpll3xxx.c
Change-Id: Ie53daed5cabbadef73d18969263ff2f7b77b3dc7
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r-- | arch/arm/mach-omap2/clock.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-omap2/dpll3xxx.c | 58 | ||||
-rw-r--r-- | arch/arm/mach-omap2/mailbox.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-omap2/mux.c | 49 | ||||
-rw-r--r-- | arch/arm/mach-omap2/mux.h | 20 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm24xx.c | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/pm34xx.c | 2 | ||||
-rwxr-xr-x | arch/arm/mach-omap2/pm44xx.c | 19 | ||||
-rw-r--r-- | arch/arm/mach-omap2/prcm-debug.c | 11 |
9 files changed, 137 insertions, 28 deletions
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index da332d2..450aabf 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -41,6 +41,7 @@ /* CM_CLKEN_PLL*.EN* bit values - not all are available for every DPLL */ #define DPLL_LOW_POWER_STOP 0x1 +#define DPLL_MN_BYPASS 0x4 #define DPLL_LOW_POWER_BYPASS 0x5 #define DPLL_LOCKED 0x7 diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index 38207d5..2499afb 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c @@ -32,8 +32,10 @@ #include <plat/clock.h> #include "clock.h" +#include "cm2_44xx.h" #include "cm2xxx_3xxx.h" #include "cm-regbits-34xx.h" +#include "cm-regbits-44xx.h" /* CM_AUTOIDLE_PLL*.AUTO_* bit values */ #define DPLL_AUTOIDLE_DISABLE 0x0 @@ -61,24 +63,75 @@ static void _omap3_dpll_write_clken(struct clk *clk, u8 clken_bits) static int _omap3_wait_dpll_status(struct clk *clk, u8 state) { const struct dpll_data *dd; - int i = 0; + int i; int ret = -EINVAL; + bool first_time = true; + u32 reg; + u32 orig_cm_div_m2_dpll_usb; + u32 orig_cm_clkdcoldo_dpll_usb; +retry: dd = clk->dpll_data; state <<= __ffs(dd->idlest_mask); + i = 0; while (((__raw_readl(dd->idlest_reg) & dd->idlest_mask) != state) && i < MAX_DPLL_WAIT_TRIES) { i++; udelay(1); } + /* restore back old values if hit work-around */ + if (!first_time) { + __raw_writel(orig_cm_div_m2_dpll_usb, + OMAP4430_CM_DIV_M2_DPLL_USB); + __raw_writel(orig_cm_clkdcoldo_dpll_usb, + OMAP4430_CM_CLKDCOLDO_DPLL_USB); + } + if (i == MAX_DPLL_WAIT_TRIES) { printk(KERN_ERR "clock: %s failed transition to '%s'\n", clk->name, (state) ? "locked" : "bypassed"); - /* Catch failing usb-dpll lock error */ + + /* Try Error Recovery: for failing usbdpll locking */ if (!strcmp(clk->name, "dpll_usb_ck")) { + reg = __raw_readl(dd->mult_div1_reg); + + /* Put in MN bypass */ + _omap3_dpll_write_clken(clk, DPLL_MN_BYPASS); + i = 0; + while (!(__raw_readl(dd->idlest_reg) & (1 << OMAP4430_ST_MN_BYPASS_SHIFT)) && + i < MAX_DPLL_WAIT_TRIES) { + i++; + udelay(1); + } + + /* MN bypass looses contents of CM_CLKSEL_DPLL_USB */ + __raw_writel(reg, dd->mult_div1_reg); + + /* Force generate request to PRCM: put in Force mode */ + + /* a) CM_DIV_M2_DPLL_USB.DPLL_CLKOUT_GATE_CTRL = 1 */ + orig_cm_div_m2_dpll_usb = __raw_readl(OMAP4430_CM_DIV_M2_DPLL_USB); + __raw_writel(orig_cm_div_m2_dpll_usb | + (1 << OMAP4430_DPLL_CLKOUT_GATE_CTRL_SHIFT), + OMAP4430_CM_DIV_M2_DPLL_USB); + + /* b) CM_CLKDCOLDO_DPLL_USB.DPLL_CLKDCOLDO_GATE_CTRL = 1 */ + orig_cm_clkdcoldo_dpll_usb = __raw_readl(OMAP4430_CM_CLKDCOLDO_DPLL_USB); + __raw_writel(orig_cm_clkdcoldo_dpll_usb | + (1 << OMAP4430_DPLL_CLKDCOLDO_GATE_CTRL_SHIFT), + OMAP4430_CM_CLKDCOLDO_DPLL_USB); + + /* Put back to locked mode */ + _omap3_dpll_write_clken(clk, DPLL_LOCKED); + + if (first_time) { + first_time = false; + goto retry; + } + pr_info("\n========== USB DPLL DUMP ===========\n"); pr_info("CM_CLKMODE_DPLL_USB :%08x\n", omap_readl(0x4A008180)); pr_info("CM_IDLEST_DPLL_USB :%08x\n", omap_readl(0x4A008184)); @@ -90,7 +143,6 @@ static int _omap3_wait_dpll_status(struct clk *clk, u8 state) pr_info("CM_CLKDCOLDO_DPLL_USB :%08x\n", omap_readl(0x4A0081B4)); pr_info("========== USB DPLL DUMP: End ===========\n"); } - } else { pr_debug("clock: %s transition to '%s' in %d loops\n", clk->name, (state) ? "locked" : "bypassed", i); diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c index d94205d..74750bf 100644 --- a/arch/arm/mach-omap2/mailbox.c +++ b/arch/arm/mach-omap2/mailbox.c @@ -397,6 +397,9 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev) } mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem) + return -ENODEV; + mbox_base = ioremap(mem->start, resource_size(mem)); if (!mbox_base) return -ENOMEM; diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index c3caae2..a2ed524 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c @@ -936,7 +936,7 @@ static struct omap_mux *omap_mux_get_by_gpio( } /* Needed for dynamic muxing of GPIO pins for off-idle */ -u16 omap_mux_get_gpio(int gpio) +struct omap_mux *omap_mux_get_gpio(int gpio) { struct omap_mux_partition *partition; struct omap_mux *m = NULL; @@ -944,13 +944,10 @@ u16 omap_mux_get_gpio(int gpio) list_for_each_entry(partition, &mux_partitions, node) { m = omap_mux_get_by_gpio(partition, gpio); if (m) - return omap_mux_read(partition, m->reg_offset); + return m; } - if (!m || m->reg_offset == OMAP_MUX_TERMINATOR) - pr_err("%s: Could not get gpio%i\n", __func__, gpio); - - return OMAP_MUX_TERMINATOR; + return NULL; } /* Needed for dynamic muxing of GPIO pins for off-idle */ @@ -971,6 +968,45 @@ void omap_mux_set_gpio(u16 val, int gpio) pr_err("%s: Could not set gpio%i\n", __func__, gpio); } +/* Has no locking, don't use on a pad that is remuxed (by hwmod or otherwise) */ +bool omap_mux_get_wakeupenable(struct omap_mux *m) +{ + u16 val; + if (IS_ERR_OR_NULL(m)) + return false; + + val = omap_mux_read(m->partition, m->reg_offset); + return val & OMAP_PIN_OFF_WAKEUPENABLE; +} + +/* Has no locking, don't use on a pad that is remuxed (by hwmod or otherwise) */ +int omap_mux_set_wakeupenable(struct omap_mux *m) +{ + u16 val; + if (IS_ERR_OR_NULL(m)) + return -EINVAL; + + val = omap_mux_read(m->partition, m->reg_offset); + val |= OMAP_PIN_OFF_WAKEUPENABLE; + omap_mux_write(m->partition, val, m->reg_offset); + + return 0; +} + +/* Has no locking, don't use on a pad that is remuxed (by hwmod or otherwise) */ +int omap_mux_clear_wakeupenable(struct omap_mux *m) +{ + u16 val; + if (IS_ERR_OR_NULL(m)) + return -EINVAL; + + val = omap_mux_read(m->partition, m->reg_offset); + val &= ~OMAP_PIN_OFF_WAKEUPENABLE; + omap_mux_write(m->partition, val, m->reg_offset); + + return 0; +} + static struct omap_mux * __init omap_mux_list_add( struct omap_mux_partition *partition, struct omap_mux *src) @@ -984,6 +1020,7 @@ static struct omap_mux * __init omap_mux_list_add( m = &entry->mux; entry->mux = *src; + m->partition = partition; #ifdef CONFIG_OMAP_MUX if (omap_mux_copy_names(src, m)) { diff --git a/arch/arm/mach-omap2/mux.h b/arch/arm/mach-omap2/mux.h index 47c47d1..87bf022 100644 --- a/arch/arm/mach-omap2/mux.h +++ b/arch/arm/mach-omap2/mux.h @@ -131,6 +131,7 @@ struct omap_mux_partition { struct omap_mux { u16 reg_offset; u16 gpio; + struct omap_mux_partition *partition; #ifdef CONFIG_OMAP_MUX char *muxnames[OMAP_MUX_NR_MODES]; #ifdef CONFIG_DEBUG_FS @@ -264,11 +265,26 @@ static struct omap_board_mux *board_mux __initdata __maybe_unused; #endif /** - * omap_mux_get_gpio() - get mux register value based on GPIO number + * omap_mux_get_gpio() - get mux struct based on GPIO number * @gpio: GPIO number * */ -u16 omap_mux_get_gpio(int gpio); +struct omap_mux *omap_mux_get_gpio(int gpio); + +/** omap_mux_set_wakeupenable() - set the wakeupenable bit on a mux struct + * @m: mux struct + */ +int omap_mux_set_wakeupenable(struct omap_mux *m); + +/** omap_mux_clear_wakeupenable() - clear the wakeupenable bit on a mux struct + * @m: mux struct + */ +int omap_mux_clear_wakeupenable(struct omap_mux *m); + +/** omap_mux_get_wakeupenable() - get the wakeupenable bit from a mux struct + * @m: mux struct + */ +bool omap_mux_get_wakeupenable(struct omap_mux *m); /** * omap_mux_set_gpio() - set mux register value based on GPIO number diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index fb999bc..faa8463 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -148,7 +148,7 @@ no_sleep: tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC; omap2_pm_dump(0, 1, tmp); } - omap2_gpio_resume_after_idle(); + omap2_gpio_resume_after_idle(0); clk_enable(osc_ck); diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 321a7e6..535480f 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -449,7 +449,7 @@ void omap_sram_idle(void) /* PER */ if (per_next_state < PWRDM_POWER_ON) { per_prev_state = pwrdm_read_prev_pwrst(per_pwrdm); - omap2_gpio_resume_after_idle(); + omap2_gpio_resume_after_idle(per_going_off); } /* Disable IO-PAD and IO-CHAIN wakeup */ diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 8c21358..8b47481 100755 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -142,6 +142,7 @@ void omap4_enter_sleep(unsigned int cpu, unsigned int power_state, bool suspend) int per_next_state = PWRDM_POWER_ON; int core_next_state = PWRDM_POWER_ON; int mpu_next_state = PWRDM_POWER_ON; + int ret; pwrdm_clear_all_prev_pwrst(cpu0_pwrdm); pwrdm_clear_all_prev_pwrst(mpu_pwrdm); @@ -154,6 +155,10 @@ void omap4_enter_sleep(unsigned int cpu, unsigned int power_state, bool suspend) core_next_state = pwrdm_read_next_pwrst(core_pwrdm); mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm); + ret = omap2_gpio_prepare_for_idle(omap4_device_next_state_off()); + if (ret) + goto abort_gpio; + if (mpu_next_state < PWRDM_POWER_INACTIVE) { if (omap_dvfs_is_scaling(mpu_voltdm)) { mpu_next_state = PWRDM_POWER_INACTIVE; @@ -190,10 +195,7 @@ void omap4_enter_sleep(unsigned int cpu, unsigned int power_state, bool suspend) } } - omap2_gpio_set_edge_wakeup(); - if (omap4_device_next_state_off()) { - omap2_gpio_prepare_for_idle(true); omap_gpmc_save_context(); omap_dma_global_context_save(); } @@ -248,26 +250,21 @@ abort_device_off: } if (omap4_device_next_state_off()) { - /* - * GPIO: since we have put_synced clks, we need to resume - * even if OFF was not really achieved - */ - omap2_gpio_resume_after_idle(); - /* Disable the extension of Non-EMIF I/O isolation */ omap4_prminst_rmw_inst_reg_bits(OMAP4430_ISOOVR_EXTEND_MASK, 0, OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_IO_PMCTRL_OFFSET); } - omap2_gpio_restore_edge_wakeup(); - if (mpu_next_state < PWRDM_POWER_INACTIVE) { omap_vc_set_auto_trans(mpu_voltdm, OMAP_VC_CHANNEL_AUTO_TRANSITION_DISABLE); omap_sr_enable(mpu_voltdm); } + omap2_gpio_resume_after_idle(omap4_device_next_state_off()); + +abort_gpio: return; } diff --git a/arch/arm/mach-omap2/prcm-debug.c b/arch/arm/mach-omap2/prcm-debug.c index 12e3e55..ab638c2 100644 --- a/arch/arm/mach-omap2/prcm-debug.c +++ b/arch/arm/mach-omap2/prcm-debug.c @@ -1480,6 +1480,8 @@ static void prcmdebug_dump_real_cd(struct seq_file *sf, struct d_clkd_info *cd, u32 clktrctrl = omap4_cminst_read_inst_reg(cd->prcm_partition, cd->cm_inst, cd->clkdm_offs + OMAP4_CM_CLKSTCTRL); + u32 mode = (clktrctrl & OMAP4430_CLKTRCTRL_MASK) >> + OMAP4430_CLKTRCTRL_SHIFT; u32 activity = clktrctrl & cd->activity; #if 0 u32 staticdep = @@ -1492,9 +1494,10 @@ static void prcmdebug_dump_real_cd(struct seq_file *sf, struct d_clkd_info *cd, int i; #endif - d_pr(sf, " %s mode=%s", cd->name, - cmtrctrl_s[(clktrctrl & OMAP4430_CLKTRCTRL_MASK) >> - OMAP4430_CLKTRCTRL_SHIFT]); + if (flags & PRCMDEBUG_LASTSLEEP && mode == 3 /* HW_AUTO */) + return; + + d_pr(sf, " %s mode=%s", cd->name, cmtrctrl_s[mode]); d_pr_ctd(sf, " activity=0x%x", activity); @@ -1525,7 +1528,7 @@ static void prcmdebug_dump_cd(struct seq_file *sf, struct d_clkd_info *cd, if (cd->cm_inst != -1) { prcmdebug_dump_real_cd(sf, cd, flags); - } else { + } else if (!(flags & PRCMDEBUG_LASTSLEEP)) { d_pr(sf, " %s\n", cd->name); } |