Loading drivers/gpu/drm/msm/dp/dp_aux.c +5 −1 Original line number Diff line number Diff line Loading @@ -497,7 +497,8 @@ static ssize_t dp_aux_transfer_debug(struct drm_dp_aux *drm_aux, msg->size); aux->aux_error_num = DP_AUX_ERR_NONE; } else { memset(msg->buffer, 0, msg->size); memcpy(aux->dpcd + msg->address, msg->buffer, msg->size); } } else { if (aux->read && msg->address == 0x50) { Loading @@ -510,6 +511,9 @@ static ssize_t dp_aux_transfer_debug(struct drm_dp_aux *drm_aux, if (aux->aux_error_num == DP_AUX_ERR_NONE) { dp_aux_hex_dump(drm_aux, msg); if (!aux->read) memset(msg->buffer, 0, msg->size); msg->reply = aux->native ? DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK; } else { Loading drivers/gpu/drm/msm/dp/dp_debug.c +105 −3 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ struct dp_debug_private { struct device *dev; struct work_struct sim_work; struct dp_debug dp_debug; struct dp_parser *parser; }; static int dp_debug_get_edid_buf(struct dp_debug_private *debug) Loading @@ -73,13 +74,13 @@ static int dp_debug_get_dpcd_buf(struct dp_debug_private *debug) int rc = 0; if (!debug->dpcd) { debug->dpcd = devm_kzalloc(debug->dev, SZ_1K, GFP_KERNEL); debug->dpcd = devm_kzalloc(debug->dev, SZ_16K, GFP_KERNEL); if (!debug->dpcd) { rc = -ENOMEM; goto end; } debug->dpcd_size = SZ_1K; debug->dpcd_size = SZ_16K; } end: return rc; Loading Loading @@ -363,6 +364,65 @@ static ssize_t dp_debug_bw_code_write(struct file *file, return len; } static ssize_t dp_debug_mst_mode_write(struct file *file, const char __user *user_buff, size_t count, loff_t *ppos) { struct dp_debug_private *debug = file->private_data; char buf[SZ_8]; size_t len = 0; u32 mst_mode = 0; if (!debug) return -ENODEV; if (*ppos) return 0; len = min_t(size_t, count, SZ_8 - 1); if (copy_from_user(buf, user_buff, len)) return 0; buf[len] = '\0'; if (kstrtoint(buf, 10, &mst_mode) != 0) return 0; debug->parser->has_mst = mst_mode ? true : false; pr_debug("mst_enable: %d\n", mst_mode); return len; } static ssize_t dp_debug_mst_sideband_mode_write(struct file *file, const char __user *user_buff, size_t count, loff_t *ppos) { struct dp_debug_private *debug = file->private_data; char buf[SZ_8]; size_t len = 0; u32 mst_sideband_mode = 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; buf[len] = '\0'; if (kstrtoint(buf, 10, &mst_sideband_mode) != 0) return 0; debug->parser->has_mst_sideband = mst_sideband_mode ? true : false; pr_debug("mst_enable: %d\n", mst_sideband_mode); return len; } static ssize_t dp_debug_tpg_write(struct file *file, const char __user *user_buff, size_t count, loff_t *ppos) { Loading Loading @@ -1078,6 +1138,16 @@ static const struct file_operations dump_fops = { .read = dp_debug_read_dump, }; static const struct file_operations mst_mode_fops = { .open = simple_open, .write = dp_debug_mst_mode_write, }; static const struct file_operations mst_sideband_mode_fops = { .open = simple_open, .write = dp_debug_mst_sideband_mode_write, }; static int dp_debug_init(struct dp_debug *dp_debug) { int rc = 0; Loading Loading @@ -1217,6 +1287,22 @@ static int dp_debug_init(struct dp_debug *dp_debug) goto error_remove_dir; } file = debugfs_create_file("mst_mode", 0644, dir, debug, &mst_mode_fops); if (IS_ERR_OR_NULL(file)) { rc = PTR_ERR(file); pr_err("[%s] debugfs max_bw_code failed, rc=%d\n", DEBUG_NAME, rc); } file = debugfs_create_file("mst_sideband_mode", 0644, dir, debug, &mst_sideband_mode_fops); if (IS_ERR_OR_NULL(file)) { rc = PTR_ERR(file); pr_err("[%s] debugfs max_bw_code failed, rc=%d\n", DEBUG_NAME, rc); } return 0; error_remove_dir: Loading @@ -1235,10 +1321,23 @@ static void dp_debug_sim_work(struct work_struct *work) debug->usbpd->simulate_attention(debug->usbpd, debug->vdo); } u8 *dp_debug_get_edid(struct dp_debug *dp_debug) { struct dp_debug_private *debug; if (!dp_debug) return NULL; debug = container_of(dp_debug, struct dp_debug_private, dp_debug); return debug->edid; } struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, struct dp_usbpd *usbpd, struct dp_link *link, struct dp_aux *aux, struct drm_connector **connector, struct dp_catalog *catalog) struct dp_catalog *catalog, struct dp_parser *parser) { int rc = 0; struct dp_debug_private *debug; Loading Loading @@ -1266,6 +1365,7 @@ struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, debug->dev = dev; debug->connector = connector; debug->catalog = catalog; debug->parser = parser; dp_debug = &debug->dp_debug; dp_debug->vdisplay = 0; Loading @@ -1278,6 +1378,8 @@ struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, goto error; } dp_debug->get_edid = dp_debug_get_edid; return dp_debug; error: return ERR_PTR(rc); Loading drivers/gpu/drm/msm/dp/dp_debug.h +5 −1 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ struct dp_debug { int hdisplay; int vrefresh; bool tpg_state; u8 *(*get_edid)(struct dp_debug *dp_debug); }; /** Loading @@ -48,6 +50,7 @@ struct dp_debug { * @link: instance of link module * @connector: double pointer to display connector * @catalog: instance of catalog module * @parser: instance of parser module * return: pointer to allocated debug module data * * This function sets up the debug module and provides a way Loading @@ -56,7 +59,8 @@ struct dp_debug { struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, struct dp_usbpd *usbpd, struct dp_link *link, struct dp_aux *aux, struct drm_connector **connector, struct dp_catalog *catalog); struct dp_catalog *catalog, struct dp_parser *parser); /** * dp_debug_put() * Loading drivers/gpu/drm/msm/dp/dp_display.c +17 −5 Original line number Diff line number Diff line Loading @@ -513,6 +513,7 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp, static void dp_display_process_mst_hpd_high(struct dp_display_private *dp) { bool is_mst_receiver; struct dp_mst_hdp_info info; if (dp->parser->has_mst && dp->mst.drm_registered) { DP_MST_DEBUG("mst_hpd_high work\n"); Loading @@ -522,8 +523,11 @@ static void dp_display_process_mst_hpd_high(struct dp_display_private *dp) if (is_mst_receiver && !dp->mst.mst_active) { dp->mst.mst_active = true; info.mst_protocol = dp->parser->has_mst_sideband; info.edid = dp->debug->get_edid(dp->debug); if (dp->mst.cbs.hpd) dp->mst.cbs.hpd(&dp->dp_display, true); dp->mst.cbs.hpd(&dp->dp_display, true, &info); } } Loading Loading @@ -613,11 +617,15 @@ static void dp_display_host_deinit(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}; if (dp->mst.mst_active) { DP_MST_DEBUG("mst_hpd_low work\n"); if (dp->mst.cbs.hpd) dp->mst.cbs.hpd(&dp->dp_display, false); if (dp->mst.cbs.hpd) { info.mst_protocol = dp->parser->has_mst_sideband; dp->mst.cbs.hpd(&dp->dp_display, false, &info); } dp->mst.mst_active = false; } Loading Loading @@ -1085,7 +1093,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp) dp->debug = dp_debug_get(dev, dp->panel, dp->usbpd, dp->link, dp->aux, &dp->dp_display.base_connector, dp->catalog); dp->catalog, dp->parser); if (IS_ERR(dp->debug)) { rc = PTR_ERR(dp->debug); Loading Loading @@ -1516,8 +1524,12 @@ static int dp_display_validate_mode(struct dp_display *dp, void *panel, mode_rate_khz = mode_pclk_khz * mode_bpp; supported_rate_khz = link_info->num_lanes * link_info->rate * 8; if (mode_rate_khz > supported_rate_khz) if (mode_rate_khz > supported_rate_khz) { DP_MST_DEBUG("pclk:%d, supported_rate:%d\n", mode_pclk_khz, supported_rate_khz); return MODE_BAD; } return MODE_OK; } Loading drivers/gpu/drm/msm/dp/dp_display.h +7 −1 Original line number Diff line number Diff line Loading @@ -20,8 +20,14 @@ #include "dp_panel.h" struct dp_mst_hdp_info { bool mst_protocol; u8 *edid; }; struct dp_mst_drm_cbs { void (*hpd)(void *display, bool hpd_status); void (*hpd)(void *display, bool hpd_status, struct dp_mst_hdp_info *info); void (*hpd_irq)(void *display); }; Loading Loading
drivers/gpu/drm/msm/dp/dp_aux.c +5 −1 Original line number Diff line number Diff line Loading @@ -497,7 +497,8 @@ static ssize_t dp_aux_transfer_debug(struct drm_dp_aux *drm_aux, msg->size); aux->aux_error_num = DP_AUX_ERR_NONE; } else { memset(msg->buffer, 0, msg->size); memcpy(aux->dpcd + msg->address, msg->buffer, msg->size); } } else { if (aux->read && msg->address == 0x50) { Loading @@ -510,6 +511,9 @@ static ssize_t dp_aux_transfer_debug(struct drm_dp_aux *drm_aux, if (aux->aux_error_num == DP_AUX_ERR_NONE) { dp_aux_hex_dump(drm_aux, msg); if (!aux->read) memset(msg->buffer, 0, msg->size); msg->reply = aux->native ? DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK; } else { Loading
drivers/gpu/drm/msm/dp/dp_debug.c +105 −3 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ struct dp_debug_private { struct device *dev; struct work_struct sim_work; struct dp_debug dp_debug; struct dp_parser *parser; }; static int dp_debug_get_edid_buf(struct dp_debug_private *debug) Loading @@ -73,13 +74,13 @@ static int dp_debug_get_dpcd_buf(struct dp_debug_private *debug) int rc = 0; if (!debug->dpcd) { debug->dpcd = devm_kzalloc(debug->dev, SZ_1K, GFP_KERNEL); debug->dpcd = devm_kzalloc(debug->dev, SZ_16K, GFP_KERNEL); if (!debug->dpcd) { rc = -ENOMEM; goto end; } debug->dpcd_size = SZ_1K; debug->dpcd_size = SZ_16K; } end: return rc; Loading Loading @@ -363,6 +364,65 @@ static ssize_t dp_debug_bw_code_write(struct file *file, return len; } static ssize_t dp_debug_mst_mode_write(struct file *file, const char __user *user_buff, size_t count, loff_t *ppos) { struct dp_debug_private *debug = file->private_data; char buf[SZ_8]; size_t len = 0; u32 mst_mode = 0; if (!debug) return -ENODEV; if (*ppos) return 0; len = min_t(size_t, count, SZ_8 - 1); if (copy_from_user(buf, user_buff, len)) return 0; buf[len] = '\0'; if (kstrtoint(buf, 10, &mst_mode) != 0) return 0; debug->parser->has_mst = mst_mode ? true : false; pr_debug("mst_enable: %d\n", mst_mode); return len; } static ssize_t dp_debug_mst_sideband_mode_write(struct file *file, const char __user *user_buff, size_t count, loff_t *ppos) { struct dp_debug_private *debug = file->private_data; char buf[SZ_8]; size_t len = 0; u32 mst_sideband_mode = 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; buf[len] = '\0'; if (kstrtoint(buf, 10, &mst_sideband_mode) != 0) return 0; debug->parser->has_mst_sideband = mst_sideband_mode ? true : false; pr_debug("mst_enable: %d\n", mst_sideband_mode); return len; } static ssize_t dp_debug_tpg_write(struct file *file, const char __user *user_buff, size_t count, loff_t *ppos) { Loading Loading @@ -1078,6 +1138,16 @@ static const struct file_operations dump_fops = { .read = dp_debug_read_dump, }; static const struct file_operations mst_mode_fops = { .open = simple_open, .write = dp_debug_mst_mode_write, }; static const struct file_operations mst_sideband_mode_fops = { .open = simple_open, .write = dp_debug_mst_sideband_mode_write, }; static int dp_debug_init(struct dp_debug *dp_debug) { int rc = 0; Loading Loading @@ -1217,6 +1287,22 @@ static int dp_debug_init(struct dp_debug *dp_debug) goto error_remove_dir; } file = debugfs_create_file("mst_mode", 0644, dir, debug, &mst_mode_fops); if (IS_ERR_OR_NULL(file)) { rc = PTR_ERR(file); pr_err("[%s] debugfs max_bw_code failed, rc=%d\n", DEBUG_NAME, rc); } file = debugfs_create_file("mst_sideband_mode", 0644, dir, debug, &mst_sideband_mode_fops); if (IS_ERR_OR_NULL(file)) { rc = PTR_ERR(file); pr_err("[%s] debugfs max_bw_code failed, rc=%d\n", DEBUG_NAME, rc); } return 0; error_remove_dir: Loading @@ -1235,10 +1321,23 @@ static void dp_debug_sim_work(struct work_struct *work) debug->usbpd->simulate_attention(debug->usbpd, debug->vdo); } u8 *dp_debug_get_edid(struct dp_debug *dp_debug) { struct dp_debug_private *debug; if (!dp_debug) return NULL; debug = container_of(dp_debug, struct dp_debug_private, dp_debug); return debug->edid; } struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, struct dp_usbpd *usbpd, struct dp_link *link, struct dp_aux *aux, struct drm_connector **connector, struct dp_catalog *catalog) struct dp_catalog *catalog, struct dp_parser *parser) { int rc = 0; struct dp_debug_private *debug; Loading Loading @@ -1266,6 +1365,7 @@ struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, debug->dev = dev; debug->connector = connector; debug->catalog = catalog; debug->parser = parser; dp_debug = &debug->dp_debug; dp_debug->vdisplay = 0; Loading @@ -1278,6 +1378,8 @@ struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, goto error; } dp_debug->get_edid = dp_debug_get_edid; return dp_debug; error: return ERR_PTR(rc); Loading
drivers/gpu/drm/msm/dp/dp_debug.h +5 −1 Original line number Diff line number Diff line Loading @@ -37,6 +37,8 @@ struct dp_debug { int hdisplay; int vrefresh; bool tpg_state; u8 *(*get_edid)(struct dp_debug *dp_debug); }; /** Loading @@ -48,6 +50,7 @@ struct dp_debug { * @link: instance of link module * @connector: double pointer to display connector * @catalog: instance of catalog module * @parser: instance of parser module * return: pointer to allocated debug module data * * This function sets up the debug module and provides a way Loading @@ -56,7 +59,8 @@ struct dp_debug { struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, struct dp_usbpd *usbpd, struct dp_link *link, struct dp_aux *aux, struct drm_connector **connector, struct dp_catalog *catalog); struct dp_catalog *catalog, struct dp_parser *parser); /** * dp_debug_put() * Loading
drivers/gpu/drm/msm/dp/dp_display.c +17 −5 Original line number Diff line number Diff line Loading @@ -513,6 +513,7 @@ static int dp_display_send_hpd_notification(struct dp_display_private *dp, static void dp_display_process_mst_hpd_high(struct dp_display_private *dp) { bool is_mst_receiver; struct dp_mst_hdp_info info; if (dp->parser->has_mst && dp->mst.drm_registered) { DP_MST_DEBUG("mst_hpd_high work\n"); Loading @@ -522,8 +523,11 @@ static void dp_display_process_mst_hpd_high(struct dp_display_private *dp) if (is_mst_receiver && !dp->mst.mst_active) { dp->mst.mst_active = true; info.mst_protocol = dp->parser->has_mst_sideband; info.edid = dp->debug->get_edid(dp->debug); if (dp->mst.cbs.hpd) dp->mst.cbs.hpd(&dp->dp_display, true); dp->mst.cbs.hpd(&dp->dp_display, true, &info); } } Loading Loading @@ -613,11 +617,15 @@ static void dp_display_host_deinit(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}; if (dp->mst.mst_active) { DP_MST_DEBUG("mst_hpd_low work\n"); if (dp->mst.cbs.hpd) dp->mst.cbs.hpd(&dp->dp_display, false); if (dp->mst.cbs.hpd) { info.mst_protocol = dp->parser->has_mst_sideband; dp->mst.cbs.hpd(&dp->dp_display, false, &info); } dp->mst.mst_active = false; } Loading Loading @@ -1085,7 +1093,7 @@ static int dp_init_sub_modules(struct dp_display_private *dp) dp->debug = dp_debug_get(dev, dp->panel, dp->usbpd, dp->link, dp->aux, &dp->dp_display.base_connector, dp->catalog); dp->catalog, dp->parser); if (IS_ERR(dp->debug)) { rc = PTR_ERR(dp->debug); Loading Loading @@ -1516,8 +1524,12 @@ static int dp_display_validate_mode(struct dp_display *dp, void *panel, mode_rate_khz = mode_pclk_khz * mode_bpp; supported_rate_khz = link_info->num_lanes * link_info->rate * 8; if (mode_rate_khz > supported_rate_khz) if (mode_rate_khz > supported_rate_khz) { DP_MST_DEBUG("pclk:%d, supported_rate:%d\n", mode_pclk_khz, supported_rate_khz); return MODE_BAD; } return MODE_OK; } Loading
drivers/gpu/drm/msm/dp/dp_display.h +7 −1 Original line number Diff line number Diff line Loading @@ -20,8 +20,14 @@ #include "dp_panel.h" struct dp_mst_hdp_info { bool mst_protocol; u8 *edid; }; struct dp_mst_drm_cbs { void (*hpd)(void *display, bool hpd_status); void (*hpd)(void *display, bool hpd_status, struct dp_mst_hdp_info *info); void (*hpd_irq)(void *display); }; Loading