/* disp_pm_add_refcount - it is called in the early start of the
 * update_reg_handler */
int disp_pm_add_refcount(struct display_driver *dispdrv)
{
	unsigned long flags;

	if (dispdrv->platform_status == DISP_STATUS_PM0) return 0;

	if (!dispdrv->pm_status.clock_gating_on) return 0;

	if (dispdrv->decon_driver.sfb->power_state == POWER_DOWN)
		return 0;

	init_gating_idle_count(dispdrv);

	flush_kthread_worker(&dispdrv->pm_status.control_clock_gating);
	flush_kthread_worker(&dispdrv->pm_status.control_power_gating);
	if (dispdrv->decon_driver.sfb->power_state == POWER_HIBER_DOWN)
		display_hibernation_power_on(dispdrv);

	display_block_clock_on(dispdrv);

	spin_lock_irqsave(&dispdrv->pm_status.slock, flags);
	if (dispdrv->pm_status.trigger_masked) {
		disable_mask(dispdrv);
	}
	spin_unlock_irqrestore(&dispdrv->pm_status.slock, flags);
	return 0;
}
Exemplo n.º 2
0
int disp_pm_runtime_get_sync(struct display_driver *dispdrv)
{
	if (!dispdrv->pm_status.clock_gating_on) {
		pm_runtime_get_sync(dispdrv->display_driver);
		return 0;
	}

	init_gating_idle_count(dispdrv);

	/* guarantee clock and power gating */
	flush_kthread_worker(&dispdrv->pm_status.control_power_gating);
	pm_runtime_get_sync(dispdrv->display_driver);
	display_block_clock_on(dispdrv);

	return 0;
}
Exemplo n.º 3
0
/* disp_pm_add_refcount - it is called in the early start of the
 * update_reg_handler */
int disp_pm_add_refcount(struct display_driver *dispdrv)
{
	if (dispdrv->platform_status == DISP_STATUS_PM0) return 0;

	if (!dispdrv->pm_status.clock_gating_on) return 0;

	if (dispdrv->decon_driver.sfb->power_state == POWER_DOWN)
		return 0;

	init_gating_idle_count(dispdrv);

	flush_kthread_worker(&dispdrv->pm_status.control_power_gating);
	if (dispdrv->decon_driver.sfb->power_state == POWER_HIBER_DOWN) {
		request_dynamic_hotplug(false);
		display_hibernation_power_on(dispdrv);
	}

	display_block_clock_on(dispdrv);

	return 0;
}
Exemplo n.º 4
0
int display_hibernation_power_off(struct display_driver *dispdrv)
{
	int ret = 0;
	struct s3c_fb *sfb = dispdrv->decon_driver.sfb;

	disp_pm_gate_lock(dispdrv, true);
	mutex_lock(&dispdrv->pm_status.pm_lock);
	if (sfb->power_state == POWER_DOWN) {
		pr_info("%s, DECON are already power off state\n", __func__);
		goto done;
	}

	if (atomic_read(&dispdrv->pm_status.lock_count) > GATE_LOCK_CNT) {
		pr_info("%s, DECON does not need power-off\n", __func__);
		goto done;
	}

	/* Should be clock on before check a H/W LINECNT */
	display_block_clock_on(dispdrv);
	if (get_display_line_count(dispdrv)) {
		pm_debug("wait until last frame is totally transferred %d:",
				get_display_line_count(dispdrv));
		goto done;
	}

	sfb->power_state = POWER_HIBER_DOWN;
	__display_hibernation_power_off(dispdrv);
	disp_pm_runtime_put_sync(dispdrv);

	request_dynamic_hotplug(true);
done:
	mutex_unlock(&dispdrv->pm_status.pm_lock);
	disp_pm_gate_lock(dispdrv, false);

	return ret;
}