static int min_cpus_notify(struct notifier_block *nb, unsigned long n, void *p) { bool g_cluster = false; if (cpq_state == TEGRA_CPQ_DISABLED) return NOTIFY_OK; mutex_lock(tegra3_cpu_lock); if ((n >= 1) && is_lp_cluster()) { /* make sure cpu rate is within g-mode * range before switching */ unsigned long speed = max((unsigned long)tegra_getspeed(0), clk_get_min_rate(cpu_g_clk) / 1000); tegra_update_cpu_speed(speed); clk_set_parent(cpu_clk, cpu_g_clk); g_cluster = true; } tegra_cpu_set_speed_cap(NULL); mutex_unlock(tegra3_cpu_lock); schedule_work(&minmax_work); if (g_cluster) cpuquiet_device_free(); return NOTIFY_OK; }
static int min_cpus_notify(struct notifier_block *nb, unsigned long n, void *p) { mutex_lock(tegra3_cpu_lock); if ((n >= 1) && is_lp_cluster()) { /* make sure cpu rate is within g-mode range before switching */ unsigned int speed = max( tegra_getspeed(0), clk_get_min_rate(cpu_g_clk) / 1000); tegra_update_cpu_speed(speed); if (!clk_set_parent(cpu_clk, cpu_g_clk)) { hp_stats_update(CONFIG_NR_CPUS, false); hp_stats_update(0, true); } } /* update governor state machine */ tegra_cpu_set_speed_cap(NULL); mutex_unlock(tegra3_cpu_lock); return NOTIFY_OK; }
int boot_secondary(unsigned int cpu, struct task_struct *idle) { int status; /* Avoid timer calibration on slave cpus. Use the value calibrated * on master cpu. This reduces the bringup time for each slave cpu * by around 260ms. */ preset_lpj = loops_per_jiffy; if (is_lp_cluster()) { struct clk *cpu_clk, *cpu_g_clk; /* The G CPU may not be available for a variety of reasons. */ status = is_g_cluster_available(cpu); if (status) goto done; cpu_clk = tegra_get_clock_by_name("cpu"); cpu_g_clk = tegra_get_clock_by_name("cpu_g"); /* Switch to G CPU before continuing. */ if (!cpu_clk || !cpu_g_clk) { /* Early boot, clock infrastructure is not initialized - CPU mode switch is not allowed */ status = -EINVAL; } else { #ifdef CONFIG_CPU_FREQ /* set cpu rate is within g-mode range before switch */ unsigned int speed = max( (unsigned long)tegra_getspeed(0), clk_get_min_rate(cpu_g_clk) / 1000); tegra_update_cpu_speed(speed); #endif status = clk_set_parent(cpu_clk, cpu_g_clk); } if (status) goto done; } smp_wmb(); /* Force the CPU into reset. The CPU must remain in reset when the flow controller state is cleared (which will cause the flow controller to stop driving reset if the CPU has been power-gated via the flow controller). This will have no effect on first boot of the CPU since it should already be in reset. */ writel(CPU_RESET(cpu), CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET); dmb(); /* Unhalt the CPU. If the flow controller was used to power-gate the CPU this will cause the flow controller to stop driving reset. The CPU will remain in reset because the clock and reset block is now driving reset. */ flowctrl_writel(0, FLOW_CTRL_HALT_CPU(cpu)); status = power_up_cpu(cpu); if (status) goto done; /* Take the CPU out of reset. */ writel(CPU_RESET(cpu), CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR); wmb(); done: return status; }
static int tegra_target(struct cpufreq_policy *policy, unsigned int index) { return tegra_update_cpu_speed(policy, freq_table[index].frequency); }