static void offline_fail_proccess(struct k3_fb_data_type *k3fd, u32 wbe_chn, int block_num) { dss_overlay_t *pov_req = NULL; char __iomem *dss_base = NULL; u32 i = 0; u32 ready = 0; BUG_ON(k3fd == NULL); pov_req = &(k3fd->ov_req); BUG_ON(wbe_chn >= K3_DSS_OFFLINE_MAX_NUM); BUG_ON(pov_req == NULL); dss_base = k3fd->dss_base; if(g_debug_ovl_offline_composer == 1) { u32 test1 = inp32(k3fd->dss_base + DSS_CMD_LIST_OFFSET +CMDLIST_CH5_STATUS); K3_FB_ERR("offline fail cmdlist status:0x%x\n", test1); cmdlist_print_all_node(&k3fd->offline_cmdlist_head[wbe_chn]); } /*single channel fail.*/ cmdlist_config_stop(k3fd, wbe_chn); for (i = 0; i < block_num; i++) { char __iomem *ctl_base = k3fd->dss_base + DSS_GLB_WBE1_CH0_CTL + wbe_chn * (DSS_GLB_WBE1_CH1_CTL - DSS_GLB_WBE1_CH0_CTL); if(inp32(dss_base + DSS_GLB_GLB_STATUS) & (0x1 << (2+wbe_chn))) { set_reg(ctl_base, 0x1, 1, 8); set_reg(ctl_base, 0x0, 1, 8); udelay(10); } set_reg(ctl_base, 0x1, 1, 8); set_reg(ctl_base, 0x0, 1, 8); } for (i = 0; i < pov_req->layer_nums; i++) { int chn_idx = pov_req->layer_infos[i].chn_idx - DPE2_CHN0; int rot_idx = 0; if(chn_idx > DPE3_CHN3 - DPE2_CHN0 || chn_idx < 0){ K3_FB_ERR("offline_add_virtual_frame chn:%d err\n", pov_req->layer_infos[i].chn_idx); return; } set_reg(dss_base +DSS_GLB_DPE2_CH0_CTL + chn_idx * 0x04, 0, 32, 0); if(isYUVPlanar(pov_req->layer_infos[i].src.format)) set_reg(dss_base +DSS_GLB_DPE2_CH0_CTL + (chn_idx + 1) * 0x04, 0, 32, 0); rot_idx = k3_get_rot_index(pov_req->layer_infos[i].chn_idx); if(rot_idx > 0){ set_reg(dss_base + DSS_GLB_ROT_TLB0_SCENE + rot_idx * 4, 0, 32, 0); } } set_reg(dss_base + g_dss_module_base[pov_req->wb_layer_info.chn_idx][MODULE_DMA0] + WDMA_CTRL, 0, 1, 25); if(pov_req->wb_layer_info.dst.mmu_enable) set_reg(dss_base + g_dss_module_base[pov_req->wb_layer_info.chn_idx][MODULE_MMU_DMA0], 0, 1, 0); if(pov_req->wb_layer_info.chn_idx == WBE1_CHN1){ set_reg(dss_base +DSS_GLB_OV2_SCENE, 0, 32, 0); } //start set_reg(dss_base + DSS_GLB_OFFLINE_S2_CPU_IRQ_CLR, 0x44 << wbe_chn, 32, 0); set_reg(dss_base + DSS_GLB_ADP_OFFLINE_START0 + wbe_chn * 0x04, 0x1, 32, 0); // wait start irq ready = 0; i=0; do { udelay(10); i++; if(inp32(dss_base + DSS_GLB_OFFLINE_S2_CPU_IRQ_RAWSTAT) & BIT(2 + wbe_chn)) ready = 1; } while((!ready) & (i < 100)); if(!ready) { K3_FB_ERR("offline wait start irq timeout:0x%x,i=%d\n", inp32(dss_base + DSS_GLB_OFFLINE_S2_CPU_IRQ_RAWSTAT), i); if(g_debug_ovl_offline_composer > 0) BUG_ON(1); } k3fd->offline_wb_status[wbe_chn] = e_status_idle; return; }
static int offline_add_pending_frame(struct k3_fb_data_type *k3fd, u32 wbe_chn, u32 flag) { dss_overlay_t *pov_req = NULL; char __iomem *dss_base = NULL; u32 i = 0; int ret = 0; BUG_ON(k3fd == NULL); pov_req = &(k3fd->ov_req); BUG_ON(wbe_chn >= K3_DSS_OFFLINE_MAX_NUM); BUG_ON(pov_req == NULL); dss_base = k3fd->dss_base; ret = cmdlist_add_new_list(k3fd, &k3fd->offline_cmdlist_head[wbe_chn], TRUE, flag); if(ret != 0){ K3_FB_ERR("cmdlist_add_new_list err:%d \n",ret); return ret; } //k3_adp_offline_start_disable(k3fd, pov_req); ret = k3_dss_module_init(k3fd); if (ret != 0) { K3_FB_ERR("k3_dss_module_init failed! ret = %d\n", ret); } for (i = 0; i < pov_req->layer_nums; i++) { int chn_idx = pov_req->layer_infos[i].chn_idx - DPE2_CHN0; int rot_idx = 0; if(chn_idx > DPE3_CHN3 - DPE2_CHN0 || chn_idx < 0){ K3_FB_ERR("offline_add_virtual_frame chn:%d err\n", pov_req->layer_infos[i].chn_idx); return -1; } k3fd->set_reg(k3fd, dss_base +DSS_GLB_DPE2_CH0_CTL + chn_idx * 0x04, 0, 32, 0); if(isYUVPlanar(pov_req->layer_infos[i].src.format)) k3fd->set_reg(k3fd, dss_base +DSS_GLB_DPE2_CH0_CTL + (chn_idx + 1) * 0x04, 0, 32, 0); rot_idx = k3_get_rot_index(pov_req->layer_infos[i].chn_idx); if(rot_idx > 0){ k3fd->set_reg(k3fd, dss_base + DSS_GLB_ROT_TLB0_SCENE + rot_idx * 4, 0, 32, 0); } } k3fd->set_reg(k3fd, dss_base + g_dss_module_base[pov_req->wb_layer_info.chn_idx][MODULE_DMA0] + WDMA_CTRL, 0, 1, 25); if(pov_req->wb_layer_info.dst.mmu_enable) k3fd->set_reg(k3fd, dss_base + g_dss_module_base[pov_req->wb_layer_info.chn_idx][MODULE_MMU_DMA0], 0, 1, 0); if(pov_req->wb_layer_info.chn_idx == WBE1_CHN1){ k3fd->set_reg(k3fd, dss_base +DSS_GLB_OV2_SCENE, 0, 32, 0); } memset(&(k3fd->dss_exception), 0, sizeof(dss_exception_t)); k3fd->dss_exception.underflow_exception = 1; k3_dss_handle_prev_ovl_req(k3fd, pov_req); memset(&(k3fd->dss_exception), 0, sizeof(dss_exception_t)); ret = k3_dss_module_config(k3fd); if (ret != 0) { K3_FB_ERR("k3_dss_module_config failed! ret = %d\n", ret); } k3_adp_offline_start_enable(k3fd, pov_req); return 0; }
void offline_dump_fail_reg(char __iomem *dss_base, dss_overlay_t *req, long timestamp) { char filename[128] = {0}; u32 i = 0; char * str_line = NULL; u32 len = 0; BUG_ON(dss_base == NULL); BUG_ON(req == NULL); snprintf(filename, sizeof(filename), "/data/hwcdump/offline_%ld_reg.txt", timestamp); str_line = kmalloc(SZ_64K, GFP_KERNEL); if(IS_ERR_OR_NULL(str_line)){ printk("offline_dump_fail_reg alloc buffer fail!\n"); return; } outp32(dss_base + 0x404, 0x0); //GLB len += snprintf(str_line + len, SZ_1K, "CLB reg:\n"); len += print_serial_reg(str_line, len, dss_base, 0x484, 0x484); len += print_serial_reg(str_line, len, dss_base, 0x4c4, 0x4c4); len += print_serial_reg(str_line, len, dss_base, 0x730, 0x758); //ADP len += snprintf(str_line + len, SZ_1K, "ADP reg:\n"); len += print_serial_reg(str_line, len, dss_base, 0x42530, 0x42538); //RDMA BRG len += snprintf(str_line + len, SZ_1K, "RDMA BRG reg:\n"); len += print_serial_reg(str_line, len, dss_base + g_dss_module_eng_base[DSS_ENG_DPE2][MODULE_ENG_DMA_BRG], 0x1C, 0x2C); len += print_serial_reg(str_line, len, dss_base + g_dss_module_eng_base[DSS_ENG_DPE3][MODULE_ENG_DMA_BRG], 0x1C, 0x2C); for(i = 0; i < req->layer_nums; i++){ int chn = req->layer_infos[i].chn_idx; len += snprintf(str_line + len, SZ_1K, "layer:%d chn:%d\n", i, chn); //RDMA len += snprintf(str_line + len, SZ_1K, "RDMA reg:\n"); len += print_serial_reg(str_line, len, dss_base + g_dss_module_base[chn][MODULE_DMA0], 0x04, 0x30); if( isYUVSemiPlanar(req->layer_infos[i].src.format)) len += print_serial_reg(str_line, len, dss_base + g_dss_module_base[chn][MODULE_DMA1], 0x04, 0x30); if(isYUVPlanar(req->layer_infos[i].src.format)) len += print_serial_reg(str_line, len, dss_base + g_dss_module_base[chn + 1][MODULE_DMA0], 0x04, 0x30); //RDFC len += snprintf(str_line + len, SZ_1K, "RDFC reg:\n"); len += print_serial_reg(str_line, len, dss_base + g_dss_module_base[chn][MODULE_DFC], 0x0, 0x24); //CSC len += snprintf(str_line + len, SZ_1K, "CSC reg:\n"); len += print_serial_reg(str_line, len, dss_base + g_dss_module_base[chn][MODULE_CSC], 0x1C, 0x1C); //SCF if(req->layer_infos[i].need_cap & CAP_SCL){ len += snprintf(str_line + len, SZ_1K, "SCF reg:\n"); len += print_serial_reg(str_line, len, dss_base + g_dss_module_base[chn][MODULE_SCF], 0x10, 0x14); } } //WDMA len += snprintf(str_line + len, SZ_1K, "WDMA reg:\n"); if(WBE1_CHN0 == req->wb_layer_info.chn_idx){ len += print_serial_reg(str_line, len, dss_base + g_dss_module_base[WBE1_CHN0][MODULE_DMA0], 0x04, 0x30); len += snprintf(str_line + len, SZ_1K, "WDFC reg:\n"); len += print_serial_reg(str_line, len, dss_base + g_dss_module_base[WBE1_CHN0][MODULE_DFC], 0x0, 0x24); }else if(WBE1_CHN1 == req->wb_layer_info.chn_idx) { len += print_serial_reg(str_line, len, dss_base + g_dss_module_base[WBE1_CHN1][MODULE_DMA0], 0x04, 0x30); len += snprintf(str_line + len, SZ_1K, "WDFC reg:\n"); len += print_serial_reg(str_line, len, dss_base + g_dss_module_base[WBE1_CHN1][MODULE_DFC], 0x0, 0x24); //CSC len += snprintf(str_line + len, SZ_1K, "W_CSC reg:\n"); len += print_serial_reg(str_line, len, dss_base + g_dss_module_base[WBE1_CHN1][MODULE_CSC], 0x1C, 0x1C); len += snprintf(str_line + len, SZ_1K, "OV reg:\n"); len += print_serial_reg(str_line, len, dss_base + g_dss_module_ovl_base[DSS_OVL_ADP][MODULE_OVL_BASE], 0x0, 0x150); } outp32(dss_base + 0x404, 0x2); offline_save_bin_file(filename, str_line, len); kfree(str_line); return; }
uint32_t hisi_dss_mif_get_invalid_sel(dss_img_t *img, uint32_t transform, int v_scaling_factor, uint8_t is_tile, bool rdma_stretch_enable) { uint32_t invalid_sel_val = 0; uint32_t tlb_tag_org = 0; if (img == NULL) { HISI_FB_ERR("img is null"); return 0; } if ((transform == (HISI_FB_TRANSFORM_ROT_90 | HISI_FB_TRANSFORM_FLIP_H)) || (transform == (HISI_FB_TRANSFORM_ROT_90 | HISI_FB_TRANSFORM_FLIP_V))) { transform = HISI_FB_TRANSFORM_ROT_90; } if (isYUVSemiPlanar(img->format) || isYUVPlanar(img->format)) { if (v_scaling_factor > (2048 / (img->stride/16) - 4)) { HISI_FB_DEBUG(" v_scaling_factor out of limit !!!! \n"); return 0; } } tlb_tag_org = (transform & 0x7) | ((is_tile ? 1 : 0) << 3) | ((rdma_stretch_enable ? 1 : 0) << 4); switch (tlb_tag_org) { case MMU_TLB_TAG_ORG_0x0: invalid_sel_val = 1; break; case MMU_TLB_TAG_ORG_0x1: invalid_sel_val = 1; break; case MMU_TLB_TAG_ORG_0x2: invalid_sel_val = 2; break; case MMU_TLB_TAG_ORG_0x3: invalid_sel_val = 2; break; case MMU_TLB_TAG_ORG_0x4: invalid_sel_val = 0; break; case MMU_TLB_TAG_ORG_0x7: invalid_sel_val = 0; break; case MMU_TLB_TAG_ORG_0x8: invalid_sel_val = 3; break; case MMU_TLB_TAG_ORG_0x9: invalid_sel_val = 3; break; case MMU_TLB_TAG_ORG_0xA: invalid_sel_val = 3; break; case MMU_TLB_TAG_ORG_0xB: invalid_sel_val = 3; break; case MMU_TLB_TAG_ORG_0xC: invalid_sel_val = 0; break; case MMU_TLB_TAG_ORG_0xF: invalid_sel_val = 0; break; case MMU_TLB_TAG_ORG_0x10: invalid_sel_val = 1; break; case MMU_TLB_TAG_ORG_0x11: invalid_sel_val = 1; break; case MMU_TLB_TAG_ORG_0x12: invalid_sel_val = 2; break; case MMU_TLB_TAG_ORG_0x13: invalid_sel_val = 2; break; case MMU_TLB_TAG_ORG_0x14: invalid_sel_val = 0; break; case MMU_TLB_TAG_ORG_0x17: invalid_sel_val = 0; break; case MMU_TLB_TAG_ORG_0x18: invalid_sel_val = 3; break; case MMU_TLB_TAG_ORG_0x19: invalid_sel_val = 3; break; case MMU_TLB_TAG_ORG_0x1A: invalid_sel_val = 3; break; case MMU_TLB_TAG_ORG_0x1B: invalid_sel_val = 3; break; case MMU_TLB_TAG_ORG_0x1C: invalid_sel_val = 0; break; case MMU_TLB_TAG_ORG_0x1F: invalid_sel_val = 0; break; default: invalid_sel_val = 0; HISI_FB_ERR("not support this tlb_tag_org(0x%x)!\n", tlb_tag_org); break; } return invalid_sel_val; }