/* 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; }
/* 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); if (dispdrv->platform_status < DISP_STATUS_PM1) { if (cmd == S3CFB_WIN_CONFIG) disp_pm_init_status(dispdrv); } flush_kthread_worker(&dispdrv->pm_status.control_power_gating); if (sfb->power_state == POWER_HIBER_DOWN) { switch (cmd) { case S3CFB_WIN_PSR_EXIT: case S3CFB_WIN_CONFIG: queue_kthread_work(&dispdrv->pm_status.control_power_gating, &dispdrv->pm_status.control_power_gating_work); break; default: return -EBUSY; } } return 0; }
static void decon_clock_gating_handler(struct kthread_work *work) { struct display_driver *dispdrv = get_display_driver(); if (dispdrv->pm_status.clk_idle_count > MAX_CLK_GATING_COUNT) display_block_clock_off(dispdrv); init_gating_idle_count(dispdrv); disp_pm_gate_lock(dispdrv, false); pm_debug("display_block_clock_off -"); }
static void decon_power_gating_handler(struct kthread_work *work) { struct display_driver *dispdrv = get_display_driver(); if (dispdrv->pm_status.pwr_idle_count > MAX_PWR_GATING_COUNT) { if (!check_camera_is_running()) { display_hibernation_power_off(dispdrv); init_gating_idle_count(dispdrv); } } else if (dispdrv->decon_driver.sfb->power_state == POWER_HIBER_DOWN) { display_hibernation_power_on(dispdrv); } }
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_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; }
/* 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; }