/* 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; }
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; }
/* 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; }
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; }