From: AKASHI Takahiro <takahiro.akashi@linaro.org>
To: Ben Chuang <benchuanggli@gmail.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>,
Ulf Hansson <ulf.hansson@linaro.org>,
linux-mmc <linux-mmc@vger.kernel.org>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Ben Chuang <ben.chuang@genesyslogic.com.tw>,
greg.tu@genesyslogic.com.tw, Renius.Chen@genesyslogic.com.tw
Subject: Re: [RFC PATCH V3 12/21] mmc: sdhci: UHS-II support, add hooks for additional operations
Date: Thu, 24 Sep 2020 18:46:20 +0900 [thread overview]
Message-ID: <20200924094620.GA38298@laputa> (raw)
In-Reply-To: <CACT4zj9L0zk1UaYLjsBpt8_tLPbfou-WDv0XwXbQE146bsT0+Q@mail.gmail.com>
Ben,
On Fri, Sep 18, 2020 at 06:27:01PM +0800, Ben Chuang wrote:
> On Fri, Sep 18, 2020 at 9:15 AM AKASHI Takahiro
> <takahiro.akashi@linaro.org> wrote:
> >
> > Ben,
> >
> > On Thu, Sep 17, 2020 at 06:12:27PM +0800, Ben Chuang wrote:
> > > Hi Takahiro,
> > >
> > > On Thu, Sep 17, 2020 at 1:12 PM AKASHI Takahiro
> > > <takahiro.akashi@linaro.org> wrote:
> > > >
> > > > Adrian, Ben,
> > > >
> > > > Regarding _reset() function,
> > > >
> > > > On Fri, Aug 21, 2020 at 05:08:32PM +0300, Adrian Hunter wrote:
> > > > > On 10/07/20 2:10 pm, Ben Chuang wrote:
> > > > > > From: Ben Chuang <ben.chuang@genesyslogic.com.tw>
> > > > > >
> > > > > > In this commit, UHS-II related operations will be called via a function
> > > > > > pointer array, sdhci_uhs2_ops, in order to make UHS-II support as
> > > > > > a kernel module.
> > > > > > This array will be initialized only if CONFIG_MMC_SDHCI_UHS2 is enabled
> > > > > > and when the UHS-II module is loaded. Otherwise, all the functions
> > > > > > stay void.
> > > > > >
> > > > > > Signed-off-by: Ben Chuang <ben.chuang@genesyslogic.com.tw>
> > > > > > Signed-off-by: AKASHI Takahiro <takahiro.akashi@linaro.org>
> > > > > > ---
> > > > > > drivers/mmc/host/sdhci.c | 152 ++++++++++++++++++++++++++++++++++-----
> > > > > > 1 file changed, 136 insertions(+), 16 deletions(-)
> > > > > >
> > > >
> > > > (snip)
> > > >
> > > > > > if (host->ops->platform_send_init_74_clocks)
> > > > > > host->ops->platform_send_init_74_clocks(host, ios->power_mode);
> > > > > >
> > > > > > @@ -2331,7 +2411,7 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> > > > > > }
> > > > > >
> > > > > > if (host->version >= SDHCI_SPEC_300) {
> > > > > > - u16 clk, ctrl_2;
> > > > > > + u16 clk;
> > > > > >
> > > > > > if (!host->preset_enabled) {
> > > > > > sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
> > > > > > @@ -3173,11 +3253,19 @@ static bool sdhci_request_done(struct sdhci_host *host)
> > > > > > /* This is to force an update */
> > > > > > host->ops->set_clock(host, host->clock);
> > > > > >
> > > > > > - /* Spec says we should do both at the same time, but Ricoh
> > > > > > - controllers do not like that. */
> > > > > > - sdhci_do_reset(host, SDHCI_RESET_CMD);
> > > > > > - sdhci_do_reset(host, SDHCI_RESET_DATA);
> > > > > > -
> > > > > > + if (IS_ENABLED(CONFIG_MMC_SDHCI_UHS2) &&
> > > > > > + host->mmc->flags & MMC_UHS2_INITIALIZED) {
> > > > > > + if (sdhci_uhs2_ops.reset)
> > > > > > + sdhci_uhs2_ops.reset(host,
> > > > > > + SDHCI_UHS2_SW_RESET_SD);
> > > > > > + } else {
> > > > > > + /*
> > > > > > + * Spec says we should do both at the same time, but
> > > > > > + * Ricoh controllers do not like that.
> > > > > > + */
> > > > > > + sdhci_do_reset(host, SDHCI_RESET_CMD);
> > > > > > + sdhci_do_reset(host, SDHCI_RESET_DATA);
> > > > > > + }
> > > > >
> > > > > Please look at using the existing ->reset() sdhci host op instead.
> > > >
> > > > Well, the second argument to those reset functions is a bit-wise value
> > > > to different "reset" registers, SDHCI_SOFTWARE_RESET and SDHCI_UHS2_SW_RESET,
> > > > respectively.
> > > >
> > > > This fact raises a couple of questions to me:
> > > >
> > > > 1) Does it make sense to merge two functionality into one, i.e.
> > > > sdhci_do_reset(), which is set to call ->reset hook?
> > > >
> > > > -> Adrian
> > > >
> > > > 2) UHS2_SW_RESET_SD is done only at this place while there are many callsites
> > > > of reset(RESET_CMD|RESET_DATA) in sdhci.c.
> > > > Why does the current code work?
> > > >
> > > > I found, in sdhci-pci-gli.c,
> > > > sdhci_gl9755_reset()
> > > > /* reset sd-tran on UHS2 mode if need to reset cmd/data */
> > > > if ((mask & SDHCI_RESET_CMD) | (mask & SDHCI_RESET_DATA))
> > > > gl9755_uhs2_reset_sd_tran(host);
> >
> > (A)
> >
> > > >
> > > > Is this the trick to avoid the issue?
> > > > (It looks redundant in terms of the hack above in sdhci_request_done()
> > > > and even quite dirty to me. Moreover, no corresponding code for gl9750
> > > > and gl9763.)
> > >
> > > GL9755 currently does SD reset and UHS-II reset together.
> >
> > Do you mean that, in UHS-II operations, you need only the reset on
> > SDHCI_UHS2_SW_RESET register?
>
> No, GL9755 does SD reset and UHS-II reset together.
Is this also true for all sdhci controller drivers in general?
As I said, I didn't find any precise description about this
in SD specification.
-Takahiro Akashi
> > But the hunk above (A) does the UHS-II reset along with UHS-I reset.
> >
> > > There is no UHS-II interface on gl9750 and gl9763e.
> > >
> > > >
> > > > -> Ben
> > > >
> > > > 3) (More or less SD specification issue)
> > > > In UHS-II mode, do we have to call reset(SHCI_RESET_ALL) along with
> > > > reset(UHS2_SW_RESET_FULL)?
> > > > Under the current implementation, both will be called at the end.
> > > >
> > >
> > > As I know, the UHS2_SW_RESET_FULL is only for UHS-II.
> > > Can you list the lines that reset(SHCI_RESET_ALL) and
> > > reset(UHS2_SW_RESET_FULL) are both called?
> >
> > I was not clear here. (The above is also another example.)
> >
> > Look at sdhci_remove_host() and shdci_uhs2_remote_host().
> > If the argument 'dead' is 0, we will do both of the resets for UHS-II.
>
> Do UHS2_SW_RESET_FULL in sdhci_uhs2_remove_host() and then do
> SDHCI_RESET_ALL in sdhci_remove_host() is ok.
>
>
> >
> > -Takahiro Akashi
> >
> > > > -> Adrian, Ben
> > > >
> > > > 4) (Not directly linked to UHS-II support)
> > > > In some places, we see the sequence:
> > > > sdhci_do_reset(host, SDHCI_RESET_CMD);
> > > > sdhci_do_reset(host, SDHCI_RESET_DATA);
> > > > while in other places,
> > > > sdhci_do_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
> > > >
> > > > If the statement below is true,
> > > > > > - /* Spec says we should do both at the same time, but Ricoh
> > > > > > - controllers do not like that. */
> > > > the latter should be wrong.
> > > >
> > > > -> Adrian
> > > >
> > > > -Takahiro Akashi
> > > >
> > > >
> > > >
> > > > > > host->pending_reset = false;
> > > > > > }
> > > > > >
> > > > > > @@ -3532,6 +3620,13 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
> > > > > > SDHCI_INT_BUS_POWER);
> > > > > > sdhci_writel(host, mask, SDHCI_INT_STATUS);
> > > > > >
> > > > > > + if (IS_ENABLED(CONFIG_MMC_SDHCI_UHS2) &&
> > > > > > + intmask & SDHCI_INT_ERROR &&
> > > > > > + host->mmc->flags & MMC_UHS2_SUPPORT) {
> > > > > > + if (sdhci_uhs2_ops.irq)
> > > > > > + sdhci_uhs2_ops.irq(host);
> > > > > > + }
> > > > > > +
> > > > >
> > > > > Please look at using the existing ->irq() sdhci host op instead
> > > > >
> > > > > > if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
> > > > > > u32 present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
> > > > > > SDHCI_CARD_PRESENT;
> > > > > > @@ -4717,6 +4812,14 @@ int sdhci_setup_host(struct sdhci_host *host)
> > > > > > /* This may alter mmc->*_blk_* parameters */
> > > > > > sdhci_allocate_bounce_buffer(host);
> > > > > >
> > > > > > + if (IS_ENABLED(CONFIG_MMC_SDHCI_UHS2) &&
> > > > > > + host->version >= SDHCI_SPEC_400 &&
> > > > > > + sdhci_uhs2_ops.add_host) {
> > > > > > + ret = sdhci_uhs2_ops.add_host(host, host->caps1);
> > > > > > + if (ret)
> > > > > > + goto unreg;
> > > > > > + }
> > > > > > +
> > > > >
> > > > > I think you should look at creating uhs2_add_host() instead
> > > > >
> > > > > > return 0;
> > > > > >
> > > > > > unreg:
> > > > > > @@ -4738,6 +4841,8 @@ void sdhci_cleanup_host(struct sdhci_host *host)
> > > > > > {
> > > > > > struct mmc_host *mmc = host->mmc;
> > > > > >
> > > > > > + /* FIXME: Do we have to do some cleanup for UHS2 here? */
> > > > > > +
> > > > > > if (!IS_ERR(mmc->supply.vqmmc))
> > > > > > regulator_disable(mmc->supply.vqmmc);
> > > > > >
> > > > > > @@ -4766,6 +4871,14 @@ int __sdhci_add_host(struct sdhci_host *host)
> > > > > > mmc->cqe_ops = NULL;
> > > > > > }
> > > > > >
> > > > > > + if ((mmc->caps & MMC_CAP_UHS2) && !host->v4_mode) {
> > > > > > + /* host doesn't want to enable UHS2 support */
> > > > > > + mmc->caps &= ~MMC_CAP_UHS2;
> > > > > > + mmc->flags &= ~MMC_UHS2_SUPPORT;
> > > > > > +
> > > > > > + /* FIXME: Do we have to do some cleanup here? */
> > > > > > + }
> > > > > > +
> > > > > > host->complete_wq = alloc_workqueue("sdhci", flags, 0);
> > > > > > if (!host->complete_wq)
> > > > > > return -ENOMEM;
> > > > > > @@ -4812,6 +4925,9 @@ int __sdhci_add_host(struct sdhci_host *host)
> > > > > > unled:
> > > > > > sdhci_led_unregister(host);
> > > > > > unirq:
> > > > > > + if (IS_ENABLED(CONFIG_MMC_SDHCI_UHS2) &&
> > > > > > + sdhci_uhs2_ops.remove_host)
> > > > > > + sdhci_uhs2_ops.remove_host(host, 0);
> > > > > > sdhci_do_reset(host, SDHCI_RESET_ALL);
> > > > > > sdhci_writel(host, 0, SDHCI_INT_ENABLE);
> > > > > > sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
> > > > > > @@ -4869,6 +4985,10 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
> > > > > >
> > > > > > sdhci_led_unregister(host);
> > > > > >
> > > > > > + if (IS_ENABLED(CONFIG_MMC_SDHCI_UHS2) &&
> > > > > > + sdhci_uhs2_ops.remove_host)
> > > > > > + sdhci_uhs2_ops.remove_host(host, dead);
> > > > > > +
> > > > >
> > > > > I think you should look at creating uhs2_remove_host() instead
> > > > >
> > > > > > if (!dead)
> > > > > > sdhci_do_reset(host, SDHCI_RESET_ALL);
> > > > > >
> > > > > >
> > > > >
next prev parent reply other threads:[~2020-09-24 9:46 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-07-10 11:10 [RFC PATCH V3 12/21] mmc: sdhci: UHS-II support, add hooks for additional operations Ben Chuang
2020-08-21 14:08 ` Adrian Hunter
2020-09-16 8:05 ` AKASHI Takahiro
2020-09-16 10:00 ` Adrian Hunter
2020-09-17 2:31 ` AKASHI Takahiro
2020-09-17 4:52 ` Adrian Hunter
2020-09-17 5:16 ` AKASHI Takahiro
2020-09-17 5:12 ` AKASHI Takahiro
2020-09-17 10:12 ` Ben Chuang
2020-09-18 1:15 ` AKASHI Takahiro
2020-09-18 10:27 ` Ben Chuang
2020-09-24 9:46 ` AKASHI Takahiro [this message]
2020-09-25 7:59 ` Ben Chuang
2020-09-18 6:38 ` AKASHI Takahiro
2020-09-18 10:50 ` Ben Chuang
2020-09-24 9:57 ` AKASHI Takahiro
2020-09-25 7:55 ` Ben Chuang
2020-09-24 9:35 ` AKASHI Takahiro
2020-09-25 9:02 ` Adrian Hunter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200924094620.GA38298@laputa \
--to=takahiro.akashi@linaro.org \
--cc=Renius.Chen@genesyslogic.com.tw \
--cc=adrian.hunter@intel.com \
--cc=ben.chuang@genesyslogic.com.tw \
--cc=benchuanggli@gmail.com \
--cc=greg.tu@genesyslogic.com.tw \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mmc@vger.kernel.org \
--cc=ulf.hansson@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.