Add the debugfs nodes needed for the video pattern
compliance tests to MSM DP driver.

Signed-off-by: Abhinav Kumar <abhin...@codeaurora.org>
---
 drivers/gpu/drm/msm/dp/dp_debug.c | 184 ++++++++++++++++++++++++++++++
 drivers/gpu/drm/msm/dp/dp_link.h  |  23 ++++
 2 files changed, 207 insertions(+)

diff --git a/drivers/gpu/drm/msm/dp/dp_debug.c 
b/drivers/gpu/drm/msm/dp/dp_debug.c
index 099e989f214d..16861aade93b 100644
--- a/drivers/gpu/drm/msm/dp/dp_debug.c
+++ b/drivers/gpu/drm/msm/dp/dp_debug.c
@@ -203,17 +203,174 @@ static ssize_t dp_debug_read_info(struct file *file, 
char __user *user_buff,
        return -EINVAL;
 }
 
+static int dp_test_data_show(struct seq_file *m, void *data)
+{
+       struct drm_device *dev;
+       struct dp_debug_private *debug;
+       struct drm_connector *connector;
+       struct drm_connector_list_iter conn_iter;
+       u32 bpc;
+
+       debug = m->private;
+       dev = debug->drm_dev;
+       drm_connector_list_iter_begin(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter) {
+
+               if (connector->connector_type !=
+                       DRM_MODE_CONNECTOR_DisplayPort)
+                       continue;
+
+               if (connector->status == connector_status_connected) {
+                       bpc = debug->link->test_video.test_bit_depth;
+                       seq_printf(m, "hdisplay: %d\n",
+                                       debug->link->test_video.test_h_width);
+                       seq_printf(m, "vdisplay: %d\n",
+                                       debug->link->test_video.test_v_height);
+                                       seq_printf(m, "bpc: %u\n",
+                                       dp_link_bit_depth_to_bpc(bpc));
+               } else
+                       seq_puts(m, "0");
+       }
+
+       drm_connector_list_iter_end(&conn_iter);
+
+       return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(dp_test_data);
+
+static int dp_test_type_show(struct seq_file *m, void *data)
+{
+       struct dp_debug_private *debug = m->private;
+       struct drm_device *dev = debug->drm_dev;
+       struct drm_connector *connector;
+       struct drm_connector_list_iter conn_iter;
+
+       drm_connector_list_iter_begin(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter) {
+
+               if (connector->connector_type !=
+                       DRM_MODE_CONNECTOR_DisplayPort)
+                       continue;
+
+               if (connector->status == connector_status_connected)
+                       seq_printf(m, "%02lx", DP_TEST_LINK_VIDEO_PATTERN);
+               else
+                       seq_puts(m, "0");
+       }
+       drm_connector_list_iter_end(&conn_iter);
+
+       return 0;
+}
+DEFINE_SHOW_ATTRIBUTE(dp_test_type);
+
+static ssize_t dp_test_active_write(struct file *file,
+               const char __user *ubuf,
+               size_t len, loff_t *offp)
+{
+       char *input_buffer;
+       int status = 0;
+       struct dp_debug_private *debug;
+       struct drm_device *dev;
+       struct drm_connector *connector;
+       struct drm_connector_list_iter conn_iter;
+       int val = 0;
+
+       debug = ((struct seq_file *)file->private_data)->private;
+       dev = debug->drm_dev;
+
+       if (len == 0)
+               return 0;
+
+       input_buffer = memdup_user_nul(ubuf, len);
+       if (IS_ERR(input_buffer))
+               return PTR_ERR(input_buffer);
+
+       DRM_DEBUG_DRIVER("Copied %d bytes from user\n", (unsigned int)len);
+
+       drm_connector_list_iter_begin(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter) {
+               if (connector->connector_type !=
+                       DRM_MODE_CONNECTOR_DisplayPort)
+                       continue;
+
+               if (connector->status == connector_status_connected) {
+                       status = kstrtoint(input_buffer, 10, &val);
+                       if (status < 0)
+                               break;
+                       DRM_DEBUG_DRIVER("Got %d for test active\n", val);
+                       /* To prevent erroneous activation of the compliance
+                        * testing code, only accept an actual value of 1 here
+                        */
+                       if (val == 1)
+                               debug->panel->video_test = true;
+                       else
+                               debug->panel->video_test = false;
+               }
+       }
+       drm_connector_list_iter_end(&conn_iter);
+       kfree(input_buffer);
+       if (status < 0)
+               return status;
+
+       *offp += len;
+       return len;
+}
+
+static int dp_test_active_show(struct seq_file *m, void *data)
+{
+       struct dp_debug_private *debug = m->private;
+       struct drm_device *dev = debug->drm_dev;
+       struct drm_connector *connector;
+       struct drm_connector_list_iter conn_iter;
+
+       drm_connector_list_iter_begin(dev, &conn_iter);
+       drm_for_each_connector_iter(connector, &conn_iter) {
+               if (connector->connector_type !=
+                       DRM_MODE_CONNECTOR_DisplayPort)
+                       continue;
+
+               if (connector->status == connector_status_connected) {
+                       if (debug->panel->video_test)
+                               seq_puts(m, "1");
+                       else
+                               seq_puts(m, "0");
+               } else
+                       seq_puts(m, "0");
+       }
+       drm_connector_list_iter_end(&conn_iter);
+
+       return 0;
+}
+
+static int dp_test_active_open(struct inode *inode,
+               struct file *file)
+{
+       return single_open(file, dp_test_active_show,
+                       inode->i_private);
+}
+
 static const struct file_operations dp_debug_fops = {
        .open = simple_open,
        .read = dp_debug_read_info,
 };
 
+static const struct file_operations test_active_fops = {
+       .owner = THIS_MODULE,
+       .open = dp_test_active_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+       .write = dp_test_active_write
+};
+
 static int dp_debug_init(struct dp_debug *dp_debug, struct drm_minor *minor)
 {
        int rc = 0;
        struct dp_debug_private *debug = container_of(dp_debug,
                        struct dp_debug_private, dp_debug);
        struct dentry *file;
+       struct dentry *test_active;
+       struct dentry *test_data, *test_type;
 
        file = debugfs_create_file("dp_debug", 0444, minor->debugfs_root,
                        debug, &dp_debug_fops);
@@ -223,6 +380,33 @@ static int dp_debug_init(struct dp_debug *dp_debug, struct 
drm_minor *minor)
                                  DEBUG_NAME, rc);
        }
 
