static int mapphone_panel_enable(struct omap_dss_device *dssdev) { int ret; /* change the DSS power state to INACTIVE with LCD on */ if (dss_pwrdm) omap_set_pwrdm_state(dss_pwrdm, PWRDM_POWER_INACTIVE); /* * TODO: * 1. mapphone_panel_regulator_enable() and mapphone_panel_reset() are * sharing the first_boot flag, and it MUST maintain this order. * 2. there is a first_boot flag in panel-mapphone.c, they need to be * to be consolidated later. * 3. mapphone_panel_reset() will reset panel base on the first_boot * flasg, but there is a macro CONFIG_FB_OMAP_BOOTLOADER_INIT will be * used to determine if the panel need to be reset at the first_boot */ ret = mapphone_panel_regulator_enable(); if (!ret) { if (dssdev->panel.panel_id == MOT_DISP_LVDS_MIPI_VM_1007_1280_800) { /* give display gpio level switchers time to power-up */ msleep(5); mapphone_panel_lvds_mipi_vm_1007_1280_800_enable(true); } mapphone_panel_reset(true); } return ret; }
static void mapphone_panel_disable(struct omap_dss_device *dssdev) { if (!dssdev->phy.dsi.d2l_use_ulps) mapphone_panel_reset(false); if (dssdev->panel.panel_id == MOT_DISP_LVDS_MIPI_VM_1007_1280_800) mapphone_panel_lvds_mipi_vm_1007_1280_800_enable(false); mapphone_panel_regulator_disable(); /* change the DSS power state to RET with LCD off */ if (dss_pwrdm) omap_set_pwrdm_state(dss_pwrdm, PWRDM_POWER_RET); }
static int am33xx_pm_suspend(unsigned int state) { int i, ret = 0; struct wkup_m3_wakeup_src wakeup_src; omap_set_pwrdm_state(gfx_pwrdm, PWRDM_POWER_OFF); am33xx_pm->ops->pre_suspend(state); ret = cpu_suspend((long unsigned int) &susp_params, am33xx_do_sram_idle); am33xx_pm->ops->post_suspend(state); if (ret) { pr_err("PM: Kernel suspend failure\n"); } else { i = wkup_m3_pm_status(); switch (i) { case 0: pr_info("PM: Successfully put all powerdomains to target state\n"); /* * The PRCM registers on AM335x do not contain * previous state information like those present on * OMAP4 so we must manually indicate transition so * state counters are properly incremented */ pwrdm_post_transition(mpu_pwrdm); pwrdm_post_transition(per_pwrdm); break; case 1: pr_err("PM: Could not transition all powerdomains to target state\n"); ret = -1; break; default: pr_err("PM: CM3 returned unknown result = %d\n", i); ret = -1; } /* print the wakeup reason */ wakeup_src = wkup_m3_wake_src(); pr_info("PM: Wakeup source %s\n", wakeup_src.src); } return ret; }
static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle) { static struct clockdomain *cpu1_clkdm; static bool booted; static struct powerdomain *cpu1_pwrdm; void __iomem *base = omap_get_wakeupgen_base(); /* * Set synchronisation state between this boot processor * and the secondary one */ spin_lock(&boot_lock); /* * Update the AuxCoreBoot0 with boot state for secondary core. * omap4_secondary_startup() routine will hold the secondary core till * the AuxCoreBoot1 register is updated with cpu state * A barrier is added to ensure that write buffer is drained */ if (omap_secure_apis_support()) omap_modify_auxcoreboot0(0x200, 0xfffffdff); else __raw_writel(0x20, base + OMAP_AUX_CORE_BOOT_0); if (!cpu1_clkdm && !cpu1_pwrdm) { cpu1_clkdm = clkdm_lookup("mpu1_clkdm"); cpu1_pwrdm = pwrdm_lookup("cpu1_pwrdm"); } /* * The SGI(Software Generated Interrupts) are not wakeup capable * from low power states. This is known limitation on OMAP4 and * needs to be worked around by using software forced clockdomain * wake-up. To wakeup CPU1, CPU0 forces the CPU1 clockdomain to * software force wakeup. The clockdomain is then put back to * hardware supervised mode. * More details can be found in OMAP4430 TRM - Version J * Section : * 4.3.4.2 Power States of CPU0 and CPU1 */ if (booted && cpu1_pwrdm && cpu1_clkdm) { /* * GIC distributor control register has changed between * CortexA9 r1pX and r2pX. The Control Register secure * banked version is now composed of 2 bits: * bit 0 == Secure Enable * bit 1 == Non-Secure Enable * The Non-Secure banked register has not changed * Because the ROM Code is based on the r1pX GIC, the CPU1 * GIC restoration will cause a problem to CPU0 Non-Secure SW. * The workaround must be: * 1) Before doing the CPU1 wakeup, CPU0 must disable * the GIC distributor * 2) CPU1 must re-enable the GIC distributor on * it's wakeup path. */ if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) { local_irq_disable(); gic_dist_disable(); } /* * Ensure that CPU power state is set to ON to avoid CPU * powerdomain transition on wfi */ clkdm_wakeup(cpu1_clkdm); omap_set_pwrdm_state(cpu1_pwrdm, PWRDM_POWER_ON); clkdm_allow_idle(cpu1_clkdm); if (IS_PM44XX_ERRATUM(PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD)) { while (gic_dist_disabled()) { udelay(1); cpu_relax(); } gic_timer_retrigger(); local_irq_enable(); } } else { dsb_sev(); booted = true; } arch_send_wakeup_ipi_mask(cpumask_of(cpu)); /* * Now the secondary core is starting up let it run its * calibrations, then wait for it to finish */ spin_unlock(&boot_lock); return 0; }
int __init am33xx_pm_init(void) { struct powerdomain *cefuse_pwrdm; #ifdef CONFIG_CPU_PM int ret; u32 temp; struct device_node *np; #endif /* CONFIG_CPU_PM */ if (!soc_is_am33xx() && !soc_is_am43xx()) return -ENODEV; #ifdef CONFIG_CPU_PM am33xx_pm = kzalloc(sizeof(*am33xx_pm), GFP_KERNEL); if (!am33xx_pm) { pr_err("Memory allocation failed\n"); ret = -ENOMEM; return ret; } ret = am33xx_map_emif(); if (ret) { pr_err("PM: Could not ioremap EMIF\n"); goto err; } #ifdef CONFIG_SUSPEND gfx_pwrdm = pwrdm_lookup("gfx_pwrdm"); per_pwrdm = pwrdm_lookup("per_pwrdm"); mpu_pwrdm = pwrdm_lookup("mpu_pwrdm"); if ((!gfx_pwrdm) || (!per_pwrdm) || (!mpu_pwrdm)) { ret = -ENODEV; goto err; } /* * Code paths for each SoC are nearly the same but set ops * handle differences during init, pre-suspend, and post-suspend */ if (soc_is_am33xx()) am33xx_pm->ops = &am33xx_ops; else if (soc_is_am43xx()) am33xx_pm->ops = &am43xx_ops; ret = am33xx_pm->ops->init(); if (ret) goto err; #endif /* CONFIG_SUSPEND */ /* Determine Memory Type */ temp = readl(am33xx_emif_base + EMIF_SDRAM_CONFIG); temp = (temp & SDRAM_TYPE_MASK) >> SDRAM_TYPE_SHIFT; /* Parameters to pass to assembly code */ susp_params.wfi_flags = 0; susp_params.emif_addr_virt = am33xx_emif_base; susp_params.dram_sync = am33xx_dram_sync; switch (temp) { case MEM_TYPE_DDR2: susp_params.wfi_flags |= WFI_MEM_TYPE_DDR2; break; case MEM_TYPE_DDR3: susp_params.wfi_flags |= WFI_MEM_TYPE_DDR3; break; } susp_params.wfi_flags |= WFI_SELF_REFRESH; susp_params.wfi_flags |= WFI_SAVE_EMIF; susp_params.wfi_flags |= WFI_DISABLE_EMIF; susp_params.wfi_flags |= WFI_WAKE_M3; am33xx_pm->ipc.reg4 = temp & MEM_TYPE_MASK; np = of_find_compatible_node(NULL, NULL, "ti,am3353-wkup-m3"); if (np) { if (of_find_property(np, "ti,needs-vtt-toggle", NULL) && (!(of_property_read_u32(np, "ti,vtt-gpio-pin", &temp)))) { if (temp >= 0 && temp <= 31) am33xx_pm->ipc.reg4 |= ((1 << VTT_STAT_SHIFT) | (temp << VTT_GPIO_PIN_SHIFT)); else pr_warn("PM: Invalid VTT GPIO(%d) pin\n", temp); } if (of_find_property(np, "ti,set-io-isolation", NULL)) am33xx_pm->ipc.reg4 |= (1 << IO_ISOLATION_STAT_SHIFT); } #ifdef CONFIG_SUSPEND ret = am33xx_setup_sleep_sequence(); if (ret) { pr_err("Error fetching I2C sleep/wake sequence\n"); goto err; } #endif /* CONFIG_SUSPEND */ #endif /* CONFIG_CPU_PM */ (void) clkdm_for_each(omap_pm_clkdms_setup, NULL); /* CEFUSE domain can be turned off post bootup */ cefuse_pwrdm = pwrdm_lookup("cefuse_pwrdm"); if (cefuse_pwrdm) omap_set_pwrdm_state(cefuse_pwrdm, PWRDM_POWER_OFF); else pr_err("PM: Failed to get cefuse_pwrdm\n"); #ifdef CONFIG_CPU_PM am33xx_pm->state = M3_STATE_RESET; wkup_m3_set_ops(&am33xx_wkup_m3_ops); /* m3 may have already loaded but ops were not set yet, * manually invoke */ if (wkup_m3_is_valid()) am33xx_m3_fw_ready_cb(); #endif /* CONFIG_CPU_PM */ return 0; #ifdef CONFIG_CPU_PM err: kfree(am33xx_pm); return ret; #endif /* CONFIG_CPU_PM */ }