static int pi_prof_get_counter(struct profiler *profiler, unsigned long *counter, int *overflow) { struct pi_profiler *pi_profiler = container_of(profiler, struct pi_profiler, profiler); struct pi *pi = pi_mgr_get(pi_profiler->pi_id); if (!pi) return -ENODEV; *overflow = 0; *counter = pwr_mgr_pi_counter_read(pi_profiler->pi_id, (bool *)overflow); return 0; }
int enter_idle_state(struct kona_idle_state *state) { struct pi* pi = NULL; #if defined(CONFIG_RHEA_WA_HWJIRA_2301) || defined(CONFIG_RHEA_WA_HWJIRA_2877) u32 lpddr2_temp_period = 0; #endif BUG_ON(!state); pwr_mgr_event_clear_events(LCDTE_EVENT,BRIDGE_TO_MODEM_EVENT); pwr_mgr_event_clear_events(USBOTG_EVENT,MODEMBUS_ACTIVE_EVENT); /*Turn off XTAL only for deep sleep state*/ if (state->flags & CPUIDLE_FLAG_XTAL_ON || keep_xtl_on) clk_set_crystal_pwr_on_idle(false); clear_wakeup_interrupts(); config_wakeup_interrupts(); pi = pi_mgr_get(PI_MGR_PI_ID_ARM_CORE); BUG_ON(pi == NULL); pi_enable(pi, 0); #if defined(CONFIG_RHEA_WA_HWJIRA_2301) || defined(CONFIG_RHEA_WA_HWJIRA_2877) if (JIRA_WA_ENABLED(2301) || JIRA_WA_ENABLED(2877)) { /* Workaround for JIRA CRMEMC-919/2301(Periodic device temp. polling will prevent entering deep sleep in Rhea B0) Workaround : Disable temp. polling when A9 enters LPM & re-enable on exit from LPM */ lpddr2_temp_period = readl(KONA_MEMC0_NS_VA + CSR_LPDDR2_DEV_TEMP_PERIOD_OFFSET); /*Disable temperature polling, 0xC3500 -> 0x350080c0 Disables periodic reading of the device temperature the period field contains the device temperature period. The timer operates in the XTAL clock domain. 0cC3500 is the default value, write it back. */ writel_relaxed(0xC3500, KONA_MEMC0_NS_VA + CSR_LPDDR2_DEV_TEMP_PERIOD_OFFSET); } #endif /* CONFIG_RHEA_WA_HWJIRA_2301 || CONFIG_RHEA_WA_HWJIRA_2877 */ #ifdef CONFIG_RHEA_WA_HWJIRA_2221 if (JIRA_WA_ENABLED(2221)) { u32 count; u32 temp_val; char *noncache_buf_tmp_va; /*JIRA HWRHEA_2221 VAR_312M is_idle from MEMC unexpectedly stays * asserted for long periods of time - preventing deepsleep entry */ /* reset all MEMC demesh entries */ noncache_buf_tmp_va = noncache_buf_va; for (count = 0; count < 16; count++, noncache_buf_tmp_va += 64) temp_val = *(volatile u32 *)noncache_buf_tmp_va; memc_freq_map = readl(KONA_MEMC0_NS_VA + CSR_MEMC_FREQ_STATE_MAPPING_OFFSET); writel_relaxed(1, KONA_MEMC0_NS_VA + CSR_MEMC_FREQ_STATE_MAPPING_OFFSET); } #endif /*CONFIG_RHEA_WA_HWJIRA_2221*/ if (dbg_dsm_suspend) if (state->flags & CPUIDLE_ENTER_SUSPEND) { rhea_clock_print_act_clks(); rhea_pi_mgr_print_act_pis(); } switch (state->state) { case RHEA_STATE_C2: case RHEA_STATE_C3: enter_retention_state(state); break; case RHEA_STATE_C4: case RHEA_STATE_C5: enter_dormant_state(state); break; } #if defined(CONFIG_RHEA_WA_HWJIRA_2301) || defined(CONFIG_RHEA_WA_HWJIRA_2877) /* Workaround for JIRA CRMEMC-919/2301(Periodic device temperature polling will prevent entering deep sleep in Rhea B0) - Disable temp. polling when A9 enters LPM & re-enable on exit from LPM */ if (JIRA_WA_ENABLED(2301) || JIRA_WA_ENABLED(2877)) writel_relaxed(lpddr2_temp_period, KONA_MEMC0_NS_VA + CSR_LPDDR2_DEV_TEMP_PERIOD_OFFSET); #endif /*CONFIG_RHEA_WA_HWJIRA_2301 || CONFIG_RHEA_WA_HWJIRA_2877*/ #ifdef CONFIG_RHEA_WA_HWJIRA_2221 if (JIRA_WA_ENABLED(2221)) writel_relaxed(memc_freq_map, KONA_MEMC0_NS_VA + CSR_MEMC_FREQ_STATE_MAPPING_OFFSET); #endif #ifdef CONFIG_RHEA_WA_HWJIRA_2045 /* Workaround for JIRA 2045: HUB timer counter value is synchronized to apb register only on next 32KHz falling edge after WFI wakeup - worst case this could be close to one 32KHz cycle (~30us). To avoid reading invalid counter value by timer driver, idle handler, on exit from WFI, should wait till timer counter is updated. */ if (JIRA_WA_ENABLED(2045)) { u32 tmr_lsw = readl(KONA_TMR_HUB_VA + KONA_GPTIMER_STCLO_OFFSET); while(tmr_lsw == readl(KONA_TMR_HUB_VA + KONA_GPTIMER_STCLO_OFFSET)); } #endif /*CONFIG_RHEA_WA_HWJIRA_2045*/ pm_dbg(LOG_SW2_STATUS, "SW2 state: %d\n", pwr_mgr_is_event_active(SOFTWARE_2_EVENT)); pwr_mgr_event_set(SOFTWARE_2_EVENT,1); pi_enable(pi,1); scu_set_power_mode(SCU_STATUS_NORMAL); #ifdef PM_DEBUG if(pwr_mgr_is_event_active(COMMON_INT_TO_AC_EVENT)) { pm_dbg(LOG_INTR_STATUS, "%s:GIC act status1 = %x\n", __func__, readl(KONA_GICDIST_VA+GICDIST_ACTIVE_STATUS1_OFFSET)); pm_dbg(LOG_INTR_STATUS, "%s:GIC act status2 = %x\n", __func__, readl(KONA_GICDIST_VA+GICDIST_ACTIVE_STATUS2_OFFSET)); pm_dbg(LOG_INTR_STATUS, "%s:GIC act status3 = %x\n", __func__, readl(KONA_GICDIST_VA+GICDIST_ACTIVE_STATUS3_OFFSET)); pm_dbg(LOG_INTR_STATUS, "%s:GIC act status4 = %x\n", __func__, readl(KONA_GICDIST_VA+GICDIST_ACTIVE_STATUS4_OFFSET)); pm_dbg(LOG_INTR_STATUS, "%s:GIC act status5 = %x\n", __func__, readl(KONA_GICDIST_VA+GICDIST_ACTIVE_STATUS5_OFFSET)); pm_dbg(LOG_INTR_STATUS, "%s:GIC act status6 = %x\n", __func__, readl(KONA_GICDIST_VA+GICDIST_ACTIVE_STATUS6_OFFSET)); pm_dbg(LOG_INTR_STATUS, "%s:GIC act status7 = %x\n", __func__, readl(KONA_GICDIST_VA+GICDIST_ACTIVE_STATUS7_OFFSET)); pm_dbg(LOG_INTR_STATUS, "%s:GIC pending status1 = %x\n", __func__, readl(KONA_GICDIST_VA+GICDIST_PENDING_SET1_OFFSET)); pm_dbg(LOG_INTR_STATUS, "%s:GIC pending status2 = %x\n", __func__, readl(KONA_GICDIST_VA+GICDIST_PENDING_SET2_OFFSET)); pm_dbg(LOG_INTR_STATUS, "%s:GIC pending status3 = %x\n", __func__, readl(KONA_GICDIST_VA+GICDIST_PENDING_SET4_OFFSET)); pm_dbg(LOG_INTR_STATUS, "%s:GIC pending status4 = %x\n", __func__, readl(KONA_GICDIST_VA+GICDIST_PENDING_SET4_OFFSET)); pm_dbg(LOG_INTR_STATUS, "%s:GIC pending status5 = %x\n", __func__, readl(KONA_GICDIST_VA+GICDIST_PENDING_SET5_OFFSET)); pm_dbg(LOG_INTR_STATUS, "%s:GIC pending status6 = %x\n", __func__, readl(KONA_GICDIST_VA+GICDIST_PENDING_SET6_OFFSET)); pm_dbg(LOG_INTR_STATUS, "%s:GIC pending status7 = %x\n", __func__, readl(KONA_GICDIST_VA+GICDIST_PENDING_SET7_OFFSET)); } #endif clear_wakeup_interrupts(); pwr_mgr_process_events(LCDTE_EVENT,BRIDGE_TO_MODEM_EVENT,false); pwr_mgr_process_events(USBOTG_EVENT,PHY_RESUME_EVENT,false); if (state->flags & CPUIDLE_ENTER_SUSPEND) log_wakeup_interrupts(); if (state->flags & CPUIDLE_FLAG_XTAL_ON || keep_xtl_on) clk_set_crystal_pwr_on_idle(true); return -1; }
int __init island_pwr_mgr_init() { struct v0x_spec_i2c_cmd_ptr v_ptr; int i; struct pi* pi; struct pm_policy_cfg cfg; cfg.ac = 1; cfg.atl = 0; v_ptr.other_ptr = 1; v_ptr.set2_val = 1; /*Retention voltage inx*/ v_ptr.set2_ptr = 45; v_ptr.set1_val = 2;/*Should be 8 ????Wakeup override*/ v_ptr.set1_ptr = 49; v_ptr.zerov_ptr = 45; /*Not used for island*/ #if 0 /*disable jtag clock instrusive during debug*/ pwr_mgr_ignore_dap_powerup_request(true); #endif pwr_mgr_init(&island_pwr_mgr_info); island_pi_mgr_init(); /*MM override is not set by default*/ //pwr_mgr_pi_set_wakeup_override(PI_MGR_PI_ID_MM,false/*clear*/); /*clear all the event */ pwr_mgr_event_clear_events(LCDTE_EVENT, EVENT_ID_ALL); pwr_mgr_event_set(SOFTWARE_2_EVENT,1); pwr_mgr_event_set(SOFTWARE_0_EVENT,1); /*Init I2c seq*/ pwr_mgr_pm_i2c_enable(false); /*Program I2C sequencer*/ island_pm_i2c_cmd_init(); //pwr_mgr_pm_i2c_cmd_write(i2c_cmd,ARRAY_SIZE(i2c_cmd)); /*Program voltage lookup table AVS driver may chnage this later*/ //pwr_mgr_pm_i2c_var_data_write(pwrmgr_default_volt_lut,VLT_LUT_SIZE); /*populate the jump voltage table */ //pwr_mgr_set_v0x_specific_i2c_cmd_ptr(VOLT0,&v_ptr); pwr_mgr_pm_i2c_enable(true); /*Init event table*/ for(i = 0; i < ARRAY_SIZE(event_table); i++) { u32 event_id; event_id = event_table[i].event_id; if (event_id >= GPIO29_A_EVENT && event_id <= SPARE10_A_EVENT) event_id = GPIO29_A_EVENT; if (event_id >= GPIO29_B_EVENT && event_id <= SPARE10_B_EVENT) event_id = GPIO29_B_EVENT; pwr_mgr_event_trg_enable(event_table[i].event_id,event_table[i].trig_type); cfg.policy = event_table[i].policy_modem; pwr_mgr_event_set_pi_policy(event_id, PI_MGR_PI_ID_MODEM, &cfg); cfg.policy = event_table[i].policy_arm_core; pwr_mgr_event_set_pi_policy(event_id, PI_MGR_PI_ID_ARM_CORE, &cfg); cfg.policy = event_table[i].policy_arm_sub; pwr_mgr_event_set_pi_policy(event_id, PI_MGR_PI_ID_ARM_SUB_SYSTEM, &cfg); cfg.policy = event_table[i].policy_hub_aon; pwr_mgr_event_set_pi_policy(event_id, PI_MGR_PI_ID_HUB_AON, &cfg); cfg.policy = event_table[i].policy_hub_switchable; pwr_mgr_event_set_pi_policy(event_id, PI_MGR_PI_ID_HUB_SWITCHABLE, &cfg); } /*Init all PIs*/ /*Init all PIs*/ for(i = 0; i < PI_MGR_PI_ID_MODEM; i++) { pi = pi_mgr_get(i); BUG_ON(pi == NULL); pi_init(pi); } island_clock_init(); /*All the initializations are done. Clear override bit here so that * appropriate policies take effect*/ #if 1 for (i = 0; i < PI_MGR_PI_ID_MODEM; i++) { pi = pi_mgr_get(i); BUG_ON(pi == NULL); pi_init_state(pi); } #endif return 0; }