From 648d5063727ae3f555317baf6a5d2dc1e8e8d2a5 Mon Sep 17 00:00:00 2001 From: Archit Taneja Date: Fri, 9 Oct 2015 11:10:59 +0530 Subject: [PATCH] drm/msm/dsi: Use a better way to figure out DSI version 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 Signed-off-by: Rob Clark --- 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 aec97c8e5ac4..7a365df91c53 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; -- 2.20.1