The current version checking mechanism works fine for DSI6G blocks. It
doesn't work so well for older generation DSIv2 blocks.

The initial read of REG_DSI_6G_HW_VERSION(offset 0x0) would result in a
read of REG_DSI_CTRL for DSIv2. This register won't necessarily be 0 on
DSIv2. It can be non zero if DSI was previously initialized by the
bootloader.

Instead of reading offset 0x0, we now read offset 0x1f0. For DSIv2, this
register is DSI_VERSION, and is bound to be non-zero. On DSI6G, this
register(offset 0x1f0) is SCRATCH_REGISTER_0, which no one ever seems to
touch, and from all register dumps I'vc seen, holds 0 all the time.

Modify dsi_get_version to read REG_DSI_VERSION to determine whether we
are DSI6G or DSIv2.

Signed-off-by: Archit Taneja <architt at codeaurora.org>
---
 drivers/gpu/drm/msm/dsi/dsi_host.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c 
b/drivers/gpu/drm/msm/dsi/dsi_host.c
index 4c49868..8e8fcc7 100644
--- a/drivers/gpu/drm/msm/dsi/dsi_host.c
+++ b/drivers/gpu/drm/msm/dsi/dsi_host.c
@@ -33,17 +33,24 @@
 static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor)
 {
        u32 ver;
-       u32 ver_6g;

        if (!major || !minor)
                return -EINVAL;

-       /* From DSI6G(v3), addition of a 6G_HW_VERSION register at offset 0
+       /*
+        * From DSI6G(v3), addition of a 6G_HW_VERSION register at offset 0
         * makes all other registers 4-byte shifted down.
+        *
+        * In order to identify between DSI6G(v3) and beyond, and DSIv2 and
+        * older, we read the DSI_VERSION register without any shift(offset
+        * 0x1f0). In the case of DSIv2, this hast to be a non-zero value. In
+        * the case of DSI6G, this has to be zero (the offset points to a
+        * scratch register which we never touch)
         */
-       ver_6g = msm_readl(base + REG_DSI_6G_HW_VERSION);
-       if (ver_6g == 0) {
-               ver = msm_readl(base + REG_DSI_VERSION);
+
+       ver = msm_readl(base + REG_DSI_VERSION);
+       if (ver) {
+               /* older dsi host, there is no register shift */
                ver = FIELD(ver, DSI_VERSION_MAJOR);
                if (ver <= MSM_DSI_VER_MAJOR_V2) {
                        /* old versions */
@@ -54,12 +61,17 @@ static int dsi_get_version(const void __iomem *base, u32 
*major, u32 *minor)
                        return -EINVAL;
                }
        } else {
+               /*
+                * newer host, offset 0 has 6G_HW_VERSION, the rest of the
+                * registers are shifted down, read DSI_VERSION again with
+                * the shifted offset
+                */
                ver = msm_readl(base + DSI_6G_REG_SHIFT + REG_DSI_VERSION);
                ver = FIELD(ver, DSI_VERSION_MAJOR);
                if (ver == MSM_DSI_VER_MAJOR_6G) {
                        /* 6G version */
                        *major = ver;
-                       *minor = ver_6g;
+                       *minor = msm_readl(base + REG_DSI_6G_HW_VERSION);
                        return 0;
                } else {
                        return -EINVAL;
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

Reply via email to