Loading techpack/display/msm/Makefile +15 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,21 @@ msm_drm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi_phy.o \ dsi/dsi_clk_manager.o \ dsi/dsi_display_test.o \ ifeq ($(CONFIG_PXLW_IRIS),y) msm_drm-$(CONFIG_PXLW_IRIS) += dsi/iris/dsi_iris6_ioctl.o \ dsi/iris/dsi_iris6_lightup.o \ dsi/iris/dsi_iris6_lightup_ocp.o \ dsi/iris/dsi_iris6_lp.o \ dsi/iris/dsi_iris6_lut.o \ dsi/iris/dsi_iris6_pq.o \ dsi/iris/dsi_iris6_cmds.o \ dsi/iris/dsi_iris6_i3c.o \ dsi/iris/dsi_iris6_gpio.o \ dsi/iris/dsi_iris6_loopback.o \ dsi/iris/dsi_iris6_dbg.o ccflags-y += -DCONFIG_PXLW_IRIS endif msm_drm-$(CONFIG_DSI_PARSER) += dsi/dsi_parser.o \ msm_drm-$(CONFIG_DRM_MSM) += \ Loading techpack/display/msm/dsi/dsi_ctrl.c +61 −0 Original line number Diff line number Diff line Loading @@ -1211,14 +1211,22 @@ int dsi_message_validate_tx_mode(struct dsi_ctrl *dsi_ctrl, DSI_CTRL_ERR(dsi_ctrl, " Cannot transfer command,ops not defined\n"); return -ENOTSUPP; } #if defined(CONFIG_PXLW_IRIS) if ((cmd_len + 4) > SZ_256K) { #else if ((cmd_len + 4) > SZ_4K) { #endif DSI_CTRL_ERR(dsi_ctrl, "Cannot transfer,size is greater than 4096\n"); return -ENOTSUPP; } } if (*flags & DSI_CTRL_CMD_FETCH_MEMORY) { #if defined(CONFIG_PXLW_IRIS) if ((dsi_ctrl->cmd_len + cmd_len + 4) > SZ_256K) { #else if ((dsi_ctrl->cmd_len + cmd_len + 4) > SZ_4K) { #endif DSI_CTRL_ERR(dsi_ctrl, "Cannot transfer,size is greater than 4096\n"); return -ENOTSUPP; } Loading Loading @@ -1255,6 +1263,12 @@ static void dsi_kickoff_msg_tx(struct dsi_ctrl *dsi_ctrl, u32 line_no = 0x1; struct dsi_ctrl_hw_ops dsi_hw_ops = dsi_ctrl->hw.ops; #if defined(CONFIG_PXLW_IRIS) if (dsi_ctrl->host_config.panel_mode == DSI_OP_VIDEO_MODE) line_no = 10; pr_debug("line_no: %d\n", line_no); #endif SDE_EVT32(dsi_ctrl->cell_index, SDE_EVTLOG_FUNC_ENTRY, flags, msg->flags); Loading Loading @@ -1370,6 +1384,45 @@ static void dsi_ctrl_validate_msg_flags(struct dsi_ctrl *dsi_ctrl, *flags &= ~DSI_CTRL_CMD_ASYNC_WAIT; } #if defined(CONFIG_PXLW_IRIS) bool dsi_cmd_log_enable = 1; static void print_cmd_desc(struct dsi_ctrl *dsi_ctrl, const struct mipi_dsi_msg *msg) { char buf[1024]; int len = 0; size_t i; char *tx_buf = (char *)msg->tx_buf; /* Packet Info */ len += snprintf(buf, sizeof(buf) - len, "%02x ", msg->type); /* Last bit */ len += snprintf(buf + len, sizeof(buf) - len, "%02x ", (msg->flags & MIPI_DSI_MSG_LASTCOMMAND) ? 1 : 0); len += snprintf(buf + len, sizeof(buf) - len, "%02x ", msg->channel); len += snprintf(buf + len, sizeof(buf) - len, "%02x ", (u32)msg->flags); /* Delay */ len += snprintf(buf + len, sizeof(buf) - len, "%02x ", msg->wait_ms); len += snprintf(buf + len, sizeof(buf) - len, "%02x %02x ", ((u32)msg->tx_len >> 8) & 0xFF, (u32)msg->tx_len & 0xFF); /* Packet Payload */ for (i = 0 ; i < msg->tx_len ; i++) { len += snprintf(buf + len, sizeof(buf) - len, "%02x ", tx_buf[i]); /* Break to prevent show too long command */ if (i > 250) break; } pr_debug("IRIS print msg begin =====================\n"); pr_debug("%s\n", buf); pr_debug("IRIS print msg end =======================\n"); } #endif static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, const struct mipi_dsi_msg *msg, u32 *flags) Loading @@ -1383,6 +1436,11 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, u32 cnt = 0; u8 *cmdbuf; #if defined(CONFIG_PXLW_IRIS) if (dsi_cmd_log_enable) print_cmd_desc(dsi_ctrl, msg); #endif /* Select the tx mode to transfer the command */ dsi_message_setup_tx_mode(dsi_ctrl, msg->tx_len, flags); Loading Loading @@ -1663,6 +1721,9 @@ static int dsi_message_rx(struct dsi_ctrl *dsi_ctrl, /* parse the data read from panel */ cmd = buff[0]; #if defined(CONFIG_PXLW_IRIS) cmd &= 0x3f; #endif switch (cmd) { case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT: DSI_CTRL_ERR(dsi_ctrl, "Rx ACK_ERROR 0x%x\n", cmd); Loading techpack/display/msm/dsi/dsi_ctrl_hw_cmn.c +25 −1 Original line number Diff line number Diff line Loading @@ -672,9 +672,14 @@ void dsi_ctrl_hw_cmn_kickoff_command(struct dsi_ctrl_hw *ctrl, reg &= ~BIT(29);/* WC_SEL to 0 */ DSI_W32(ctrl, DSI_COMMAND_MODE_DMA_CTRL, reg); #if defined(CONFIG_PXLW_IRIS) /* set DMA FIFO read watermark to 15/16 full */ reg = 0x33; #else reg = DSI_R32(ctrl, DSI_DMA_FIFO_CTRL); reg |= BIT(20);/* Disable write watermark*/ reg |= BIT(16);/* Disable read watermark */ #endif DSI_W32(ctrl, DSI_DMA_FIFO_CTRL, reg); DSI_W32(ctrl, DSI_DMA_CMD_OFFSET, cmd->offset); Loading Loading @@ -859,7 +864,26 @@ u32 dsi_ctrl_hw_cmn_get_cmd_read_data(struct dsi_ctrl_hw *ctrl, *temp++ = ntohl(data); off -= 4; } #if defined(CONFIG_PXLW_IRIS) pr_debug("dsi: rx_byte %d, read_cnt %d, ack_err %d, cnt %d, off 0x%x\n", rx_byte, read_cnt, ack_err, cnt, off); pr_debug("DSI_ACK_ERR_STATUS = 0x%x\n", DSI_R32(ctrl, DSI_ACK_ERR_STATUS)); if (read_cnt == 12) { int cmd, wc, data2, data1, prefix; data2 = DSI_R32(ctrl, DSI_RDBK_DATA2); data1 = DSI_R32(ctrl, DSI_RDBK_DATA1); data = DSI_R32(ctrl, DSI_RDBK_DATA0); cmd = (data2 >> 24) & 0x3f; wc = ((data2 >> 16) & 0xff) + (data2 & 0xff00); prefix = (data1 >> 16) & 0xffff; if (cmd == 0x1a && wc == 6 && prefix == 0x203) { pr_err("Panel dsi error detected in aux."); pr_err("dsi rdbk data: %08x %08x %08x \n", data2, data1, data); } } #endif if (repeated_bytes) { for (i = repeated_bytes; i < 16; i++) rd_buf[j++] = reg[i]; Loading techpack/display/msm/dsi/dsi_display.c +363 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,11 @@ #include "dsi_pwr.h" #include "sde_dbg.h" #include "dsi_parser.h" #if defined(CONFIG_PXLW_IRIS) #include "iris/dsi_iris6_api.h" #include "iris/dsi_iris6_log.h" #include <video/mipi_display.h> #endif #ifdef CONFIG_TOUCHSCREEN_FTS extern int fts_esd_check(void); Loading Loading @@ -486,7 +491,11 @@ static int dsi_host_alloc_cmd_tx_buffer(struct dsi_display *display) struct dsi_display_ctrl *display_ctrl; display->tx_cmd_buf = msm_gem_new(display->drm_dev, #if defined(CONFIG_PXLW_IRIS) SZ_256K, #else SZ_4K, #endif MSM_BO_UNCACHED); if ((display->tx_cmd_buf) == NULL) { Loading @@ -495,7 +504,11 @@ static int dsi_host_alloc_cmd_tx_buffer(struct dsi_display *display) goto error; } #if defined(CONFIG_PXLW_IRIS) display->cmd_buffer_size = SZ_256K; #else display->cmd_buffer_size = SZ_4K; #endif display->aspace = msm_gem_smmu_address_space_get( display->drm_dev, MSM_SMMU_DOMAIN_UNSECURE); Loading Loading @@ -529,7 +542,11 @@ static int dsi_host_alloc_cmd_tx_buffer(struct dsi_display *display) display_for_each_ctrl(cnt, display) { display_ctrl = &display->ctrl[cnt]; #if defined(CONFIG_PXLW_IRIS) display_ctrl->ctrl->cmd_buffer_size = SZ_256K; #else display_ctrl->ctrl->cmd_buffer_size = SZ_4K; #endif display_ctrl->ctrl->cmd_buffer_iova = display->cmd_buffer_iova; display_ctrl->ctrl->vaddr = display->vaddr; Loading Loading @@ -682,6 +699,11 @@ static int dsi_display_validate_status(struct dsi_display_ctrl *ctrl, { int rc = 0; #if defined(CONFIG_PXLW_IRIS) rc = iris_status_get(ctrl, panel); return rc; #endif rc = dsi_display_read_status(ctrl, panel); if (rc <= 0) { goto exit; Loading Loading @@ -767,6 +789,15 @@ static int dsi_display_status_check_te(struct dsi_display *display) int rc = 1; int const esd_te_timeout = msecs_to_jiffies(3*20); #if defined(CONFIG_PXLW_IRIS) struct dsi_display_ctrl *ctrl; ctrl = &display->ctrl[display->cmd_master_idx]; rc = iris_status_get(ctrl, display->panel); if (rc < 0) return rc; #endif dsi_display_change_te_irq_status(display, true); reinit_completion(&display->esd_te_gate); Loading Loading @@ -835,6 +866,10 @@ int dsi_display_check_status(struct drm_connector *connector, void *display, dsi_display_set_ctrl_esd_check_flag(dsi_display, true); dsi_display_mask_ctrl_error_interrupts(dsi_display, mask, true); #if defined(CONFIG_PXLW_IRIS) iris_dma_ch1_trigger(false, 0); #endif if (status_mode == ESD_MODE_REG_READ) { rc = dsi_display_status_reg_read(dsi_display); } else if (status_mode == ESD_MODE_SW_BTA) { Loading @@ -850,6 +885,10 @@ int dsi_display_check_status(struct drm_connector *connector, void *display, panel->esd_config.esd_enabled = false; } #if defined(CONFIG_PXLW_IRIS) iris_dma_ch1_trigger(true, 0); #endif /* Unmask error interrupts if check passed*/ if (rc > 0) { dsi_display_set_ctrl_esd_check_flag(dsi_display, false); Loading Loading @@ -1537,6 +1576,276 @@ static const struct file_operations esd_check_mode_fops = { .read = debugfs_read_esd_check_mode, }; #if defined(CONFIG_PXLW_IRIS) static int panel_debug_base_open(struct inode *inode, struct file *file) { /* non-seekable */ file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE); file->private_data = inode->i_private; return 0; } static int panel_debug_base_release(struct inode *inode, struct file *file) { return 0; } #define PANEL_REG_MAX_OFFSET 1024 // FIXME static ssize_t panel_debug_base_offset_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct dsi_display *display = file->private_data; u32 off, cnt; char buf[64]; if (!display) return -ENODEV; if (count >= sizeof(buf)) return -EINVAL; if (copy_from_user(buf, user_buf, count)) return -EFAULT; buf[count] = 0; /* end of string */ if (sscanf(buf, "%x %u", &off, &cnt) != 2) return -EINVAL; if (off > PANEL_REG_MAX_OFFSET) return -EINVAL; if (cnt > (PANEL_REG_MAX_OFFSET - off)) cnt = PANEL_REG_MAX_OFFSET - off; display->off = off; display->cnt = cnt; pr_debug("offset=%x cnt=%d\n", off, cnt); return count; } static ssize_t panel_debug_base_offset_read(struct file *file, char __user *buff, size_t count, loff_t *ppos) { struct dsi_display *display = file->private_data; int len; char buf[64]; if (!display) return -ENODEV; if (*ppos) return 0; /* the end */ len = snprintf(buf, sizeof(buf), "0x%02x %x\n", display->off, display->cnt); if (len < 0 || len >= sizeof(buf)) return -EINVAL; if (count < sizeof(buf)) return -EINVAL; if (copy_to_user(buff, buf, len)) return -EFAULT; *ppos += len; /* increase offset */ return len; } /* Hex number + whitespace */ #define NEXT_VALUE_OFFSET 3 #define PANEL_CMD_MIN_TX_COUNT 2 static ssize_t panel_debug_base_reg_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct dsi_display *display = file->private_data; char buf[64]; char reg[64]; u32 len = 0, value = 0; char *bufp; bool state = false; int rc; struct dsi_cmd_desc cmds = { { 0 }, // msg 1, // last 0 // wait }; #ifndef IRIS_ABYP_LIGHTUP struct dsi_panel_cmd_set cmdset = { .state = DSI_CMD_SET_STATE_HS, .count = 1, .cmds = &cmds, }; #endif if (!display) return -ENODEV; /* get command string from user */ if (count >= sizeof(buf)) return -EINVAL; if (copy_from_user(buf, user_buf, count)) return -EFAULT; buf[count] = 0; /* end of string */ bufp = buf; /* End of a hex value in given string */ bufp[NEXT_VALUE_OFFSET - 1] = 0; while (kstrtouint(bufp, 16, &value) == 0) { reg[len++] = value; if (len >= sizeof(reg)) { pr_err("wrong input reg len\n"); return -EINVAL; } bufp += NEXT_VALUE_OFFSET; if ((bufp >= (buf + count)) || (bufp < buf)) { pr_warn("%s,buffer out-of-bounds\n", __func__); break; } /* End of a hex value in given string */ if ((bufp + NEXT_VALUE_OFFSET - 1) < (buf + count)) bufp[NEXT_VALUE_OFFSET - 1] = 0; } if (len < PANEL_CMD_MIN_TX_COUNT) { pr_err("wrong input reg len\n"); return -EINVAL; } cmds.msg.type = display->cmd_data_type; cmds.msg.flags = MIPI_DSI_MSG_LASTCOMMAND; cmds.msg.tx_len = len; cmds.msg.tx_buf = reg; rc = dsi_display_ctrl_get_host_init_state(display, &state); if (!rc && state) { dsi_panel_acquire_panel_lock(display->panel); #ifdef IRIS_ABYP_LIGHTUP rc = display->host.ops->transfer(&display->host, &cmds.msg); #else iris_pt_send_panel_cmd(display->panel, &cmdset); #endif dsi_panel_release_panel_lock(display->panel); } return rc ? rc : count; } #define PANEL_REG_ADDR_LEN 8 #define PANEL_REG_FORMAT_LEN 5 static ssize_t panel_debug_base_reg_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct dsi_display *display = file->private_data; u32 i, len = 0, reg_buf_len = 0; char *panel_reg_buf, *rx_buf; int rc; bool state = false; char panel_reg[2] = { 0 }; struct dsi_cmd_desc cmds = { { 0 }, // msg 1, // last 0 // wait }; #ifndef IRIS_ABYP_LIGHTUP struct dsi_panel_cmd_set cmdset = { .state = DSI_CMD_SET_STATE_HS, .count = 1, .cmds = &cmds, }; #endif if (!display) return -ENODEV; if (!display->cnt) return 0; if (*ppos) return 0; /* the end */ /* '0x' + 2 digit + blank = 5 bytes for each number */ reg_buf_len = (display->cnt * PANEL_REG_FORMAT_LEN) + PANEL_REG_ADDR_LEN + 1; if (count < reg_buf_len) return -EINVAL; rx_buf = kzalloc(display->cnt, GFP_KERNEL); panel_reg_buf = kzalloc(reg_buf_len, GFP_KERNEL); if (!rx_buf || !panel_reg_buf) { pr_err("not enough memory to hold panel reg dump\n"); rc = -ENOMEM; goto read_reg_fail; } panel_reg[0] = display->off; cmds.msg.type = MIPI_DSI_DCS_READ; cmds.msg.flags = MIPI_DSI_MSG_LASTCOMMAND | MIPI_DSI_MSG_REQ_ACK; cmds.msg.tx_len = 2; cmds.msg.tx_buf = panel_reg; cmds.msg.rx_len = display->cnt; cmds.msg.rx_buf = rx_buf; rc = dsi_display_ctrl_get_host_init_state(display, &state); if (!rc && state) { dsi_panel_acquire_panel_lock(display->panel); #ifdef IRIS_ABYP_LIGHTUP rc = display->host.ops->transfer(&display->host, &cmds.msg); #else iris_pt_send_panel_cmd(display->panel, &cmdset); #endif dsi_panel_release_panel_lock(display->panel); } if (rc) goto read_reg_fail; len = scnprintf(panel_reg_buf, reg_buf_len, "0x%02x: ", display->off); for (i = 0; (len < reg_buf_len) && (i < display->cnt); i++) len += scnprintf(panel_reg_buf + len, reg_buf_len - len, "0x%02x ", rx_buf[i]); if (len) panel_reg_buf[len - 1] = '\n'; if (copy_to_user(user_buf, panel_reg_buf, len)) { rc = -EFAULT; goto read_reg_fail; } *ppos += len; /* increase offset */ rc = len; read_reg_fail: kfree(rx_buf); kfree(panel_reg_buf); return rc; } static const struct file_operations panel_off_fops = { .open = panel_debug_base_open, .release = panel_debug_base_release, .read = panel_debug_base_offset_read, .write = panel_debug_base_offset_write, }; static const struct file_operations panel_reg_fops = { .open = panel_debug_base_open, .release = panel_debug_base_release, .read = panel_debug_base_reg_read, .write = panel_debug_base_reg_write, }; #endif static int dsi_display_debugfs_init(struct dsi_display *display) { int rc = 0; Loading Loading @@ -1657,6 +1966,35 @@ static int dsi_display_debugfs_init(struct dsi_display *display) goto error_remove_dir; } #if defined(CONFIG_PXLW_IRIS) display->off = 0x0a; display->cnt = 1; display->cmd_data_type = MIPI_DSI_DCS_LONG_WRITE; dump_file = debugfs_create_x8("cmd_data_type", 0600, dir, &display->cmd_data_type); if (IS_ERR_OR_NULL(dump_file)) pr_err("[%s] debugfs create panel cmd_data_type file failed, rc=%ld\n", display->name, PTR_ERR(dump_file)); dump_file = debugfs_create_file("off", 0600, dir, display, &panel_off_fops); if (IS_ERR_OR_NULL(dump_file)) pr_err("[%s] debugfs create panel off file failed, rc=%ld\n", display->name, PTR_ERR(dump_file)); dump_file = debugfs_create_file("reg", 0600, dir, display, &panel_reg_fops); if (IS_ERR_OR_NULL(dump_file)) pr_err("[%s] debugfs create panel reg file failed, rc=%ld\n", display->name, PTR_ERR(dump_file)); #endif display->root = dir; dsi_parser_dbg_init(display->parser, dir); Loading Loading @@ -2948,9 +3286,18 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host, msg->flags & MIPI_DSI_MSG_ASYNC_OVERRIDE) cmd_flags |= DSI_CTRL_CMD_ASYNC_WAIT; #if defined(CONFIG_PXLW_IRIS) if (msg->rx_buf && msg->rx_len) cmd_flags |= DSI_CTRL_CMD_READ; #endif rc = dsi_ctrl_cmd_transfer(display->ctrl[ctrl_idx].ctrl, msg, &cmd_flags); #if defined(CONFIG_PXLW_IRIS) if (rc < 0) { #else if (rc) { #endif DSI_ERR("[%s] cmd transfer failed, rc=%d\n", display->name, rc); goto error_disable_cmd_engine; Loading Loading @@ -3822,6 +4169,11 @@ static int dsi_display_res_init(struct dsi_display *display) display->panel->host_config.phy_type; } #if defined(CONFIG_PXLW_IRIS) iris_parse_param(display->panel_node, display->panel); iris_init(display, display->panel); #endif rc = dsi_display_parse_lane_map(display); if (rc) { DSI_ERR("Lane map not found, rc=%d\n", rc); Loading Loading @@ -5471,6 +5823,10 @@ int dsi_display_dev_remove(struct platform_device *pdev) display = platform_get_drvdata(pdev); #if defined(CONFIG_PXLW_IRIS) iris_deinit(); #endif /* decrement ref count */ of_node_put(display->panel_node); Loading Loading @@ -7309,6 +7665,10 @@ int dsi_display_prepare(struct dsi_display *display) error: mutex_unlock(&display->display_lock); SDE_EVT32(SDE_EVTLOG_FUNC_EXIT); #if defined(CONFIG_PXLW_IRIS) iris_prepare(); #endif return rc; } Loading Loading @@ -7596,7 +7956,9 @@ int dsi_display_enable(struct dsi_display *display) if (display->is_cont_splash_enabled) { dsi_display_config_ctrl_for_cont_splash(display); #if defined(CONFIG_PXLW_IRIS) //iris_send_cont_splash(IRIS_CONT_SPLASH_KERNEL); #endif rc = dsi_display_splash_res_cleanup(display); if (rc) { DSI_ERR("Continuous splash res cleanup failed, rc=%d\n", Loading techpack/display/msm/dsi/dsi_display.h +7 −0 Original line number Diff line number Diff line Loading @@ -274,6 +274,13 @@ struct dsi_display { u32 clk_gating_config; bool queue_cmd_waits; struct workqueue_struct *dma_cmd_workq; #if defined(CONFIG_PXLW_IRIS) u32 off; u32 cnt; u8 cmd_data_type; #endif }; int dsi_display_dev_probe(struct platform_device *pdev); Loading Loading
techpack/display/msm/Makefile +15 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,21 @@ msm_drm-$(CONFIG_DRM_MSM_DSI) += dsi/dsi_phy.o \ dsi/dsi_clk_manager.o \ dsi/dsi_display_test.o \ ifeq ($(CONFIG_PXLW_IRIS),y) msm_drm-$(CONFIG_PXLW_IRIS) += dsi/iris/dsi_iris6_ioctl.o \ dsi/iris/dsi_iris6_lightup.o \ dsi/iris/dsi_iris6_lightup_ocp.o \ dsi/iris/dsi_iris6_lp.o \ dsi/iris/dsi_iris6_lut.o \ dsi/iris/dsi_iris6_pq.o \ dsi/iris/dsi_iris6_cmds.o \ dsi/iris/dsi_iris6_i3c.o \ dsi/iris/dsi_iris6_gpio.o \ dsi/iris/dsi_iris6_loopback.o \ dsi/iris/dsi_iris6_dbg.o ccflags-y += -DCONFIG_PXLW_IRIS endif msm_drm-$(CONFIG_DSI_PARSER) += dsi/dsi_parser.o \ msm_drm-$(CONFIG_DRM_MSM) += \ Loading
techpack/display/msm/dsi/dsi_ctrl.c +61 −0 Original line number Diff line number Diff line Loading @@ -1211,14 +1211,22 @@ int dsi_message_validate_tx_mode(struct dsi_ctrl *dsi_ctrl, DSI_CTRL_ERR(dsi_ctrl, " Cannot transfer command,ops not defined\n"); return -ENOTSUPP; } #if defined(CONFIG_PXLW_IRIS) if ((cmd_len + 4) > SZ_256K) { #else if ((cmd_len + 4) > SZ_4K) { #endif DSI_CTRL_ERR(dsi_ctrl, "Cannot transfer,size is greater than 4096\n"); return -ENOTSUPP; } } if (*flags & DSI_CTRL_CMD_FETCH_MEMORY) { #if defined(CONFIG_PXLW_IRIS) if ((dsi_ctrl->cmd_len + cmd_len + 4) > SZ_256K) { #else if ((dsi_ctrl->cmd_len + cmd_len + 4) > SZ_4K) { #endif DSI_CTRL_ERR(dsi_ctrl, "Cannot transfer,size is greater than 4096\n"); return -ENOTSUPP; } Loading Loading @@ -1255,6 +1263,12 @@ static void dsi_kickoff_msg_tx(struct dsi_ctrl *dsi_ctrl, u32 line_no = 0x1; struct dsi_ctrl_hw_ops dsi_hw_ops = dsi_ctrl->hw.ops; #if defined(CONFIG_PXLW_IRIS) if (dsi_ctrl->host_config.panel_mode == DSI_OP_VIDEO_MODE) line_no = 10; pr_debug("line_no: %d\n", line_no); #endif SDE_EVT32(dsi_ctrl->cell_index, SDE_EVTLOG_FUNC_ENTRY, flags, msg->flags); Loading Loading @@ -1370,6 +1384,45 @@ static void dsi_ctrl_validate_msg_flags(struct dsi_ctrl *dsi_ctrl, *flags &= ~DSI_CTRL_CMD_ASYNC_WAIT; } #if defined(CONFIG_PXLW_IRIS) bool dsi_cmd_log_enable = 1; static void print_cmd_desc(struct dsi_ctrl *dsi_ctrl, const struct mipi_dsi_msg *msg) { char buf[1024]; int len = 0; size_t i; char *tx_buf = (char *)msg->tx_buf; /* Packet Info */ len += snprintf(buf, sizeof(buf) - len, "%02x ", msg->type); /* Last bit */ len += snprintf(buf + len, sizeof(buf) - len, "%02x ", (msg->flags & MIPI_DSI_MSG_LASTCOMMAND) ? 1 : 0); len += snprintf(buf + len, sizeof(buf) - len, "%02x ", msg->channel); len += snprintf(buf + len, sizeof(buf) - len, "%02x ", (u32)msg->flags); /* Delay */ len += snprintf(buf + len, sizeof(buf) - len, "%02x ", msg->wait_ms); len += snprintf(buf + len, sizeof(buf) - len, "%02x %02x ", ((u32)msg->tx_len >> 8) & 0xFF, (u32)msg->tx_len & 0xFF); /* Packet Payload */ for (i = 0 ; i < msg->tx_len ; i++) { len += snprintf(buf + len, sizeof(buf) - len, "%02x ", tx_buf[i]); /* Break to prevent show too long command */ if (i > 250) break; } pr_debug("IRIS print msg begin =====================\n"); pr_debug("%s\n", buf); pr_debug("IRIS print msg end =======================\n"); } #endif static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, const struct mipi_dsi_msg *msg, u32 *flags) Loading @@ -1383,6 +1436,11 @@ static int dsi_message_tx(struct dsi_ctrl *dsi_ctrl, u32 cnt = 0; u8 *cmdbuf; #if defined(CONFIG_PXLW_IRIS) if (dsi_cmd_log_enable) print_cmd_desc(dsi_ctrl, msg); #endif /* Select the tx mode to transfer the command */ dsi_message_setup_tx_mode(dsi_ctrl, msg->tx_len, flags); Loading Loading @@ -1663,6 +1721,9 @@ static int dsi_message_rx(struct dsi_ctrl *dsi_ctrl, /* parse the data read from panel */ cmd = buff[0]; #if defined(CONFIG_PXLW_IRIS) cmd &= 0x3f; #endif switch (cmd) { case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT: DSI_CTRL_ERR(dsi_ctrl, "Rx ACK_ERROR 0x%x\n", cmd); Loading
techpack/display/msm/dsi/dsi_ctrl_hw_cmn.c +25 −1 Original line number Diff line number Diff line Loading @@ -672,9 +672,14 @@ void dsi_ctrl_hw_cmn_kickoff_command(struct dsi_ctrl_hw *ctrl, reg &= ~BIT(29);/* WC_SEL to 0 */ DSI_W32(ctrl, DSI_COMMAND_MODE_DMA_CTRL, reg); #if defined(CONFIG_PXLW_IRIS) /* set DMA FIFO read watermark to 15/16 full */ reg = 0x33; #else reg = DSI_R32(ctrl, DSI_DMA_FIFO_CTRL); reg |= BIT(20);/* Disable write watermark*/ reg |= BIT(16);/* Disable read watermark */ #endif DSI_W32(ctrl, DSI_DMA_FIFO_CTRL, reg); DSI_W32(ctrl, DSI_DMA_CMD_OFFSET, cmd->offset); Loading Loading @@ -859,7 +864,26 @@ u32 dsi_ctrl_hw_cmn_get_cmd_read_data(struct dsi_ctrl_hw *ctrl, *temp++ = ntohl(data); off -= 4; } #if defined(CONFIG_PXLW_IRIS) pr_debug("dsi: rx_byte %d, read_cnt %d, ack_err %d, cnt %d, off 0x%x\n", rx_byte, read_cnt, ack_err, cnt, off); pr_debug("DSI_ACK_ERR_STATUS = 0x%x\n", DSI_R32(ctrl, DSI_ACK_ERR_STATUS)); if (read_cnt == 12) { int cmd, wc, data2, data1, prefix; data2 = DSI_R32(ctrl, DSI_RDBK_DATA2); data1 = DSI_R32(ctrl, DSI_RDBK_DATA1); data = DSI_R32(ctrl, DSI_RDBK_DATA0); cmd = (data2 >> 24) & 0x3f; wc = ((data2 >> 16) & 0xff) + (data2 & 0xff00); prefix = (data1 >> 16) & 0xffff; if (cmd == 0x1a && wc == 6 && prefix == 0x203) { pr_err("Panel dsi error detected in aux."); pr_err("dsi rdbk data: %08x %08x %08x \n", data2, data1, data); } } #endif if (repeated_bytes) { for (i = repeated_bytes; i < 16; i++) rd_buf[j++] = reg[i]; Loading
techpack/display/msm/dsi/dsi_display.c +363 −1 Original line number Diff line number Diff line Loading @@ -20,6 +20,11 @@ #include "dsi_pwr.h" #include "sde_dbg.h" #include "dsi_parser.h" #if defined(CONFIG_PXLW_IRIS) #include "iris/dsi_iris6_api.h" #include "iris/dsi_iris6_log.h" #include <video/mipi_display.h> #endif #ifdef CONFIG_TOUCHSCREEN_FTS extern int fts_esd_check(void); Loading Loading @@ -486,7 +491,11 @@ static int dsi_host_alloc_cmd_tx_buffer(struct dsi_display *display) struct dsi_display_ctrl *display_ctrl; display->tx_cmd_buf = msm_gem_new(display->drm_dev, #if defined(CONFIG_PXLW_IRIS) SZ_256K, #else SZ_4K, #endif MSM_BO_UNCACHED); if ((display->tx_cmd_buf) == NULL) { Loading @@ -495,7 +504,11 @@ static int dsi_host_alloc_cmd_tx_buffer(struct dsi_display *display) goto error; } #if defined(CONFIG_PXLW_IRIS) display->cmd_buffer_size = SZ_256K; #else display->cmd_buffer_size = SZ_4K; #endif display->aspace = msm_gem_smmu_address_space_get( display->drm_dev, MSM_SMMU_DOMAIN_UNSECURE); Loading Loading @@ -529,7 +542,11 @@ static int dsi_host_alloc_cmd_tx_buffer(struct dsi_display *display) display_for_each_ctrl(cnt, display) { display_ctrl = &display->ctrl[cnt]; #if defined(CONFIG_PXLW_IRIS) display_ctrl->ctrl->cmd_buffer_size = SZ_256K; #else display_ctrl->ctrl->cmd_buffer_size = SZ_4K; #endif display_ctrl->ctrl->cmd_buffer_iova = display->cmd_buffer_iova; display_ctrl->ctrl->vaddr = display->vaddr; Loading Loading @@ -682,6 +699,11 @@ static int dsi_display_validate_status(struct dsi_display_ctrl *ctrl, { int rc = 0; #if defined(CONFIG_PXLW_IRIS) rc = iris_status_get(ctrl, panel); return rc; #endif rc = dsi_display_read_status(ctrl, panel); if (rc <= 0) { goto exit; Loading Loading @@ -767,6 +789,15 @@ static int dsi_display_status_check_te(struct dsi_display *display) int rc = 1; int const esd_te_timeout = msecs_to_jiffies(3*20); #if defined(CONFIG_PXLW_IRIS) struct dsi_display_ctrl *ctrl; ctrl = &display->ctrl[display->cmd_master_idx]; rc = iris_status_get(ctrl, display->panel); if (rc < 0) return rc; #endif dsi_display_change_te_irq_status(display, true); reinit_completion(&display->esd_te_gate); Loading Loading @@ -835,6 +866,10 @@ int dsi_display_check_status(struct drm_connector *connector, void *display, dsi_display_set_ctrl_esd_check_flag(dsi_display, true); dsi_display_mask_ctrl_error_interrupts(dsi_display, mask, true); #if defined(CONFIG_PXLW_IRIS) iris_dma_ch1_trigger(false, 0); #endif if (status_mode == ESD_MODE_REG_READ) { rc = dsi_display_status_reg_read(dsi_display); } else if (status_mode == ESD_MODE_SW_BTA) { Loading @@ -850,6 +885,10 @@ int dsi_display_check_status(struct drm_connector *connector, void *display, panel->esd_config.esd_enabled = false; } #if defined(CONFIG_PXLW_IRIS) iris_dma_ch1_trigger(true, 0); #endif /* Unmask error interrupts if check passed*/ if (rc > 0) { dsi_display_set_ctrl_esd_check_flag(dsi_display, false); Loading Loading @@ -1537,6 +1576,276 @@ static const struct file_operations esd_check_mode_fops = { .read = debugfs_read_esd_check_mode, }; #if defined(CONFIG_PXLW_IRIS) static int panel_debug_base_open(struct inode *inode, struct file *file) { /* non-seekable */ file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE); file->private_data = inode->i_private; return 0; } static int panel_debug_base_release(struct inode *inode, struct file *file) { return 0; } #define PANEL_REG_MAX_OFFSET 1024 // FIXME static ssize_t panel_debug_base_offset_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct dsi_display *display = file->private_data; u32 off, cnt; char buf[64]; if (!display) return -ENODEV; if (count >= sizeof(buf)) return -EINVAL; if (copy_from_user(buf, user_buf, count)) return -EFAULT; buf[count] = 0; /* end of string */ if (sscanf(buf, "%x %u", &off, &cnt) != 2) return -EINVAL; if (off > PANEL_REG_MAX_OFFSET) return -EINVAL; if (cnt > (PANEL_REG_MAX_OFFSET - off)) cnt = PANEL_REG_MAX_OFFSET - off; display->off = off; display->cnt = cnt; pr_debug("offset=%x cnt=%d\n", off, cnt); return count; } static ssize_t panel_debug_base_offset_read(struct file *file, char __user *buff, size_t count, loff_t *ppos) { struct dsi_display *display = file->private_data; int len; char buf[64]; if (!display) return -ENODEV; if (*ppos) return 0; /* the end */ len = snprintf(buf, sizeof(buf), "0x%02x %x\n", display->off, display->cnt); if (len < 0 || len >= sizeof(buf)) return -EINVAL; if (count < sizeof(buf)) return -EINVAL; if (copy_to_user(buff, buf, len)) return -EFAULT; *ppos += len; /* increase offset */ return len; } /* Hex number + whitespace */ #define NEXT_VALUE_OFFSET 3 #define PANEL_CMD_MIN_TX_COUNT 2 static ssize_t panel_debug_base_reg_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct dsi_display *display = file->private_data; char buf[64]; char reg[64]; u32 len = 0, value = 0; char *bufp; bool state = false; int rc; struct dsi_cmd_desc cmds = { { 0 }, // msg 1, // last 0 // wait }; #ifndef IRIS_ABYP_LIGHTUP struct dsi_panel_cmd_set cmdset = { .state = DSI_CMD_SET_STATE_HS, .count = 1, .cmds = &cmds, }; #endif if (!display) return -ENODEV; /* get command string from user */ if (count >= sizeof(buf)) return -EINVAL; if (copy_from_user(buf, user_buf, count)) return -EFAULT; buf[count] = 0; /* end of string */ bufp = buf; /* End of a hex value in given string */ bufp[NEXT_VALUE_OFFSET - 1] = 0; while (kstrtouint(bufp, 16, &value) == 0) { reg[len++] = value; if (len >= sizeof(reg)) { pr_err("wrong input reg len\n"); return -EINVAL; } bufp += NEXT_VALUE_OFFSET; if ((bufp >= (buf + count)) || (bufp < buf)) { pr_warn("%s,buffer out-of-bounds\n", __func__); break; } /* End of a hex value in given string */ if ((bufp + NEXT_VALUE_OFFSET - 1) < (buf + count)) bufp[NEXT_VALUE_OFFSET - 1] = 0; } if (len < PANEL_CMD_MIN_TX_COUNT) { pr_err("wrong input reg len\n"); return -EINVAL; } cmds.msg.type = display->cmd_data_type; cmds.msg.flags = MIPI_DSI_MSG_LASTCOMMAND; cmds.msg.tx_len = len; cmds.msg.tx_buf = reg; rc = dsi_display_ctrl_get_host_init_state(display, &state); if (!rc && state) { dsi_panel_acquire_panel_lock(display->panel); #ifdef IRIS_ABYP_LIGHTUP rc = display->host.ops->transfer(&display->host, &cmds.msg); #else iris_pt_send_panel_cmd(display->panel, &cmdset); #endif dsi_panel_release_panel_lock(display->panel); } return rc ? rc : count; } #define PANEL_REG_ADDR_LEN 8 #define PANEL_REG_FORMAT_LEN 5 static ssize_t panel_debug_base_reg_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct dsi_display *display = file->private_data; u32 i, len = 0, reg_buf_len = 0; char *panel_reg_buf, *rx_buf; int rc; bool state = false; char panel_reg[2] = { 0 }; struct dsi_cmd_desc cmds = { { 0 }, // msg 1, // last 0 // wait }; #ifndef IRIS_ABYP_LIGHTUP struct dsi_panel_cmd_set cmdset = { .state = DSI_CMD_SET_STATE_HS, .count = 1, .cmds = &cmds, }; #endif if (!display) return -ENODEV; if (!display->cnt) return 0; if (*ppos) return 0; /* the end */ /* '0x' + 2 digit + blank = 5 bytes for each number */ reg_buf_len = (display->cnt * PANEL_REG_FORMAT_LEN) + PANEL_REG_ADDR_LEN + 1; if (count < reg_buf_len) return -EINVAL; rx_buf = kzalloc(display->cnt, GFP_KERNEL); panel_reg_buf = kzalloc(reg_buf_len, GFP_KERNEL); if (!rx_buf || !panel_reg_buf) { pr_err("not enough memory to hold panel reg dump\n"); rc = -ENOMEM; goto read_reg_fail; } panel_reg[0] = display->off; cmds.msg.type = MIPI_DSI_DCS_READ; cmds.msg.flags = MIPI_DSI_MSG_LASTCOMMAND | MIPI_DSI_MSG_REQ_ACK; cmds.msg.tx_len = 2; cmds.msg.tx_buf = panel_reg; cmds.msg.rx_len = display->cnt; cmds.msg.rx_buf = rx_buf; rc = dsi_display_ctrl_get_host_init_state(display, &state); if (!rc && state) { dsi_panel_acquire_panel_lock(display->panel); #ifdef IRIS_ABYP_LIGHTUP rc = display->host.ops->transfer(&display->host, &cmds.msg); #else iris_pt_send_panel_cmd(display->panel, &cmdset); #endif dsi_panel_release_panel_lock(display->panel); } if (rc) goto read_reg_fail; len = scnprintf(panel_reg_buf, reg_buf_len, "0x%02x: ", display->off); for (i = 0; (len < reg_buf_len) && (i < display->cnt); i++) len += scnprintf(panel_reg_buf + len, reg_buf_len - len, "0x%02x ", rx_buf[i]); if (len) panel_reg_buf[len - 1] = '\n'; if (copy_to_user(user_buf, panel_reg_buf, len)) { rc = -EFAULT; goto read_reg_fail; } *ppos += len; /* increase offset */ rc = len; read_reg_fail: kfree(rx_buf); kfree(panel_reg_buf); return rc; } static const struct file_operations panel_off_fops = { .open = panel_debug_base_open, .release = panel_debug_base_release, .read = panel_debug_base_offset_read, .write = panel_debug_base_offset_write, }; static const struct file_operations panel_reg_fops = { .open = panel_debug_base_open, .release = panel_debug_base_release, .read = panel_debug_base_reg_read, .write = panel_debug_base_reg_write, }; #endif static int dsi_display_debugfs_init(struct dsi_display *display) { int rc = 0; Loading Loading @@ -1657,6 +1966,35 @@ static int dsi_display_debugfs_init(struct dsi_display *display) goto error_remove_dir; } #if defined(CONFIG_PXLW_IRIS) display->off = 0x0a; display->cnt = 1; display->cmd_data_type = MIPI_DSI_DCS_LONG_WRITE; dump_file = debugfs_create_x8("cmd_data_type", 0600, dir, &display->cmd_data_type); if (IS_ERR_OR_NULL(dump_file)) pr_err("[%s] debugfs create panel cmd_data_type file failed, rc=%ld\n", display->name, PTR_ERR(dump_file)); dump_file = debugfs_create_file("off", 0600, dir, display, &panel_off_fops); if (IS_ERR_OR_NULL(dump_file)) pr_err("[%s] debugfs create panel off file failed, rc=%ld\n", display->name, PTR_ERR(dump_file)); dump_file = debugfs_create_file("reg", 0600, dir, display, &panel_reg_fops); if (IS_ERR_OR_NULL(dump_file)) pr_err("[%s] debugfs create panel reg file failed, rc=%ld\n", display->name, PTR_ERR(dump_file)); #endif display->root = dir; dsi_parser_dbg_init(display->parser, dir); Loading Loading @@ -2948,9 +3286,18 @@ static ssize_t dsi_host_transfer(struct mipi_dsi_host *host, msg->flags & MIPI_DSI_MSG_ASYNC_OVERRIDE) cmd_flags |= DSI_CTRL_CMD_ASYNC_WAIT; #if defined(CONFIG_PXLW_IRIS) if (msg->rx_buf && msg->rx_len) cmd_flags |= DSI_CTRL_CMD_READ; #endif rc = dsi_ctrl_cmd_transfer(display->ctrl[ctrl_idx].ctrl, msg, &cmd_flags); #if defined(CONFIG_PXLW_IRIS) if (rc < 0) { #else if (rc) { #endif DSI_ERR("[%s] cmd transfer failed, rc=%d\n", display->name, rc); goto error_disable_cmd_engine; Loading Loading @@ -3822,6 +4169,11 @@ static int dsi_display_res_init(struct dsi_display *display) display->panel->host_config.phy_type; } #if defined(CONFIG_PXLW_IRIS) iris_parse_param(display->panel_node, display->panel); iris_init(display, display->panel); #endif rc = dsi_display_parse_lane_map(display); if (rc) { DSI_ERR("Lane map not found, rc=%d\n", rc); Loading Loading @@ -5471,6 +5823,10 @@ int dsi_display_dev_remove(struct platform_device *pdev) display = platform_get_drvdata(pdev); #if defined(CONFIG_PXLW_IRIS) iris_deinit(); #endif /* decrement ref count */ of_node_put(display->panel_node); Loading Loading @@ -7309,6 +7665,10 @@ int dsi_display_prepare(struct dsi_display *display) error: mutex_unlock(&display->display_lock); SDE_EVT32(SDE_EVTLOG_FUNC_EXIT); #if defined(CONFIG_PXLW_IRIS) iris_prepare(); #endif return rc; } Loading Loading @@ -7596,7 +7956,9 @@ int dsi_display_enable(struct dsi_display *display) if (display->is_cont_splash_enabled) { dsi_display_config_ctrl_for_cont_splash(display); #if defined(CONFIG_PXLW_IRIS) //iris_send_cont_splash(IRIS_CONT_SPLASH_KERNEL); #endif rc = dsi_display_splash_res_cleanup(display); if (rc) { DSI_ERR("Continuous splash res cleanup failed, rc=%d\n", Loading
techpack/display/msm/dsi/dsi_display.h +7 −0 Original line number Diff line number Diff line Loading @@ -274,6 +274,13 @@ struct dsi_display { u32 clk_gating_config; bool queue_cmd_waits; struct workqueue_struct *dma_cmd_workq; #if defined(CONFIG_PXLW_IRIS) u32 off; u32 cnt; u8 cmd_data_type; #endif }; int dsi_display_dev_probe(struct platform_device *pdev); Loading