static int hisi_offlinecompser_panel_on(struct platform_device *pdev) { int ret = 0; struct hisi_fb_data_type *hisifd = NULL; int i = 0; BUG_ON(pdev == NULL); hisifd = platform_get_drvdata(pdev); BUG_ON(hisifd == NULL); HISI_FB_DEBUG("index=%d, enter!\n", hisifd->index); for (i = 0; i < HISI_DSS_OFFLINE_MAX_NUM; i++) { char __iomem *ctl_base = hisifd->dss_base + DSS_GLB_WBE1_CH0_CTL + i * (DSS_GLB_WBE1_CH1_CTL - DSS_GLB_WBE1_CH0_CTL); cmdlist_config_start(hisifd, i); hisifd->offline_wb_status[i] = e_status_wait; set_reg(ctl_base, 0x1, 1, 8); set_reg(ctl_base, 0x0, 1, 8); } HISI_FB_DEBUG("index=%d, exit!\n", hisifd->index); return ret; }
int k3_ov_offline_play(struct k3_fb_data_type *k3fd, unsigned long *argp) { char __iomem *dss_base = NULL; dss_overlay_t *pov_req = NULL; dss_layer_t *layer = NULL; dss_wb_layer_t *wb_layer = NULL; int i = 0; int k = 0; int ret = 0; struct fb_info *fbi = NULL; int block_num = 0; dss_rect_t wb_block_rect; struct timeval tv; u32 flag; u32 wbe_chn = 0; bool first_valid_block = true; BUG_ON(k3fd == NULL); fbi = k3fd->fbi; BUG_ON(fbi == NULL); pov_req = &(k3fd->ov_req); BUG_ON(pov_req == NULL); dss_base = k3fd->dss_base; do_gettimeofday(&tv); flag = tv.tv_usec; /*lock for k3fd data*/ down(&k3fd->ov_wb_sem); ret = copy_from_user(pov_req, argp, sizeof(dss_overlay_t)); if (ret) { K3_FB_ERR("copy_from_user failed!\n"); goto err_nodump; } wb_layer = &(k3fd->ov_req.wb_layer_info); wbe_chn = wb_layer->chn_idx - WBE1_CHN0; if(wbe_chn >= K3_DSS_OFFLINE_MAX_NUM){ K3_FB_ERR("write back chn:%d not surport!\n",wb_layer->chn_idx); goto err_nodump; } if (fbi->fbops->fb_blank) fbi->fbops->fb_blank(FB_BLANK_UNBLANK, fbi); /*in case of single channel fail.*/ if (k3fd->offline_wb_status[wbe_chn] == e_status_idle) { cmdlist_config_start(k3fd, wbe_chn); k3fd->offline_wb_status[wbe_chn] = e_status_wait; } ret = get_block_rect(pov_req, (wb_layer->dst_rect.x + wb_layer->dst_rect.w), (wb_layer->dst_rect.y + wb_layer->dst_rect.h), &block_num, k3fd->block_rects); if ((ret != 0) || (block_num == 0)|| block_num >= K3_DSS_OFFLINE_MAX_BLOCK) { K3_FB_ERR("get_block_rect failed! ret = %d, block_num[%d]\n", ret, block_num); goto err_return; } for (k = 0; k < block_num; k++) { ret = get_block_layers(pov_req, *k3fd->block_rects[k], k3fd->block_overlay); if (ret != 0) { K3_FB_ERR("get_block_layers err ret = %d\n", ret); goto err_return; } ret = rect_across_rect(*k3fd->block_rects[k], wb_layer->src_rect, &wb_block_rect); if (ret == 0) { K3_FB_ERR("no cross! block_rects[%d]{%d %d %d %d}, wb src_rect{%d %d %d %d}\n", k, k3fd->block_rects[k]->x, k3fd->block_rects[k]->y, k3fd->block_rects[k]->w, k3fd->block_rects[k]->h, wb_layer->src_rect.x, wb_layer->src_rect.y, wb_layer->src_rect.w, wb_layer->src_rect.h); continue; } if (true == first_valid_block) { ret = k3_dss_module_init(k3fd); if (ret != 0) { K3_FB_ERR("k3_dss_module_init failed! ret = %d\n", ret); goto err_return; } } if(g_debug_ovl_offline_cmdlist - 1 == k){ ret = cmdlist_add_new_list(k3fd, &k3fd->offline_cmdlist_head[wbe_chn], TRUE, flag); }else{ ret = cmdlist_add_new_list(k3fd, &k3fd->offline_cmdlist_head[wbe_chn], FALSE, flag); } if(ret != 0){ K3_FB_ERR("cmdlist_add_new_list err:%d \n",ret); return ret; } if (true == first_valid_block) { offline_stop_glb(k3fd, wbe_chn); k3_dss_scf_coef_load(k3fd); first_valid_block = false; } k3_adp_offline_start_disable(k3fd, pov_req); if (g_debug_ovl_offline_composer == 1) { K3_FB_INFO("dump block_overlay:\n"); K3_FB_INFO("{%d %d %d %d} cross {%d %d %d %d} = {%d %d %d %d}\n", k3fd->block_rects[k]->x, k3fd->block_rects[k]->y, k3fd->block_rects[k]->w, k3fd->block_rects[k]->h, wb_layer->src_rect.x, wb_layer->src_rect.y, wb_layer->src_rect.w, wb_layer->src_rect.h, wb_block_rect.x, wb_block_rect.y, wb_block_rect.w, wb_block_rect.h); } k3_dss_handle_cur_ovl_req(k3fd, k3fd->block_overlay); k3_dss_handle_cur_ovl_req_wb(k3fd, k3fd->block_overlay); ret = k3_dss_ovl_base_config(k3fd, &wb_block_rect, k3fd->ov_req.ovl_flags); if (ret != 0) { K3_FB_ERR("k3_dss_ovl_init failed! ret = %d\n", ret); goto err_return; } ret = k3_dss_rdma_bridge_config(k3fd, k3fd->block_overlay); if (ret != 0) { K3_FB_ERR("k3_dss_rdma_bridge_config failed! ret = %d\n", ret); goto err_return; } /* Go through all layers */ for (i = 0; i < k3fd->block_overlay->layer_nums; i++) { layer = &k3fd->block_overlay->layer_infos[i]; ret = k3_dss_offline_one_layer_config(k3fd, layer, &wb_block_rect); if (ret != 0) { K3_FB_ERR("k3_dss_offline_one_layer_config failed, ret = %d\n", ret); goto err_return; } } ret = k3_dss_write_back_config(k3fd, wb_layer, &wb_block_rect); if (ret != 0) { K3_FB_ERR("k3_dss_offline_one_layer_config failed, ret = %d\n", ret); goto err_return; } ret = k3_dss_module_config(k3fd); if (ret != 0) { K3_FB_ERR("k3_dss_module_config failed! ret = %d\n", ret); goto err_return; } k3_adp_offline_start_enable(k3fd, k3fd->block_overlay); if (k < (block_num - 1)) { ret = k3_dss_module_init(k3fd); if (ret != 0) { K3_FB_ERR("k3_dss_module_init failed! ret = %d\n", ret); goto err_return; } k3_dss_handle_prev_ovl_req(k3fd, k3fd->block_overlay); k3_dss_handle_prev_ovl_req_wb(k3fd, k3fd->block_overlay); } } ret = offline_add_pending_frame(k3fd, wbe_chn, flag); if (ret != 0) { K3_FB_ERR("offline_add_virtual_frame failed! ret = %d\n", ret); goto err_return; } cmdlist_frame_valid(&k3fd->offline_cmdlist_head[wbe_chn]); cmdlist_add_nop_list(k3fd, &k3fd->offline_cmdlist_head[wbe_chn], FALSE); #ifdef CONFIG_BUF_SYNC_USED for (i = 0; i < pov_req->layer_nums; i++) { if (pov_req->layer_infos[i].acquire_fence >= 0){ k3fb_buf_sync_wait(pov_req->layer_infos[i].acquire_fence); } } #endif //flush cache before start frame cmdlist_flush_cmdlistmemory_cache(&k3fd->offline_cmdlist_head[wbe_chn], k3fd->ion_client); cmdlist_start_frame(k3fd, wbe_chn); /*unlock for k3fd data*/ up(&k3fd->ov_wb_sem); /*lock if use dpe3 chn0 and chn1*/ offline_chn_lock(k3fd); ret = wait_event_interruptible_timeout(k3fd->offline_writeback_wq[wbe_chn], (k3fd->offline_wb_done[wbe_chn] == flag), msecs_to_jiffies(OFFLINE_COMPOSE_TIMEOUT)); /*unlock if use dpe3 chn0 and chn1*/ offline_chn_unlock(k3fd); /*lock for k3fd data*/ down(&k3fd->ov_wb_sem); cmdlist_prepare_next_frame(k3fd, wbe_chn); cmdlist_free_nop(&k3fd->offline_cmdlist_head[wbe_chn], k3fd->ion_client); if (ret <= 0) { ret = -ETIMEDOUT; if(g_debug_ovl_offline_composer > 0) offline_dump_fail_reg(dss_base, pov_req, tv.tv_sec); offline_fail_proccess(k3fd, wbe_chn, block_num); goto err_return; } ret = 0; err_return: if (ret != 0 && g_debug_ovl_offline_composer > 0) { do_gettimeofday(&tv); offline_dump_fail_info_to_file(pov_req, tv.tv_sec); } err_nodump: cmdlist_free_frame(&k3fd->offline_cmdlist_head[wbe_chn], k3fd->ion_client); k3_dss_rptb_handler(k3fd, false, wbe_chn); k3_dss_rptb_handler(k3fd, true, wbe_chn); if(g_debug_ovl_offline_composer == 3) { do_gettimeofday(&tv); offline_dump_fail_info_to_file(pov_req, tv.tv_sec); g_debug_ovl_offline_composer = 0; } if(first_valid_block == false) k3_dss_scf_coef_unload(k3fd); if ((k3fd->offline_wb_status[0] <= e_status_wait) && (k3fd->offline_wb_status[1] <= e_status_wait) && fbi->fbops->fb_blank && !g_debug_dss_adp_sr) { fbi->fbops->fb_blank(FB_BLANK_POWERDOWN, fbi); } /*unlock for k3fd data*/ up(&k3fd->ov_wb_sem); if(g_debug_ovl_offline_composer == 2) { struct timeval tv_last; u32 use_time = 0; do_gettimeofday(&tv_last); use_time = (tv_last.tv_sec - tv.tv_sec) * 1000 + (tv_last.tv_usec - tv.tv_usec) /1000; printk("--use:%d ms \n",use_time); } return ret; }