Exemplo n.º 1
0
void debug_function(struct display_driver *dispdrv, const char *buf)
{
	long input_time;
#ifndef CONFIG_FB_HIBERNATION_DISPLAY
	pm_info("%s: does not support", __func__);
	return;
#endif
	pm_info("calls [%s] to control gating function\n", buf);

	if (!kstrtol(buf, 10, &input_time)) {
		if (input_time == 0) {
			request_dynamic_hotplug(false);
			dispdrv->pm_status.hotplug_gating_on = false;
		} else {
			dispdrv->pm_status.hotplug_delay_msec = input_time;
			dispdrv->pm_status.hotplug_gating_on = true;
			if (dispdrv->decon_driver.sfb->power_state == POWER_HIBER_DOWN) {
				request_dynamic_hotplug(true);
			}
		}
		pm_info("Hotplug delay time is : %ld ms\n", input_time);
		pm_info("HOTPLUG GATING MODE: %s\n",
				dispdrv->pm_status.hotplug_gating_on == true? "TRUE":"FALSE");
		return;
	}
	if (!strcmp(buf, "clk-gate-on")) {
		dispdrv->pm_status.clock_gating_on = true;
	} else if (!strcmp(buf, "clk-gate-off")) {
		dispdrv->pm_status.clock_gating_on = false;
	} else if (!strcmp(buf, "pwr-gate-on")) {
		dispdrv->pm_status.power_gating_on = true;
	} else if (!strcmp(buf, "pwr-gate-off")) {
		dispdrv->pm_status.power_gating_on = false;
	} else if (!strcmp(buf, "hotplug-gate-on")) {
		dispdrv->pm_status.hotplug_gating_on = true;
	} else if (!strcmp(buf, "hotplug-gate-off")) {
		request_dynamic_hotplug(false);
		dispdrv->pm_status.hotplug_gating_on = false;
	} else {
		pr_err("INVALID parameter: '%s'\n", buf);
	}
	pm_info("CLOCK GATING MODE: %s\n",
		dispdrv->pm_status.clock_gating_on == true? "TRUE":"FALSE");
	pm_info("POWER GATING MODE: %s\n",
		dispdrv->pm_status.power_gating_on == true? "TRUE":"FALSE");
	pm_info("HOTPLUG GATING MODE: %s\n",
		dispdrv->pm_status.hotplug_gating_on == true? "TRUE":"FALSE");
}
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;
	}
	if (get_display_line_count(dispdrv)) {
		pm_debug("wait until last frame is totally transferred %d:",
				get_display_line_count(dispdrv));
		goto done;
	}

	pm_info("##### +");
	sfb->power_state = POWER_HIBER_DOWN;
	__display_hibernation_power_off(dispdrv);
	disp_pm_runtime_put_sync(dispdrv);

	request_dynamic_hotplug(true);
	pm_info("##### -\n");
done:
	mutex_unlock(&dispdrv->pm_status.pm_lock);
	disp_pm_gate_lock(dispdrv, false);

	return ret;
}
int display_hibernation_power_on(struct display_driver *dispdrv)
{
	int ret = 0;
	struct s3c_fb *sfb = dispdrv->decon_driver.sfb;

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

	request_dynamic_hotplug(false);

	pm_runtime_get_sync(dispdrv->display_driver);
	__display_hibernation_power_on(dispdrv);
	sfb->power_state = POWER_ON;

done:
	mutex_unlock(&dispdrv->pm_status.pm_lock);
	disp_pm_gate_lock(dispdrv, false);
	pm_info("##### -\n");
	return ret;
}
Exemplo n.º 4
0
/* disp_pm_sched_power_on - it is called in the early start of the
 * fb_ioctl to exit HDM */
int disp_pm_sched_power_on(struct display_driver *dispdrv, unsigned int cmd)
{
	struct s3c_fb *sfb = dispdrv->decon_driver.sfb;

	init_gating_idle_count(dispdrv);

	/* First WIN_CONFIG should be on clock and power-gating */
	if (dispdrv->platform_status < DISP_STATUS_PM1) {
		if (cmd == S3CFB_WIN_CONFIG)
			disp_pm_set_plat_status(dispdrv, true);
	}

	flush_kthread_worker(&dispdrv->pm_status.control_power_gating);
	if (sfb->power_state == POWER_HIBER_DOWN) {
		switch (cmd) {
		case S3CFB_PLATFORM_RESET:
			disp_pm_gate_lock(dispdrv, true);
			queue_kthread_work(&dispdrv->pm_status.control_power_gating,
				&dispdrv->pm_status.control_power_gating_work);
			/* Prevent next clock and power-gating */
			disp_pm_set_plat_status(dispdrv, false);
			break;
		case S3CFB_WIN_PSR_EXIT:
		case S3CFB_WIN_CONFIG:
		case S3CFB_SET_VSYNC_INT:
			request_dynamic_hotplug(false);
			disp_pm_gate_lock(dispdrv, true);
			queue_kthread_work(&dispdrv->pm_status.control_power_gating,
				&dispdrv->pm_status.control_power_gating_work);
			break;
		default:
			return -EBUSY;
		}
	} else {
		switch (cmd) {
		case S3CFB_PLATFORM_RESET:
			/* Prevent next clock and power-gating */
			disp_pm_set_plat_status(dispdrv, false);
			break;
		}
	}

	return 0;
}
Exemplo n.º 5
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;
}