From patchwork Mon Apr 20 11:38:14 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: durgadoss.r@intel.com X-Patchwork-Id: 6241481 Return-Path: X-Original-To: patchwork-intel-gfx@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id CA55FBF4A6 for ; Mon, 20 Apr 2015 11:22:04 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C361D203E3 for ; Mon, 20 Apr 2015 11:22:03 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by mail.kernel.org (Postfix) with ESMTP id AE388203E1 for ; Mon, 20 Apr 2015 11:22:02 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id BB45C6E366; Mon, 20 Apr 2015 04:22:01 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id A64E36E366 for ; Mon, 20 Apr 2015 04:22:00 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga101.jf.intel.com with ESMTP; 20 Apr 2015 04:21:39 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.11,609,1422950400"; d="scan'208";a="712126091" Received: from dr3-desktop.iind.intel.com ([10.223.26.125]) by fmsmga002.fm.intel.com with ESMTP; 20 Apr 2015 04:21:37 -0700 From: Durgadoss R To: intel-gfx@lists.freedesktop.org Date: Mon, 20 Apr 2015 17:08:14 +0530 Message-Id: <1429529894-8771-1-git-send-email-durgadoss.r@intel.com> X-Mailer: git-send-email 1.9.1 Cc: ville.syrjala@intel.com, paulo.r.zanoni@intel.com Subject: [Intel-gfx] [PATCH v3] drm/i915: Add debugfs to read/write any DPCD register X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: intel-gfx-bounces@lists.freedesktop.org Sender: "Intel-gfx" X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch creates a connector specific debugfs interface to read any particular DPCD register. The DPCD register address (hex format) is written to 'i915_dpcd_addr' interface and the corresponding value can be read from 'i915_dpcd_val' interface. To write into a DPCD register, echo a value into 'i915_dpcd_val' interface. This will return -EIO for invalid writes. Example usage: echo 0x2 > i915_dpcd_addr cat i915_dpcd_val 0x84 To write 0x1 to DPCD 0x170: echo 0x170 > i915_dpcd_addr echo 0x1 > i915_dpcd_val cat i915_dpcd_val 0x1 v2: Address Jani's comments. v3: Added capability to write DPCD also (Ville) Signed-off-by: Durgadoss R Reviewed-by: Sivakumar Thulasimani Tested-By: Intel Graphics QA PRTS (Patch Regression Test System Contact: shuang.he@intel.com) --- drivers/gpu/drm/i915/i915_debugfs.c | 120 +++++++++++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_drv.h | 1 + 2 files changed, 120 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9c2b9e4..79c876e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -4968,6 +4968,119 @@ static const struct file_operations i915_dpcd_fops = { .release = single_release, }; +static ssize_t i915_dpcd_addr_write(struct file *file, const char __user *ubuf, + size_t len, loff_t *offp) +{ + struct seq_file *m = file->private_data; + struct drm_connector *connector = m->private; + struct intel_dp *intel_dp = + enc_to_intel_dp(&intel_attached_encoder(connector)->base); + unsigned int reg_addr; + char tmp[16]; + + if (len >= sizeof(tmp)) + return -EINVAL; + + if (copy_from_user(tmp, ubuf, len)) + return -EFAULT; + + tmp[len] = '\0'; + + if (kstrtouint(tmp, 16, ®_addr)) + return -EINVAL; + + intel_dp->debugfs_dpcd_addr = reg_addr; + + return len; +} + +static int i915_dpcd_addr_show(struct seq_file *m, void *data) +{ + struct drm_connector *connector = m->private; + struct intel_dp *intel_dp = + enc_to_intel_dp(&intel_attached_encoder(connector)->base); + + seq_printf(m, "0x%x\n", intel_dp->debugfs_dpcd_addr); + + return 0; +} + +static int i915_dpcd_addr_open(struct inode *inode, struct file *file) +{ + return single_open(file, i915_dpcd_addr_show, inode->i_private); +} + +static const struct file_operations i915_dpcd_addr_fops = { + .owner = THIS_MODULE, + .open = i915_dpcd_addr_open, + .read = seq_read, + .write = i915_dpcd_addr_write, + .llseek = seq_lseek, + .release = single_release, +}; + +static ssize_t i915_dpcd_val_write(struct file *file, const char __user *ubuf, + size_t len, loff_t *offp) +{ + struct seq_file *m = file->private_data; + struct drm_connector *connector = m->private; + struct intel_dp *intel_dp = + enc_to_intel_dp(&intel_attached_encoder(connector)->base); + unsigned int addr = intel_dp->debugfs_dpcd_addr; + unsigned int val; + char tmp[16]; + int ret; + + if (len >= sizeof(tmp)) + return -EINVAL; + + if (copy_from_user(tmp, ubuf, len)) + return -EFAULT; + + tmp[len] = '\0'; + + if (kstrtouint(tmp, 16, &val)) + return -EINVAL; + + ret = drm_dp_dpcd_writeb(&intel_dp->aux, addr, val); + if (ret < 0) + return ret; + + return len; +} + +static int i915_dpcd_val_show(struct seq_file *m, void *data) +{ + struct drm_connector *connector = m->private; + struct intel_dp *intel_dp = + enc_to_intel_dp(&intel_attached_encoder(connector)->base); + unsigned int addr; + u8 val; + int ret; + + addr = intel_dp->debugfs_dpcd_addr; + ret = drm_dp_dpcd_readb(&intel_dp->aux, addr, &val); + if (ret < 0) + return ret; + + seq_printf(m, "0x%x\n", val); + return 0; +} + +static int i915_dpcd_val_open(struct inode *inode, struct file *file) +{ + return single_open(file, i915_dpcd_val_show, inode->i_private); +} + +static const struct file_operations i915_dpcd_val_fops = { + .owner = THIS_MODULE, + .open = i915_dpcd_val_open, + .read = seq_read, + .write = i915_dpcd_val_write, + .llseek = seq_lseek, + .release = single_release, +}; + /** * i915_debugfs_connector_add - add i915 specific connector debugfs files * @connector: pointer to a registered drm_connector @@ -4986,9 +5099,14 @@ int i915_debugfs_connector_add(struct drm_connector *connector) return -ENODEV; if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort || - connector->connector_type == DRM_MODE_CONNECTOR_eDP) + connector->connector_type == DRM_MODE_CONNECTOR_eDP) { debugfs_create_file("i915_dpcd", S_IRUGO, root, connector, &i915_dpcd_fops); + debugfs_create_file("i915_dpcd_addr", S_IRUGO | S_IWUSR, + root, connector, &i915_dpcd_addr_fops); + debugfs_create_file("i915_dpcd_val", S_IRUGO | S_IWUSR, + root, connector, &i915_dpcd_val_fops); + } return 0; } diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 23a42a4..4477d14 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -709,6 +709,7 @@ struct intel_dp { unsigned long last_power_cycle; unsigned long last_power_on; unsigned long last_backlight_off; + unsigned int debugfs_dpcd_addr; struct notifier_block edp_notifier;