Loading drivers/gpu/drm/msm/dp/dp_debug.c +94 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,9 @@ struct dp_debug_private { u8 *edid; u32 edid_size; u8 *dpcd; u32 dpcd_size; struct dp_usbpd *usbpd; struct dp_link *link; struct dp_panel *panel; Loading Loading @@ -106,6 +109,73 @@ static ssize_t dp_debug_write_edid(struct file *file, return rc; } static ssize_t dp_debug_write_dpcd(struct file *file, const char __user *user_buff, size_t count, loff_t *ppos) { struct dp_debug_private *debug = file->private_data; u8 *buf = NULL, *buf_t = NULL, *dpcd = NULL; const int char_to_nib = 2; size_t dpcd_size = 0; size_t size = 0, dpcd_buf_index = 0; ssize_t rc = count; pr_debug("count=%zu\n", count); if (!debug) return -ENODEV; if (*ppos) goto bail; size = min_t(size_t, count, SZ_32); buf = kzalloc(size, GFP_KERNEL); if (!buf) { rc = -ENOMEM; goto bail; } if (copy_from_user(buf, user_buff, size)) goto bail; dpcd_size = size / char_to_nib; buf_t = buf; memset(debug->dpcd, 0, debug->dpcd_size); if (dpcd_size != debug->dpcd_size) { pr_debug("clearing debug dpcd\n"); goto bail; } while (dpcd_size--) { char t[3]; int d; memcpy(t, buf_t, sizeof(char) * char_to_nib); t[char_to_nib] = '\0'; if (kstrtoint(t, 16, &d)) { pr_err("kstrtoint error\n"); goto bail; } if (dpcd_buf_index < debug->dpcd_size) debug->dpcd[dpcd_buf_index++] = d; buf_t += char_to_nib; } print_hex_dump(KERN_DEBUG, "DEBUG DPCD: ", DUMP_PREFIX_NONE, 8, 1, debug->dpcd, debug->dpcd_size, false); dpcd = debug->dpcd; bail: kfree(buf); debug->panel->set_dpcd(debug->panel, dpcd); return rc; } static ssize_t dp_debug_write_hpd(struct file *file, const char __user *user_buff, size_t count, loff_t *ppos) { Loading Loading @@ -503,6 +573,11 @@ static const struct file_operations edid_fops = { .write = dp_debug_write_edid, }; static const struct file_operations dpcd_fops = { .open = simple_open, .write = dp_debug_write_dpcd, }; static const struct file_operations connected_fops = { .open = simple_open, .read = dp_debug_read_connected, Loading Loading @@ -585,6 +660,15 @@ static int dp_debug_init(struct dp_debug *dp_debug) goto error_remove_dir; } file = debugfs_create_file("dpcd", 0644, dir, debug, &dpcd_fops); if (IS_ERR_OR_NULL(file)) { rc = PTR_ERR(file); pr_err("[%s] debugfs dpcd failed, rc=%d\n", DEBUG_NAME, rc); goto error_remove_dir; } return 0; error_remove_dir: Loading Loading @@ -622,6 +706,15 @@ struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, debug->edid_size = SZ_256; debug->dpcd = devm_kzalloc(dev, SZ_16, GFP_KERNEL); if (!debug->dpcd) { rc = -ENOMEM; kfree(debug); goto error; } debug->dpcd_size = SZ_16; debug->dp_debug.debug_en = false; debug->usbpd = usbpd; debug->link = link; Loading Loading @@ -671,5 +764,6 @@ void dp_debug_put(struct dp_debug *dp_debug) dp_debug_deinit(dp_debug); devm_kfree(debug->dev, debug->edid); devm_kfree(debug->dev, debug->dpcd); devm_kfree(debug->dev, debug); } drivers/gpu/drm/msm/dp/dp_panel.c +37 −6 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ struct dp_panel_private { struct dp_catalog_panel *catalog; bool aux_cfg_update_done; bool custom_edid; bool custom_dpcd; }; static const struct dp_panel_info fail_safe = { Loading Loading @@ -70,14 +71,19 @@ static int dp_panel_read_dpcd(struct dp_panel *dp_panel) panel = container_of(dp_panel, struct dp_panel_private, dp_panel); link_info = &dp_panel->link_info; if (!panel->custom_dpcd) { rlen = drm_dp_dpcd_read(panel->aux->drm_aux, DP_DPCD_REV, dpcd, (DP_RECEIVER_CAP_SIZE + 1)); dp_panel->dpcd, (DP_RECEIVER_CAP_SIZE + 1)); if (rlen < (DP_RECEIVER_CAP_SIZE + 1)) { pr_err("dpcd read failed, rlen=%d\n", rlen); rc = -EINVAL; goto end; } print_hex_dump(KERN_DEBUG, "[drm-dp] SINK DPCD: ", DUMP_PREFIX_NONE, 8, 1, dp_panel->dpcd, rlen, false); } link_info->revision = dp_panel->dpcd[DP_DPCD_REV]; major = (link_info->revision >> 4) & 0x0f; Loading Loading @@ -159,6 +165,30 @@ static int dp_panel_set_edid(struct dp_panel *dp_panel, u8 *edid) return 0; } static int dp_panel_set_dpcd(struct dp_panel *dp_panel, u8 *dpcd) { struct dp_panel_private *panel; u8 *dp_dpcd; if (!dp_panel) { pr_err("invalid input\n"); return -EINVAL; } dp_dpcd = dp_panel->dpcd; panel = container_of(dp_panel, struct dp_panel_private, dp_panel); if (dpcd) { memcpy(dp_dpcd, dpcd, DP_RECEIVER_CAP_SIZE + 1); panel->custom_dpcd = true; } else { panel->custom_dpcd = false; } return 0; } static int dp_panel_read_edid(struct dp_panel *dp_panel, struct drm_connector *connector) { Loading Loading @@ -569,6 +599,7 @@ struct dp_panel *dp_panel_get(struct dp_panel_in *in) dp_panel->get_modes = dp_panel_get_modes; dp_panel->handle_sink_request = dp_panel_handle_sink_request; dp_panel->set_edid = dp_panel_set_edid; dp_panel->set_dpcd = dp_panel_set_dpcd; dp_panel_edid_register(panel); Loading drivers/gpu/drm/msm/dp/dp_panel.h +2 −1 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ struct dp_panel_in { struct dp_panel { /* dpcd raw data */ u8 dpcd[DP_RECEIVER_CAP_SIZE]; u8 dpcd[DP_RECEIVER_CAP_SIZE + 1]; u8 ds_ports[DP_MAX_DOWNSTREAM_PORTS]; struct drm_dp_link link_info; Loading @@ -85,6 +85,7 @@ struct dp_panel { struct drm_connector *connector, struct dp_display_mode *mode); void (*handle_sink_request)(struct dp_panel *dp_panel); int (*set_edid)(struct dp_panel *dp_panel, u8 *edid); int (*set_dpcd)(struct dp_panel *dp_panel, u8 *dpcd); }; /** Loading Loading
drivers/gpu/drm/msm/dp/dp_debug.c +94 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,9 @@ struct dp_debug_private { u8 *edid; u32 edid_size; u8 *dpcd; u32 dpcd_size; struct dp_usbpd *usbpd; struct dp_link *link; struct dp_panel *panel; Loading Loading @@ -106,6 +109,73 @@ static ssize_t dp_debug_write_edid(struct file *file, return rc; } static ssize_t dp_debug_write_dpcd(struct file *file, const char __user *user_buff, size_t count, loff_t *ppos) { struct dp_debug_private *debug = file->private_data; u8 *buf = NULL, *buf_t = NULL, *dpcd = NULL; const int char_to_nib = 2; size_t dpcd_size = 0; size_t size = 0, dpcd_buf_index = 0; ssize_t rc = count; pr_debug("count=%zu\n", count); if (!debug) return -ENODEV; if (*ppos) goto bail; size = min_t(size_t, count, SZ_32); buf = kzalloc(size, GFP_KERNEL); if (!buf) { rc = -ENOMEM; goto bail; } if (copy_from_user(buf, user_buff, size)) goto bail; dpcd_size = size / char_to_nib; buf_t = buf; memset(debug->dpcd, 0, debug->dpcd_size); if (dpcd_size != debug->dpcd_size) { pr_debug("clearing debug dpcd\n"); goto bail; } while (dpcd_size--) { char t[3]; int d; memcpy(t, buf_t, sizeof(char) * char_to_nib); t[char_to_nib] = '\0'; if (kstrtoint(t, 16, &d)) { pr_err("kstrtoint error\n"); goto bail; } if (dpcd_buf_index < debug->dpcd_size) debug->dpcd[dpcd_buf_index++] = d; buf_t += char_to_nib; } print_hex_dump(KERN_DEBUG, "DEBUG DPCD: ", DUMP_PREFIX_NONE, 8, 1, debug->dpcd, debug->dpcd_size, false); dpcd = debug->dpcd; bail: kfree(buf); debug->panel->set_dpcd(debug->panel, dpcd); return rc; } static ssize_t dp_debug_write_hpd(struct file *file, const char __user *user_buff, size_t count, loff_t *ppos) { Loading Loading @@ -503,6 +573,11 @@ static const struct file_operations edid_fops = { .write = dp_debug_write_edid, }; static const struct file_operations dpcd_fops = { .open = simple_open, .write = dp_debug_write_dpcd, }; static const struct file_operations connected_fops = { .open = simple_open, .read = dp_debug_read_connected, Loading Loading @@ -585,6 +660,15 @@ static int dp_debug_init(struct dp_debug *dp_debug) goto error_remove_dir; } file = debugfs_create_file("dpcd", 0644, dir, debug, &dpcd_fops); if (IS_ERR_OR_NULL(file)) { rc = PTR_ERR(file); pr_err("[%s] debugfs dpcd failed, rc=%d\n", DEBUG_NAME, rc); goto error_remove_dir; } return 0; error_remove_dir: Loading Loading @@ -622,6 +706,15 @@ struct dp_debug *dp_debug_get(struct device *dev, struct dp_panel *panel, debug->edid_size = SZ_256; debug->dpcd = devm_kzalloc(dev, SZ_16, GFP_KERNEL); if (!debug->dpcd) { rc = -ENOMEM; kfree(debug); goto error; } debug->dpcd_size = SZ_16; debug->dp_debug.debug_en = false; debug->usbpd = usbpd; debug->link = link; Loading Loading @@ -671,5 +764,6 @@ void dp_debug_put(struct dp_debug *dp_debug) dp_debug_deinit(dp_debug); devm_kfree(debug->dev, debug->edid); devm_kfree(debug->dev, debug->dpcd); devm_kfree(debug->dev, debug); }
drivers/gpu/drm/msm/dp/dp_panel.c +37 −6 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ struct dp_panel_private { struct dp_catalog_panel *catalog; bool aux_cfg_update_done; bool custom_edid; bool custom_dpcd; }; static const struct dp_panel_info fail_safe = { Loading Loading @@ -70,14 +71,19 @@ static int dp_panel_read_dpcd(struct dp_panel *dp_panel) panel = container_of(dp_panel, struct dp_panel_private, dp_panel); link_info = &dp_panel->link_info; if (!panel->custom_dpcd) { rlen = drm_dp_dpcd_read(panel->aux->drm_aux, DP_DPCD_REV, dpcd, (DP_RECEIVER_CAP_SIZE + 1)); dp_panel->dpcd, (DP_RECEIVER_CAP_SIZE + 1)); if (rlen < (DP_RECEIVER_CAP_SIZE + 1)) { pr_err("dpcd read failed, rlen=%d\n", rlen); rc = -EINVAL; goto end; } print_hex_dump(KERN_DEBUG, "[drm-dp] SINK DPCD: ", DUMP_PREFIX_NONE, 8, 1, dp_panel->dpcd, rlen, false); } link_info->revision = dp_panel->dpcd[DP_DPCD_REV]; major = (link_info->revision >> 4) & 0x0f; Loading Loading @@ -159,6 +165,30 @@ static int dp_panel_set_edid(struct dp_panel *dp_panel, u8 *edid) return 0; } static int dp_panel_set_dpcd(struct dp_panel *dp_panel, u8 *dpcd) { struct dp_panel_private *panel; u8 *dp_dpcd; if (!dp_panel) { pr_err("invalid input\n"); return -EINVAL; } dp_dpcd = dp_panel->dpcd; panel = container_of(dp_panel, struct dp_panel_private, dp_panel); if (dpcd) { memcpy(dp_dpcd, dpcd, DP_RECEIVER_CAP_SIZE + 1); panel->custom_dpcd = true; } else { panel->custom_dpcd = false; } return 0; } static int dp_panel_read_edid(struct dp_panel *dp_panel, struct drm_connector *connector) { Loading Loading @@ -569,6 +599,7 @@ struct dp_panel *dp_panel_get(struct dp_panel_in *in) dp_panel->get_modes = dp_panel_get_modes; dp_panel->handle_sink_request = dp_panel_handle_sink_request; dp_panel->set_edid = dp_panel_set_edid; dp_panel->set_dpcd = dp_panel_set_dpcd; dp_panel_edid_register(panel); Loading
drivers/gpu/drm/msm/dp/dp_panel.h +2 −1 Original line number Diff line number Diff line Loading @@ -59,7 +59,7 @@ struct dp_panel_in { struct dp_panel { /* dpcd raw data */ u8 dpcd[DP_RECEIVER_CAP_SIZE]; u8 dpcd[DP_RECEIVER_CAP_SIZE + 1]; u8 ds_ports[DP_MAX_DOWNSTREAM_PORTS]; struct drm_dp_link link_info; Loading @@ -85,6 +85,7 @@ struct dp_panel { struct drm_connector *connector, struct dp_display_mode *mode); void (*handle_sink_request)(struct dp_panel *dp_panel); int (*set_edid)(struct dp_panel *dp_panel, u8 *edid); int (*set_dpcd)(struct dp_panel *dp_panel, u8 *dpcd); }; /** Loading