static void iommu_disable(struct iommu *obj) { u32 reg; if (!obj) return; if (cpu_is_omap44xx() && !strcmp(obj->name, "ducati")) { reg = prm_read_mod_reg(OMAP4430_PRM_CORE_MOD, OMAP4_RM_DUCATI_RSTCTRL_OFFSET); prm_write_mod_reg((reg | RM_M3_RST1ST | RM_M3_RST2ST), OMAP4430_PRM_CORE_MOD, OMAP4_RM_DUCATI_RSTCTRL_OFFSET); } if (cpu_is_omap44xx() && !strcmp(obj->name, "tesla")) { reg = prm_read_mod_reg(OMAP4430_PRM_TESLA_MOD, OMAP4_RM_TESLA_RSTCTRL_OFFSET); prm_write_mod_reg((reg | RM_TESLA_RST1ST), OMAP4430_PRM_CORE_MOD, OMAP4_RM_TESLA_RSTCTRL_OFFSET); } if (!cpu_is_omap44xx()) clk_enable(obj->clk); arch_iommu->disable(obj); if (!cpu_is_omap44xx()) clk_disable(obj->clk); if (cpu_is_omap44xx() && !strcmp(obj->name, "ducati")) { pr_info("iommu_disable: Ducati Assert RST1, RST2 and RST3\n"); reg = prm_read_mod_reg(OMAP4430_PRM_CORE_MOD, OMAP4_RM_DUCATI_RSTCTRL_OFFSET); prm_write_mod_reg((reg | RM_M3_MPU_ALL_RESETS), OMAP4430_PRM_CORE_MOD, OMAP4_RM_DUCATI_RSTCTRL_OFFSET); pr_info("iommu_disable: Ducati Reset Status RSTST = 0x%x\n", prm_read_mod_reg(OMAP4430_PRM_CORE_MOD, OMAP4_RM_DUCATI_RSTST_OFFSET)); } if (cpu_is_omap44xx() && !strcmp(obj->name, "tesla")) { pr_info("iommu_disable: Tesla Assert DSP RST1 and RST2\n"); reg = prm_read_mod_reg(OMAP4430_PRM_TESLA_MOD, OMAP4_RM_TESLA_RSTCTRL_OFFSET); prm_write_mod_reg((reg | RM_TESLA_ALL_RESETS), OMAP4430_PRM_CORE_MOD, OMAP4_RM_TESLA_RSTCTRL_OFFSET); pr_info("iommu_disable: Tesla Reset Status RSTST = 0x%x\n", prm_read_mod_reg(OMAP4430_PRM_TESLA_MOD, OMAP4_RM_TESLA_RSTST_OFFSET)); } }
/* * PRCM Interrupt Handler Helper Function * * The purpose of this function is to clear any wake-up events latched * in the PRCM PM_WKST_x registers. It is possible that a wake-up event * may occur whilst attempting to clear a PM_WKST_x register and thus * set another bit in this register. A while loop is used to ensure * that any peripheral wake-up events occurring while attempting to * clear the PM_WKST_x are detected and cleared. */ static int prcm_clear_mod_irqs(s16 module, u8 regs) { u32 wkst, fclk, iclk, clken; u16 wkst_off = (regs == 3) ? OMAP3430ES2_PM_WKST3 : PM_WKST1; u16 fclk_off = (regs == 3) ? OMAP3430ES2_CM_FCLKEN3 : CM_FCLKEN1; u16 iclk_off = (regs == 3) ? CM_ICLKEN3 : CM_ICLKEN1; u16 grpsel_off = (regs == 3) ? OMAP3430ES2_PM_MPUGRPSEL3 : OMAP3430_PM_MPUGRPSEL; int c = 0; wkst = prm_read_mod_reg(module, wkst_off); wkst &= prm_read_mod_reg(module, grpsel_off); if (wkst) { iclk = cm_read_mod_reg(module, iclk_off); fclk = cm_read_mod_reg(module, fclk_off); while (wkst) { clken = wkst; cm_set_mod_reg_bits(clken, module, iclk_off); /* * For USBHOST, we don't know whether HOST1 or * HOST2 woke us up, so enable both f-clocks */ if (module == OMAP3430ES2_USBHOST_MOD) clken |= 1 << OMAP3430ES2_EN_USBHOST2_SHIFT; cm_set_mod_reg_bits(clken, module, fclk_off); prm_write_mod_reg(wkst, module, wkst_off); wkst = prm_read_mod_reg(module, wkst_off); c++; } cm_write_mod_reg(iclk, module, iclk_off); cm_write_mod_reg(fclk, module, fclk_off); } return c; }
static void omap2_enter_mpu_retention(void) { int only_idle = 0; struct timespec ts_preidle, ts_postidle, ts_idle; /* Putting MPU into the WFI state while a transfer is active * seems to cause the I2C block to timeout. Why? Good question. */ if (omap2_i2c_active()) return; /* The peripherals seem not to be able to wake up the MPU when * it is in retention mode. */ if (omap2_allow_mpu_retention()) { /* REVISIT: These write to reserved bits? */ prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1); prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2); prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST); /* Try to enter MPU retention */ prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) | OMAP_LOGICRETSTATE_MASK, MPU_MOD, OMAP2_PM_PWSTCTRL); } else { /* Block MPU retention */ prm_write_mod_reg(OMAP_LOGICRETSTATE_MASK, MPU_MOD, OMAP2_PM_PWSTCTRL); only_idle = 1; } if (omap2_pm_debug) { omap2_pm_dump(only_idle ? 2 : 1, 0, 0); getnstimeofday(&ts_preidle); } omap2_sram_idle(); if (omap2_pm_debug) { unsigned long long tmp; getnstimeofday(&ts_postidle); ts_idle = timespec_sub(ts_postidle, ts_preidle); tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC; omap2_pm_dump(only_idle ? 2 : 1, 1, tmp); } }
static void omap2_enter_mpu_retention(void) { u32 sleep_time = 0; int only_idle = 0; /* Putting MPU into the WFI state while a transfer is active * seems to cause the I2C block to timeout. Why? Good question. */ if (omap2_i2c_active()) return; /* The peripherals seem not to be able to wake up the MPU when * it is in retention mode. */ if (omap2_allow_mpu_retention()) { /* REVISIT: These write to reserved bits? */ prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1); prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2); prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST); /* Try to enter MPU retention */ prm_write_mod_reg((0x01 << OMAP_POWERSTATE_SHIFT) | OMAP_LOGICRETSTATE, MPU_MOD, PM_PWSTCTRL); } else { /* Block MPU retention */ prm_write_mod_reg(OMAP_LOGICRETSTATE, MPU_MOD, PM_PWSTCTRL); only_idle = 1; } if (omap2_pm_debug) { omap2_pm_dump(only_idle ? 2 : 1, 0, 0); sleep_time = omap2_read_32k_sync_counter(); } omap2_sram_idle(); if (omap2_pm_debug) { unsigned long long tmp; u32 resume_time; resume_time = omap2_read_32k_sync_counter(); tmp = resume_time - sleep_time; tmp *= 1000000; omap2_pm_dump(only_idle ? 2 : 1, 1, tmp / 32768); } }
static int omap2_pm_suspend(void) { u32 wken_wkup, mir1; wken_wkup = prm_read_mod_reg(WKUP_MOD, PM_WKEN); prm_write_mod_reg(wken_wkup & ~OMAP24XX_EN_GPT1, WKUP_MOD, PM_WKEN); /* Mask GPT1 */ mir1 = omap_readl(0x480fe0a4); omap_writel(1 << 5, 0x480fe0ac); omap2_enter_full_retention(); omap_writel(mir1, 0x480fe0a4); prm_write_mod_reg(wken_wkup, WKUP_MOD, PM_WKEN); return 0; }
static void pm_init_serial_console(void) { const struct omap_serial_console_config *conf; char name[16]; u32 l; conf = omap_get_config(OMAP_TAG_SERIAL_CONSOLE, struct omap_serial_console_config); if (conf == NULL) return; if (conf->console_uart > 3 || conf->console_uart < 1) return; serial_console_uart = conf->console_uart; sprintf(name, "uart%d_fck", conf->console_uart); console_fclk = clk_get(NULL, name); if (IS_ERR(console_fclk)) console_fclk = NULL; name[6] = 'i'; console_iclk = clk_get(NULL, name); if (IS_ERR(console_fclk)) console_iclk = NULL; if (console_fclk == NULL || console_iclk == NULL) { serial_console_uart = 0; return; } switch (serial_console_uart) { case 1: l = prm_read_mod_reg(CORE_MOD, PM_WKEN1); l |= OMAP24XX_ST_UART1; prm_write_mod_reg(l, CORE_MOD, PM_WKEN1); break; case 2: l = prm_read_mod_reg(CORE_MOD, PM_WKEN1); l |= OMAP24XX_ST_UART2; prm_write_mod_reg(l, CORE_MOD, PM_WKEN1); break; case 3: l = prm_read_mod_reg(CORE_MOD, OMAP24XX_PM_WKEN2); l |= OMAP24XX_ST_UART3; prm_write_mod_reg(l, CORE_MOD, OMAP24XX_PM_WKEN2); break; } }
/* Read-modify-write a register in a PRM module. Caller must lock */ u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx) { u32 v; v = prm_read_mod_reg(module, idx); v &= ~mask; v |= bits; prm_write_mod_reg(v, module, idx); return v; }
int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) { u32 reg; prm_rmw_mod_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK, 0x3 << OMAP4430_LASTPOWERSTATEENTERED_SHIFT, pwrdm->prcm_offs, OMAP4_PM_PWSTST); reg = prm_read_mod_reg(pwrdm->prcm_offs, pwrdm->context_offset); prm_write_mod_reg(reg, pwrdm->prcm_offs, pwrdm->context_offset); return 0; }
/** * _omap2xxx_clk_commit - commit clock parent/rate changes in hardware * @clk: struct clk * * * If @clk has the DELAYED_APP flag set, meaning that parent/rate changes * don't take effect until the VALID_CONFIG bit is written, write the * VALID_CONFIG bit and wait for the write to complete. No return value. */ static void _omap2xxx_clk_commit(struct clk *clk) { if (!cpu_is_omap24xx()) return; if (!(clk->flags & DELAYED_APP)) return; prm_write_mod_reg(OMAP24XX_VALID_CONFIG, OMAP24XX_GR_MOD, OMAP2_PRCM_CLKCFG_CTRL_OFFSET); /* OCP barrier */ prm_read_mod_reg(OMAP24XX_GR_MOD, OMAP2_PRCM_CLKCFG_CTRL_OFFSET); }
static int prcm_wakeup_event_control ( u32 reg_bit, u8 operation ) { volatile u32 prcm_val=0; prcm_val = prm_read_mod_reg( WKUP_MOD, PM_WKEN1 ); if ( operation ) prcm_val = prcm_val | reg_bit; else prcm_val = prcm_val & ~reg_bit; prm_write_mod_reg( prcm_val, WKUP_MOD, PM_WKEN1 ); return 0; }
/* * PRCM Interrupt Handler * * The PRM_IRQSTATUS_MPU register indicates if there are any pending * interrupts from the PRCM for the MPU. These bits must be cleared in * order to clear the PRCM interrupt. The PRCM interrupt handler is * implemented to simply clear the PRM_IRQSTATUS_MPU in order to clear * the PRCM interrupt. Please note that bit 0 of the PRM_IRQSTATUS_MPU * register indicates that a wake-up event is pending for the MPU and * this bit can only be cleared if the all the wake-up events latched * in the various PM_WKST_x registers have been cleared. The interrupt * handler is implemented using a do-while loop so that if a wake-up * event occurred during the processing of the prcm interrupt handler * (setting a bit in the corresponding PM_WKST_x register and thus * preventing us from clearing bit 0 of the PRM_IRQSTATUS_MPU register) * this would be handled. */ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) { u32 irqenable_mpu, irqstatus_mpu; int c = 0; int ct = 0; irqenable_mpu = prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET); irqstatus_mpu = prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); irqstatus_mpu &= irqenable_mpu; do { if (irqstatus_mpu & (OMAP3430_WKUP_ST_MASK | OMAP3430_IO_ST_MASK)) { c = _prcm_int_handle_wakeup(); ct++; /* * Is the MPU PRCM interrupt handler racing with the * IVA2 PRCM interrupt handler ? */ WARN(!c && (ct == 1), "prcm: WARNING: PRCM indicated " "MPU wakeup but no wakeup sources are " "marked\n"); } else { /* XXX we need to expand our PRCM interrupt handler */ WARN(1, "prcm: WARNING: PRCM interrupt received, but " "no code to handle it (%08x)\n", irqstatus_mpu); } prm_write_mod_reg(irqstatus_mpu, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); irqstatus_mpu = prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET); irqstatus_mpu &= irqenable_mpu; } while (irqstatus_mpu); return IRQ_HANDLED; }
/* Read-modify-write a register in a PRM module. Caller must lock */ u32 prm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module, s16 idx) { u32 v; /* CHIRON CPU0/1 domains are not part of PRM */ if (cpu_is_omap44xx() && ((module == OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD) || (module == OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD))) v = chiron_read_mod_reg(module, idx); else v = prm_read_mod_reg(module, idx); v &= ~mask; v |= bits; if (cpu_is_omap44xx() && ((module == OMAP4430_CHIRONSS_CHIRONSS_CPU0_MOD) || (module == OMAP4430_CHIRONSS_CHIRONSS_CPU1_MOD))) chiron_write_mod_reg(v, module, idx); else prm_write_mod_reg(v, module, idx); return v; }
static void omap2_enter_full_retention(void) { u32 l; struct timespec ts_preidle, ts_postidle, ts_idle; /* There is 1 reference hold for all children of the oscillator * clock, the following will remove it. If no one else uses the * oscillator itself it will be disabled if/when we enter retention * mode. */ clk_disable(osc_ck); /* Clear old wake-up events */ /* REVISIT: These write to reserved bits? */ prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1); prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2); prm_write_mod_reg(0xffffffff, WKUP_MOD, PM_WKST); /* * Set MPU powerdomain's next power state to RETENTION; * preserve logic state during retention */ pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET); pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET); /* Workaround to kill USB */ l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL; omap_ctrl_writel(l, OMAP2_CONTROL_DEVCONF0); omap2_gpio_prepare_for_idle(PWRDM_POWER_RET); if (omap2_pm_debug) { omap2_pm_dump(0, 0, 0); getnstimeofday(&ts_preidle); } /* One last check for pending IRQs to avoid extra latency due * to sleeping unnecessarily. */ if (omap_irq_pending()) goto no_sleep; omap_uart_prepare_idle(0); omap_uart_prepare_idle(1); omap_uart_prepare_idle(2); /* Jump to SRAM suspend code */ omap2_sram_suspend(sdrc_read_reg(SDRC_DLLA_CTRL), OMAP_SDRC_REGADDR(SDRC_DLLA_CTRL), OMAP_SDRC_REGADDR(SDRC_POWER)); no_sleep: omap_uart_resume_idle(2); omap_uart_resume_idle(1); omap_uart_resume_idle(0); if (omap2_pm_debug) { unsigned long long tmp; getnstimeofday(&ts_postidle); ts_idle = timespec_sub(ts_postidle, ts_preidle); tmp = timespec_to_ns(&ts_idle) * NSEC_PER_USEC; omap2_pm_dump(0, 1, tmp); } omap2_gpio_resume_after_idle(); clk_enable(osc_ck); /* clear CORE wake-up events */ prm_write_mod_reg(0xffffffff, CORE_MOD, PM_WKST1); prm_write_mod_reg(0xffffffff, CORE_MOD, OMAP24XX_PM_WKST2); /* wakeup domain events - bit 1: GPT1, bit5 GPIO */ prm_clear_mod_reg_bits(0x4 | 0x1, WKUP_MOD, PM_WKST); /* MPU domain wake events */ l = prm_read_mod_reg(OCP_MOD, OMAP2_PRM_IRQSTATUS_MPU_OFFSET); if (l & 0x01) prm_write_mod_reg(0x01, OCP_MOD, OMAP2_PRM_IRQSTATUS_MPU_OFFSET); if (l & 0x20) prm_write_mod_reg(0x20, OCP_MOD, OMAP2_PRM_IRQSTATUS_MPU_OFFSET); /* Mask future PRCM-to-MPU interrupts */ prm_write_mod_reg(0x0, OCP_MOD, OMAP2_PRM_IRQSTATUS_MPU_OFFSET); }
static void __init prcm_setup_regs(void) { int i, num_mem_banks; struct powerdomain *pwrdm; /* Enable autoidle */ prm_write_mod_reg(OMAP24XX_AUTOIDLE, OCP_MOD, OMAP24XX_PRM_SYSCONFIG_OFFSET); /* Set all domain wakeup dependencies */ prm_write_mod_reg(OMAP_EN_WKUP_MASK, MPU_MOD, PM_WKDEP); prm_write_mod_reg(0, OMAP24XX_DSP_MOD, PM_WKDEP); prm_write_mod_reg(0, GFX_MOD, PM_WKDEP); prm_write_mod_reg(0, CORE_MOD, PM_WKDEP); if (cpu_is_omap2430()) prm_write_mod_reg(0, OMAP2430_MDM_MOD, PM_WKDEP); /* * Set CORE powerdomain memory banks to retain their contents * during RETENTION */ num_mem_banks = pwrdm_get_mem_bank_count(core_pwrdm); for (i = 0; i < num_mem_banks; i++) pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_POWER_RET); /* Set CORE powerdomain's next power state to RETENTION */ pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET); /* * Set MPU powerdomain's next power state to RETENTION; * preserve logic state during retention */ pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET); pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET); /* Force-power down DSP, GFX powerdomains */ pwrdm = clkdm_get_pwrdm(dsp_clkdm); pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); omap2_clkdm_sleep(dsp_clkdm); pwrdm = clkdm_get_pwrdm(gfx_clkdm); pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); omap2_clkdm_sleep(gfx_clkdm); /* Enable clockdomain hardware-supervised control for all clkdms */ clkdm_for_each(_pm_clkdm_enable_hwsup, NULL); /* Enable clock autoidle for all domains */ cm_write_mod_reg(OMAP24XX_AUTO_CAM | OMAP24XX_AUTO_MAILBOXES | OMAP24XX_AUTO_WDT4 | OMAP2420_AUTO_WDT3 | OMAP24XX_AUTO_MSPRO | OMAP2420_AUTO_MMC | OMAP24XX_AUTO_FAC | OMAP2420_AUTO_EAC | OMAP24XX_AUTO_HDQ | OMAP24XX_AUTO_UART2 | OMAP24XX_AUTO_UART1 | OMAP24XX_AUTO_I2C2 | OMAP24XX_AUTO_I2C1 | OMAP24XX_AUTO_MCSPI2 | OMAP24XX_AUTO_MCSPI1 | OMAP24XX_AUTO_MCBSP2 | OMAP24XX_AUTO_MCBSP1 | OMAP24XX_AUTO_GPT12 | OMAP24XX_AUTO_GPT11 | OMAP24XX_AUTO_GPT10 | OMAP24XX_AUTO_GPT9 | OMAP24XX_AUTO_GPT8 | OMAP24XX_AUTO_GPT7 | OMAP24XX_AUTO_GPT6 | OMAP24XX_AUTO_GPT5 | OMAP24XX_AUTO_GPT4 | OMAP24XX_AUTO_GPT3 | OMAP24XX_AUTO_GPT2 | OMAP2420_AUTO_VLYNQ | OMAP24XX_AUTO_DSS, CORE_MOD, CM_AUTOIDLE1); cm_write_mod_reg(OMAP24XX_AUTO_UART3 | OMAP24XX_AUTO_SSI | OMAP24XX_AUTO_USB, CORE_MOD, CM_AUTOIDLE2); cm_write_mod_reg(OMAP24XX_AUTO_SDRC | OMAP24XX_AUTO_GPMC | OMAP24XX_AUTO_SDMA, CORE_MOD, CM_AUTOIDLE3); cm_write_mod_reg(OMAP24XX_AUTO_PKA | OMAP24XX_AUTO_AES | OMAP24XX_AUTO_RNG | OMAP24XX_AUTO_SHA | OMAP24XX_AUTO_DES, CORE_MOD, OMAP24XX_CM_AUTOIDLE4); cm_write_mod_reg(OMAP2420_AUTO_DSP_IPI, OMAP24XX_DSP_MOD, CM_AUTOIDLE); /* Put DPLL and both APLLs into autoidle mode */ cm_write_mod_reg((0x03 << OMAP24XX_AUTO_DPLL_SHIFT) | (0x03 << OMAP24XX_AUTO_96M_SHIFT) | (0x03 << OMAP24XX_AUTO_54M_SHIFT), PLL_MOD, CM_AUTOIDLE); cm_write_mod_reg(OMAP24XX_AUTO_OMAPCTRL | OMAP24XX_AUTO_WDT1 | OMAP24XX_AUTO_MPU_WDT | OMAP24XX_AUTO_GPIOS | OMAP24XX_AUTO_32KSYNC | OMAP24XX_AUTO_GPT1, WKUP_MOD, CM_AUTOIDLE); /* REVISIT: Configure number of 32 kHz clock cycles for sys_clk * stabilisation */ prm_write_mod_reg(15 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD, OMAP24XX_PRCM_CLKSSETUP_OFFSET); /* Configure automatic voltage transition */ prm_write_mod_reg(2 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD, OMAP24XX_PRCM_VOLTSETUP_OFFSET); prm_write_mod_reg(OMAP24XX_AUTO_EXTVOLT | (0x1 << OMAP24XX_SETOFF_LEVEL_SHIFT) | OMAP24XX_MEMRETCTRL | (0x1 << OMAP24XX_SETRET_LEVEL_SHIFT) | (0x0 << OMAP24XX_VOLT_LEVEL_SHIFT), OMAP24XX_GR_MOD, OMAP24XX_PRCM_VOLTCTRL_OFFSET); /* Enable wake-up events */ prm_write_mod_reg(OMAP24XX_EN_GPIOS | OMAP24XX_EN_GPT1, WKUP_MOD, PM_WKEN); }
void omap3_prcm_restore_context(void) { omap_ctrl_writel(prcm_context.control_padconf_sys_nirq, OMAP343X_CONTROL_PADCONF_SYSNIRQ); cm_write_mod_reg(prcm_context.iva2_cm_clksel1, OMAP3430_IVA2_MOD, CM_CLKSEL1); cm_write_mod_reg(prcm_context.iva2_cm_clksel2, OMAP3430_IVA2_MOD, CM_CLKSEL2); __raw_writel(prcm_context.cm_sysconfig, OMAP3430_CM_SYSCONFIG); cm_write_mod_reg(prcm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD, CM_CLKSEL); cm_write_mod_reg(prcm_context.dss_cm_clksel, OMAP3430_DSS_MOD, CM_CLKSEL); cm_write_mod_reg(prcm_context.cam_cm_clksel, OMAP3430_CAM_MOD, CM_CLKSEL); cm_write_mod_reg(prcm_context.per_cm_clksel, OMAP3430_PER_MOD, CM_CLKSEL); cm_write_mod_reg(prcm_context.emu_cm_clksel, OMAP3430_EMU_MOD, CM_CLKSEL1); cm_write_mod_reg(prcm_context.emu_cm_clkstctrl, OMAP3430_EMU_MOD, OMAP2_CM_CLKSTCTRL); cm_write_mod_reg(prcm_context.pll_cm_autoidle2, PLL_MOD, CM_AUTOIDLE2); cm_write_mod_reg(prcm_context.pll_cm_clksel4, PLL_MOD, OMAP3430ES2_CM_CLKSEL4); cm_write_mod_reg(prcm_context.pll_cm_clksel5, PLL_MOD, OMAP3430ES2_CM_CLKSEL5); cm_write_mod_reg(prcm_context.pll_cm_clken2, PLL_MOD, OMAP3430ES2_CM_CLKEN2); __raw_writel(prcm_context.cm_polctrl, OMAP3430_CM_POLCTRL); cm_write_mod_reg(prcm_context.iva2_cm_fclken, OMAP3430_IVA2_MOD, CM_FCLKEN); cm_write_mod_reg(prcm_context.iva2_cm_clken_pll, OMAP3430_IVA2_MOD, OMAP3430_CM_CLKEN_PLL); cm_write_mod_reg(prcm_context.core_cm_fclken1, CORE_MOD, CM_FCLKEN1); cm_write_mod_reg(prcm_context.core_cm_fclken3, CORE_MOD, OMAP3430ES2_CM_FCLKEN3); cm_write_mod_reg(prcm_context.sgx_cm_fclken, OMAP3430ES2_SGX_MOD, CM_FCLKEN); cm_write_mod_reg(prcm_context.wkup_cm_fclken, WKUP_MOD, CM_FCLKEN); cm_write_mod_reg(prcm_context.dss_cm_fclken, OMAP3430_DSS_MOD, CM_FCLKEN); cm_write_mod_reg(prcm_context.cam_cm_fclken, OMAP3430_CAM_MOD, CM_FCLKEN); cm_write_mod_reg(prcm_context.per_cm_fclken, OMAP3430_PER_MOD, CM_FCLKEN); cm_write_mod_reg(prcm_context.usbhost_cm_fclken, OMAP3430ES2_USBHOST_MOD, CM_FCLKEN); cm_write_mod_reg(prcm_context.core_cm_iclken1, CORE_MOD, CM_ICLKEN1); cm_write_mod_reg(prcm_context.core_cm_iclken2, CORE_MOD, CM_ICLKEN2); cm_write_mod_reg(prcm_context.core_cm_iclken3, CORE_MOD, CM_ICLKEN3); cm_write_mod_reg(prcm_context.sgx_cm_iclken, OMAP3430ES2_SGX_MOD, CM_ICLKEN); cm_write_mod_reg(prcm_context.wkup_cm_iclken, WKUP_MOD, CM_ICLKEN); cm_write_mod_reg(prcm_context.dss_cm_iclken, OMAP3430_DSS_MOD, CM_ICLKEN); cm_write_mod_reg(prcm_context.cam_cm_iclken, OMAP3430_CAM_MOD, CM_ICLKEN); cm_write_mod_reg(prcm_context.per_cm_iclken, OMAP3430_PER_MOD, CM_ICLKEN); cm_write_mod_reg(prcm_context.usbhost_cm_iclken, OMAP3430ES2_USBHOST_MOD, CM_ICLKEN); cm_write_mod_reg(prcm_context.iva2_cm_autiidle2, OMAP3430_IVA2_MOD, CM_AUTOIDLE2); cm_write_mod_reg(prcm_context.mpu_cm_autoidle2, MPU_MOD, CM_AUTOIDLE2); cm_write_mod_reg(prcm_context.iva2_cm_clkstctrl, OMAP3430_IVA2_MOD, OMAP2_CM_CLKSTCTRL); cm_write_mod_reg(prcm_context.mpu_cm_clkstctrl, MPU_MOD, OMAP2_CM_CLKSTCTRL); cm_write_mod_reg(prcm_context.core_cm_clkstctrl, CORE_MOD, OMAP2_CM_CLKSTCTRL); cm_write_mod_reg(prcm_context.sgx_cm_clkstctrl, OMAP3430ES2_SGX_MOD, OMAP2_CM_CLKSTCTRL); cm_write_mod_reg(prcm_context.dss_cm_clkstctrl, OMAP3430_DSS_MOD, OMAP2_CM_CLKSTCTRL); cm_write_mod_reg(prcm_context.cam_cm_clkstctrl, OMAP3430_CAM_MOD, OMAP2_CM_CLKSTCTRL); cm_write_mod_reg(prcm_context.per_cm_clkstctrl, OMAP3430_PER_MOD, OMAP2_CM_CLKSTCTRL); cm_write_mod_reg(prcm_context.neon_cm_clkstctrl, OMAP3430_NEON_MOD, OMAP2_CM_CLKSTCTRL); cm_write_mod_reg(prcm_context.usbhost_cm_clkstctrl, OMAP3430ES2_USBHOST_MOD, OMAP2_CM_CLKSTCTRL); cm_write_mod_reg(prcm_context.core_cm_autoidle1, CORE_MOD, CM_AUTOIDLE1); cm_write_mod_reg(prcm_context.core_cm_autoidle2, CORE_MOD, CM_AUTOIDLE2); cm_write_mod_reg(prcm_context.core_cm_autoidle3, CORE_MOD, CM_AUTOIDLE3); cm_write_mod_reg(prcm_context.wkup_cm_autoidle, WKUP_MOD, CM_AUTOIDLE); cm_write_mod_reg(prcm_context.dss_cm_autoidle, OMAP3430_DSS_MOD, CM_AUTOIDLE); cm_write_mod_reg(prcm_context.cam_cm_autoidle, OMAP3430_CAM_MOD, CM_AUTOIDLE); cm_write_mod_reg(prcm_context.per_cm_autoidle, OMAP3430_PER_MOD, CM_AUTOIDLE); cm_write_mod_reg(prcm_context.usbhost_cm_autoidle, OMAP3430ES2_USBHOST_MOD, CM_AUTOIDLE); cm_write_mod_reg(prcm_context.sgx_cm_sleepdep, OMAP3430ES2_SGX_MOD, OMAP3430_CM_SLEEPDEP); cm_write_mod_reg(prcm_context.dss_cm_sleepdep, OMAP3430_DSS_MOD, OMAP3430_CM_SLEEPDEP); cm_write_mod_reg(prcm_context.cam_cm_sleepdep, OMAP3430_CAM_MOD, OMAP3430_CM_SLEEPDEP); cm_write_mod_reg(prcm_context.per_cm_sleepdep, OMAP3430_PER_MOD, OMAP3430_CM_SLEEPDEP); cm_write_mod_reg(prcm_context.usbhost_cm_sleepdep, OMAP3430ES2_USBHOST_MOD, OMAP3430_CM_SLEEPDEP); cm_write_mod_reg(prcm_context.cm_clkout_ctrl, OMAP3430_CCR_MOD, OMAP3_CM_CLKOUT_CTRL_OFFSET); prm_write_mod_reg(prcm_context.prm_clkout_ctrl, OMAP3430_CCR_MOD, OMAP3_PRM_CLKOUT_CTRL_OFFSET); prm_write_mod_reg(prcm_context.sgx_pm_wkdep, OMAP3430ES2_SGX_MOD, PM_WKDEP); prm_write_mod_reg(prcm_context.dss_pm_wkdep, OMAP3430_DSS_MOD, PM_WKDEP); prm_write_mod_reg(prcm_context.cam_pm_wkdep, OMAP3430_CAM_MOD, PM_WKDEP); prm_write_mod_reg(prcm_context.per_pm_wkdep, OMAP3430_PER_MOD, PM_WKDEP); prm_write_mod_reg(prcm_context.neon_pm_wkdep, OMAP3430_NEON_MOD, PM_WKDEP); prm_write_mod_reg(prcm_context.usbhost_pm_wkdep, OMAP3430ES2_USBHOST_MOD, PM_WKDEP); prm_write_mod_reg(prcm_context.core_pm_mpugrpsel1, CORE_MOD, OMAP3430_PM_MPUGRPSEL1); prm_write_mod_reg(prcm_context.iva2_pm_ivagrpsel1, OMAP3430_IVA2_MOD, OMAP3430_PM_IVAGRPSEL1); prm_write_mod_reg(prcm_context.core_pm_mpugrpsel3, CORE_MOD, OMAP3430ES2_PM_MPUGRPSEL3); prm_write_mod_reg(prcm_context.core_pm_ivagrpsel3, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3); prm_write_mod_reg(prcm_context.wkup_pm_mpugrpsel, WKUP_MOD, OMAP3430_PM_MPUGRPSEL); prm_write_mod_reg(prcm_context.wkup_pm_ivagrpsel, WKUP_MOD, OMAP3430_PM_IVAGRPSEL); prm_write_mod_reg(prcm_context.per_pm_mpugrpsel, OMAP3430_PER_MOD, OMAP3430_PM_MPUGRPSEL); prm_write_mod_reg(prcm_context.per_pm_ivagrpsel, OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL); prm_write_mod_reg(prcm_context.wkup_pm_wken, WKUP_MOD, PM_WKEN); return; }
static void __init prcm_setup_regs(void) { int i, num_mem_banks; struct powerdomain *pwrdm; /* Enable autoidle */ prm_write_mod_reg(OMAP24XX_AUTOIDLE_MASK, OCP_MOD, OMAP2_PRCM_SYSCONFIG_OFFSET); /* * Set CORE powerdomain memory banks to retain their contents * during RETENTION */ num_mem_banks = pwrdm_get_mem_bank_count(core_pwrdm); for (i = 0; i < num_mem_banks; i++) pwrdm_set_mem_retst(core_pwrdm, i, PWRDM_POWER_RET); /* Set CORE powerdomain's next power state to RETENTION */ pwrdm_set_next_pwrst(core_pwrdm, PWRDM_POWER_RET); /* * Set MPU powerdomain's next power state to RETENTION; * preserve logic state during retention */ pwrdm_set_logic_retst(mpu_pwrdm, PWRDM_POWER_RET); pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_RET); /* Force-power down DSP, GFX powerdomains */ pwrdm = clkdm_get_pwrdm(dsp_clkdm); pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); omap2_clkdm_sleep(dsp_clkdm); pwrdm = clkdm_get_pwrdm(gfx_clkdm); pwrdm_set_next_pwrst(pwrdm, PWRDM_POWER_OFF); omap2_clkdm_sleep(gfx_clkdm); /* * Clear clockdomain wakeup dependencies and enable * hardware-supervised idle for all clkdms */ clkdm_for_each(clkdms_setup, NULL); clkdm_add_wkdep(mpu_clkdm, wkup_clkdm); /* Enable clock autoidle for all domains */ cm_write_mod_reg(OMAP24XX_AUTO_CAM_MASK | OMAP24XX_AUTO_MAILBOXES_MASK | OMAP24XX_AUTO_WDT4_MASK | OMAP2420_AUTO_WDT3_MASK | OMAP24XX_AUTO_MSPRO_MASK | OMAP2420_AUTO_MMC_MASK | OMAP24XX_AUTO_FAC_MASK | OMAP2420_AUTO_EAC_MASK | OMAP24XX_AUTO_HDQ_MASK | OMAP24XX_AUTO_UART2_MASK | OMAP24XX_AUTO_UART1_MASK | OMAP24XX_AUTO_I2C2_MASK | OMAP24XX_AUTO_I2C1_MASK | OMAP24XX_AUTO_MCSPI2_MASK | OMAP24XX_AUTO_MCSPI1_MASK | OMAP24XX_AUTO_MCBSP2_MASK | OMAP24XX_AUTO_MCBSP1_MASK | OMAP24XX_AUTO_GPT12_MASK | OMAP24XX_AUTO_GPT11_MASK | OMAP24XX_AUTO_GPT10_MASK | OMAP24XX_AUTO_GPT9_MASK | OMAP24XX_AUTO_GPT8_MASK | OMAP24XX_AUTO_GPT7_MASK | OMAP24XX_AUTO_GPT6_MASK | OMAP24XX_AUTO_GPT5_MASK | OMAP24XX_AUTO_GPT4_MASK | OMAP24XX_AUTO_GPT3_MASK | OMAP24XX_AUTO_GPT2_MASK | OMAP2420_AUTO_VLYNQ_MASK | OMAP24XX_AUTO_DSS_MASK, CORE_MOD, CM_AUTOIDLE1); cm_write_mod_reg(OMAP24XX_AUTO_UART3_MASK | OMAP24XX_AUTO_SSI_MASK | OMAP24XX_AUTO_USB_MASK, CORE_MOD, CM_AUTOIDLE2); cm_write_mod_reg(OMAP24XX_AUTO_SDRC_MASK | OMAP24XX_AUTO_GPMC_MASK | OMAP24XX_AUTO_SDMA_MASK, CORE_MOD, CM_AUTOIDLE3); cm_write_mod_reg(OMAP24XX_AUTO_PKA_MASK | OMAP24XX_AUTO_AES_MASK | OMAP24XX_AUTO_RNG_MASK | OMAP24XX_AUTO_SHA_MASK | OMAP24XX_AUTO_DES_MASK, CORE_MOD, OMAP24XX_CM_AUTOIDLE4); cm_write_mod_reg(OMAP2420_AUTO_DSP_IPI_MASK, OMAP24XX_DSP_MOD, CM_AUTOIDLE); /* Put DPLL and both APLLs into autoidle mode */ cm_write_mod_reg((0x03 << OMAP24XX_AUTO_DPLL_SHIFT) | (0x03 << OMAP24XX_AUTO_96M_SHIFT) | (0x03 << OMAP24XX_AUTO_54M_SHIFT), PLL_MOD, CM_AUTOIDLE); cm_write_mod_reg(OMAP24XX_AUTO_OMAPCTRL_MASK | OMAP24XX_AUTO_WDT1_MASK | OMAP24XX_AUTO_MPU_WDT_MASK | OMAP24XX_AUTO_GPIOS_MASK | OMAP24XX_AUTO_32KSYNC_MASK | OMAP24XX_AUTO_GPT1_MASK, WKUP_MOD, CM_AUTOIDLE); /* REVISIT: Configure number of 32 kHz clock cycles for sys_clk * stabilisation */ prm_write_mod_reg(15 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD, OMAP2_PRCM_CLKSSETUP_OFFSET); /* Configure automatic voltage transition */ prm_write_mod_reg(2 << OMAP_SETUP_TIME_SHIFT, OMAP24XX_GR_MOD, OMAP2_PRCM_VOLTSETUP_OFFSET); prm_write_mod_reg(OMAP24XX_AUTO_EXTVOLT_MASK | (0x1 << OMAP24XX_SETOFF_LEVEL_SHIFT) | OMAP24XX_MEMRETCTRL_MASK | (0x1 << OMAP24XX_SETRET_LEVEL_SHIFT) | (0x0 << OMAP24XX_VOLT_LEVEL_SHIFT), OMAP24XX_GR_MOD, OMAP2_PRCM_VOLTCTRL_OFFSET); /* Enable wake-up events */ prm_write_mod_reg(OMAP24XX_EN_GPIOS_MASK | OMAP24XX_EN_GPT1_MASK, WKUP_MOD, PM_WKEN); }
static int iommu_enable(struct iommu *obj) { int err; u32 reg; if (!obj) return -EINVAL; if (cpu_is_omap44xx() && !strcmp(obj->name, "ducati")) { /* Check that releasing resets would indeed be effective */ reg = prm_read_mod_reg(OMAP4430_PRM_CORE_MOD, OMAP4_RM_DUCATI_RSTCTRL_OFFSET); pr_info("iommu_enable: OMAP4_RM_DUCATI_RSTCTRL_OFFSET = 0x%x", reg); if ((reg & RM_M3_MPU_ALL_RESETS) != RM_M3_MPU_ALL_RESETS) { pr_info("iommu_enable: Ducati Resets in not proper " "state!\n"); pr_info("iommu_enable: Ducati Asserting RST1, RST2, " "and RST3...\n"); prm_write_mod_reg(RM_M3_MPU_ALL_RESETS, OMAP4430_PRM_CORE_MOD, OMAP4_RM_DUCATI_RSTCTRL_OFFSET); while (prm_read_mod_reg(OMAP4430_PRM_CORE_MOD, OMAP4_RM_DUCATI_RSTCTRL_OFFSET) != RM_M3_MPU_ALL_RESETS); } /* De-assert RST3, and clear the Reset status */ pr_info("iommu_enable: De-assert Ducati RST3\n"); reg = prm_read_mod_reg(OMAP4430_PRM_CORE_MOD, OMAP4_RM_DUCATI_RSTCTRL_OFFSET); pr_info("iommu_enable: Ducati RSTCTRL = 0x%x\n", reg); prm_write_mod_reg(RM_M3_REL_RST3_MASK, OMAP4430_PRM_CORE_MOD, OMAP4_RM_DUCATI_RSTCTRL_OFFSET); while (!(prm_read_mod_reg(OMAP4430_PRM_CORE_MOD, OMAP4_RM_DUCATI_RSTST_OFFSET) & RM_M3_RST3ST)); pr_info("iommu_enable: Ducati RST3 released!"); prm_write_mod_reg(RM_M3_RST3ST, OMAP4430_PRM_CORE_MOD, OMAP4_RM_DUCATI_RSTST_OFFSET); pr_info("iommu_enable: Ducati %s %d\n", __func__, __LINE__); } if (cpu_is_omap44xx() && !strcmp(obj->name, "tesla")) { /* Check that releasing resets would indeed be effective */ reg = prm_read_mod_reg(OMAP4430_PRM_TESLA_MOD, OMAP4_RM_TESLA_RSTCTRL_OFFSET); pr_info("iommu_enable: OMAP4_RM_TESLA_RSTCTRL_OFFSET = 0x%x", reg); if ((reg & RM_TESLA_ALL_RESETS) != RM_TESLA_ALL_RESETS) { pr_info("iommu_enable: Tesla Resets in not proper " "state!\n"); pr_info("iommu_enable: Tesla Assert RST1 and RST2.n"); prm_write_mod_reg(RM_TESLA_ALL_RESETS, OMAP4430_PRM_TESLA_MOD, OMAP4_RM_TESLA_RSTCTRL_OFFSET); while (prm_read_mod_reg(OMAP4430_PRM_TESLA_MOD, OMAP4_RM_TESLA_RSTCTRL_OFFSET) != RM_TESLA_ALL_RESETS); } /* De-assert RST2, and clear the Reset status */ pr_info("iommu_enable: De-assert Tesla RST2\n"); reg = prm_read_mod_reg(OMAP4430_PRM_TESLA_MOD, OMAP4_RM_TESLA_RSTCTRL_OFFSET); pr_info("iommu_enable: Tesla RSTCTRL = 0x%x\n", reg); prm_write_mod_reg(RM_TESLA_REL_RST2_MASK, OMAP4430_PRM_TESLA_MOD, OMAP4_RM_TESLA_RSTCTRL_OFFSET); while (!(prm_read_mod_reg(OMAP4430_PRM_TESLA_MOD, OMAP4_RM_TESLA_RSTST_OFFSET) & RM_TESLA_RST2ST)); pr_info("iommu_enable: Tesla RST2 released!"); prm_write_mod_reg(RM_TESLA_RST2ST, OMAP4430_PRM_TESLA_MOD, OMAP4_RM_TESLA_RSTST_OFFSET); pr_info("iommu_enable: Tesla %s %d\n", __func__, __LINE__); } if (!cpu_is_omap44xx()) clk_enable(obj->clk); err = arch_iommu->enable(obj); if (!cpu_is_omap44xx()) clk_disable(obj->clk); return err; }
int omap2_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm) { prm_write_mod_reg(0, pwrdm->prcm_offs, OMAP3430_PM_PREPWSTST); return 0; }
static void omap3_voltage_write_reg(u32 val, u16 mod, u8 offset) { prm_write_mod_reg(val, mod, offset); }