/*delete mdss_mdp_get_clk_rate() to avoid panic*/ void mdp_underrun_dsm_report(unsigned long num,unsigned long underrun_cnt) { /* try to get permission to use the buffer */ if(dsm_client_ocuppy(lcd_dclient)) { /* buffer is busy */ LCD_LOG_ERR("%s: buffer is busy!\n", __func__); return; } dsm_client_record(lcd_dclient, "Lcd underrun detected for ctl=%d,count=%d\n",num,underrun_cnt); dsm_client_notify(lcd_dclient, DSM_LCD_MDSS_UNDERRUN_ERROR_NO); }
int mdss_record_dsm_err(u32 *dsi_status) { if( NULL == lcd_dclient ) { LCD_LOG_ERR("%s: there is no lcd_dclient!\n", __func__); return -1; } /* try to get permission to use the buffer */ if(dsm_client_ocuppy(lcd_dclient)) { /* buffer is busy */ LCD_LOG_ERR("%s: buffer is busy!\n", __func__); return -1; } LCD_LOG_INFO("%s: entry!\n", __func__); if (dsi_status[0]) dsm_client_record(lcd_dclient, "DSI_ACK_ERR_STATUS is wrong ,err number :%x\n", dsi_status[0]); if (dsi_status[1] & 0x0111) dsm_client_record(lcd_dclient, "DSI_TIMEOUT_STATUS is wrong ,err number :%x\n", dsi_status[1]); if (dsi_status[2] & 0x011111) dsm_client_record(lcd_dclient, "DSI_DLN0_PHY_ERR is wrong ,err number :%x\n", dsi_status[2]); if (dsi_status[3] & 0xcccc4489) dsm_client_record(lcd_dclient, "DSI_FIFO_STATUS is wrong ,err number :%x\n", dsi_status[3]); if (dsi_status[4] & 0x80000000) dsm_client_record(lcd_dclient, "DSI_STATUS is wrong ,err number :%x\n", dsi_status[4]); dsm_client_notify(lcd_dclient, DSM_LCD_MDSS_DSI_ISR_ERROR_NO); return 0; }
static int fget_dtsi_style(unsigned char * buf, int max_num, int fd,off_t *fd_seek) { int cur_seek=*fd_seek; unsigned char ch = '\0'; unsigned char last_char = 'Z'; int j =0; sys_lseek(fd, (off_t)0,0); while (j < max_num) { if ((unsigned)sys_read(fd, &ch, 1) != 1) { LCD_LOG_INFO("\n%s: its end of file %d : len = %d\n", __func__, __LINE__, j); return j; } else { if (!IS_VALID_CHAR(ch)) { last_char = 'Z'; cur_seek++; sys_lseek(fd, (off_t)cur_seek,0); continue; } if (last_char != 'Z') { /*two char value is possible like F0, so make it a single char*/ --j; buf[j] = (buf[j] * HEX_BASE) + hex_char_to_value(ch); last_char = 'Z'; } else { buf[j]= hex_char_to_value(ch); last_char = buf[j]; } j++; cur_seek++; sys_lseek(fd, (off_t)cur_seek,0); } } if (j >= max_num){ LCD_LOG_ERR("%s:Buffer is not enough", __func__); j *= -1; } *fd_seek=cur_seek; return j; }
/* set global ctrl_pdata pointer */ void lcd_dbg_set_dsi_ctrl_pdata(struct mdss_dsi_ctrl_pdata *ctrl) { static char already_set = 0; /* judge if already set or not*/ if (already_set) { LCD_LOG_ERR("%s: already set\n", __func__); } else { g_lcd_dbg_dsi_ctrl_pdata = ctrl; already_set = 1; } return; }
bool lcd_debug_malloc_dtsi_para(void **para_table, uint32_t *para_num) { int ret = 0 ; int fd = 0 ; void * table_tmp = NULL; int num_tmp =0 ; mm_segment_t fs; if(NULL==para_table){ return FALSE; } fs = get_fs(); /* save previous value */ set_fs (get_ds()); /* use kernel limit */ fd = sys_open((const char __force *) HW_LCD_INIT_TEST_PARAM, O_RDONLY, 0); if (fd < 0) { LCD_LOG_INFO("%s: %s file doesn't exsit\n", __func__, HW_LCD_INIT_TEST_PARAM); set_fs(fs); return FALSE; } LCD_LOG_INFO( "%s: Config file %s opened. \n", __func__, HW_LCD_INIT_TEST_PARAM); //resolve the config file ret = lcd_resolve_dtsi_config_file(fd, &table_tmp,&num_tmp); sys_close(fd); set_fs(fs); *para_table = table_tmp; *para_num = (uint32_t)num_tmp; if (FALSE == ret){ LCD_LOG_ERR("%s failed to read the init code into memory\n",__func__); return FALSE; } *para_table = table_tmp; LCD_LOG_INFO("%s init code is copied into memory\n",__func__); return TRUE; }
int lcd_report_dsm_err(int type, int err_value,int add_value) { if ((DSM_LCD_MIPI_ERROR_NO == type && 0x51 == add_value)|| DSM_LCD_MDSS_DSI_ISR_ERROR_NO == type) { return 0; } LCD_LOG_INFO("%s: entry! type:%d\n", __func__, type); if( NULL == lcd_dclient ) { LCD_LOG_ERR("%s: there is not lcd_dclient!\n", __func__); return -1; } /* try to get permission to use the buffer */ if(dsm_client_ocuppy(lcd_dclient)) { /* buffer is busy */ LCD_LOG_ERR("%s: buffer is busy!\n", __func__); return -1; } /* lcd report err according to err type */ switch(type) { case DSM_LCD_STATUS_ERROR_NO: dsm_client_record(lcd_dclient, "lcd register %x status wrong, value :%x\n",add_value, err_value); break; case DSM_LCD_MIPI_ERROR_NO: dsm_client_record(lcd_dclient, "mipi transmit register %x time out ,err number :%x\n", add_value, err_value ); break; /* add for lcd esd */ case DSM_LCD_ESD_STATUS_ERROR_NO: dsm_client_record(lcd_dclient, "LCD STATUS ERROR %x read data = %x\n", add_value, err_value ); break; case DSM_LCD_ESD_REBOOT_ERROR_NO: dsm_client_record(lcd_dclient, "LCD RESET register %x read data =%x\n", add_value, err_value ); break; case DSM_LCD_MDSS_IOMMU_ERROR_NO: dsm_client_record(lcd_dclient, "mdss iommu attach/detach or map memory fail (%d)\n", err_value); break; case DSM_LCD_MDSS_PIPE_ERROR_NO: dsm_client_record(lcd_dclient, "mdss pipe status error (%d)\n",err_value); break; case DSM_LCD_MDSS_PINGPONG_ERROR_NO: dsm_client_record(lcd_dclient, "mdss wait pingpong time out (%d)\n",err_value); break; case DSM_LCD_MDSS_VSP_ERROR_NO: dsm_client_record(lcd_dclient, "get vsp/vsn(%d) register fail (%d) \n", add_value, err_value); break; case DSM_LCD_MDSS_ROTATOR_ERROR_NO: dsm_client_record(lcd_dclient, "mdss rotator queue fail (%d) \n",err_value); break; case DSM_LCD_MDSS_FENCE_ERROR_NO: dsm_client_record(lcd_dclient, "mdss sync_fence_wait fail (%d) \n", err_value); break; case DSM_LCD_MDSS_CMD_STOP_ERROR_NO: dsm_client_record(lcd_dclient, "mdss stop cmd time out (%d) \n", err_value); break; case DSM_LCD_MDSS_VIDEO_DISPLAY_ERROR_NO: dsm_client_record(lcd_dclient, "mdss commit without wait! ctl=%d", err_value); break; case DSM_LCD_MDSS_MDP_CLK_ERROR_NO: dsm_client_record(lcd_dclient, "mdss mdp clk can't be turned off\n", err_value); break; case DSM_LCD_MDSS_MDP_BUSY_ERROR_NO: dsm_client_record(lcd_dclient, "mdss mdp dma tx time out (%d)\n", err_value); break; default: break; } dsm_client_notify(lcd_dclient, type); return 0; }
/********************************************************************************** *function:process read and write commands for lcd reg debug *op_type: read or write *reg: lcd register *cmd_type: DCS or GEN *param_num: the count of prameters to tranfer *param_buf: prameters *read_value: value from lcd panel *delay_ms: delay time *return: 0 - success, negative - fail **********************************************************************************/ int lcd_dbg_mipi_prcess_ic_reg(int op_type,int reg, int cmd_type, int param_num, char *param_buf,int *read_value, int delay_ms) { static struct dcs_cmd_req cmdreq; static struct dsi_cmd_desc dsi_cmd; // dsi cmd struct struct mdss_dsi_ctrl_pdata *ctrl = NULL; #if LCD_MIPI_DEBUG_ON int i = 0; #endif /* check if input legal */ if (is_mipi_input_legal(op_type,reg, cmd_type, param_num,param_buf)) { LCD_LOG_ERR("%s, input illegal.\n", __func__); return -1; } ctrl = lcd_dbg_get_dsi_ctrl_pdata(); /* translate cmd_type from huawei to qcom's format */ switch (param_num) { case 0: { if(OPER_READ == op_type) { /* DCS MODE */ if (MIPI_DCS_COMMAND == cmd_type) { cmd_type = DTYPE_DCS_READ; } /* GEN MODE */ else if (MIPI_GEN_COMMAND == cmd_type) { cmd_type = DTYPE_GEN_READ; } } else { /* DCS MODE */ if (MIPI_DCS_COMMAND == cmd_type) { cmd_type = DTYPE_DCS_WRITE; } /* GEN MODE */ else if (MIPI_GEN_COMMAND == cmd_type) { cmd_type = DTYPE_GEN_WRITE1; } } break; } case 1: { if(OPER_READ == op_type) { /* DCS MODE */ if (MIPI_DCS_COMMAND == cmd_type) { LCD_LOG_ERR("%s ,not support this kind of dcs read! \n",__func__); return -1; } /* GEN MODE */ else if (MIPI_GEN_COMMAND == cmd_type) { cmd_type = DTYPE_GEN_READ1; } } else { /* DCS MODE */ if (MIPI_DCS_COMMAND == cmd_type) { cmd_type = DTYPE_DCS_WRITE1; } /* GEN MODE */ else if (MIPI_GEN_COMMAND == cmd_type) { cmd_type = DTYPE_GEN_WRITE2; } } break; } default: { if(OPER_READ == op_type) { /* DCS MODE */ if (MIPI_DCS_COMMAND == cmd_type) { LCD_LOG_ERR("%s ,not support this kind of dcs read! \n",__func__); return -1; } /* GEN MODE */ else if (MIPI_GEN_COMMAND == cmd_type) { cmd_type = DTYPE_GEN_READ2; } } else { /* DCS MODE */ if (MIPI_DCS_COMMAND == cmd_type) { cmd_type = DTYPE_DCS_LWRITE; } /* GEN MODE */ else if (MIPI_GEN_COMMAND == cmd_type) { cmd_type = DTYPE_GEN_LWRITE; } } break; } } /* insert reg into param_buf's beginning */ memmove(param_buf + 1, param_buf, param_num); param_buf[0] = reg; param_num++; /* debug begin */ #if LCD_MIPI_DEBUG_ON LCD_LOG_INFO("%s,op_type=%d, reg=0x%02x, cmd_type=0x%02x, param_num=0x%02x, delay_ms=0x%02x\n", __func__, op_type,reg, cmd_type, param_num, delay_ms); LCD_LOG_INFO("%s, print param_buf begin\n", __func__); for (i = 0; i < param_num; i++) { LCD_LOG_INFO("0x%02x ", param_buf[i]); } LCD_LOG_INFO("%s, print param_buf end\n", __func__); #endif /* debug end */ dsi_cmd.dchdr.dtype = cmd_type; dsi_cmd.dchdr.last =1; dsi_cmd.dchdr.vc = 0; dsi_cmd.dchdr.dlen = param_num; dsi_cmd.payload = param_buf; memset(&cmdreq, 0, sizeof(cmdreq)); switch(op_type) { case OPER_READ: dsi_cmd.dchdr.ack = 1; dsi_cmd.dchdr.wait = 5;//5 ms cmdreq.flags = CMD_REQ_RX | CMD_REQ_COMMIT; cmdreq.rbuf = (char*)read_value; break; case OPER_WRITE: dsi_cmd.dchdr.ack = 0; dsi_cmd.dchdr.wait = delay_ms;//5 ms cmdreq.flags = CMD_REQ_COMMIT; cmdreq.rbuf = NULL; break; } cmdreq.cmds = &dsi_cmd; cmdreq.cmds_cnt = 1; if (ctrl->long_read_flag) { cmdreq.rlen = 3; }else { cmdreq.rlen = 1; } cmdreq.cb = NULL; /* call back */ mdss_dsi_cmdlist_put(ctrl, &cmdreq); if( op_type ==OPER_READ ) { LCD_LOG_INFO("%s, read value is 0x%02x\n", __func__,cmdreq.rbuf[0]); } return 0; }
/* G730: BOE: ID[1:0] {1:1} --->is is 5 tianma: ID[1:0] {0:0} --->id is 0 youda: ID[1:0] {1:0} --->id is 4 BYD: ID[1:0] {0:1} --->id is 1 BOE IC NT35517 tianma IC HX8389-B youda IC RM68190 BYD IC NT35517 */ int hw_get_lcd_id(void) { int ret = 0; int id0,id1; int gpio_id0,gpio_id1; int pullup_read,pulldown_read; static int lcd_id = GET_LCD_ID_FAIL; id0=0; id1=0; pullup_read = 0; pulldown_read = 0; gpio_id0 = LCD_ID_0_GPIO; gpio_id1 = LCD_ID_1_GPIO; if( (lcd_id >= 0x0) && (lcd_id <= 0xA) )//if lcd_id had read successfully,just return lcd_id. return lcd_id; if(gpio_id0 <= GET_GPIO_FAIL ||gpio_id1 <= GET_GPIO_FAIL) return GET_LCD_ID_FAIL; LCD_LOG_INFO("gpio_lcd_id0:%d gpio_lcd_id1:%d\n",gpio_id0,gpio_id1); ret = gpio_request(gpio_id0, "lcd_id0"); if (ret) { LCD_LOG_ERR("lcd_id0 gpio[%d] request failed\n", gpio_id0); goto lcd_id0_req_fail; } ret = gpio_request(gpio_id1, "lcd_id1"); if (ret) { LCD_LOG_ERR("lcd_id1 gpio[%d] request failed\n", gpio_id1); goto lcd_id1_req_fail; } /*config id0 to pull down and read*/ ret = gpio_tlmm_config(GPIO_CFG(gpio_id0,0,GPIO_CFG_INPUT,GPIO_CFG_PULL_DOWN,GPIO_CFG_2MA),GPIO_CFG_ENABLE); if (ret) { LCD_LOG_ERR("config id0 to pull down failed\n"); goto get_lcd_id_fail; } udelay(10); pulldown_read = gpio_get_value(gpio_id0); /*config id0 to pull up and read*/ ret = gpio_tlmm_config(GPIO_CFG(gpio_id0,0,GPIO_CFG_INPUT,GPIO_CFG_PULL_UP,GPIO_CFG_2MA),GPIO_CFG_ENABLE); if (ret) { LCD_LOG_ERR("config id0 to pull up failed\n"); goto get_lcd_id_fail; } udelay(10); pullup_read = gpio_get_value(gpio_id0); if(pulldown_read != pullup_read)//float { id0 = BIT(1); gpio_tlmm_config(GPIO_CFG(gpio_id0,0,GPIO_CFG_INPUT,GPIO_CFG_PULL_DOWN,GPIO_CFG_2MA),GPIO_CFG_ENABLE); } else//connect { id0 = pullup_read;//pullup_read==pulldown_read switch(id0) { case LCD_ID_PULL_DOWN: case LCD_ID_PULL_UP: default: gpio_tlmm_config(GPIO_CFG(gpio_id0,0,GPIO_CFG_INPUT,GPIO_CFG_NO_PULL,GPIO_CFG_2MA),GPIO_CFG_ENABLE); break; } } /*config id1 to pull down and read*/ ret = gpio_tlmm_config(GPIO_CFG(gpio_id1,0,GPIO_CFG_INPUT,GPIO_CFG_PULL_DOWN,GPIO_CFG_2MA),GPIO_CFG_ENABLE); if (ret) { LCD_LOG_ERR("config id1 to pull down failed\n"); goto get_lcd_id_fail; } udelay(10); pulldown_read = gpio_get_value(gpio_id1); /*config id1 to pull up and read*/ ret = gpio_tlmm_config(GPIO_CFG(gpio_id1,0,GPIO_CFG_INPUT,GPIO_CFG_PULL_UP,GPIO_CFG_2MA),GPIO_CFG_ENABLE); if (ret) { LCD_LOG_ERR("config id1 to pull up failed\n"); goto get_lcd_id_fail; } udelay(10); pullup_read = gpio_get_value(gpio_id1); if(pulldown_read != pullup_read)//float { id1 = BIT(1); gpio_tlmm_config(GPIO_CFG(gpio_id1,0,GPIO_CFG_INPUT,GPIO_CFG_PULL_DOWN,GPIO_CFG_2MA),GPIO_CFG_ENABLE); } else//connect { id1 = pullup_read;//pullup_read==pulldown_read switch(id1) { case LCD_ID_PULL_DOWN: case LCD_ID_PULL_UP: default: gpio_tlmm_config(GPIO_CFG(gpio_id1,0,GPIO_CFG_INPUT,GPIO_CFG_NO_PULL,GPIO_CFG_2MA),GPIO_CFG_ENABLE); break; } } gpio_free(gpio_id0); gpio_free(gpio_id1); lcd_id = (id1<<2) | id0; return lcd_id; get_lcd_id_fail: gpio_free(gpio_id1); lcd_id1_req_fail: gpio_free(gpio_id0); lcd_id0_req_fail: return GET_LCD_ID_FAIL; }
int hw_parse_dsi_cmds(struct dsi_panel_cmds *pcmds) { int blen = 0, len = 0; char *buf = NULL, *bp = NULL; struct dsi_ctrl_hdr *dchdr; int i = 0, cnt = 0; memset(pcmds, sizeof(struct dsi_panel_cmds), 0); if (!lcd_debug_malloc_dtsi_para((void **)&buf, &blen)) { //LCD_LOG_ERR("%s: failed\n", __func__); return -ENOMEM; } /* scan dcs commands */ bp = buf; len = blen; cnt = 0; while (len > sizeof(*dchdr)) { dchdr = (struct dsi_ctrl_hdr *)bp; dchdr->dlen = ntohs(dchdr->dlen); if (dchdr->dlen > len) { LCD_LOG_ERR("%s: dtsi cmd=%x error, len=%d", __func__, dchdr->dtype, dchdr->dlen); return -ENOMEM; } bp += sizeof(*dchdr); len -= sizeof(*dchdr); bp += dchdr->dlen; len -= dchdr->dlen; cnt++; } if (len != 0) { LCD_LOG_ERR("%s: dcs_cmd=%x len=%d error!", __func__, buf[0], blen); kfree(buf); return -ENOMEM; } pcmds->cmds = kzalloc(cnt * sizeof(struct dsi_cmd_desc), GFP_KERNEL); if (!pcmds->cmds){ kfree(buf); return -ENOMEM; } pcmds->cmd_cnt = cnt; pcmds->buf = buf; pcmds->blen = blen; bp = buf; len = blen; for (i = 0; i < cnt; i++) { dchdr = (struct dsi_ctrl_hdr *)bp; len -= sizeof(*dchdr); bp += sizeof(*dchdr); pcmds->cmds[i].dchdr = *dchdr; pcmds->cmds[i].payload = bp; bp += dchdr->dlen; len -= dchdr->dlen; } print_cmds(pcmds->cmds, pcmds->cmd_cnt); LCD_LOG_INFO("%s: dcs_cmd=%x len=%d, cmd_cnt=%d\n", __func__, pcmds->buf[0], pcmds->blen, pcmds->cmd_cnt); return 0; }