+       test_active = debugfs_create_file("msm_dp_test_active", 0444,
+                       minor->debugfs_root,
+                       debug, &test_active_fops);
+       if (IS_ERR_OR_NULL(test_active)) {
+               rc = PTR_ERR(test_active);
+               DRM_ERROR("[%s] debugfs test_active failed, rc=%d\n",
+                                 DEBUG_NAME, rc);
+       }
+
+       test_data = debugfs_create_file("msm_dp_test_data", 0444,
+                       minor->debugfs_root,
+                       debug, &dp_test_data_fops);
+       if (IS_ERR_OR_NULL(test_data)) {
+               rc = PTR_ERR(test_data);
+               DRM_ERROR("[%s] debugfs test_data failed, rc=%d\n",
+                                 DEBUG_NAME, rc);
+       }
+
+       test_type = debugfs_create_file("msm_dp_test_type", 0444,
+                       minor->debugfs_root,
+                       debug, &dp_test_type_fops);
+       if (IS_ERR_OR_NULL(test_type)) {
+               rc = PTR_ERR(test_type);
+               DRM_ERROR("[%s] debugfs test_type failed, rc=%d\n",
+                                 DEBUG_NAME, rc);
+       }
+
        debug->root = minor->debugfs_root;
 
        return rc;
diff --git a/drivers/gpu/drm/msm/dp/dp_link.h b/drivers/gpu/drm/msm/dp/dp_link.h
index e9d54db8fb61..49811b6221e5 100644
--- a/drivers/gpu/drm/msm/dp/dp_link.h
+++ b/drivers/gpu/drm/msm/dp/dp_link.h
@@ -112,6 +112,29 @@ static inline u32 dp_link_bit_depth_to_bpp(u32 tbd)
        }
 }
 
+/**
+ * dp_test_bit_depth_to_bpc() - convert test bit depth to bpc
+ * @tbd: test bit depth
+ *
+ * Returns the bits per comp (bpc) to be used corresponding to the
+ * bit depth value. This function assumes that bit depth has
+ * already been validated.
+ */
+static inline u32 dp_link_bit_depth_to_bpc(u32 tbd)
+{
+       switch (tbd) {
+       case DP_TEST_BIT_DEPTH_6:
+               return 6;
+       case DP_TEST_BIT_DEPTH_8:
+               return 8;
+       case DP_TEST_BIT_DEPTH_10:
+               return 10;
+       case DP_TEST_BIT_DEPTH_UNKNOWN:
+       default:
+               return 0;
+       }
+}
+
 u32 dp_link_get_test_bits_depth(struct dp_link *dp_link, u32 bpp);
 int dp_link_process_request(struct dp_link *dp_link);
 int dp_link_get_colorimetry_config(struct dp_link *dp_link);
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to