Loading drivers/gpu/drm/msm/dp/dp_debug.c +49 −16 Original line number Diff line number Diff line Loading @@ -451,8 +451,10 @@ static ssize_t dp_debug_write_mst_con_id(struct file *file, struct dp_mst_connector *mst_connector; char buf[SZ_32]; size_t len = 0; int con_id = 0; int con_id = 0, status; bool in_list = false; const int dp_en = BIT(3), hpd_high = BIT(7), hpd_irq = BIT(8); int vdo = dp_en | hpd_high | hpd_irq; if (!debug) return -ENODEV; Loading @@ -467,8 +469,10 @@ static ssize_t dp_debug_write_mst_con_id(struct file *file, buf[len] = '\0'; if (kstrtoint(buf, 10, &con_id) != 0) goto clear; if (sscanf(buf, "%d %d", &con_id, &status) != 2) { len = 0; goto end; } if (!con_id) goto clear; Loading @@ -480,6 +484,7 @@ static ssize_t dp_debug_write_mst_con_id(struct file *file, if (mst_connector->con_id == con_id) { in_list = true; debug->mst_con_id = con_id; mst_connector->state = status; break; } } Loading @@ -487,6 +492,10 @@ static ssize_t dp_debug_write_mst_con_id(struct file *file, if (!in_list) pr_err("invalid connector id %u\n", con_id); else if (status != connector_status_unknown) { debug->dp_debug.mst_hpd_sim = true; debug->hpd->simulate_attention(debug->hpd, vdo); } goto end; clear: Loading Loading @@ -530,6 +539,21 @@ static ssize_t dp_debug_bw_code_write(struct file *file, return len; } static ssize_t dp_debug_mst_mode_read(struct file *file, char __user *user_buff, size_t count, loff_t *ppos) { struct dp_debug_private *debug = file->private_data; char buf[64]; ssize_t len; len = scnprintf(buf, sizeof(buf), "mst_mode = %d, mst_state = %d\n", debug->parser->has_mst, debug->panel->mst_state); return simple_read_from_buffer(user_buff, count, ppos, buf, len); } static ssize_t dp_debug_mst_mode_write(struct file *file, const char __user *user_buff, size_t count, loff_t *ppos) { Loading Loading @@ -631,28 +655,35 @@ static ssize_t dp_debug_mst_sideband_mode_write(struct file *file, struct dp_debug_private *debug = file->private_data; char buf[SZ_8]; size_t len = 0; u32 mst_sideband_mode = 0; int mst_sideband_mode = 0; u32 mst_port_cnt = 0; if (!debug) return -ENODEV; if (*ppos) return 0; /* Leave room for termination char */ len = min_t(size_t, count, SZ_8 - 1); if (copy_from_user(buf, user_buff, len)) return 0; return -EFAULT; buf[len] = '\0'; if (kstrtoint(buf, 10, &mst_sideband_mode) != 0) return 0; if (sscanf(buf, "%d %u", &mst_sideband_mode, &mst_port_cnt) != 2) { pr_err("invalid input\n"); return -EINVAL; } debug->parser->has_mst_sideband = mst_sideband_mode ? true : false; pr_debug("mst_enable: %d\n", mst_sideband_mode); if (mst_port_cnt > DP_MST_SIM_MAX_PORTS) { pr_err("port cnt:%d exceeding max:%d\n", mst_port_cnt, DP_MST_SIM_MAX_PORTS); return -EINVAL; } return len; debug->parser->has_mst_sideband = mst_sideband_mode ? true : false; debug->dp_debug.mst_port_cnt = mst_port_cnt; pr_debug("mst_sideband_mode: %d port_cnt:%d\n", mst_sideband_mode, mst_port_cnt); return count; } static ssize_t dp_debug_widebus_mode_write(struct file *file, Loading Loading @@ -1049,9 +1080,10 @@ static ssize_t dp_debug_read_mst_conn_info(struct file *file, continue; } ret = snprintf(buf + len, max_size, "conn name:%s, conn id:%d\n", connector->name, connector->base.id); ret = scnprintf(buf + len, max_size, "conn name:%s, conn id:%d state:%d\n", connector->name, connector->base.id, connector->status); if (dp_debug_check_buffer_overflow(ret, &max_size, &len)) break; } Loading Loading @@ -1659,6 +1691,7 @@ static const struct file_operations dump_fops = { static const struct file_operations mst_mode_fops = { .open = simple_open, .write = dp_debug_mst_mode_write, .read = dp_debug_mst_mode_read, }; static const struct file_operations mst_sideband_mode_fops = { Loading drivers/gpu/drm/msm/dp/dp_debug.h +2 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,8 @@ struct dp_debug { bool force_encryption; char hdcp_status[SZ_128]; struct dp_mst_connector dp_mst_connector_list; bool mst_hpd_sim; u32 mst_port_cnt; u8 *(*get_edid)(struct dp_debug *dp_debug); void (*abort)(struct dp_debug *dp_debug); Loading drivers/gpu/drm/msm/dp/dp_display.c +63 −8 Original line number Diff line number Diff line Loading @@ -572,10 +572,17 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp) return 0; } static void dp_display_update_mst_state(struct dp_display_private *dp, bool state) { dp->mst.mst_active = state; dp->panel->mst_state = state; } static void dp_display_process_mst_hpd_high(struct dp_display_private *dp) { bool is_mst_receiver; struct dp_mst_hdp_info info; struct dp_mst_hpd_info info; if (dp->parser->has_mst && dp->mst.drm_registered) { DP_MST_DEBUG("mst_hpd_high work\n"); Loading @@ -583,9 +590,14 @@ static void dp_display_process_mst_hpd_high(struct dp_display_private *dp) is_mst_receiver = dp->panel->read_mst_cap(dp->panel); if (is_mst_receiver && !dp->mst.mst_active) { dp->mst.mst_active = true; /* clear sink mst state */ drm_dp_dpcd_writeb(dp->aux->drm_aux, DP_MSTM_CTRL, 0); dp_display_update_mst_state(dp, true); info.mst_protocol = dp->parser->has_mst_sideband; info.mst_port_cnt = dp->debug->mst_port_cnt; info.edid = dp->debug->get_edid(dp->debug); if (dp->mst.cbs.hpd) Loading Loading @@ -694,7 +706,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp) static void dp_display_process_mst_hpd_low(struct dp_display_private *dp) { struct dp_mst_hdp_info info = {0}; struct dp_mst_hpd_info info = {0}; if (dp->mst.mst_active) { DP_MST_DEBUG("mst_hpd_low work\n"); Loading @@ -703,8 +715,7 @@ static void dp_display_process_mst_hpd_low(struct dp_display_private *dp) info.mst_protocol = dp->parser->has_mst_sideband; dp->mst.cbs.hpd(&dp->dp_display, false, &info); } dp->mst.mst_active = false; dp_display_update_mst_state(dp, false); } DP_MST_DEBUG("mst_hpd_low. mst_active:%d\n", dp->mst.mst_active); Loading Loading @@ -927,8 +938,13 @@ static int dp_display_stream_enable(struct dp_display_private *dp, static void dp_display_mst_attention(struct dp_display_private *dp) { if (dp->mst.mst_active && dp->mst.cbs.hpd_irq) dp->mst.cbs.hpd_irq(&dp->dp_display); struct dp_mst_hpd_info hpd_irq = {0}; if (dp->mst.mst_active && dp->mst.cbs.hpd_irq) { hpd_irq.mst_hpd_sim = dp->debug->mst_hpd_sim; dp->mst.cbs.hpd_irq(&dp->dp_display, &hpd_irq); dp->debug->mst_hpd_sim = false; } DP_MST_DEBUG("mst_attention_work. mst_active:%d\n", dp->mst.mst_active); } Loading @@ -938,6 +954,9 @@ static void dp_display_attention_work(struct work_struct *work) struct dp_display_private *dp = container_of(work, struct dp_display_private, attention_work); if (dp->debug->mst_hpd_sim) goto mst_attention; if (dp->link->process_request(dp->link)) goto cp_irq; Loading Loading @@ -1003,7 +1022,8 @@ static int dp_display_usbpd_attention_cb(struct device *dev) if (!dp->hpd->hpd_high) dp_display_disconnect_sync(dp); else if (dp->hpd->hpd_irq && dp->core_initialized) else if ((dp->hpd->hpd_irq && dp->core_initialized) || dp->debug->mst_hpd_sim) queue_work(dp->wq, &dp->attention_work); else if (!dp->power_on) queue_delayed_work(dp->wq, &dp->connect_work, 0); Loading Loading @@ -2044,6 +2064,7 @@ static int dp_display_mst_connector_install(struct dp_display *dp_display, mst_connector->debug_en = false; mst_connector->conn = connector; mst_connector->con_id = connector->base.id; mst_connector->state = connector_status_unknown; INIT_LIST_HEAD(&mst_connector->list); list_add(&mst_connector->list, Loading Loading @@ -2109,6 +2130,38 @@ static int dp_display_mst_connector_uninstall(struct dp_display *dp_display, return rc; } static int dp_display_mst_get_connector_info(struct dp_display *dp_display, struct drm_connector *connector, struct dp_mst_connector *mst_conn) { struct dp_display_private *dp; struct dp_mst_connector *conn, *temp_conn; if (!connector || !mst_conn) { pr_err("invalid input\n"); return -EINVAL; } dp = container_of(dp_display, struct dp_display_private, dp_display); mutex_lock(&dp->session_lock); if (!dp->mst.drm_registered) { pr_debug("drm mst not registered\n"); mutex_unlock(&dp->session_lock); return -EPERM; } mutex_lock(&dp->debug->dp_mst_connector_list.lock); list_for_each_entry_safe(conn, temp_conn, &dp->debug->dp_mst_connector_list.list, list) { if (conn->con_id == connector->base.id) memcpy(mst_conn, conn, sizeof(*mst_conn)); } mutex_unlock(&dp->debug->dp_mst_connector_list.lock); mutex_unlock(&dp->session_lock); return 0; } static int dp_display_mst_connector_update_edid(struct dp_display *dp_display, struct drm_connector *connector, struct edid *edid) Loading Loading @@ -2231,6 +2284,8 @@ static int dp_display_probe(struct platform_device *pdev) g_dp_display->get_mst_caps = dp_display_get_mst_caps; g_dp_display->set_stream_info = dp_display_set_stream_info; g_dp_display->convert_to_dp_mode = dp_display_convert_to_dp_mode; g_dp_display->mst_get_connector_info = dp_display_mst_get_connector_info; rc = component_add(&pdev->dev, &dp_display_comp_ops); if (rc) { Loading drivers/gpu/drm/msm/dp/dp_display.h +11 −3 Original line number Diff line number Diff line Loading @@ -21,15 +21,19 @@ #include "dp_panel.h" struct dp_mst_hdp_info { #define DP_MST_SIM_MAX_PORTS 2 struct dp_mst_hpd_info { bool mst_protocol; bool mst_hpd_sim; u32 mst_port_cnt; u8 *edid; }; struct dp_mst_drm_cbs { void (*hpd)(void *display, bool hpd_status, struct dp_mst_hdp_info *info); void (*hpd_irq)(void *display); struct dp_mst_hpd_info *info); void (*hpd_irq)(void *display, struct dp_mst_hpd_info *info); }; struct dp_mst_drm_install_info { Loading @@ -54,6 +58,7 @@ struct dp_mst_connector { struct drm_connector *conn; struct mutex lock; struct list_head list; enum drm_connector_status state; }; struct dp_display { Loading Loading @@ -96,6 +101,9 @@ struct dp_display { int (*mst_connector_update_edid)(struct dp_display *dp_display, struct drm_connector *connector, struct edid *edid); int (*mst_get_connector_info)(struct dp_display *dp_display, struct drm_connector *connector, struct dp_mst_connector *mst_conn); int (*get_mst_caps)(struct dp_display *dp_display, struct dp_mst_caps *mst_caps); int (*set_stream_info)(struct dp_display *dp_display, void *panel, Loading drivers/gpu/drm/msm/dp/dp_mst_drm.c +193 −232 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
drivers/gpu/drm/msm/dp/dp_debug.c +49 −16 Original line number Diff line number Diff line Loading @@ -451,8 +451,10 @@ static ssize_t dp_debug_write_mst_con_id(struct file *file, struct dp_mst_connector *mst_connector; char buf[SZ_32]; size_t len = 0; int con_id = 0; int con_id = 0, status; bool in_list = false; const int dp_en = BIT(3), hpd_high = BIT(7), hpd_irq = BIT(8); int vdo = dp_en | hpd_high | hpd_irq; if (!debug) return -ENODEV; Loading @@ -467,8 +469,10 @@ static ssize_t dp_debug_write_mst_con_id(struct file *file, buf[len] = '\0'; if (kstrtoint(buf, 10, &con_id) != 0) goto clear; if (sscanf(buf, "%d %d", &con_id, &status) != 2) { len = 0; goto end; } if (!con_id) goto clear; Loading @@ -480,6 +484,7 @@ static ssize_t dp_debug_write_mst_con_id(struct file *file, if (mst_connector->con_id == con_id) { in_list = true; debug->mst_con_id = con_id; mst_connector->state = status; break; } } Loading @@ -487,6 +492,10 @@ static ssize_t dp_debug_write_mst_con_id(struct file *file, if (!in_list) pr_err("invalid connector id %u\n", con_id); else if (status != connector_status_unknown) { debug->dp_debug.mst_hpd_sim = true; debug->hpd->simulate_attention(debug->hpd, vdo); } goto end; clear: Loading Loading @@ -530,6 +539,21 @@ static ssize_t dp_debug_bw_code_write(struct file *file, return len; } static ssize_t dp_debug_mst_mode_read(struct file *file, char __user *user_buff, size_t count, loff_t *ppos) { struct dp_debug_private *debug = file->private_data; char buf[64]; ssize_t len; len = scnprintf(buf, sizeof(buf), "mst_mode = %d, mst_state = %d\n", debug->parser->has_mst, debug->panel->mst_state); return simple_read_from_buffer(user_buff, count, ppos, buf, len); } static ssize_t dp_debug_mst_mode_write(struct file *file, const char __user *user_buff, size_t count, loff_t *ppos) { Loading Loading @@ -631,28 +655,35 @@ static ssize_t dp_debug_mst_sideband_mode_write(struct file *file, struct dp_debug_private *debug = file->private_data; char buf[SZ_8]; size_t len = 0; u32 mst_sideband_mode = 0; int mst_sideband_mode = 0; u32 mst_port_cnt = 0; if (!debug) return -ENODEV; if (*ppos) return 0; /* Leave room for termination char */ len = min_t(size_t, count, SZ_8 - 1); if (copy_from_user(buf, user_buff, len)) return 0; return -EFAULT; buf[len] = '\0'; if (kstrtoint(buf, 10, &mst_sideband_mode) != 0) return 0; if (sscanf(buf, "%d %u", &mst_sideband_mode, &mst_port_cnt) != 2) { pr_err("invalid input\n"); return -EINVAL; } debug->parser->has_mst_sideband = mst_sideband_mode ? true : false; pr_debug("mst_enable: %d\n", mst_sideband_mode); if (mst_port_cnt > DP_MST_SIM_MAX_PORTS) { pr_err("port cnt:%d exceeding max:%d\n", mst_port_cnt, DP_MST_SIM_MAX_PORTS); return -EINVAL; } return len; debug->parser->has_mst_sideband = mst_sideband_mode ? true : false; debug->dp_debug.mst_port_cnt = mst_port_cnt; pr_debug("mst_sideband_mode: %d port_cnt:%d\n", mst_sideband_mode, mst_port_cnt); return count; } static ssize_t dp_debug_widebus_mode_write(struct file *file, Loading Loading @@ -1049,9 +1080,10 @@ static ssize_t dp_debug_read_mst_conn_info(struct file *file, continue; } ret = snprintf(buf + len, max_size, "conn name:%s, conn id:%d\n", connector->name, connector->base.id); ret = scnprintf(buf + len, max_size, "conn name:%s, conn id:%d state:%d\n", connector->name, connector->base.id, connector->status); if (dp_debug_check_buffer_overflow(ret, &max_size, &len)) break; } Loading Loading @@ -1659,6 +1691,7 @@ static const struct file_operations dump_fops = { static const struct file_operations mst_mode_fops = { .open = simple_open, .write = dp_debug_mst_mode_write, .read = dp_debug_mst_mode_read, }; static const struct file_operations mst_sideband_mode_fops = { Loading
drivers/gpu/drm/msm/dp/dp_debug.h +2 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,8 @@ struct dp_debug { bool force_encryption; char hdcp_status[SZ_128]; struct dp_mst_connector dp_mst_connector_list; bool mst_hpd_sim; u32 mst_port_cnt; u8 *(*get_edid)(struct dp_debug *dp_debug); void (*abort)(struct dp_debug *dp_debug); Loading
drivers/gpu/drm/msm/dp/dp_display.c +63 −8 Original line number Diff line number Diff line Loading @@ -572,10 +572,17 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp) return 0; } static void dp_display_update_mst_state(struct dp_display_private *dp, bool state) { dp->mst.mst_active = state; dp->panel->mst_state = state; } static void dp_display_process_mst_hpd_high(struct dp_display_private *dp) { bool is_mst_receiver; struct dp_mst_hdp_info info; struct dp_mst_hpd_info info; if (dp->parser->has_mst && dp->mst.drm_registered) { DP_MST_DEBUG("mst_hpd_high work\n"); Loading @@ -583,9 +590,14 @@ static void dp_display_process_mst_hpd_high(struct dp_display_private *dp) is_mst_receiver = dp->panel->read_mst_cap(dp->panel); if (is_mst_receiver && !dp->mst.mst_active) { dp->mst.mst_active = true; /* clear sink mst state */ drm_dp_dpcd_writeb(dp->aux->drm_aux, DP_MSTM_CTRL, 0); dp_display_update_mst_state(dp, true); info.mst_protocol = dp->parser->has_mst_sideband; info.mst_port_cnt = dp->debug->mst_port_cnt; info.edid = dp->debug->get_edid(dp->debug); if (dp->mst.cbs.hpd) Loading Loading @@ -694,7 +706,7 @@ static int dp_display_process_hpd_high(struct dp_display_private *dp) static void dp_display_process_mst_hpd_low(struct dp_display_private *dp) { struct dp_mst_hdp_info info = {0}; struct dp_mst_hpd_info info = {0}; if (dp->mst.mst_active) { DP_MST_DEBUG("mst_hpd_low work\n"); Loading @@ -703,8 +715,7 @@ static void dp_display_process_mst_hpd_low(struct dp_display_private *dp) info.mst_protocol = dp->parser->has_mst_sideband; dp->mst.cbs.hpd(&dp->dp_display, false, &info); } dp->mst.mst_active = false; dp_display_update_mst_state(dp, false); } DP_MST_DEBUG("mst_hpd_low. mst_active:%d\n", dp->mst.mst_active); Loading Loading @@ -927,8 +938,13 @@ static int dp_display_stream_enable(struct dp_display_private *dp, static void dp_display_mst_attention(struct dp_display_private *dp) { if (dp->mst.mst_active && dp->mst.cbs.hpd_irq) dp->mst.cbs.hpd_irq(&dp->dp_display); struct dp_mst_hpd_info hpd_irq = {0}; if (dp->mst.mst_active && dp->mst.cbs.hpd_irq) { hpd_irq.mst_hpd_sim = dp->debug->mst_hpd_sim; dp->mst.cbs.hpd_irq(&dp->dp_display, &hpd_irq); dp->debug->mst_hpd_sim = false; } DP_MST_DEBUG("mst_attention_work. mst_active:%d\n", dp->mst.mst_active); } Loading @@ -938,6 +954,9 @@ static void dp_display_attention_work(struct work_struct *work) struct dp_display_private *dp = container_of(work, struct dp_display_private, attention_work); if (dp->debug->mst_hpd_sim) goto mst_attention; if (dp->link->process_request(dp->link)) goto cp_irq; Loading Loading @@ -1003,7 +1022,8 @@ static int dp_display_usbpd_attention_cb(struct device *dev) if (!dp->hpd->hpd_high) dp_display_disconnect_sync(dp); else if (dp->hpd->hpd_irq && dp->core_initialized) else if ((dp->hpd->hpd_irq && dp->core_initialized) || dp->debug->mst_hpd_sim) queue_work(dp->wq, &dp->attention_work); else if (!dp->power_on) queue_delayed_work(dp->wq, &dp->connect_work, 0); Loading Loading @@ -2044,6 +2064,7 @@ static int dp_display_mst_connector_install(struct dp_display *dp_display, mst_connector->debug_en = false; mst_connector->conn = connector; mst_connector->con_id = connector->base.id; mst_connector->state = connector_status_unknown; INIT_LIST_HEAD(&mst_connector->list); list_add(&mst_connector->list, Loading Loading @@ -2109,6 +2130,38 @@ static int dp_display_mst_connector_uninstall(struct dp_display *dp_display, return rc; } static int dp_display_mst_get_connector_info(struct dp_display *dp_display, struct drm_connector *connector, struct dp_mst_connector *mst_conn) { struct dp_display_private *dp; struct dp_mst_connector *conn, *temp_conn; if (!connector || !mst_conn) { pr_err("invalid input\n"); return -EINVAL; } dp = container_of(dp_display, struct dp_display_private, dp_display); mutex_lock(&dp->session_lock); if (!dp->mst.drm_registered) { pr_debug("drm mst not registered\n"); mutex_unlock(&dp->session_lock); return -EPERM; } mutex_lock(&dp->debug->dp_mst_connector_list.lock); list_for_each_entry_safe(conn, temp_conn, &dp->debug->dp_mst_connector_list.list, list) { if (conn->con_id == connector->base.id) memcpy(mst_conn, conn, sizeof(*mst_conn)); } mutex_unlock(&dp->debug->dp_mst_connector_list.lock); mutex_unlock(&dp->session_lock); return 0; } static int dp_display_mst_connector_update_edid(struct dp_display *dp_display, struct drm_connector *connector, struct edid *edid) Loading Loading @@ -2231,6 +2284,8 @@ static int dp_display_probe(struct platform_device *pdev) g_dp_display->get_mst_caps = dp_display_get_mst_caps; g_dp_display->set_stream_info = dp_display_set_stream_info; g_dp_display->convert_to_dp_mode = dp_display_convert_to_dp_mode; g_dp_display->mst_get_connector_info = dp_display_mst_get_connector_info; rc = component_add(&pdev->dev, &dp_display_comp_ops); if (rc) { Loading
drivers/gpu/drm/msm/dp/dp_display.h +11 −3 Original line number Diff line number Diff line Loading @@ -21,15 +21,19 @@ #include "dp_panel.h" struct dp_mst_hdp_info { #define DP_MST_SIM_MAX_PORTS 2 struct dp_mst_hpd_info { bool mst_protocol; bool mst_hpd_sim; u32 mst_port_cnt; u8 *edid; }; struct dp_mst_drm_cbs { void (*hpd)(void *display, bool hpd_status, struct dp_mst_hdp_info *info); void (*hpd_irq)(void *display); struct dp_mst_hpd_info *info); void (*hpd_irq)(void *display, struct dp_mst_hpd_info *info); }; struct dp_mst_drm_install_info { Loading @@ -54,6 +58,7 @@ struct dp_mst_connector { struct drm_connector *conn; struct mutex lock; struct list_head list; enum drm_connector_status state; }; struct dp_display { Loading Loading @@ -96,6 +101,9 @@ struct dp_display { int (*mst_connector_update_edid)(struct dp_display *dp_display, struct drm_connector *connector, struct edid *edid); int (*mst_get_connector_info)(struct dp_display *dp_display, struct drm_connector *connector, struct dp_mst_connector *mst_conn); int (*get_mst_caps)(struct dp_display *dp_display, struct dp_mst_caps *mst_caps); int (*set_stream_info)(struct dp_display *dp_display, void *panel, Loading
drivers/gpu/drm/msm/dp/dp_mst_drm.c +193 −232 File changed.Preview size limit exceeded, changes collapsed. Show changes