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);
}