On Tue, Jul 31, 2018 at 05:39:26AM -0700, Tejas Upadhyay wrote:
> Patch adds support for debugging DisplayPort :
> 
> * All dpcd read/write transactions are logged
> * Logging done per AUX interface
> * Use following command to to list AUX transactions:

Hi Tejas,
Thanks for your patch. We already have this information going to the logs via
the DRM_DEBUG_KMS() prints in the i2c-over-aux function and via the
drm_dp_dump_access() function in the native read/write functions. So you should
be able to access this information already by writing 0x100 to drm.debug module
param.

Does that satisfy your requirements?

Sean

> 
> bash # cat /sys/kernel/debug/drm_dp_aux/$AUXNAME
> @0x0000: 0x12
> @0x0001: 0x14
> @0x0002: 0xc4
> @0x0003: 0x01
> @0x0004: 0x01
> @0x0005: 0x01
> @0x0006: 0x01
> @0x0007: 0x81
> @0x0008: 0x02
> @0x0009: 0x02
> @0x000a: 0x06
> @0x000b: 0x00
> @0x000c: 0x00
> @0x000d: 0x00
> @0x000e: 0x00
> @0x0100: 0x14
> @0x0101: 0x82
> @0x0102: 0x00
> @0x0103: 0x0a
> @0x0104: 0x0a
> @0x0107: 0x10
> @0x0108: 0x01
> @0x0202: 0x77
> @0x0203: 0x00
> @0x0204: 0x01
> @0x0205: 0x02
> @0x0206: 0x66
> @0x0207: 0x00
> 
> Above information will help to debug DisplayPort related runtime issues
> knowing what communication was done between DisplayPort sink and source.
> 
> Signed-off-by: Tejas Upadhyay <[email protected]>
> Signed-off-by: Hyun Kwon <[email protected]>
> ---
>  drivers/gpu/drm/Kconfig         |  10 +++
>  drivers/gpu/drm/drm_dp_helper.c | 174 
> +++++++++++++++++++++++++++++++++++++++-
>  include/drm/drm_dp_helper.h     |   7 ++
>  3 files changed, 190 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index f3c71e3..bb16e24 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -34,6 +34,16 @@ config DRM_DP_AUX_CHARDEV
>           read and write values to arbitrary DPCD registers on the DP aux
>           channel.
> 
> +config DRM_DEBUG_DP
> +       bool "DRM dp debug helper"
> +       default n
> +       depends on DRM
> +       help
> +         Choose this option to enable a debugfs functionality for drm-dp.
> +         Will help in debugging display port related issue.
> +         Recommended for driver developer as well as tester.
> +         Say "Y" to enable debug support.
> +
>  config DRM_DEBUG_MM
>         bool "Insert extra checks and debug info into the DRM range managers"
>         default n
> diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
> index 08af8d6..e8be361 100644
> --- a/drivers/gpu/drm/drm_dp_helper.c
> +++ b/drivers/gpu/drm/drm_dp_helper.c
> @@ -28,6 +28,9 @@
>  #include <linux/sched.h>
>  #include <linux/i2c.h>
>  #include <linux/seq_file.h>
> +#ifdef CONFIG_DRM_DEBUG_DP
> +#include <linux/debugfs.h>
> +#endif
>  #include <drm/drm_dp_helper.h>
>  #include <drm/drmP.h>
> 
> @@ -57,6 +60,171 @@ static u8 dp_get_lane_status(const u8 
> link_status[DP_LINK_STATUS_SIZE],
>         return (l >> s) & 0xf;
>  }
> 
> +#ifdef CONFIG_DRM_DEBUG_DP
> +
> +static uint drm_dp_debugfs_dpcd_size = 0x5ff;
> +module_param_named(debugfs_dpcd_size, drm_dp_debugfs_dpcd_size, uint, 0444);
> +MODULE_PARM_DESC(debugfs_dpcd_size, "Debugfs DPCD buffer size (default: 
> 1544)");
> +
> +static struct dentry *root;
> +
> +static bool drm_dp_debugfs_bitmap_is_set(struct drm_dp_aux *aux,
> +                                        unsigned int pos)
> +{
> +       u8 byte, bit;
> +
> +       byte = pos / 8;
> +       bit = pos % 8;
> +
> +       return !!(aux->dpcd_bitmap[byte] & BIT(bit));
> +}
> +
> +static void drm_dp_debugfs_bitmap_set(struct drm_dp_aux *aux, unsigned int 
> pos)
> +{
> +       u8 byte, bit;
> +
> +       byte = pos / 8;
> +       bit = pos % 8;
> +       aux->dpcd_bitmap[byte] |= BIT(bit);
> +}
> +
> +/* DP debugfs read API, to be called by user app */
> +static ssize_t drm_dp_debugfs_read(struct file *f, char __user *buf,
> +                                  size_t size, loff_t *pos)
> +{
> +       struct drm_dp_aux *aux = (struct drm_dp_aux *)f->f_inode->i_private;
> +       char *kern_buff = NULL;
> +       unsigned int i;
> +       size_t kern_buff_len;
> +       int err;
> +
> +       if (size <= 0)
> +               return -EINVAL;
> +       if (*pos != 0)
> +               return 0;
> +
> +       kern_buff_len = size;
> +       kern_buff = kzalloc(kern_buff_len, GFP_KERNEL);
> +       if (!kern_buff)
> +               return -ENOMEM;
> +
> +       for (i = 0; i < drm_dp_debugfs_dpcd_size; i++) {
> +               if (drm_dp_debugfs_bitmap_is_set(aux, i)) {
> +                       char str[16] = "";
> +
> +                       sprintf(str, "@0x%04x: 0x%02x\n", i, 
> aux->dpcd_data[i]);
> +                       if (kern_buff_len < strlen(str))
> +                               break;
> +
> +                       strcat(kern_buff, str);
> +                       kern_buff_len -= strlen(str);
> +               }
> +       }
> +       kern_buff_len = strlen(kern_buff);
> +       size = min(size, kern_buff_len);
> +       err = copy_to_user(buf, kern_buff, size);
> +       kfree(kern_buff);
> +       if (err)
> +               return err;
> +       *pos = size + 1;
> +
> +       return size;
> +}
> +
> +static const struct file_operations fops_drm_dp_dbgfs = {
> +       .owner = THIS_MODULE,
> +       .read = drm_dp_debugfs_read,
> +};
> +
> +static int drm_dp_debugfs_init(struct drm_dp_aux *aux)
> +{
> +       struct dentry *entry;
> +       u8 *bitmap, *data;
> +       int err;
> +
> +       /* FIXME: better be under drm debugfs dir, and cleaned up properly */
> +       if (!root) {
> +               root = debugfs_create_dir("drm_dp_aux", NULL);
> +               if (!root) {
> +                       DRM_ERROR("debugfs_create_dir failed for root\n");
> +                       return -ENODEV;
> +               }
> +       }
> +
> +       /* FIXME: There may be a better name than the aux name */
> +       entry = debugfs_create_file(aux->name, 0444, root, aux,
> +                                   &fops_drm_dp_dbgfs);
> +       if (!entry) {
> +               DRM_ERROR("debugfs_create_file testcase failed\n");
> +               err = -ENODEV;
> +               goto err_dbgfs;
> +       }
> +
> +       bitmap = devm_kzalloc(aux->dev,
> +                             sizeof(*bitmap) * (drm_dp_debugfs_dpcd_size / 
> 8),
> +                             GFP_KERNEL);
> +       if (unlikely(!bitmap)) {
> +               err = -ENOMEM;
> +               goto err_dbgfs;
> +       }
> +
> +       data = devm_kzalloc(aux->dev, sizeof(*data) * 
> drm_dp_debugfs_dpcd_size,
> +                           GFP_KERNEL);
> +       if (unlikely(!data)) {
> +               err = -ENOMEM;
> +               goto err_dbgfs;
> +       }
> +
> +       aux->dpcd_data = data;
> +       aux->dpcd_bitmap = bitmap;
> +
> +       return 0;
> +
> +err_dbgfs:
> +       debugfs_remove_recursive(entry);
> +       return err;
> +}
> +
> +/* Deinit DP debugfs */
> +static void drm_dp_debugfs_deinit(struct drm_dp_aux *aux)
> +{
> +       struct dentry *entry;
> +
> +       entry = debugfs_lookup(aux->name, root);
> +       debugfs_remove_recursive(entry);
> +}
> +
> +static void drm_dp_debugfs_log(struct drm_dp_aux *aux,
> +                              struct drm_dp_aux_msg *msg)
> +{
> +       u8 *buf;
> +       unsigned int i;
> +
> +       buf = (u8 *)msg->buffer;
> +       for (i = 0; i < msg->size; i++) {
> +               aux->dpcd_data[msg->address + i] = buf[i];
> +               drm_dp_debugfs_bitmap_set(aux, msg->address + i);
> +       }
> +}
> +
> +#else
> +
> +static void drm_dp_debugfs_log(struct drm_dp_aux *aux,
> +                              struct drm_dp_aux_msg *msg)
> +{
> +}
> +
> +static int drm_dp_debugfs_init(struct drm_dp_aux *aux)
> +{
> +       return 0;
> +}
> +
> +static void drm_dp_debugfs_deinit(struct drm_dp_aux *aux)
> +{
> +}
> +
> +#endif
> +
>  bool drm_dp_channel_eq_ok(const u8 link_status[DP_LINK_STATUS_SIZE],
>                           int lane_count)
>  {
> @@ -229,6 +397,8 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 
> request,
>         ret = err;
> 
>  unlock:
> +       /* Log dpcd aux write transactions*/
> +       drm_dp_debugfs_log(aux, &msg);
>         mutex_unlock(&aux->hw_mutex);
>         return ret;
>  }
> @@ -1108,7 +1278,8 @@ int drm_dp_aux_register(struct drm_dp_aux *aux)
>                 drm_dp_aux_unregister_devnode(aux);
>                 return ret;
>         }
> -
> +       /* Init DP debufs*/
> +       drm_dp_debugfs_init(aux);
>         return 0;
>  }
>  EXPORT_SYMBOL(drm_dp_aux_register);
> @@ -1119,6 +1290,7 @@ EXPORT_SYMBOL(drm_dp_aux_register);
>   */
>  void drm_dp_aux_unregister(struct drm_dp_aux *aux)
>  {
> +       drm_dp_debugfs_deinit(aux);
>         drm_dp_aux_unregister_devnode(aux);
>         i2c_del_adapter(&aux->ddc);
>  }
> diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
> index b17476a..442dfb8 100644
> --- a/include/drm/drm_dp_helper.h
> +++ b/include/drm/drm_dp_helper.h
> @@ -962,6 +962,8 @@ struct drm_dp_aux_msg {
>   * @crc_work: worker that captures CRCs for each frame
>   * @crc_count: counter of captured frame CRCs
>   * @transfer: transfers a message representing a single AUX transaction
> + * @dpcd_data: store aux transactions for dp debugfs
> + * @dpcd_bitmap: store a bitmap for valid dpcd data
>   *
>   * The .dev field should be set to a pointer to the device that implements
>   * the AUX channel.
> @@ -1010,6 +1012,11 @@ struct drm_dp_aux {
>          * @i2c_defer_count: Counts I2C DEFERs, used for DP validation.
>          */
>         unsigned i2c_defer_count;
> +#ifdef CONFIG_DRM_DEBUG_DP
> +       /* aux transactions for dp debugfs*/
> +       u8 *dpcd_data;
> +       u8 *dpcd_bitmap;
> +#endif
>  };
> 
>  ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset,
> --
> 2.7.4
> 
> This email and any attachments are intended for the sole use of the named 
> recipient(s) and contain(s) confidential information that may be proprietary, 
> privileged or copyrighted under applicable law. If you are not the intended 
> recipient, do not read, copy, or forward this email message or any 
> attachments. Delete this email message and any attachments immediately.

-- 
Sean Paul, Software Engineer, Google / Chromium OS
_______________________________________________
dri-devel mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to