drm/msm/dsi: Use a better way to figure out DSI version
authorArchit Taneja <architt@codeaurora.org>
Fri, 9 Oct 2015 05:40:59 +0000 (11:10 +0530)
committerRob Clark <robdclark@gmail.com>
Mon, 14 Dec 2015 15:40:18 +0000 (10:40 -0500)
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@codeaurora.org>
Signed-off-by: Rob Clark <robdclark@gmail.com>
drivers/gpu/drm/msm/dsi/dsi_host.c

index aec97c8e5ac4cd65bdd7c03cb59a69ca0655e562..7a365df91c530198de73d5d523371bfb4543dde1 100644 (file)
 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;