* [PATCH V2 3/9] mmc: sdhci: Fix tuning reset after exhausting the maximum number of loops
From: Adrian Hunter @ 2016-12-02 13:14 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc
In-Reply-To: <1480684467-26833-1-git-send-email-adrian.hunter@intel.com>
If the driver has exhausted the maximum number of tuning loops, then fixed
sampling is used. To do that both SDHCI_CTRL_TUNED_CLK and
SDHCI_CTRL_EXEC_TUNING must be reset to 0, but only SDHCI_CTRL_TUNED_CLK
was being reset. Reset SDHCI_CTRL_EXEC_TUNING to 0 also.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
drivers/mmc/host/sdhci.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 1d72a51287d4..ad2f2c6113e4 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2134,6 +2134,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
*/
if (tuning_loop_counter < 0) {
ctrl &= ~SDHCI_CTRL_TUNED_CLK;
+ ctrl &= ~SDHCI_CTRL_EXEC_TUNING;
sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
}
if (!(ctrl & SDHCI_CTRL_TUNED_CLK)) {
--
1.9.1
^ permalink raw reply related
* [PATCH V2 0/9] mmc: sdhci: Fix recovery from tuning timeout
From: Adrian Hunter @ 2016-12-02 13:14 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc
Hi
Here are some small SDHCI tuning-related fixes and some clean-ups.
Changes in V2:
Added clean-up patches
Adrian Hunter (9):
Revert "mmc: sdhci: Reset cmd and data circuits after tuning failure"
mmc: sdhci: Fix recovery from tuning timeout
mmc: sdhci: Fix tuning reset after exhausting the maximum number of loops
mmc: sdhci: Always allow tuning to fall back to fixed sampling
mmc: mmc: Introduce mmc_abort_tuning()
mmc: sdhci: Use mmc_abort_tuning()
mmc: sdhci: Factor out tuning helper functions
mmc: sdhci: Simplify tuning block size logic
mmc: sdhci: Tidy tuning loop
drivers/mmc/core/mmc_ops.c | 25 ++++
drivers/mmc/host/sdhci.c | 278 ++++++++++++++++++++++++---------------------
include/linux/mmc/core.h | 1 +
3 files changed, 173 insertions(+), 131 deletions(-)
Regards
Adrian
^ permalink raw reply
* [PATCH V2 1/9] Revert "mmc: sdhci: Reset cmd and data circuits after tuning failure"
From: Adrian Hunter @ 2016-12-02 13:14 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc
In-Reply-To: <1480684467-26833-1-git-send-email-adrian.hunter@intel.com>
This reverts commit fe5fb2e3b58f ("mmc: sdhci: Reset cmd and data circuits
after tuning failure").
A better fix is available, and it will be applied to older stable releases,
so get this out of the way by reverting it.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: stable@vger.kernel.org # v4.9+
---
drivers/mmc/host/sdhci.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 7f2526c9572f..e761fe2aa99e 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2090,10 +2090,6 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
if (!host->tuning_done) {
pr_info(DRIVER_NAME ": Timeout waiting for Buffer Read Ready interrupt during tuning procedure, falling back to fixed sampling clock\n");
-
- sdhci_do_reset(host, SDHCI_RESET_CMD);
- sdhci_do_reset(host, SDHCI_RESET_DATA);
-
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
ctrl &= ~SDHCI_CTRL_TUNED_CLK;
ctrl &= ~SDHCI_CTRL_EXEC_TUNING;
--
1.9.1
^ permalink raw reply related
* [PATCH V2 2/9] mmc: sdhci: Fix recovery from tuning timeout
From: Adrian Hunter @ 2016-12-02 13:14 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc
In-Reply-To: <1480684467-26833-1-git-send-email-adrian.hunter@intel.com>
Clearing the tuning bits should reset the tuning circuit. However there is
more to do. Reset the command and data lines for good measure, and then
for eMMC ensure the card is not still trying to process a tuning command by
sending a stop command.
Note the JEDEC eMMC specification says the stop command (CMD12) can be used
to stop a tuning command (CMD21) whereas the SD specification is silent on
the subject with respect to the SD tuning command (CMD19). Considering that
CMD12 is not a valid SDIO command, the stop command is sent only when the
tuning command is CMD21 i.e. for eMMC. That addresses cases seen so far
which have been on eMMC.
Note that this replaces the commit fe5fb2e3b58f ("mmc: sdhci: Reset cmd and
data circuits after tuning failure") which is being reverted for v4.9+.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Dan O'Donovan <dan@emutex.com>
Cc: stable@vger.kernel.org
---
drivers/mmc/host/sdhci.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index e761fe2aa99e..1d72a51287d4 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2095,7 +2095,27 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
ctrl &= ~SDHCI_CTRL_EXEC_TUNING;
sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+ sdhci_do_reset(host, SDHCI_RESET_CMD);
+ sdhci_do_reset(host, SDHCI_RESET_DATA);
+
err = -EIO;
+
+ if (cmd.opcode != MMC_SEND_TUNING_BLOCK_HS200)
+ goto out;
+
+ sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
+
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.opcode = MMC_STOP_TRANSMISSION;
+ cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
+ cmd.busy_timeout = 50;
+ mmc_wait_for_cmd(mmc, &cmd, 0);
+
+ spin_lock_irqsave(&host->lock, flags);
+
goto out;
}
--
1.9.1
^ permalink raw reply related
* [PATCH V2 1/1] mmc: mmc: Relax checking for switch errors after HS200 switch
From: Adrian Hunter @ 2016-12-02 11:16 UTC (permalink / raw)
To: Ulf Hansson
Cc: linux-mmc, Jaehoon Chung, Chaotian Jing, Stephen Boyd,
Michael Walle, Yong Mao, Shawn Lin
In-Reply-To: <1480677395-14169-1-git-send-email-adrian.hunter@intel.com>
The JEDEC specification indicates CMD13 can be used after a HS200 switch
to check for errors. However in practice some boards experience CRC errors
in the CMD13 response. Consequently, for HS200, CRC errors are not a
reliable way to know the switch failed. If there really is a problem, we
would expect tuning will fail and the result ends up the same. So change
the error condition to ignore CRC errors in that case.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
drivers/mmc/core/mmc.c | 15 +++++++++++++--
drivers/mmc/core/mmc_ops.c | 9 ++++++++-
drivers/mmc/core/mmc_ops.h | 1 +
3 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index 033e00abe93f..b61b52f9da3d 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -1240,7 +1240,12 @@ int mmc_hs400_to_hs200(struct mmc_card *card)
mmc_set_timing(host, MMC_TIMING_MMC_HS200);
- err = mmc_switch_status(card);
+ /*
+ * For HS200, CRC errors are not a reliable way to know the switch
+ * failed. If there really is a problem, we would expect tuning will
+ * fail and the result ends up the same.
+ */
+ err = __mmc_switch_status(card, false);
if (err)
goto out_err;
@@ -1403,7 +1408,13 @@ static int mmc_select_hs200(struct mmc_card *card)
old_timing = host->ios.timing;
mmc_set_timing(host, MMC_TIMING_MMC_HS200);
- err = mmc_switch_status(card);
+ /*
+ * For HS200, CRC errors are not a reliable way to know the
+ * switch failed. If there really is a problem, we would expect
+ * tuning will fail and the result ends up the same.
+ */
+ err = __mmc_switch_status(card, false);
+
/*
* mmc_select_timing() assumes timing has not changed if
* it is a switch error.
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index cb7006feb5c4..81ce63bb0773 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -431,18 +431,25 @@ static int mmc_switch_status_error(struct mmc_host *host, u32 status)
}
/* Caller must hold re-tuning */
-int mmc_switch_status(struct mmc_card *card)
+int __mmc_switch_status(struct mmc_card *card, bool crc_err_fatal)
{
u32 status;
int err;
err = mmc_send_status(card, &status);
+ if (!crc_err_fatal && err == -EILSEQ)
+ return 0;
if (err)
return err;
return mmc_switch_status_error(card->host, status);
}
+int mmc_switch_status(struct mmc_card *card)
+{
+ return __mmc_switch_status(card, true);
+}
+
static int mmc_poll_for_busy(struct mmc_card *card, unsigned int timeout_ms,
bool send_status, bool retry_crc_err)
{
diff --git a/drivers/mmc/core/mmc_ops.h b/drivers/mmc/core/mmc_ops.h
index 761cb69c46af..abd525ed74be 100644
--- a/drivers/mmc/core/mmc_ops.h
+++ b/drivers/mmc/core/mmc_ops.h
@@ -28,6 +28,7 @@
int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status);
int mmc_can_ext_csd(struct mmc_card *card);
int mmc_switch_status(struct mmc_card *card);
+int __mmc_switch_status(struct mmc_card *card, bool crc_err_fatal);
int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
unsigned int timeout_ms, unsigned char timing,
bool use_busy_signal, bool send_status, bool retry_crc_err);
--
1.9.1
^ permalink raw reply related
* [PATCH V2 0/1] mmc: mmc: Relax checking for switch errors after HS200 switch
From: Adrian Hunter @ 2016-12-02 11:16 UTC (permalink / raw)
To: Ulf Hansson
Cc: linux-mmc, Jaehoon Chung, Chaotian Jing, Stephen Boyd,
Michael Walle, Yong Mao, Shawn Lin
Hi
Here is V2 of a patch for an issue we discussed briefly here:
https://marc.info/?l=linux-mmc&m=147937852408104
and here:
https://marc.info/?l=linux-mmc&m=148060118031658
Changes in V2:
Add __mmc_switch_status() to use a parameter bool crc_err_fatal
Adrian Hunter (1):
mmc: mmc: Relax checking for switch errors after HS200 switch
drivers/mmc/core/mmc.c | 15 +++++++++++++--
drivers/mmc/core/mmc_ops.c | 9 ++++++++-
drivers/mmc/core/mmc_ops.h | 1 +
3 files changed, 22 insertions(+), 3 deletions(-)
Regards
Adrian
^ permalink raw reply
* Re: [PATCH 4/4] mmc: pwrseq-simple: add disable-post-power-on option
From: Matt Ranostay @ 2016-12-02 9:06 UTC (permalink / raw)
To: Ulf Hansson, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA, Tony Lindgren, Liam Breck
In-Reply-To: <CAPDyKFp9t1SEwQZ=uTHegbpgxxevQEy4kC=wPkc8Bo16030MNg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Fri, Dec 2, 2016 at 12:28 AM, Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> On 2 December 2016 at 08:22, Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org> wrote:
>>
>>
>>> On Dec 1, 2016, at 23:13, Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
>>>
>>>> On 2 December 2016 at 07:17, Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org> wrote:
>>>> Add optional device-post-power-on parameters to disable post_power_on
>>>> function from being called since this breaks some device.
>>>>
>>>> Cc: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
>>>> Cc: Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>>> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
>>>> ---
>>>> Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++
>>>> drivers/mmc/core/pwrseq_simple.c | 7 +++++++
>>>> 2 files changed, 9 insertions(+)
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
>>>> index bea306d772d1..09fa153f743e 100644
>>>> --- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
>>>> +++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
>>>> @@ -24,6 +24,8 @@ Optional properties:
>>>> de-asserting the reset-gpios (if any)
>>>> - invert-off-state: Invert the power down state for the reset-gpios (if any)
>>>> and pwrdn-gpios (if any)
>>>> +- disable-post-power-on : Avoid post_power_on function from being called since
>>>> + this breaks some devices
>>>
>>> This is a bit weird. I would like to avoid this, if possible.
>>>
>>> Perhaps if you simply describe the sequence in detail for your device
>>> we can figure out the best option together.
>>
>> Yeah I know it is a bit weird but we need to keep that reset pin high for at least some time after pre power on. So any case it would be another property
>
> This went offlist, please resend.
>
> Moreover, please try to describe the sequence you need in detail
> according to your HW spec.
>
Yeah oops....
So basically we need to drive the reset and powerdown lines high with
a 300 milliseconds delay between both...
can't have the reset line low with post power on (pretty sure but
would need a delay anyway), and we need both reset + powerdown line
set low on powerdown.
So the power down sequence would need to be reversed for this
application in pwrseq-simple.
> Br
> Uffe
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH RFC 0/5] mmc: sdhci: Tidy tuning
From: Adrian Hunter @ 2016-12-02 8:28 UTC (permalink / raw)
To: Ulf Hansson; +Cc: linux-mmc
In-Reply-To: <CAPDyKFqbpGQuzirU98MTX4TXjn6inDY8K8NozrSwBZVJGMDyLg@mail.gmail.com>
On 01/12/16 16:57, Ulf Hansson wrote:
> On 1 December 2016 at 15:04, Adrian Hunter <adrian.hunter@intel.com> wrote:
>> Hi
>>
>> Here are some tidy-ups wrt SDHCI tuning. Un-tested so far.
>
> Nice. Thanks!
>
>>
>> Any other suggestions? Otherwise I will test and submit the whole series.
>
> As an additional step, could you try to make use of mmc_send_tuning(),
> instead of sending the command internally from sdhci_send_tuning()?
mmc_send_tuning() is not a good fit. SDHCI tuning command does not have a
data payload (or rather the hardware does it automatically) so unless
mmc_send_tuning() is changed it will return -EIO. If that is changed then,
SDHCI request function needs to be changed to special-case the tuning
command because the interrupt setup is different. Then the problem is that
there is no timeout interrupt so another timer is needed, so a special case
would have to be created for that too.
The current code is much simpler.
^ permalink raw reply
* Re: [PATCH 3/4] mmc: pwrseq-simple: allow inverting of off state logic
From: Matt Ranostay @ 2016-12-02 8:24 UTC (permalink / raw)
To: Ulf Hansson
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Tony Lindgren
In-Reply-To: <313A249C-2BB9-487E-AF75-02ADB8AE83CC-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
On Thu, Dec 1, 2016 at 11:28 PM, Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org> wrote:
>
>
>
>>> On Dec 1, 2016, at 22:57, Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
>>
>>> On 2 December 2016 at 07:17, Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org> wrote:
>>> Some devices need a logic level low instead of high to be in the
>>> off state.
>>>
>>> Cc: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
>>> Cc: Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
>>> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
>>> ---
>>> .../devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++
>>> drivers/mmc/core/pwrseq_simple.c | 15 +++++++++++----
>>> 2 files changed, 13 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
>>> index 703a714201d8..bea306d772d1 100644
>>> --- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
>>> +++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
>>> @@ -22,6 +22,8 @@ Optional properties:
>>> the reset-gpios (if any) are asserted
>>> - post-power-on-delay-ms : Delay in ms after powering the card and
>>> de-asserting the reset-gpios (if any)
>>> +- invert-off-state: Invert the power down state for the reset-gpios (if any)
>>> + and pwrdn-gpios (if any)
>>
>> We already have DT bindings to describe GPIO pins as active high or
>> low. I think we should be able to use that instead, don't you think?
>
> Ah issue is we are using inverse logic in the power down from anything else. But I guess we could read the gpios active high and low stats from device tree and deduce it from that
>
BTW this quirkiness is which why me and Lindgren went the route of an
another pwrseq driver versus hacking the pwrseq-simple initially...
In any case we can change the active high or low in the gpio
descriptors but doesn't change the timing we need or the inverse state
for power down.
Thanks,
Matt
>
>>
>> [...]
>>
>> Kind regards
>> Uffe
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 3/4] mmc: pwrseq-simple: allow inverting of off state logic
From: Matt Ranostay @ 2016-12-02 7:28 UTC (permalink / raw)
To: Ulf Hansson
Cc: devicetree@vger.kernel.org, linux-mmc@vger.kernel.org,
Tony Lindgren
In-Reply-To: <CAPDyKFrYVL52N22JVDA3wiWLAwUhht+6-=fi9kbGA8DYu=zPiA@mail.gmail.com>
Sent from my iPhone
> On Dec 1, 2016, at 22:57, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>
>> On 2 December 2016 at 07:17, Matt Ranostay <matt@ranostay.consulting> wrote:
>> Some devices need a logic level low instead of high to be in the
>> off state.
>>
>> Cc: Tony Lindgren <tony@atomide.com>
>> Cc: Ulf Hansson <ulf.hansson@linaro.org>
>> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
>> ---
>> .../devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++
>> drivers/mmc/core/pwrseq_simple.c | 15 +++++++++++----
>> 2 files changed, 13 insertions(+), 4 deletions(-)
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
>> index 703a714201d8..bea306d772d1 100644
>> --- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
>> +++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
>> @@ -22,6 +22,8 @@ Optional properties:
>> the reset-gpios (if any) are asserted
>> - post-power-on-delay-ms : Delay in ms after powering the card and
>> de-asserting the reset-gpios (if any)
>> +- invert-off-state: Invert the power down state for the reset-gpios (if any)
>> + and pwrdn-gpios (if any)
>
> We already have DT bindings to describe GPIO pins as active high or
> low. I think we should be able to use that instead, don't you think?
Ah issue is we are using inverse logic in the power down from anything else. But I guess we could read the gpios active high and low stats from device tree and deduce it from that
>
> [...]
>
> Kind regards
> Uffe
^ permalink raw reply
* Re: [PATCH 4/4] mmc: pwrseq-simple: add disable-post-power-on option
From: Ulf Hansson @ 2016-12-02 7:13 UTC (permalink / raw)
To: Matt Ranostay
Cc: devicetree@vger.kernel.org, linux-mmc@vger.kernel.org,
Tony Lindgren
In-Reply-To: <1480659462-29536-5-git-send-email-matt@ranostay.consulting>
On 2 December 2016 at 07:17, Matt Ranostay <matt@ranostay.consulting> wrote:
> Add optional device-post-power-on parameters to disable post_power_on
> function from being called since this breaks some device.
>
> Cc: Tony Lindgren <tony@atomide.com>
> Cc: Ulf Hansson <ulf.hansson@linaro.org>
> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
> ---
> Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++
> drivers/mmc/core/pwrseq_simple.c | 7 +++++++
> 2 files changed, 9 insertions(+)
>
> diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
> index bea306d772d1..09fa153f743e 100644
> --- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
> +++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
> @@ -24,6 +24,8 @@ Optional properties:
> de-asserting the reset-gpios (if any)
> - invert-off-state: Invert the power down state for the reset-gpios (if any)
> and pwrdn-gpios (if any)
> +- disable-post-power-on : Avoid post_power_on function from being called since
> + this breaks some devices
This is a bit weird. I would like to avoid this, if possible.
Perhaps if you simply describe the sequence in detail for your device
we can figure out the best option together.
[...]
Kind regards
Uffe
^ permalink raw reply
* Re: [PATCH 3/4] mmc: pwrseq-simple: allow inverting of off state logic
From: Ulf Hansson @ 2016-12-02 6:57 UTC (permalink / raw)
To: Matt Ranostay
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-mmc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Tony Lindgren
In-Reply-To: <1480659462-29536-4-git-send-email-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
On 2 December 2016 at 07:17, Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org> wrote:
> Some devices need a logic level low instead of high to be in the
> off state.
>
> Cc: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
> Cc: Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
> ---
> .../devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++
> drivers/mmc/core/pwrseq_simple.c | 15 +++++++++++----
> 2 files changed, 13 insertions(+), 4 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
> index 703a714201d8..bea306d772d1 100644
> --- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
> +++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
> @@ -22,6 +22,8 @@ Optional properties:
> the reset-gpios (if any) are asserted
> - post-power-on-delay-ms : Delay in ms after powering the card and
> de-asserting the reset-gpios (if any)
> +- invert-off-state: Invert the power down state for the reset-gpios (if any)
> + and pwrdn-gpios (if any)
We already have DT bindings to describe GPIO pins as active high or
low. I think we should be able to use that instead, don't you think?
[...]
Kind regards
Uffe
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 2/4] mmc: pwrseq-simple: add support for power down GPIO pins
From: Ulf Hansson @ 2016-12-02 6:47 UTC (permalink / raw)
To: Matt Ranostay
Cc: devicetree@vger.kernel.org, linux-mmc@vger.kernel.org,
Tony Lindgren
In-Reply-To: <1480659462-29536-3-git-send-email-matt@ranostay.consulting>
On 2 December 2016 at 07:17, Matt Ranostay <matt@ranostay.consulting> wrote:
> Some devices have additional pins that control power but need to
> asserted separately from reset-gpios using a defined time delay.
>
> Cc: Tony Lindgren <tony@atomide.com>
> Cc: Ulf Hansson <ulf.hansson@linaro.org>
> Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
> ---
> .../devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++
> drivers/mmc/core/pwrseq_simple.c | 26 +++++++++++++---------
> 2 files changed, 18 insertions(+), 10 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
> index 88826f7d1d38..703a714201d8 100644
> --- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
> +++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
> @@ -12,6 +12,8 @@ Optional properties:
> at initialization and prior we start the power up procedure of the card.
> They will be de-asserted right after the power has been provided to the
> card.
> +- pwrdn-gpios : contains a list of GPIO specifiers. The pwrdn GPIOs are asserted
> + at initialization and prior we start the power up procedure of the card.
I think "powerdown-gpios" would be better, as Rob earlier also suggested.
Moreover I think the DT doc change be a separate change. This comment
applies to the other changes in this series as well.
[...]
Kind regards
Uffe
^ permalink raw reply
* Re: [PATCH] mmc: sdhci-of-at91: remove bogus MMC_SDHCI_IO_ACCESSORS select
From: Ludovic Desroches @ 2016-12-02 6:41 UTC (permalink / raw)
To: Masahiro Yamada
Cc: linux-mmc, Adrian Hunter, linux-kernel, Stefan Wahren, Al Cooper,
Wolfram Sang, Andrei Pistirica, Simon Horman, Geert Uytterhoeven,
Ulf Hansson
In-Reply-To: <1480565146-4857-1-git-send-email-yamada.masahiro@socionext.com>
On Thu, Dec 01, 2016 at 01:05:46PM +0900, Masahiro Yamada wrote:
> I see no override of read/write callbacks in sdhci-of-at91.c.
>
> Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Acked-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Thanks
> ---
>
> BTW, this config may not be so useful in recent multi-platforms.
> Perhaps, is it better to remove this config entirely instead of
> the AT91 fix only.
>
>
> drivers/mmc/host/Kconfig | 1 -
> 1 file changed, 1 deletion(-)
>
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 39f6f96..8ac1640 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -135,7 +135,6 @@ config MMC_SDHCI_OF_AT91
> tristate "SDHCI OF support for the Atmel SDMMC controller"
> depends on MMC_SDHCI_PLTFM
> depends on OF
> - select MMC_SDHCI_IO_ACCESSORS
> help
> This selects the Atmel SDMMC driver
>
> --
> 2.7.4
>
> --
> 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
^ permalink raw reply
* [PATCH 2/4] mmc: pwrseq-simple: add support for power down GPIO pins
From: Matt Ranostay @ 2016-12-02 6:17 UTC (permalink / raw)
To: devicetree, linux-mmc; +Cc: Matt Ranostay, Tony Lindgren, Ulf Hansson
In-Reply-To: <1480659462-29536-1-git-send-email-matt@ranostay.consulting>
Some devices have additional pins that control power but need to
asserted separately from reset-gpios using a defined time delay.
Cc: Tony Lindgren <tony@atomide.com>
Cc: Ulf Hansson <ulf.hansson@linaro.org>
Signed-off-by: Matt Ranostay <matt@ranostay.consulting>
---
.../devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++
drivers/mmc/core/pwrseq_simple.c | 26 +++++++++++++---------
2 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
index 88826f7d1d38..703a714201d8 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
@@ -12,6 +12,8 @@ Optional properties:
at initialization and prior we start the power up procedure of the card.
They will be de-asserted right after the power has been provided to the
card.
+- pwrdn-gpios : contains a list of GPIO specifiers. The pwrdn GPIOs are asserted
+ at initialization and prior we start the power up procedure of the card.
- clocks : Must contain an entry for the entry in clock-names.
See ../clocks/clock-bindings.txt for details.
- clock-names : Must include the following entry:
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index cb2ba7b11383..adf1f7161fe3 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -30,24 +30,23 @@ struct mmc_pwrseq_simple {
u32 post_power_on_delay_ms;
struct clk *ext_clk;
struct gpio_descs *reset_gpios;
+ struct gpio_descs *pwrdn_gpios;
};
#define to_pwrseq_simple(p) container_of(p, struct mmc_pwrseq_simple, pwrseq)
static void mmc_pwrseq_simple_set_gpios_value(struct mmc_pwrseq_simple *pwrseq,
+ struct gpio_descs *gpios,
int value)
{
- struct gpio_descs *reset_gpios = pwrseq->reset_gpios;
-
- if (!IS_ERR(reset_gpios)) {
+ if (!IS_ERR(gpios)) {
int i;
- int values[reset_gpios->ndescs];
+ int values[gpios->ndescs];
- for (i = 0; i < reset_gpios->ndescs; i++)
+ for (i = 0; i < gpios->ndescs; i++)
values[i] = value;
- gpiod_set_array_value_cansleep(
- reset_gpios->ndescs, reset_gpios->desc, values);
+ gpiod_set_array_value_cansleep(gpios->ndescs, gpios->desc, values);
}
}
@@ -60,17 +59,19 @@ static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host)
pwrseq->clk_enabled = true;
}
- mmc_pwrseq_simple_set_gpios_value(pwrseq, 1);
+ mmc_pwrseq_simple_set_gpios_value(pwrseq, pwrseq->reset_gpios, 1);
if (pwrseq->pre_power_on_delay_ms)
msleep(pwrseq->pre_power_on_delay_ms);
+
+ mmc_pwrseq_simple_set_gpios_value(pwrseq, pwrseq->pwrdn_gpios, 1);
}
static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host)
{
struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
- mmc_pwrseq_simple_set_gpios_value(pwrseq, 0);
+ mmc_pwrseq_simple_set_gpios_value(pwrseq, pwrseq->reset_gpios, 0);
if (pwrseq->post_power_on_delay_ms)
msleep(pwrseq->post_power_on_delay_ms);
@@ -80,12 +81,14 @@ static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
{
struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
- mmc_pwrseq_simple_set_gpios_value(pwrseq, 1);
+ mmc_pwrseq_simple_set_gpios_value(pwrseq, pwrseq->reset_gpios, 1);
+ mmc_pwrseq_simple_set_gpios_value(pwrseq, pwrseq->pwrdn_gpios, 1);
if (!IS_ERR(pwrseq->ext_clk) && pwrseq->clk_enabled) {
clk_disable_unprepare(pwrseq->ext_clk);
pwrseq->clk_enabled = false;
}
+
}
static const struct mmc_pwrseq_ops mmc_pwrseq_simple_ops = {
@@ -121,6 +124,9 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev)
return PTR_ERR(pwrseq->reset_gpios);
}
+ pwrseq->pwrdn_gpios = devm_gpiod_get_array(dev, "pwrdn",
+ GPIOD_OUT_HIGH);
+
device_property_read_u32(dev, "pre-power-on-delay-ms",
&pwrseq->pre_power_on_delay_ms);
--
2.7.4
^ permalink raw reply related
* [PATCH 4/4] mmc: pwrseq-simple: add disable-post-power-on option
From: Matt Ranostay @ 2016-12-02 6:17 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA
Cc: Matt Ranostay, Tony Lindgren, Ulf Hansson
In-Reply-To: <1480659462-29536-1-git-send-email-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
Add optional device-post-power-on parameters to disable post_power_on
function from being called since this breaks some device.
Cc: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
Cc: Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
---
Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++
drivers/mmc/core/pwrseq_simple.c | 7 +++++++
2 files changed, 9 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
index bea306d772d1..09fa153f743e 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
@@ -24,6 +24,8 @@ Optional properties:
de-asserting the reset-gpios (if any)
- invert-off-state: Invert the power down state for the reset-gpios (if any)
and pwrdn-gpios (if any)
+- disable-post-power-on : Avoid post_power_on function from being called since
+ this breaks some devices
Example:
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index 857dde3e0456..d34084c51f9c 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -26,6 +26,7 @@
struct mmc_pwrseq_simple {
struct mmc_pwrseq pwrseq;
bool clk_enabled;
+ bool disable_post_power_on;
bool invert_off_state;
u32 pre_power_on_delay_ms;
u32 post_power_on_delay_ms;
@@ -72,6 +73,9 @@ static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host)
{
struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
+ if (pwrseq->disable_post_power_on)
+ return;
+
mmc_pwrseq_simple_set_gpios_value(pwrseq, pwrseq->reset_gpios, 0);
if (pwrseq->post_power_on_delay_ms)
@@ -139,6 +143,9 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev)
device_property_read_u32(dev, "post-power-on-delay-ms",
&pwrseq->post_power_on_delay_ms);
+ if (device_property_read_bool(dev, "disable-post-power-on"))
+ pwrseq->disable_post_power_on = true;
+
pwrseq->pwrseq.dev = dev;
pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops;
pwrseq->pwrseq.owner = THIS_MODULE;
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 3/4] mmc: pwrseq-simple: allow inverting of off state logic
From: Matt Ranostay @ 2016-12-02 6:17 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA
Cc: Matt Ranostay, Tony Lindgren, Ulf Hansson
In-Reply-To: <1480659462-29536-1-git-send-email-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
Some devices need a logic level low instead of high to be in the
off state.
Cc: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
Cc: Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
---
.../devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++
drivers/mmc/core/pwrseq_simple.c | 15 +++++++++++----
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
index 703a714201d8..bea306d772d1 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
@@ -22,6 +22,8 @@ Optional properties:
the reset-gpios (if any) are asserted
- post-power-on-delay-ms : Delay in ms after powering the card and
de-asserting the reset-gpios (if any)
+- invert-off-state: Invert the power down state for the reset-gpios (if any)
+ and pwrdn-gpios (if any)
Example:
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index adf1f7161fe3..857dde3e0456 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -26,6 +26,7 @@
struct mmc_pwrseq_simple {
struct mmc_pwrseq pwrseq;
bool clk_enabled;
+ bool invert_off_state;
u32 pre_power_on_delay_ms;
u32 post_power_on_delay_ms;
struct clk *ext_clk;
@@ -80,9 +81,10 @@ static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host)
static void mmc_pwrseq_simple_power_off(struct mmc_host *host)
{
struct mmc_pwrseq_simple *pwrseq = to_pwrseq_simple(host->pwrseq);
+ unsigned int off_state = !(pwrseq->invert_off_state);
- mmc_pwrseq_simple_set_gpios_value(pwrseq, pwrseq->reset_gpios, 1);
- mmc_pwrseq_simple_set_gpios_value(pwrseq, pwrseq->pwrdn_gpios, 1);
+ mmc_pwrseq_simple_set_gpios_value(pwrseq, pwrseq->reset_gpios, off_state);
+ mmc_pwrseq_simple_set_gpios_value(pwrseq, pwrseq->pwrdn_gpios, off_state);
if (!IS_ERR(pwrseq->ext_clk) && pwrseq->clk_enabled) {
clk_disable_unprepare(pwrseq->ext_clk);
@@ -107,6 +109,7 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev)
{
struct mmc_pwrseq_simple *pwrseq;
struct device *dev = &pdev->dev;
+ bool invert_off_state = false;
pwrseq = devm_kzalloc(dev, sizeof(*pwrseq), GFP_KERNEL);
if (!pwrseq)
@@ -116,8 +119,11 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev)
if (IS_ERR(pwrseq->ext_clk) && PTR_ERR(pwrseq->ext_clk) != -ENOENT)
return PTR_ERR(pwrseq->ext_clk);
+ if (device_property_read_bool(dev, "invert-off-state"))
+ invert_off_state = true;
+
pwrseq->reset_gpios = devm_gpiod_get_array(dev, "reset",
- GPIOD_OUT_HIGH);
+ invert_off_state ? GPIOD_OUT_LOW : GPIOD_OUT_HIGH);
if (IS_ERR(pwrseq->reset_gpios) &&
PTR_ERR(pwrseq->reset_gpios) != -ENOENT &&
PTR_ERR(pwrseq->reset_gpios) != -ENOSYS) {
@@ -125,7 +131,7 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev)
}
pwrseq->pwrdn_gpios = devm_gpiod_get_array(dev, "pwrdn",
- GPIOD_OUT_HIGH);
+ invert_off_state ? GPIOD_OUT_LOW : GPIOD_OUT_HIGH);
device_property_read_u32(dev, "pre-power-on-delay-ms",
&pwrseq->pre_power_on_delay_ms);
@@ -136,6 +142,7 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev)
pwrseq->pwrseq.dev = dev;
pwrseq->pwrseq.ops = &mmc_pwrseq_simple_ops;
pwrseq->pwrseq.owner = THIS_MODULE;
+ pwrseq->invert_off_state = invert_off_state;
platform_set_drvdata(pdev, pwrseq);
return mmc_pwrseq_register(&pwrseq->pwrseq);
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 1/4] mmc: pwrseq-simple: add an optional pre-power-on-delay
From: Matt Ranostay @ 2016-12-02 6:17 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA
Cc: Matt Ranostay, Tony Lindgren, Ulf Hansson
In-Reply-To: <1480659462-29536-1-git-send-email-matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
Some devices need some time between asserting reset-gpios before can
receive sdio commands.
This commits adds a pre-power-on-delay-ms devicetree property to
mmc-pwrseq-simple for use with such devices.
Cc: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
Cc: Ulf Hansson <ulf.hansson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
Signed-off-by: Matt Ranostay <matt-sk+viVC6FLCDq+mSdOJa79kegs52MxvZ@public.gmane.org>
---
Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 2 ++
drivers/mmc/core/pwrseq_simple.c | 7 +++++++
2 files changed, 9 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
index e25436861867..88826f7d1d38 100644
--- a/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
+++ b/Documentation/devicetree/bindings/mmc/mmc-pwrseq-simple.txt
@@ -16,6 +16,8 @@ Optional properties:
See ../clocks/clock-bindings.txt for details.
- clock-names : Must include the following entry:
"ext_clock" (External clock provided to the card).
+- pre-power-on-delay-ms : Delay in ms before powering the card which
+ the reset-gpios (if any) are asserted
- post-power-on-delay-ms : Delay in ms after powering the card and
de-asserting the reset-gpios (if any)
diff --git a/drivers/mmc/core/pwrseq_simple.c b/drivers/mmc/core/pwrseq_simple.c
index 1304160de168..cb2ba7b11383 100644
--- a/drivers/mmc/core/pwrseq_simple.c
+++ b/drivers/mmc/core/pwrseq_simple.c
@@ -26,6 +26,7 @@
struct mmc_pwrseq_simple {
struct mmc_pwrseq pwrseq;
bool clk_enabled;
+ u32 pre_power_on_delay_ms;
u32 post_power_on_delay_ms;
struct clk *ext_clk;
struct gpio_descs *reset_gpios;
@@ -60,6 +61,9 @@ static void mmc_pwrseq_simple_pre_power_on(struct mmc_host *host)
}
mmc_pwrseq_simple_set_gpios_value(pwrseq, 1);
+
+ if (pwrseq->pre_power_on_delay_ms)
+ msleep(pwrseq->pre_power_on_delay_ms);
}
static void mmc_pwrseq_simple_post_power_on(struct mmc_host *host)
@@ -117,6 +121,9 @@ static int mmc_pwrseq_simple_probe(struct platform_device *pdev)
return PTR_ERR(pwrseq->reset_gpios);
}
+ device_property_read_u32(dev, "pre-power-on-delay-ms",
+ &pwrseq->pre_power_on_delay_ms);
+
device_property_read_u32(dev, "post-power-on-delay-ms",
&pwrseq->post_power_on_delay_ms);
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 0/4] mmc: pwrseq-simple: add various functionality for devices
From: Matt Ranostay @ 2016-12-02 6:17 UTC (permalink / raw)
To: devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-mmc-u79uwXL29TY76Z2rM5mHXA
Cc: Matt Ranostay
Primarily these additions are used with wifi cards that have an
power down pin, and timing constraints betweens assertions/deassertions.
Matt Ranostay (4):
mmc: pwrseq-simple: add an optional pre-power-on-delay
mmc: pwrseq-simple: add support for power down GPIO pins
mmc: pwrseq-simple: allow inverting of off state logic
mmc: pwrseq-simple: add disable-post-power-on option
.../devicetree/bindings/mmc/mmc-pwrseq-simple.txt | 8 ++++
drivers/mmc/core/pwrseq_simple.c | 49 +++++++++++++++++-----
2 files changed, 46 insertions(+), 11 deletions(-)
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [RFC] mmc: tmio: use SDIO master interrupt bit only when allowed
From: Yasushi SHOJI @ 2016-12-02 5:57 UTC (permalink / raw)
To: wsa+renesas; +Cc: linux-mmc, linux-renesas-soc
In-Reply-To: <20161201150813.13058-1-wsa+renesas@sang-engineering.com>
On Fri, 02 Dec 2016 00:08:13 +0900,
Wolfram Sang wrote:
>
> The master bit to enable SDIO interrupts can only be accessed if
> SCLKDIVEN bit allows that. However, the core uses the SDIO enable
> callback at times when SCLKDIVEN forbids the change. This leads to
> "timeout waiting for SD bus idle" messages.
>
> We now activate the master bit in probe once if SDIO is supported. IRQ
> en-/disabling will be done now by the individual IRQ enablement bits
> only.
>
> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
> ---
>
> Compile tested only, due to no testcase.
We've reviewed and tested your patch. It looks good and works fine
under the condition we had.
Reviewed-by: Yasushi SHOJI <yashi@atmark-techno.com>
Cc: stable@vger.kernel.org if other boards with the same controller
can confirm.
Thanks you Wolfram for your quick response and the rfc.
--
yashi
^ permalink raw reply
* RE: [PATCH 1/2] mmc: sdhci-esdhc: clean up register definitions
From: Y.B. Lu @ 2016-12-02 2:36 UTC (permalink / raw)
To: linux-mmc@vger.kernel.org, ulf.hansson@linaro.org; +Cc: Xiaobo Xie
In-Reply-To: <1480046451-29492-1-git-send-email-yangbo.lu@nxp.com>
Any comments on this patchset?
Thanks.
Best regards,
Yangbo Lu
> -----Original Message-----
> From: Yangbo Lu [mailto:yangbo.lu@nxp.com]
> Sent: Friday, November 25, 2016 12:01 PM
> To: linux-mmc@vger.kernel.org; ulf.hansson@linaro.org
> Cc: Xiaobo Xie; Y.B. Lu
> Subject: [PATCH 1/2] mmc: sdhci-esdhc: clean up register definitions
>
> The eSDHC register definitions in header file were messy and confusing.
> This patch is to clean up these definitions.
>
> Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
> ---
> drivers/mmc/host/sdhci-esdhc.h | 39 ++++++++++++++++++++----------------
> ---
> 1 file changed, 20 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-
> esdhc.h index de132e2..8cd8449 100644
> --- a/drivers/mmc/host/sdhci-esdhc.h
> +++ b/drivers/mmc/host/sdhci-esdhc.h
> @@ -24,30 +24,31 @@
> SDHCI_QUIRK_PIO_NEEDS_DELAY | \
> SDHCI_QUIRK_NO_HISPD_BIT)
>
> -#define ESDHC_PROCTL 0x28
> -
> -#define ESDHC_SYSTEM_CONTROL 0x2c
> -#define ESDHC_CLOCK_MASK 0x0000fff0
> -#define ESDHC_PREDIV_SHIFT 8
> -#define ESDHC_DIVIDER_SHIFT 4
> -#define ESDHC_CLOCK_PEREN 0x00000004
> -#define ESDHC_CLOCK_HCKEN 0x00000002
> -#define ESDHC_CLOCK_IPGEN 0x00000001
> -
> /* pltfm-specific */
> #define ESDHC_HOST_CONTROL_LE 0x20
>
> /*
> - * P2020 interpretation of the SDHCI_HOST_CONTROL register
> + * eSDHC register definition
> */
> -#define ESDHC_CTRL_4BITBUS (0x1 << 1)
> -#define ESDHC_CTRL_8BITBUS (0x2 << 1)
> -#define ESDHC_CTRL_BUSWIDTH_MASK (0x3 << 1)
> -
> -/* OF-specific */
> -#define ESDHC_DMA_SYSCTL 0x40c
> -#define ESDHC_DMA_SNOOP 0x00000040
>
> -#define ESDHC_HOST_CONTROL_RES 0x01
> +/* Protocol Control Register */
> +#define ESDHC_PROCTL 0x28
> +#define ESDHC_CTRL_4BITBUS (0x1 << 1)
> +#define ESDHC_CTRL_8BITBUS (0x2 << 1)
> +#define ESDHC_CTRL_BUSWIDTH_MASK (0x3 << 1)
> +#define ESDHC_HOST_CONTROL_RES 0x01
> +
> +/* System Control Register */
> +#define ESDHC_SYSTEM_CONTROL 0x2c
> +#define ESDHC_CLOCK_MASK 0x0000fff0
> +#define ESDHC_PREDIV_SHIFT 8
> +#define ESDHC_DIVIDER_SHIFT 4
> +#define ESDHC_CLOCK_PEREN 0x00000004
> +#define ESDHC_CLOCK_HCKEN 0x00000002
> +#define ESDHC_CLOCK_IPGEN 0x00000001
> +
> +/* Control Register for DMA transfer */
> +#define ESDHC_DMA_SYSCTL 0x40c
> +#define ESDHC_DMA_SNOOP 0x00000040
>
> #endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */
> --
> 2.1.0.27.g96db324
^ permalink raw reply
* [PATCH v3 1/2] mmc: sdhci: continue normal tuning if unsupported by platform tuning
From: Masahiro Yamada @ 2016-12-02 2:21 UTC (permalink / raw)
To: linux-mmc; +Cc: Adrian Hunter, Ulf Hansson, Masahiro Yamada, linux-kernel
In-Reply-To: <1480645311-13004-1-git-send-email-yamada.masahiro@socionext.com>
Some SDHCI-compat controllers support not only SD, but also eMMC,
but they use different commands for tuning: CMD19 for SD, CMD21 for
eMMC.
Due to the difference of the underlying mechanism, some controllers
(at least, the Cadence IP is the case) provide their own registers
for the eMMC tuning.
This commit will be useful when we want to use platform-specific
tuning (to support eMMC HS200), but still let it reuse the code
provided by sdhci_execute_tuning() for SD timing.
If sdhci_ops::platform_execute_tuning receives a timing it does not
take care of, it can return -ENOTSUPP. Then, it will fall back to
the SDHCI standard tuning.
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
---
I want to use this in the next commit.
The Cadence IP supports eMMC as well as SD.
The tuning for SD is pretty simple; just set the "Execute Tuning" bit
of the HOST_CONTROL2 register. So, I can re-use the
sdhci_execute_tuning().
On the other hand, Cadence provides its own way for eMMC HS200 tuning;
I need to touch some registers that are specific to Cadence's design.
Changes in v3: None
Changes in v2: None
drivers/mmc/host/sdhci.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 42ef3eb..cdce489 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -2004,7 +2004,9 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
if (host->ops->platform_execute_tuning) {
spin_unlock_irqrestore(&host->lock, flags);
err = host->ops->platform_execute_tuning(host, opcode);
- return err;
+ if (err != -ENOTSUPP)
+ return err;
+ spin_lock_irqsave(&host->lock, flags);
}
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
--
2.7.4
^ permalink raw reply related
* [PATCH v3 2/2] mmc: sdhci-cadence: add Cadence SD4HC support
From: Masahiro Yamada @ 2016-12-02 2:21 UTC (permalink / raw)
To: linux-mmc-u79uwXL29TY76Z2rM5mHXA
Cc: Adrian Hunter, Ulf Hansson, Masahiro Yamada,
devicetree-u79uwXL29TY76Z2rM5mHXA, Joshua Henderson,
Linus Walleij, linux-kernel-u79uwXL29TY76Z2rM5mHXA, Stefan Wahren,
Rob Herring, Al Cooper, Wolfram Sang, Andrei Pistirica,
Mark Rutland, Simon Horman, Geert Uytterhoeven
In-Reply-To: <1480645311-13004-1-git-send-email-yamada.masahiro-uWyLwvC0a2jby3iVrkZq2A@public.gmane.org>
Add a driver for the Cadence SD4HC SD/SDIO/eMMC Controller.
For SD, it basically relies on the SDHCI standard code.
For eMMC, this driver provides some callbacks to support the
hardware part that is specific to this IP design.
Signed-off-by: Masahiro Yamada <yamada.masahiro-uWyLwvC0a2jby3iVrkZq2A@public.gmane.org>
---
Changes in v3:
- Remove unneeded explanation about HRS and SRS from DT binding;
the offsets to HRS/SRS are fixed for this hardware and this is
quite normal, like each hardware has a fixed register view except
the register base. The detailed register map is what the driver
cares about, so no need to explain it in the binding.
Changes in v2:
- Remove unnecessary "select MMC_SDHCI_IO_ACCESSORS"
.../devicetree/bindings/mmc/sdhci-cadence.txt | 30 +++
drivers/mmc/host/Kconfig | 11 +
drivers/mmc/host/Makefile | 1 +
drivers/mmc/host/sdhci-cadence.c | 279 +++++++++++++++++++++
4 files changed, 321 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-cadence.txt
create mode 100644 drivers/mmc/host/sdhci-cadence.c
diff --git a/Documentation/devicetree/bindings/mmc/sdhci-cadence.txt b/Documentation/devicetree/bindings/mmc/sdhci-cadence.txt
new file mode 100644
index 0000000..750374f
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-cadence.txt
@@ -0,0 +1,30 @@
+* Cadence SD/SDIO/eMMC Host Controller
+
+Required properties:
+- compatible: should be "cdns,sd4hc".
+- reg: offset and length of the register set for the device.
+- interrupts: a single interrupt specifier.
+- clocks: phandle to the input clock.
+
+Optional properties:
+For eMMC configuration, supported speed modes are not indicated by the SDHCI
+Capabilities Register. Instead, the following properties should be specified
+if supported. See mmc.txt for details.
+- mmc-ddr-1_8v
+- mmc-ddr-1_2v
+- mmc-hs200-1_8v
+- mmc-hs200-1_2v
+- mmc-hs400-1_8v
+- mmc-hs400-1_2v
+
+Example:
+ emmc: sdhci@5a000000 {
+ compatible = "cdns,sd4hc";
+ reg = <0x5a000000 0x400>;
+ interrupts = <0 78 4>;
+ clocks = <&clk 4>;
+ bus-width = <8>;
+ mmc-ddr-1_8v;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ };
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index ab9181e..8ac1640 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -164,6 +164,17 @@ config MMC_SDHCI_OF_HLWD
If unsure, say N.
+config MMC_SDHCI_CADENCE
+ tristate "SDHCI support for the Cadence SD/SDIO/eMMC controller"
+ depends on MMC_SDHCI_PLTFM
+ depends on OF
+ help
+ This selects the Cadence SD/SDIO/eMMC driver.
+
+ If you have a controller with this interface, say Y or M here.
+
+ If unsure, say N.
+
config MMC_SDHCI_CNS3XXX
tristate "SDHCI support on the Cavium Networks CNS3xxx SoC"
depends on ARCH_CNS3XXX
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index e49a82a..55f7193 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -63,6 +63,7 @@ obj-$(CONFIG_MMC_REALTEK_PCI) += rtsx_pci_sdmmc.o
obj-$(CONFIG_MMC_REALTEK_USB) += rtsx_usb_sdmmc.o
obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o
+obj-$(CONFIG_MMC_SDHCI_CADENCE) += sdhci-cadence.o
obj-$(CONFIG_MMC_SDHCI_CNS3XXX) += sdhci-cns3xxx.o
obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc-imx.o
obj-$(CONFIG_MMC_SDHCI_DOVE) += sdhci-dove.o
diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence.c
new file mode 100644
index 0000000..a7daf00
--- /dev/null
+++ b/drivers/mmc/host/sdhci-cadence.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2016 Socionext Inc.
+ * Author: Masahiro Yamada <yamada.masahiro-uWyLwvC0a2jby3iVrkZq2A@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/bitops.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/mmc/host.h>
+
+#include "sdhci-pltfm.h"
+
+/* HRS - Host Register Set (specific to Cadence) */
+#define SDHCI_CDNS_HRS04 0x10 /* PHY access port */
+#define SDHCI_CDNS_HRS04_ACK BIT(26)
+#define SDHCI_CDNS_HRS04_RD BIT(25)
+#define SDHCI_CDNS_HRS04_WR BIT(24)
+#define SDHCI_CDNS_HRS04_RDATA_SHIFT 12
+#define SDHCI_CDNS_HRS04_WDATA_SHIFT 8
+#define SDHCI_CDNS_HRS04_ADDR_SHIFT 0
+
+#define SDHCI_CDNS_HRS06 0x18 /* eMMC control */
+#define SDHCI_CDNS_HRS06_TUNE_UP BIT(15)
+#define SDHCI_CDNS_HRS06_TUNE_SHIFT 8
+#define SDHCI_CDNS_HRS06_TUNE_MASK 0x3f
+#define SDHCI_CDNS_HRS06_MODE_MASK 0x7
+#define SDHCI_CDNS_HRS06_MODE_SD 0x0
+#define SDHCI_CDNS_HRS06_MODE_MMC_SDR 0x2
+#define SDHCI_CDNS_HRS06_MODE_MMC_DDR 0x3
+#define SDHCI_CDNS_HRS06_MODE_MMC_HS200 0x4
+#define SDHCI_CDNS_HRS06_MODE_MMC_HS400 0x5
+
+/* SRS - Slot Register Set (SDHCI-compatible) */
+#define SDHCI_CDNS_SRS_BASE 0x200
+
+/* PHY */
+#define SDHCI_CDNS_PHY_DLY_SD_HS 0x00
+#define SDHCI_CDNS_PHY_DLY_SD_DEFAULT 0x01
+#define SDHCI_CDNS_PHY_DLY_UHS_SDR12 0x02
+#define SDHCI_CDNS_PHY_DLY_UHS_SDR25 0x03
+#define SDHCI_CDNS_PHY_DLY_UHS_SDR50 0x04
+#define SDHCI_CDNS_PHY_DLY_UHS_DDR50 0x05
+#define SDHCI_CDNS_PHY_DLY_EMMC_LEGACY 0x06
+#define SDHCI_CDNS_PHY_DLY_EMMC_SDR 0x07
+#define SDHCI_CDNS_PHY_DLY_EMMC_DDR 0x08
+
+/*
+ * The tuned val register is 6 bit-wide, but not the whole of the range is
+ * available. The range 0-42 seems to be available (then 43 wraps around to 0)
+ * but I am not quite sure if it is official. Use only 0 to 39 for safety.
+ */
+#define SDHCI_CDNS_MAX_TUNING_LOOP 40
+
+struct sdhci_cdns_priv {
+ void __iomem *hrs_addr;
+};
+
+static void sdhci_cdns_write_phy_reg(struct sdhci_cdns_priv *priv,
+ u8 addr, u8 data)
+{
+ void __iomem *reg = priv->hrs_addr + SDHCI_CDNS_HRS04;
+ u32 tmp;
+
+ tmp = (data << SDHCI_CDNS_HRS04_WDATA_SHIFT) |
+ (addr << SDHCI_CDNS_HRS04_ADDR_SHIFT);
+ writel(tmp, reg);
+
+ tmp |= SDHCI_CDNS_HRS04_WR;
+ writel(tmp, reg);
+
+ tmp &= ~SDHCI_CDNS_HRS04_WR;
+ writel(tmp, reg);
+}
+
+static void sdhci_cdns_phy_init(struct sdhci_cdns_priv *priv)
+{
+ sdhci_cdns_write_phy_reg(priv, SDHCI_CDNS_PHY_DLY_SD_HS, 4);
+ sdhci_cdns_write_phy_reg(priv, SDHCI_CDNS_PHY_DLY_SD_DEFAULT, 4);
+ sdhci_cdns_write_phy_reg(priv, SDHCI_CDNS_PHY_DLY_EMMC_LEGACY, 9);
+ sdhci_cdns_write_phy_reg(priv, SDHCI_CDNS_PHY_DLY_EMMC_SDR, 2);
+ sdhci_cdns_write_phy_reg(priv, SDHCI_CDNS_PHY_DLY_EMMC_DDR, 3);
+}
+
+static inline void *sdhci_cdns_priv(struct sdhci_host *host)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+ return sdhci_pltfm_priv(pltfm_host);
+}
+
+static unsigned int sdhci_cdns_get_timeout_clock(struct sdhci_host *host)
+{
+ /*
+ * Cadence's spec says the Timeout Clock Frequency is the same as the
+ * Base Clock Frequency. Divide it by 1000 to return a value in kHz.
+ */
+ return host->max_clk / 1000;
+}
+
+static int sdhci_cdns_set_tune_val(struct sdhci_host *host, unsigned int val)
+{
+ struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host);
+ void __iomem *reg = priv->hrs_addr + SDHCI_CDNS_HRS06;
+ u32 tmp;
+
+ if (WARN_ON(val > SDHCI_CDNS_HRS06_TUNE_MASK))
+ return -EINVAL;
+
+ tmp = readl(reg);
+ tmp &= ~(SDHCI_CDNS_HRS06_TUNE_MASK << SDHCI_CDNS_HRS06_TUNE_SHIFT);
+ tmp |= val << SDHCI_CDNS_HRS06_TUNE_SHIFT;
+ tmp |= SDHCI_CDNS_HRS06_TUNE_UP;
+ writel(tmp, reg);
+
+ return readl_poll_timeout(reg, tmp, !(tmp & SDHCI_CDNS_HRS06_TUNE_UP),
+ 0, 1);
+}
+
+static int sdhci_cdns_execute_tuning(struct sdhci_host *host, u32 opcode)
+{
+ int max_streak = 0;
+ int cur_streak = 0;
+ int end_of_streak, i;
+
+ /*
+ * This handler only implements the eMMC tuning that is specific to
+ * this controller. Fall back to the standard method for SD timing.
+ */
+ if (host->timing != MMC_TIMING_MMC_HS200)
+ return -ENOTSUPP;
+
+ if (WARN_ON(opcode != MMC_SEND_TUNING_BLOCK_HS200))
+ return -EINVAL;
+
+ for (i = 0; i < SDHCI_CDNS_MAX_TUNING_LOOP; i++) {
+ if (sdhci_cdns_set_tune_val(host, i) ||
+ mmc_send_tuning(host->mmc, opcode, NULL)) { /* bad */
+ cur_streak = 0;
+ } else { /* good */
+ cur_streak++;
+ max_streak = max(max_streak, cur_streak);
+ end_of_streak = i;
+ }
+ }
+
+ if (!max_streak) {
+ dev_err(mmc_dev(host->mmc), "no tuning point found\n");
+ return -EIO;
+ }
+
+ return sdhci_cdns_set_tune_val(host, end_of_streak - max_streak / 2);
+}
+
+static void sdhci_cdns_set_uhs_signaling(struct sdhci_host *host,
+ unsigned int timing)
+{
+ struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host);
+ u32 mode, tmp;
+
+ switch (timing) {
+ case MMC_TIMING_MMC_HS:
+ mode = SDHCI_CDNS_HRS06_MODE_MMC_SDR;
+ break;
+ case MMC_TIMING_MMC_DDR52:
+ mode = SDHCI_CDNS_HRS06_MODE_MMC_DDR;
+ break;
+ case MMC_TIMING_MMC_HS200:
+ mode = SDHCI_CDNS_HRS06_MODE_MMC_HS200;
+ break;
+ case MMC_TIMING_MMC_HS400:
+ mode = SDHCI_CDNS_HRS06_MODE_MMC_HS400;
+ break;
+ default:
+ mode = SDHCI_CDNS_HRS06_MODE_SD;
+ break;
+ }
+
+ /* The speed mode for eMMC is selected by HRS06 register */
+ tmp = readl(priv->hrs_addr + SDHCI_CDNS_HRS06);
+ tmp &= ~SDHCI_CDNS_HRS06_MODE_MASK;
+ tmp |= mode;
+ writel(tmp, priv->hrs_addr + SDHCI_CDNS_HRS06);
+
+ /* For SD, fall back to the default handler */
+ if (mode == SDHCI_CDNS_HRS06_MODE_SD)
+ sdhci_set_uhs_signaling(host, timing);
+}
+
+static const struct sdhci_ops sdhci_cdns_ops = {
+ .set_clock = sdhci_set_clock,
+ .get_timeout_clock = sdhci_cdns_get_timeout_clock,
+ .set_bus_width = sdhci_set_bus_width,
+ .reset = sdhci_reset,
+ .platform_execute_tuning = sdhci_cdns_execute_tuning,
+ .set_uhs_signaling = sdhci_cdns_set_uhs_signaling,
+};
+
+static const struct sdhci_pltfm_data sdhci_cdns_pltfm_data = {
+ .ops = &sdhci_cdns_ops,
+};
+
+static int sdhci_cdns_probe(struct platform_device *pdev)
+{
+ struct sdhci_host *host;
+ struct sdhci_pltfm_host *pltfm_host;
+ struct sdhci_cdns_priv *priv;
+ struct clk *clk;
+ int ret;
+
+ clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(clk))
+ return PTR_ERR(clk);
+
+ ret = clk_prepare_enable(clk);
+ if (ret)
+ return ret;
+
+ host = sdhci_pltfm_init(pdev, &sdhci_cdns_pltfm_data, sizeof(*priv));
+ if (IS_ERR(host)) {
+ ret = PTR_ERR(host);
+ goto disable_clk;
+ }
+
+ pltfm_host = sdhci_priv(host);
+ pltfm_host->clk = clk;
+
+ priv = sdhci_cdns_priv(host);
+ priv->hrs_addr = host->ioaddr;
+ host->ioaddr += SDHCI_CDNS_SRS_BASE;
+
+ ret = mmc_of_parse(host->mmc);
+ if (ret)
+ goto free;
+
+ sdhci_cdns_phy_init(priv);
+
+ ret = sdhci_add_host(host);
+ if (ret)
+ goto free;
+
+ return 0;
+free:
+ sdhci_pltfm_free(pdev);
+disable_clk:
+ clk_disable_unprepare(clk);
+
+ return ret;
+}
+
+static const struct of_device_id sdhci_cdns_match[] = {
+ { .compatible = "cdns,sd4hc" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, sdhci_cdns_match);
+
+static struct platform_driver sdhci_cdns_driver = {
+ .driver = {
+ .name = "sdhci-cdns",
+ .pm = &sdhci_pltfm_pmops,
+ .of_match_table = sdhci_cdns_match,
+ },
+ .probe = sdhci_cdns_probe,
+ .remove = sdhci_pltfm_unregister,
+};
+module_platform_driver(sdhci_cdns_driver);
+
+MODULE_AUTHOR("Masahiro Yamada <yamada.masahiro-uWyLwvC0a2jby3iVrkZq2A@public.gmane.org>");
+MODULE_DESCRIPTION("Cadence SD/SDIO/eMMC Host Controller Driver");
+MODULE_LICENSE("GPL");
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v3 0/2] mmc: sdhci: one expansion for SDHCI base code and add Cadence SDHCI driver
From: Masahiro Yamada @ 2016-12-02 2:21 UTC (permalink / raw)
To: linux-mmc
Cc: Adrian Hunter, Ulf Hansson, Masahiro Yamada, devicetree,
Joshua Henderson, Linus Walleij, linux-kernel, Stefan Wahren,
Rob Herring, Al Cooper, Wolfram Sang, Andrei Pistirica,
Mark Rutland, Simon Horman, Geert Uytterhoeven
1/2 tweaks sdhci_execute_tuning(), which I want to use for 2/2.
2/2 adds a new driver for Cadence's controller IP.
Masahiro Yamada (2):
mmc: sdhci: continue normal tuning if unsupported by platform tuning
mmc: sdhci-cadence: add Cadence SD4HC support
.../devicetree/bindings/mmc/sdhci-cadence.txt | 30 +++
drivers/mmc/host/Kconfig | 11 +
drivers/mmc/host/Makefile | 1 +
drivers/mmc/host/sdhci-cadence.c | 279 +++++++++++++++++++++
drivers/mmc/host/sdhci.c | 4 +-
5 files changed, 324 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-cadence.txt
create mode 100644 drivers/mmc/host/sdhci-cadence.c
--
2.7.4
^ permalink raw reply
* Re: [PATCH 1/2] dt-bindings: mmc: add DT binding for S3C24XX MMC/SD/SDIO controller
From: Jaehoon Chung @ 2016-12-02 0:48 UTC (permalink / raw)
To: Sergio Prado, ulf.hansson, robh+dt, mark.rutland, linux-mmc,
devicetree, linux-kernel, ben-linux, linux-arm-kernel
In-Reply-To: <1480637665-6325-2-git-send-email-sergio.prado@e-labworks.com>
On 12/02/2016 09:14 AM, Sergio Prado wrote:
> Adds the device tree bindings description for Samsung S3C24XX
> MMC/SD/SDIO controller, used as a connectivity interface with external
> MMC, SD and SDIO storage mediums.
>
> Signed-off-by: Sergio Prado <sergio.prado@e-labworks.com>
> ---
> .../devicetree/bindings/mmc/samsung,s3cmci.txt | 38 ++++++++++++++++++++++
> 1 file changed, 38 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
>
> diff --git a/Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt b/Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
> new file mode 100644
> index 000000000000..3f044076e69a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/samsung,s3cmci.txt
> @@ -0,0 +1,38 @@
> +* Samsung's S3C24XX MMC/SD/SDIO controller device tree bindings
> +
> +Samsung's S3C24XX MMC/SD/SDIO controller is used as a connectivity interface
> +with external MMC, SD and SDIO storage mediums.
> +
> +This file documents differences between the core mmc properties described by
> +mmc.txt and the properties used by the Samsung S3C24XX MMC/SD/SDIO controller
> +implementation.
> +
> +Required SoC Specific Properties:
> +- compatible: should be one of the following
> + - "samsung,s3c2410-sdi": for controllers compatible with s3c2410
> + - "samsung,s3c2412-sdi": for controllers compatible with s3c2412
> + - "samsung,s3c2440-sdi": for controllers compatible with s3c2440
> +- clocks: Should reference the controller clock
> +- clock-names: Should contain "sdi"
> +
> +Required Board Specific Properties:
> +- pinctrl-0: Should specify pin control groups used for this controller.
> +- pinctrl-names: Should contain only one value - "default".
I'm not sure but i think this description doesn't need at here.
> +
> +Example:
> + sdi: sdi@5a000000 {
I think it needs to use "mmc0: sdi@5a000000" instead of "sdi: sdi@5a000000"
Because mmc is more clear than sdi.
> + compatible = "samsung,s3c2440-sdi";
> + pinctrl-names = "default";
> + pinctrl-0 = <&sdi_pins>;
> + reg = <0x5a000000 0x100000>;
> + interrupts = <0 0 21 3>;
> + clocks = <&clocks PCLK_SDI>;
> + clock-names = "sdi";
> + bus-width = <4>;
> + cd-gpios = <&gpg 8 GPIO_ACTIVE_LOW>;
> + wp-gpios = <&gph 8 GPIO_ACTIVE_LOW>;
> + };
> +
> + Note: This example shows both SoC specific and board specific properties
> + in a single device node. The properties can be actually be separated
> + into SoC specific node and board specific node.
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox