drm/msm/sde: enable sde clocks during debugfs register read

SDE clocks need to be enabled when attempting to read h/w
registers through the debugfs interface. The clocks themselves
are reference counted, so it's safe to enable/disable them
around the debugfs access.

Change-Id: I937b29e327799f78b821d4beb4f93504bea28fdc
Signed-off-by: Clarence Ip <cip@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index 2604000..d99dc19 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -53,15 +53,54 @@
 
 static int sde_debugfs_show_regset32(struct seq_file *s, void *data)
 {
-	struct sde_debugfs_regset32 *regset = s->private;
+	struct sde_debugfs_regset32 *regset;
+	struct sde_kms *sde_kms;
+	struct drm_device *dev;
+	struct msm_drm_private *priv;
 	void __iomem *base;
-	int i;
+	uint32_t i, addr;
 
-	base = regset->base + regset->offset;
+	if (!s || !s->private)
+		return 0;
 
-	for (i = 0; i < regset->blk_len; i += 4)
-		seq_printf(s, "[%x] 0x%08x\n",
-				regset->offset + i, readl_relaxed(base + i));
+	regset = s->private;
+
+	sde_kms = regset->sde_kms;
+	if (!sde_kms || !sde_kms->mmio)
+		return 0;
+
+	dev = sde_kms->dev;
+	if (!dev)
+		return 0;
+
+	priv = dev->dev_private;
+	if (!priv)
+		return 0;
+
+	base = sde_kms->mmio + regset->offset;
+
+	/* insert padding spaces, if needed */
+	if (regset->offset & 0xF) {
+		seq_printf(s, "[%x]", regset->offset & ~0xF);
+		for (i = 0; i < (regset->offset & 0xF); i += 4)
+			seq_puts(s, "         ");
+	}
+
+	if (sde_power_resource_enable(&priv->phandle,
+				sde_kms->core_client, true)) {
+		seq_puts(s, "failed to enable sde clocks\n");
+		return 0;
+	}
+
+	/* main register output */
+	for (i = 0; i < regset->blk_len; i += 4) {
+		addr = regset->offset + i;
+		if ((addr & 0xF) == 0x0)
+			seq_printf(s, i ? "\n[%x]" : "[%x]", addr);
+		seq_printf(s, " %08x", readl_relaxed(base + i));
+	}
+	seq_puts(s, "\n");
+	sde_power_resource_enable(&priv->phandle, sde_kms->core_client, false);
 
 	return 0;
 }
@@ -79,19 +118,19 @@
 };
 
 void sde_debugfs_setup_regset32(struct sde_debugfs_regset32 *regset,
-		uint32_t offset, uint32_t length, void __iomem *base)
+		uint32_t offset, uint32_t length, struct sde_kms *sde_kms)
 {
 	if (regset) {
 		regset->offset = offset;
 		regset->blk_len = length;
-		regset->base = base;
+		regset->sde_kms = sde_kms;
 	}
 }
 
 void *sde_debugfs_create_regset32(const char *name, umode_t mode,
 		void *parent, struct sde_debugfs_regset32 *regset)
 {
-	if (!name || !regset || !regset->base || !regset->blk_len)
+	if (!name || !regset || !regset->sde_kms || !regset->blk_len)
 		return NULL;
 
 	/* make sure offset is a multiple of 4 */
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h
index 0928b95..c485bea 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.h
+++ b/drivers/gpu/drm/msm/sde/sde_kms.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -216,7 +216,7 @@
 struct sde_debugfs_regset32 {
 	uint32_t offset;
 	uint32_t blk_len;
-	void __iomem *base;
+	struct sde_kms *sde_kms;
 };
 
 /**
@@ -226,10 +226,10 @@
  * @regset: opaque register definition structure
  * @offset: sub-block offset
  * @length: sub-block length, in bytes
- * @base: base IOMEM address
+ * @sde_kms: pointer to sde kms structure
  */
 void sde_debugfs_setup_regset32(struct sde_debugfs_regset32 *regset,
-		uint32_t offset, uint32_t length, void __iomem *base);
+		uint32_t offset, uint32_t length, struct sde_kms *sde_kms);
 
 /**
  * sde_debugfs_create_regset32 - Create register read back file for debugfs
diff --git a/drivers/gpu/drm/msm/sde/sde_plane.c b/drivers/gpu/drm/msm/sde/sde_plane.c
index 12f6da1..329e454 100644
--- a/drivers/gpu/drm/msm/sde/sde_plane.c
+++ b/drivers/gpu/drm/msm/sde/sde_plane.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1890,14 +1890,14 @@
 			sde_debugfs_setup_regset32(&psde->debugfs_src,
 					sblk->src_blk.base + cfg->base,
 					sblk->src_blk.len,
-					kms->mmio);
+					kms);
 			sde_debugfs_create_regset32("src_blk", 0444,
 					psde->debugfs_root, &psde->debugfs_src);
 
 			sde_debugfs_setup_regset32(&psde->debugfs_scaler,
 					sblk->scaler_blk.base + cfg->base,
 					sblk->scaler_blk.len,
-					kms->mmio);
+					kms);
 			sde_debugfs_create_regset32("scaler_blk", 0444,
 					psde->debugfs_root,
 					&psde->debugfs_scaler);
@@ -1905,7 +1905,7 @@
 			sde_debugfs_setup_regset32(&psde->debugfs_csc,
 					sblk->csc_blk.base + cfg->base,
 					sblk->csc_blk.len,
-					kms->mmio);
+					kms);
 			sde_debugfs_create_regset32("csc_blk", 0444,
 					psde->debugfs_root, &psde->debugfs_csc);
 		}