コード例 #1
0
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;
}
コード例 #2
0
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;
}
コード例 #3
0
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;
}
コード例 #4
0
ファイル: tegra-cpufreq.c プロジェクト: 7799/linux
static int tegra_target(struct cpufreq_policy *policy, unsigned int index)
{
	return tegra_update_cpu_speed(policy, freq_table[index].frequency);
}