static void hisifb_vsync_ctrl_workqueue_handler(struct work_struct *work) { struct hisi_fb_data_type *hisifd = NULL; struct hisifb_vsync *vsync_ctrl = NULL; struct hisi_fb_panel_data *pdata = NULL; unsigned long flags = 0; vsync_ctrl = container_of(work, typeof(*vsync_ctrl), vsync_ctrl_work); BUG_ON(vsync_ctrl == NULL); hisifd = vsync_ctrl->hisifd; BUG_ON(hisifd == NULL); pdata = dev_get_platdata(&hisifd->pdev->dev); BUG_ON(pdata == NULL); down(&(hisifd->blank_sem)); if (!hisifd->panel_power_on) { HISI_FB_DEBUG("fb%d, panel is power off!", hisifd->index); up(&(hisifd->blank_sem)); return; } mutex_lock(&(vsync_ctrl->vsync_lock)); if (vsync_ctrl->vsync_ctrl_disabled_set && (vsync_ctrl->vsync_ctrl_expire_count == 0) && vsync_ctrl->vsync_ctrl_enabled && !vsync_ctrl->vsync_enabled) { HISI_FB_DEBUG("fb%d, dss clk off!\n", hisifd->index); spin_lock_irqsave(&(vsync_ctrl->spin_lock), flags); if (pdata->vsync_ctrl) { pdata->vsync_ctrl(hisifd->pdev, 0); } else { HISI_FB_ERR("fb%d, vsync_ctrl not supported!\n", hisifd->index); } vsync_ctrl->vsync_ctrl_enabled = 0; vsync_ctrl->vsync_ctrl_disabled_set = 0; spin_unlock_irqrestore(&(vsync_ctrl->spin_lock), flags); if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_MIPI_ULPS) { mipi_dsi_ulps_cfg(hisifd, 0); } if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_CLK_OFF) { dpe_clk_disable(hisifd); mipi_dsi_clk_disable(hisifd); } if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_VCC_OFF) { dpe_regulator_disable(hisifd); } } mutex_unlock(&(vsync_ctrl->vsync_lock)); if (vsync_ctrl->vsync_report_fnc) { vsync_ctrl->vsync_report_fnc(1); } up(&(hisifd->blank_sem)); }
void hisifb_activate_vsync(struct hisi_fb_data_type *hisifd) { struct hisi_fb_panel_data *pdata = NULL; struct hisifb_vsync *vsync_ctrl = NULL; unsigned long flags = 0; int clk_enabled = 0; BUG_ON(hisifd == NULL); pdata = dev_get_platdata(&hisifd->pdev->dev); BUG_ON(pdata == NULL); vsync_ctrl = &(hisifd->vsync_ctrl); BUG_ON(vsync_ctrl == NULL); if (hisifd->panel_info.vsync_ctrl_type == VSYNC_CTRL_NONE) return; mutex_lock(&(vsync_ctrl->vsync_lock)); if (vsync_ctrl->vsync_ctrl_enabled == 0) { HISI_FB_DEBUG("fb%d, dss clk on!\n", hisifd->index); if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_VCC_OFF) { dpe_regulator_enable(hisifd); } if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_CLK_OFF) { mipi_dsi_clk_enable(hisifd); dpe_clk_enable(hisifd); } if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_MIPI_ULPS) { mipi_dsi_ulps_cfg(hisifd, 1); } vsync_ctrl->vsync_ctrl_enabled = 1; clk_enabled = 1; } spin_lock_irqsave(&(vsync_ctrl->spin_lock), flags); vsync_ctrl->vsync_ctrl_disabled_set = 0; vsync_ctrl->vsync_ctrl_expire_count = 0; if (clk_enabled) { if (pdata->vsync_ctrl) { pdata->vsync_ctrl(hisifd->pdev, 1); } else { HISI_FB_ERR("fb%d, vsync_ctrl not supported!\n", hisifd->index); } } spin_unlock_irqrestore(&(vsync_ctrl->spin_lock), flags); mutex_unlock(&(vsync_ctrl->vsync_lock)); }
int hisifb_vsync_resume(struct hisi_fb_data_type *hisifd) { struct hisifb_vsync *vsync_ctrl = NULL; BUG_ON(hisifd == NULL); vsync_ctrl = &(hisifd->vsync_ctrl); BUG_ON(vsync_ctrl == NULL); vsync_ctrl->vsync_enabled = 0; vsync_ctrl->vsync_ctrl_expire_count = 0; vsync_ctrl->vsync_ctrl_disabled_set = 0; vsync_ctrl->vsync_ctrl_enabled = 1; vsync_ctrl->vsync_ctrl_isr_enabled = 1; //vsync_ctrl->vsync_infinite = 0; atomic_set(&(vsync_ctrl->buffer_updated), 1); #if 0 if (hisifd->panel_info.vsync_ctrl_type != VSYNC_CTRL_NONE) { if ((hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_MIPI_ULPS) || (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_CLK_OFF) || (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_VCC_OFF)) { if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_MIPI_ULPS) { mipi_dsi_ulps_cfg(hisifd, 0); } if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_CLK_OFF) { dpe_inner_clk_disable(hisifd); dpe_common_clk_disable(hisifd); mipi_dsi_clk_disable(hisifd); } if (hisifd->panel_info.vsync_ctrl_type & VSYNC_CTRL_VCC_OFF) { dpe_regulator_disable(hisifd); } } } #endif return 0; }