mmc: sdhci-msm: Add support for vendor capabilities registers

Message ID 1426769720-18657-1-git-send-email-georgi.djakov@linaro.org
State New
Headers show

Commit Message

Georgi Djakov March 19, 2015, 12:55 p.m.
Some versions of this controller do not advertise their 3.0v and
8bit bus-width support capabilities. It is required to explicitly
set these capabilities for the specific controller versions.

Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
---
Tested on msm8916-mtp board.

 drivers/mmc/host/sdhci-msm.c |   29 ++++++++++++++++++++++++++++-
 1 file changed, 28 insertions(+), 1 deletion(-)

--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Georgi Djakov March 19, 2015, 4:21 p.m. | #1
Hi Bjorn,
Thanks for taking a look.

On 03/19/2015 05:36 PM, Bjorn Andersson wrote:
> On Thu, Mar 19, 2015 at 5:55 AM, Georgi Djakov <georgi.djakov@linaro.org> wrote:
> [..]
> 
>> @@ -516,6 +527,22 @@ static int sdhci_msm_probe(struct platform_device *pdev)
>>                 host_version, ((host_version & SDHCI_VENDOR_VER_MASK) >>
>>                                SDHCI_VENDOR_VER_SHIFT));
>>
>> +       core_version = readl_relaxed(msm_host->core_mem + CORE_MCI_VERSION);
>> +       core_major = (core_version & CORE_VERSION_MAJOR_MASK) >>
>> +                     CORE_VERSION_MAJOR_SHIFT;
>> +       core_minor = core_version & CORE_VERSION_MINOR_MASK;
>> +       dev_dbg(&pdev->dev, "MCI Version: 0x%08x, major: 0x%04x, minor: 0x%02x\n",
>> +               core_version, core_major, core_minor);
>> +
>> +       /*
>> +        * Support for 3v and 8bit bus-width is not advertised by some
>> +        * controller versions and must be explicitly enabled.
>> +        */
>> +       if (core_major >= 1 && core_minor != 0x11 && core_minor != 0x12)
>> +               writel_relaxed(readl_relaxed(host->ioaddr + SDHCI_CAPABILITIES)
>> +                              | CORE_3_0V_SUPPORT | CORE_8_BIT_SUPPORT,
>> +                              host->ioaddr + CORE_VENDOR_SPEC_CAPABILITIES0);
> 
> Please split this into read, modify, write statements and put braces around it.

Ok, i will.

> 
>> +
> 
> Does the 8916 board you have work without bumping the
> regulator_set_load() (previously regulator_set_optimum_mode())? None
> of my 8974 boards work reliably without it.

My 8916 board seems to be working fine with this, at least when doing basic tests
like mounting filesystems and file transfers. I'm not calling any regulator_set_load()
functions. Is your board a dragonboard or something else? If you are doing any
specific tests maybe i can try the same on my board?

Thanks,
Georgi
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Georgi Djakov March 20, 2015, 3:23 p.m. | #2
On 03/19/2015 07:55 PM, Bjorn Andersson wrote:
> On Thu, Mar 19, 2015 at 9:21 AM, Georgi Djakov <georgi.djakov@linaro.org> wrote:
> [..]
>>> Does the 8916 board you have work without bumping the
>>> regulator_set_load() (previously regulator_set_optimum_mode())? None
>>> of my 8974 boards work reliably without it.
>>
>> My 8916 board seems to be working fine with this, at least when doing basic tests
>> like mounting filesystems and file transfers. I'm not calling any regulator_set_load()
>> functions. Is your board a dragonboard or something else? If you are doing any
>> specific tests maybe i can try the same on my board?
>>
> 
> My test setup is Xperia Z1, where I get issues when running with
> hs200. On Xperia Z3 i can't even read out the partition table during
> boot. I'm not sure what causes the difference to the dragonboard -
> perhaps just different memories.
> 

Thanks for the information. Currently i do not notice such issues, but
however i will do some more testing.

> So I have a patch where I hook up the mmc framework with some calls to
> regulator_set_load(), but it need some more love before I can send it
> out. I postponed it due to the rework of regulator_set_optimum_mode()
> that I did.

Ok, sounds good. I can test it on a few boards that i have.

Thanks,
Georgi
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Patch

diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
index 3d32ce896b09..80d9ca7cb1e6 100644
--- a/drivers/mmc/host/sdhci-msm.c
+++ b/drivers/mmc/host/sdhci-msm.c
@@ -41,6 +41,15 @@ 
 #define CORE_VENDOR_SPEC	0x10c
 #define CORE_CLK_PWRSAVE	BIT(1)
 
+#define CORE_MCI_VERSION		0x050
+#define CORE_VERSION_MAJOR_SHIFT	28
+#define CORE_VERSION_MAJOR_MASK		(0xf << CORE_VERSION_MAJOR_SHIFT)
+#define CORE_VERSION_MINOR_MASK		0xff
+
+#define CORE_VENDOR_SPEC_CAPABILITIES0	0x11c
+#define CORE_8_BIT_SUPPORT		BIT(18)
+#define CORE_3_0V_SUPPORT		BIT(25)
+
 #define CDR_SELEXT_SHIFT	20
 #define CDR_SELEXT_MASK		(0xf << CDR_SELEXT_SHIFT)
 #define CMUX_SHIFT_PHASE_SHIFT	24
@@ -426,7 +435,9 @@  static int sdhci_msm_probe(struct platform_device *pdev)
 	struct sdhci_msm_host *msm_host;
 	struct resource *core_memres;
 	int ret;
-	u16 host_version;
+	u16 host_version, core_minor;
+	u32 core_version;
+	u8 core_major;
 
 	msm_host = devm_kzalloc(&pdev->dev, sizeof(*msm_host), GFP_KERNEL);
 	if (!msm_host)
@@ -516,6 +527,22 @@  static int sdhci_msm_probe(struct platform_device *pdev)
 		host_version, ((host_version & SDHCI_VENDOR_VER_MASK) >>
 			       SDHCI_VENDOR_VER_SHIFT));
 
+	core_version = readl_relaxed(msm_host->core_mem + CORE_MCI_VERSION);
+	core_major = (core_version & CORE_VERSION_MAJOR_MASK) >>
+		      CORE_VERSION_MAJOR_SHIFT;
+	core_minor = core_version & CORE_VERSION_MINOR_MASK;
+	dev_dbg(&pdev->dev, "MCI Version: 0x%08x, major: 0x%04x, minor: 0x%02x\n",
+		core_version, core_major, core_minor);
+
+	/*
+	 * Support for 3v and 8bit bus-width is not advertised by some
+	 * controller versions and must be explicitly enabled.
+	 */
+	if (core_major >= 1 && core_minor != 0x11 && core_minor != 0x12)
+		writel_relaxed(readl_relaxed(host->ioaddr + SDHCI_CAPABILITIES)
+			       | CORE_3_0V_SUPPORT | CORE_8_BIT_SUPPORT,
+			       host->ioaddr + CORE_VENDOR_SPEC_CAPABILITIES0);
+
 	ret = sdhci_add_host(host);
 	if (ret)
 		goto clk_disable;