void omap4_prminst_global_cold_sw_reset(void) { u32 v; s16 dev_inst = cpu_is_omap44xx() ? OMAP4430_PRM_DEVICE_INST : OMAP54XX_PRM_DEVICE_INST; /* If bootloader/PPA has'nt cleared, ensure it is cleared */ omap4_prminst_write_inst_reg(OMAP4430_GLOBAL_COLD_RST_MASK, OMAP4430_PRM_PARTITION, dev_inst, OMAP4_RM_RSTST); v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, dev_inst, OMAP4_RM_RSTCTRL); v |= OMAP4430_RST_GLOBAL_COLD_SW_MASK; omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION, dev_inst, OMAP4_RM_RSTCTRL); /* OCP barrier */ v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, dev_inst, OMAP4_RM_RSTCTRL); /* * Upon writing the PRM_RSTCTRL.RST_GLOBAL_COLD_SW to '1', * PRCM takes 2-3 32KHz clock cycles to assert cold reset * inside OMAP - approx 91.6uSec. Wait double that time. */ udelay(184); }
void omap4_prminst_global_warm_sw_reset(void) { u32 v; s16 dev_inst; if (cpu_is_omap44xx()) dev_inst = OMAP4430_PRM_DEVICE_INST; else if (soc_is_omap54xx()) dev_inst = OMAP54XX_PRM_DEVICE_INST; else if (soc_is_dra7xx()) dev_inst = DRA7XX_PRM_DEVICE_INST; else if (soc_is_am43xx()) dev_inst = AM43XX_PRM_DEVICE_INST; else return; v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, dev_inst, OMAP4_PRM_RSTCTRL_OFFSET); v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK; omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION, dev_inst, OMAP4_PRM_RSTCTRL_OFFSET); /* OCP barrier */ v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, dev_inst, OMAP4_PRM_RSTCTRL_OFFSET); }
static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm) { u32 c = 0; /* * REVISIT: pwrdm_wait_transition() may be better implemented * via a callback and a periodic timer check -- how long do we expect * powerdomain transitions to take? */ /* XXX Is this udelay() value meaningful? */ while ((omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, OMAP4_PM_PWSTST) & OMAP_INTRANSITION_MASK) && (c++ < PWRDM_TRANSITION_BAILOUT)) udelay(1); if (c > PWRDM_TRANSITION_BAILOUT) { printk(KERN_ERR "powerdomain: waited too long for " "powerdomain %s to complete transition\n", pwrdm->name); return -EAGAIN; } pr_debug("powerdomain: completed transition in %d loops\n", c); return 0; }
void omap4_prminst_global_warm_sw_reset(void) { u32 v; v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_RSTCTRL_OFFSET); v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK; omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_RSTCTRL_OFFSET); /* OCP barrier */ v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_RSTCTRL_OFFSET); }
void omap4_prminst_global_warm_sw_reset(void) { u32 v; s32 inst = omap4_prmst_get_prm_dev_inst(); if (inst == PRM_INSTANCE_UNKNOWN) return; v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, inst, OMAP4_PRM_RSTCTRL_OFFSET); v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK; omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION, inst, OMAP4_PRM_RSTCTRL_OFFSET); /* OCP barrier */ v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, inst, OMAP4_PRM_RSTCTRL_OFFSET); }
/** * omap4_mpuss_read_prev_context_state: * Function returns the MPUSS previous context state */ u32 omap4_mpuss_read_prev_context_state(void) { u32 reg; reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET); reg &= OMAP4430_LOSTCONTEXT_DFF_MASK; return reg; }
/* Helper functions for MPUSS OSWR */ static inline void mpuss_clear_prev_logic_pwrst(void) { u32 reg; reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET); omap4_prminst_write_inst_reg(reg, OMAP4430_PRM_PARTITION, OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET); }
void omap4_prminst_global_warm_sw_reset(void) { u32 v; s16 dev_inst = cpu_is_omap44xx() ? OMAP4430_PRM_DEVICE_INST : OMAP54XX_PRM_DEVICE_INST; v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, dev_inst, OMAP4_PRM_RSTCTRL_OFFSET); v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK; omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION, dev_inst, OMAP4_PRM_RSTCTRL_OFFSET); /* OCP barrier */ v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, dev_inst, OMAP4_PRM_RSTCTRL_OFFSET); }
static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm) { u32 v; v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, OMAP4_PM_PWSTST); v &= OMAP4430_LASTPOWERSTATEENTERED_MASK; v >>= OMAP4430_LASTPOWERSTATEENTERED_SHIFT; return v; }
static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm) { u32 v; v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL); v &= OMAP4430_LOGICRETSTATE_MASK; v >>= OMAP4430_LOGICRETSTATE_SHIFT; return v; }
static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm) { u32 v; v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL); v &= OMAP_POWERSTATE_MASK; v >>= OMAP_POWERSTATE_SHIFT; return v; }
/** * omap4_prminst_is_hardreset_asserted - read the HW reset line state of * submodules contained in the hwmod module * @rstctrl_reg: RM_RSTCTRL register address for this module * @shift: register bit shift corresponding to the reset line to check * * Returns 1 if the (sub)module hardreset line is currently asserted, * 0 if the (sub)module hardreset line is not currently asserted, or * -EINVAL upon parameter error. */ int omap4_prminst_is_hardreset_asserted(u8 shift, u8 part, s16 inst, u16 rstctrl_offs) { u32 v; v = omap4_prminst_read_inst_reg(part, inst, rstctrl_offs); v &= 1 << shift; v >>= shift; return v; }
/* Read-modify-write a register in PRM. Caller must lock */ u32 omap4_prminst_rmw_inst_reg_bits(u32 mask, u32 bits, u8 part, s16 inst, u16 idx) { u32 v; v = omap4_prminst_read_inst_reg(part, inst, idx); v &= ~mask; v |= bits; omap4_prminst_write_inst_reg(v, part, inst, idx); return v; }
static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank) { u32 m, v; m = omap2_pwrdm_get_mem_bank_retst_mask(bank); v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL); v &= m; v >>= __ffs(m); return v; }
/** * omap4_device_read_next_state_off - read device off state * * Checks if device off is enabled or not. * Returns true if enabled, false otherwise. */ static bool omap4_device_read_next_state_off(void) { u32 val; u16 offset, inst, partition; if (cpu_is_omap44xx()) { partition = OMAP4430_PRM_PARTITION; offset = OMAP4_PRM_DEVICE_OFF_CTRL_OFFSET; inst = OMAP4430_PRM_DEVICE_INST; } else { return false; } val = omap4_prminst_read_inst_reg(partition, inst, offset); val &= OMAP4430_DEVICE_OFF_ENABLE_MASK; return val ? true : false; }
/** * omap4_pwrdm_lost_context_rff - check if a pwrdm has lost it rff context * @pwrdm: struct powerdomain * to check * * Checks if the powerdomain has lost its RFF context or not. Basically * this means if the device has entered off or not. Returns true if the * context has been lost, false otherwise. */ static bool omap4_pwrdm_lost_context_rff(struct powerdomain *pwrdm) { u32 val; s16 inst, offset; if (!pwrdm) return false; inst = pwrdm->prcm_offs; offset = pwrdm->context_offs; if (!offset) return false; val = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, inst, offset); if (val & OMAP4430_LOSTCONTEXT_RFF_MASK) return true; return false; }
static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm) { u32 c = 0; while ((omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs, OMAP4_PM_PWSTST) & OMAP_INTRANSITION_MASK) && (c++ < PWRDM_TRANSITION_BAILOUT)) udelay(1); if (c > PWRDM_TRANSITION_BAILOUT) { printk(KERN_ERR "powerdomain: waited too long for " "powerdomain %s to complete transition\n", pwrdm->name); return -EAGAIN; } pr_debug("powerdomain: completed transition in %d loops\n", c); return 0; }
static int __init resetreason_init(void) { int i; u32 reasons = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_RSTST_OFFSET); memset(resetreason, 0, RESET_REASON_SIZE); for (i = 0; i < ARRAY_SIZE(resetreason_flags); i++) if (reasons & resetreason_flags[i].mask) strlcat(resetreason, resetreason_flags[i].str, sizeof(resetreason)); strlcat(resetreason, "Reset", sizeof(resetreason)); pr_info("Last OMAP reset reason was %s (PRM_RSTST=0x%x)\n", resetreason, reasons); omap4_prminst_write_inst_reg(reasons, OMAP4430_PRM_PARTITION, OMAP4430_PRM_DEVICE_INST, OMAP4_PRM_RSTST_OFFSET); return 0; }
static u32 omap4_voltage_read_reg(u16 mod, u8 offset) { return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, mod, offset); }