Пример #1
0
int tegra_cpuquiet_force_gmode(void)
{
    cputime64_t on_time = 0;

	if (no_lp)
		return -EBUSY;
		
	if (!is_g_cluster_present())
		return -EBUSY;

	if (cpq_state == TEGRA_CPQ_DISABLED)
		return -EBUSY;

	if (is_lp_cluster()) {
		mutex_lock(tegra3_cpu_lock);

		if (switch_clk_to_gmode()) {
			pr_err(CPUQUIET_TAG "tegra_cpuquiet_force_gmode - switch_clk_to_gmode failed\n");
    		mutex_unlock(tegra3_cpu_lock);
    		return -EBUSY;
		}
		
		on_time = ktime_to_ms(ktime_get()) - lp_on_time;
		show_status("LP -> off - force", on_time, -1);

    	mutex_unlock(tegra3_cpu_lock);

		if (!manual_hotplug)
			cpuquiet_device_free();
	}
	
	return 0;
}
Пример #2
0
void tegra_auto_hotplug_governor(unsigned int cpu_freq, bool suspend)
{
	if (!is_g_cluster_present())
		return;

	if (cpq_state == TEGRA_CPQ_DISABLED)
		return;

	cpq_state = TEGRA_CPQ_IDLE;
	is_suspended = suspend;
	
	if (suspend) {
		return;
	}

	if (is_lp_cluster() && 
			(cpu_freq > idle_top_freq || no_lp)) {
       	cpq_state = TEGRA_CPQ_SWITCH_TO_G;
		queue_delayed_work(cpuquiet_wq, &cpuquiet_work, msecs_to_jiffies(lp_up_delay));
	} else if (cpu_freq <= idle_top_freq && lp_possible()) {
		cpq_state = TEGRA_CPQ_SWITCH_TO_LP;
		if (queue_delayed_work(cpuquiet_wq, &cpuquiet_work, msecs_to_jiffies(lp_down_delay)))
#if CPUQUIET_DEBUG_VERBOSE
        	pr_info(CPUQUIET_TAG "qeued TEGRA_CPQ_SWITCH_TO_LP\n");		
#else
			;
#endif
	}
}
Пример #3
0
void tegra_auto_hotplug_governor(unsigned int cpu_freq, bool suspend)
{
	if (!is_g_cluster_present())
		return;

	if (cpq_state == TEGRA_CPQ_DISABLED)
		return;

	if (suspend) {
		cpq_state = TEGRA_CPQ_IDLE;

		/* Switch to G-mode if suspend rate is high enough */
		if (is_lp_cluster() && (cpu_freq >= idle_bottom_freq)) {
			clk_set_parent(cpu_clk, cpu_g_clk);
			cpuquiet_device_free();
		}
		return;
	}

	if (is_lp_cluster() && pm_qos_request(PM_QOS_MIN_ONLINE_CPUS) >= 2) {
		if (cpq_state != TEGRA_CPQ_SWITCH_TO_G) {
			/* Force switch */
			cpq_state = TEGRA_CPQ_SWITCH_TO_G;
			queue_delayed_work(
				cpuquiet_wq, &cpuquiet_work, up_delay);
		}
		return;
	}

	if (is_lp_cluster() && (cpu_freq >= idle_top_freq || no_lp)) {
		cpq_state = TEGRA_CPQ_SWITCH_TO_G;
		queue_delayed_work(cpuquiet_wq, &cpuquiet_work, up_delay);
	} else if (!is_lp_cluster() && !no_lp &&
		   cpu_freq <= idle_bottom_freq) {
		cpq_state = TEGRA_CPQ_SWITCH_TO_LP;
		queue_delayed_work(cpuquiet_wq, &cpuquiet_work, down_delay);
	} else {
		cpq_state = TEGRA_CPQ_IDLE;
	}
}
void tegra_auto_hotplug_governor(unsigned int cpu_freq, bool suspend)
{
    unsigned long up_delay, top_freq, bottom_freq;

    if (!is_g_cluster_present())
        return;

    if (hp_state == TEGRA_HP_DISABLED)
        return;

    if (suspend) {
        hp_state = TEGRA_HP_IDLE;

        /* Switch to G-mode if suspend rate is high enough */
        if (is_lp_cluster() && (cpu_freq >= idle_bottom_freq)) {
            if (!clk_set_parent(cpu_clk, cpu_g_clk)) {
                hp_stats_update(CONFIG_NR_CPUS, false);
                hp_stats_update(0, true);
            }
        }
        return;
    }

    if (is_lp_cluster()) {
        up_delay = up2g0_delay;
        top_freq = idle_top_freq;
        bottom_freq = 0;
    } else {
        up_delay = up2gn_delay;
        top_freq = idle_bottom_freq;
        bottom_freq = idle_bottom_freq;
    }

    if (pm_qos_request(PM_QOS_MIN_ONLINE_CPUS) >= 2) {
        if (hp_state != TEGRA_HP_UP) {
            hp_state = TEGRA_HP_UP;
            queue_delayed_work(
                hotplug_wq, &hotplug_work, up_delay);
        }
        return;
    }

    switch (hp_state) {
    case TEGRA_HP_IDLE:
        if (cpu_freq > top_freq) {
            hp_state = TEGRA_HP_UP;
            queue_delayed_work(
                hotplug_wq, &hotplug_work, up_delay);
        } else if (cpu_freq <= bottom_freq) {
            hp_state = TEGRA_HP_DOWN;
            queue_delayed_work(
                hotplug_wq, &hotplug_work, down_delay);
        }
        break;
    case TEGRA_HP_DOWN:
        if (cpu_freq > top_freq) {
            hp_state = TEGRA_HP_UP;
            queue_delayed_work(
                hotplug_wq, &hotplug_work, up_delay);
        } else if (cpu_freq > bottom_freq) {
            hp_state = TEGRA_HP_IDLE;
        }
        break;
    case TEGRA_HP_UP:
        if (cpu_freq <= bottom_freq) {
            hp_state = TEGRA_HP_DOWN;
            queue_delayed_work(
                hotplug_wq, &hotplug_work, down_delay);
        } else if (cpu_freq <= top_freq) {
            hp_state = TEGRA_HP_IDLE;
        }
        break;
    default:
        pr_err("%s: invalid tegra hotplug state %d\n",
               __func__, hp_state);
        BUG();
    }
}