unsigned long acpuclk_power_collapse(void) { unsigned long rate = acpuclk_get_rate(smp_processor_id()); acpuclk_set_rate(smp_processor_id(), acpuclk_data->power_collapse_khz, SETRATE_PC); return rate; }
unsigned long acpuclk_wait_for_irq(void) { unsigned long rate = acpuclk_get_rate(smp_processor_id()); acpuclk_set_rate(smp_processor_id(), acpuclk_data->wait_for_irq_khz, SETRATE_SWFI); return rate; }
/* * Bring the Apps processor to SWFI. * * Return value: * -EIO: could not ramp Apps processor clock * 0: success */ static int msm_pm_swfi(bool ramp_acpu) { unsigned long saved_acpuclk_rate = 0; if (ramp_acpu) { saved_acpuclk_rate = acpuclk_wait_for_irq(); MSM_PM_DPRINTK(MSM_PM_DEBUG_CLOCK, KERN_INFO, "%s(): change clock rate (old rate = %lu)\n", __func__, saved_acpuclk_rate); if (!saved_acpuclk_rate) return -EIO; } if (!cpu_is_msm8625()) msm_pm_config_hw_before_swfi(); msm_arch_idle(); if (ramp_acpu) { MSM_PM_DPRINTK(MSM_PM_DEBUG_CLOCK, KERN_INFO, "%s(): restore clock rate to %lu\n", __func__, saved_acpuclk_rate); if (acpuclk_set_rate(smp_processor_id(), saved_acpuclk_rate, SETRATE_SWFI) < 0) printk(KERN_ERR "%s(): failed to restore clock rate(%lu)\n", __func__, saved_acpuclk_rate); } return 0; }
void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *clkdata) { unsigned int max_freq; mutex_init(&drv_state.lock); drv_state.acpu_switch_time_us = clkdata->acpu_switch_time_us; drv_state.max_speed_delta_khz = clkdata->max_speed_delta_khz; drv_state.max_vdd = clkdata->max_vdd; drv_state.acpu_set_vdd = clkdata->acpu_set_vdd; max_freq = msm_acpu_clock_fixup(); /* Configure hardware. */ move_off_scpll(); scpll_init(); lpj_init(); /* Improve boot time */ acpuclk_set_rate(smp_processor_id(), max_freq, SETRATE_CPUFREQ); #ifdef CONFIG_CPU_FREQ_MSM cpufreq_table_init(); cpufreq_frequency_table_get_attr(freq_table, smp_processor_id()); #endif }
void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *clkdata) { int cpu; mutex_init(&drv_state.lock); drv_state.acpu_switch_time_us = clkdata->acpu_switch_time_us; drv_state.vdd_switch_time_us = clkdata->vdd_switch_time_us; drv_state.max_speed_delta_khz = clkdata->max_speed_delta_khz; /* Configure hardware. */ regulator_init(); force_all_to_afab(); scpll_set_refs(); for_each_possible_cpu(cpu) scpll_init(cpu); scpll_init(L2); lpj_init(); precompute_stepping(); /* Improve boot time by ramping up CPUs immediately. */ for_each_online_cpu(cpu) acpuclk_set_rate(cpu, 1080000, SETRATE_CPUFREQ); cpufreq_table_init(); }
static void msm_pm_restart(char str, const char *cmd) { int rc; unsigned size; #if defined(CONFIG_MACH_ARUBASLIM_OPEN) unsigned int freq = 600000; rc = acpuclk_set_rate(0, freq, SETRATE_CPUFREQ); if (rc) { printk(KERN_ERR "%s(): failed to restore clock rate(%lu)\n", __func__, freq); } pr_info("%s: Current ACPU frequency %ld\n", __func__, acpuclk_get_rate(0)); #endif samsung_vendor1_id *smem_vendor1 = \ (samsung_vendor1_id *)smem_get_entry(SMEM_ID_VENDOR1, &size); if (smem_vendor1) { smem_vendor1->silent_reset = 0xAEAEAEAE; smem_vendor1->reboot_reason = restart_reason; smem_vendor1->AP_reserved[0] = 0; } else { printk(KERN_EMERG "smem_flag is NULL\n"); } pr_debug("The reset reason is %x\n", restart_reason); rc = ncp6335d_restart_config(); if (rc) pr_err("Unable to configure NCP6335D for restart\n"); /* Disable interrupts */ local_irq_disable(); local_fiq_disable(); /* * Take out a flat memory mapping and will * insert a 1:1 mapping in place of * the user-mode pages to ensure predictable results * This function takes care of flushing the caches * and flushing the TLB. */ setup_mm_for_reboot(); msm_proc_comm(PCOM_RESET_CHIP, &restart_reason, 0); for (;;) ; }
/* * Power collapse the Apps processor. This function executes the handshake * protocol with Modem. * * Return value: * -EAGAIN: modem reset occurred or early exit from power collapse * -EBUSY: modem not ready for our power collapse -- no power loss * -ETIMEDOUT: timed out waiting for modem's handshake -- no power loss * 0: success */ static int msm_pm_power_collapse (bool from_idle, uint32_t sleep_delay, uint32_t sleep_limit) { struct msm_pm_polled_group state_grps[2]; unsigned long saved_acpuclk_rate; int collapsed = 0; int ret; int val; int modem_early_exit = 0; MSM_PM_DPRINTK(MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE, KERN_INFO, "%s(): idle %d, delay %u, limit %u\n", __func__, (int)from_idle, sleep_delay, sleep_limit); if (!(smsm_get_state(SMSM_POWER_MASTER_DEM) & DEM_MASTER_SMSM_READY)) { MSM_PM_DPRINTK( MSM_PM_DEBUG_SUSPEND | MSM_PM_DEBUG_POWER_COLLAPSE, KERN_INFO, "%s(): master not ready\n", __func__); ret = -EBUSY; goto power_collapse_bail; } memset(msm_pm_smem_data, 0, sizeof(*msm_pm_smem_data)); if (cpu_is_msm8625()) { /* Program the SPM */ ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_POWER_COLLAPSE, false); WARN_ON(ret); } /* Call CPR suspend only for "idlePC" case */ if (msm_cpr_ops && from_idle) msm_cpr_ops->cpr_suspend(); msm_pm_irq_extns->enter_sleep1(true, from_idle, &msm_pm_smem_data->irq_mask); msm_sirc_enter_sleep(); msm_gpio_enter_sleep(from_idle); msm_pm_smem_data->sleep_time = sleep_delay; msm_pm_smem_data->resources_used = sleep_limit; /* Enter PWRC/PWRC_SUSPEND */ if (from_idle) smsm_change_state(SMSM_APPS_DEM, DEM_SLAVE_SMSM_RUN, DEM_SLAVE_SMSM_PWRC); else smsm_change_state(SMSM_APPS_DEM, DEM_SLAVE_SMSM_RUN, DEM_SLAVE_SMSM_PWRC | DEM_SLAVE_SMSM_PWRC_SUSPEND); MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): PWRC"); MSM_PM_DEBUG_PRINT_SLEEP_INFO(); memset(state_grps, 0, sizeof(state_grps)); state_grps[0].group_id = SMSM_POWER_MASTER_DEM; state_grps[0].bits_all_set = DEM_MASTER_SMSM_RSA; state_grps[1].group_id = SMSM_MODEM_STATE; state_grps[1].bits_all_set = SMSM_RESET; ret = msm_pm_poll_state(ARRAY_SIZE(state_grps), state_grps); if (ret < 0) { printk(KERN_EMERG "%s(): power collapse entry " "timed out waiting for Modem's response\n", __func__); msm_pm_timeout(); } if (ret == 1) { MSM_PM_DPRINTK( MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE, KERN_INFO, "%s(): msm_pm_poll_state detected Modem reset\n", __func__); goto power_collapse_early_exit; } /* DEM Master in RSA */ MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): PWRC RSA"); ret = msm_pm_irq_extns->enter_sleep2(true, from_idle); if (ret < 0) { MSM_PM_DPRINTK( MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE, KERN_INFO, "%s(): msm_irq_enter_sleep2 aborted, %d\n", __func__, ret); goto power_collapse_early_exit; } msm_pm_config_hw_before_power_down(); MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): pre power down"); saved_acpuclk_rate = acpuclk_power_collapse(); MSM_PM_DPRINTK(MSM_PM_DEBUG_CLOCK, KERN_INFO, "%s(): change clock rate (old rate = %lu)\n", __func__, saved_acpuclk_rate); if (saved_acpuclk_rate == 0) { msm_pm_config_hw_after_power_up(); goto power_collapse_early_exit; } msm_pm_boot_config_before_pc(smp_processor_id(), virt_to_phys(msm_pm_collapse_exit)); #ifdef CONFIG_VFP if (from_idle) vfp_pm_suspend(); #endif #ifdef CONFIG_CACHE_L2X0 if (!cpu_is_msm8625()) l2cc_suspend(); else apps_power_collapse = 1; #endif collapsed = msm_pm_collapse(); /* * TBD: Currently recognise the MODEM early exit * path by reading the MPA5_GDFS_CNT_VAL register. */ if (cpu_is_msm8625()) { /* * on system reset, default value of MPA5_GDFS_CNT_VAL * is = 0x0, later modem reprogram this value to * 0x00030004. Once APPS did a power collapse and * coming out of it expected value of this register * always be 0x00030004. Incase if APPS sees the value * as 0x00030002 consider this case as a modem early * exit. */ val = __raw_readl(MSM_CFG_CTL_BASE + 0x38); if (val != 0x00030002) power_collapsed = 1; else modem_early_exit = 1; } #ifdef CONFIG_CACHE_L2X0 if (!cpu_is_msm8625()) l2cc_resume(); else apps_power_collapse = 0; #endif msm_pm_boot_config_after_pc(smp_processor_id()); if (collapsed) { #ifdef CONFIG_VFP if (from_idle) vfp_pm_resume(); #endif cpu_init(); local_fiq_enable(); } MSM_PM_DPRINTK(MSM_PM_DEBUG_SUSPEND | MSM_PM_DEBUG_POWER_COLLAPSE, KERN_INFO, "%s(): msm_pm_collapse returned %d\n", __func__, collapsed); MSM_PM_DPRINTK(MSM_PM_DEBUG_CLOCK, KERN_INFO, "%s(): restore clock rate to %lu\n", __func__, saved_acpuclk_rate); if (acpuclk_set_rate(smp_processor_id(), saved_acpuclk_rate, SETRATE_PC) < 0) printk(KERN_ERR "%s(): failed to restore clock rate(%lu)\n", __func__, saved_acpuclk_rate); msm_pm_irq_extns->exit_sleep1(msm_pm_smem_data->irq_mask, msm_pm_smem_data->wakeup_reason, msm_pm_smem_data->pending_irqs); msm_pm_config_hw_after_power_up(); MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): post power up"); memset(state_grps, 0, sizeof(state_grps)); state_grps[0].group_id = SMSM_POWER_MASTER_DEM; state_grps[0].bits_any_set = DEM_MASTER_SMSM_RSA | DEM_MASTER_SMSM_PWRC_EARLY_EXIT; state_grps[1].group_id = SMSM_MODEM_STATE; state_grps[1].bits_all_set = SMSM_RESET; ret = msm_pm_poll_state(ARRAY_SIZE(state_grps), state_grps); if (ret < 0) { printk(KERN_EMERG "%s(): power collapse exit " "timed out waiting for Modem's response\n", __func__); msm_pm_timeout(); } if (ret == 1) { MSM_PM_DPRINTK( MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE, KERN_INFO, "%s(): msm_pm_poll_state detected Modem reset\n", __func__); goto power_collapse_early_exit; } /* Sanity check */ if (collapsed && !modem_early_exit) { BUG_ON(!(state_grps[0].value_read & DEM_MASTER_SMSM_RSA)); } else { BUG_ON(!(state_grps[0].value_read & DEM_MASTER_SMSM_PWRC_EARLY_EXIT)); goto power_collapse_early_exit; } /* Enter WFPI */ smsm_change_state(SMSM_APPS_DEM, DEM_SLAVE_SMSM_PWRC | DEM_SLAVE_SMSM_PWRC_SUSPEND, DEM_SLAVE_SMSM_WFPI); MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): WFPI"); memset(state_grps, 0, sizeof(state_grps)); state_grps[0].group_id = SMSM_POWER_MASTER_DEM; state_grps[0].bits_all_set = DEM_MASTER_SMSM_RUN; state_grps[1].group_id = SMSM_MODEM_STATE; state_grps[1].bits_all_set = SMSM_RESET; ret = msm_pm_poll_state(ARRAY_SIZE(state_grps), state_grps); if (ret < 0) { printk(KERN_EMERG "%s(): power collapse WFPI " "timed out waiting for Modem's response\n", __func__); msm_pm_timeout(); } if (ret == 1) { MSM_PM_DPRINTK( MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE, KERN_INFO, "%s(): msm_pm_poll_state detected Modem reset\n", __func__); ret = -EAGAIN; goto power_collapse_restore_gpio_bail; } /* DEM Master == RUN */ MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): WFPI RUN"); MSM_PM_DEBUG_PRINT_SLEEP_INFO(); msm_pm_irq_extns->exit_sleep2(msm_pm_smem_data->irq_mask, msm_pm_smem_data->wakeup_reason, msm_pm_smem_data->pending_irqs); msm_pm_irq_extns->exit_sleep3(msm_pm_smem_data->irq_mask, msm_pm_smem_data->wakeup_reason, msm_pm_smem_data->pending_irqs); msm_gpio_exit_sleep(); msm_sirc_exit_sleep(); smsm_change_state(SMSM_APPS_DEM, DEM_SLAVE_SMSM_WFPI, DEM_SLAVE_SMSM_RUN); MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): RUN"); smd_sleep_exit(); if (cpu_is_msm8625()) { ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING, false); WARN_ON(ret); } /* Call CPR resume only for "idlePC" case */ if (msm_cpr_ops && from_idle) msm_cpr_ops->cpr_resume(); return 0; power_collapse_early_exit: /* Enter PWRC_EARLY_EXIT */ smsm_change_state(SMSM_APPS_DEM, DEM_SLAVE_SMSM_PWRC | DEM_SLAVE_SMSM_PWRC_SUSPEND, DEM_SLAVE_SMSM_PWRC_EARLY_EXIT); MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): EARLY_EXIT"); memset(state_grps, 0, sizeof(state_grps)); state_grps[0].group_id = SMSM_POWER_MASTER_DEM; state_grps[0].bits_all_set = DEM_MASTER_SMSM_PWRC_EARLY_EXIT; state_grps[1].group_id = SMSM_MODEM_STATE; state_grps[1].bits_all_set = SMSM_RESET; ret = msm_pm_poll_state(ARRAY_SIZE(state_grps), state_grps); MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): EARLY_EXIT EE"); if (ret < 0) { printk(KERN_EMERG "%s(): power collapse EARLY_EXIT " "timed out waiting for Modem's response\n", __func__); msm_pm_timeout(); } if (ret == 1) { MSM_PM_DPRINTK( MSM_PM_DEBUG_SUSPEND|MSM_PM_DEBUG_POWER_COLLAPSE, KERN_INFO, "%s(): msm_pm_poll_state detected Modem reset\n", __func__); } /* DEM Master == RESET or PWRC_EARLY_EXIT */ ret = -EAGAIN; power_collapse_restore_gpio_bail: msm_gpio_exit_sleep(); msm_sirc_exit_sleep(); /* Enter RUN */ smsm_change_state(SMSM_APPS_DEM, DEM_SLAVE_SMSM_PWRC | DEM_SLAVE_SMSM_PWRC_SUSPEND | DEM_SLAVE_SMSM_PWRC_EARLY_EXIT, DEM_SLAVE_SMSM_RUN); MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): RUN"); if (collapsed) smd_sleep_exit(); /* Call CPR resume only for "idlePC" case */ if (msm_cpr_ops && from_idle) msm_cpr_ops->cpr_resume(); power_collapse_bail: if (cpu_is_msm8625()) { ret = msm_spm_set_low_power_mode(MSM_SPM_MODE_CLOCK_GATING, false); WARN_ON(ret); } return ret; }
unsigned long acpuclk_wait_for_irq(void) { int ret = acpuclk_get_rate(smp_processor_id()); acpuclk_set_rate(smp_processor_id(), WAIT_FOR_IRQ_KHZ, SETRATE_SWFI); return ret; }
unsigned long acpuclk_power_collapse(void) { int ret = acpuclk_get_rate(smp_processor_id()); acpuclk_set_rate(smp_processor_id(), POWER_COLLAPSE_KHZ, SETRATE_PC); return ret; }