From: Ulf Hansson <ulf.hansson@linaro.org>
To: "Gabriel L. Somlo" <gsomlo@gmail.com>
Cc: linux-kernel@vger.kernel.org, robh+dt@kernel.org,
devicetree@vger.kernel.org, linux-mmc@vger.kernel.org,
kgugala@antmicro.com, mholenko@antmicro.com,
krakoczy@antmicro.com, mdudek@internships.antmicro.com,
paulus@ozlabs.org, joel@jms.id.au, shorne@gmail.com,
geert@linux-m68k.org, david.abdurachmanov@sifive.com,
florent@enjoy-digital.fr, rdunlap@infradead.org
Subject: Re: [PATCH v5 3/3] mmc: Add driver for LiteX's LiteSDCard interface
Date: Tue, 11 Jan 2022 16:47:07 +0100 [thread overview]
Message-ID: <CAPDyKFohOHYu_bdXsAYvDmMLqnGUW=9pG+yJDwP5-db1B6F1Dw@mail.gmail.com> (raw)
In-Reply-To: <YdOUbYpGFNyxz3iD@errol.ini.cmu.edu>
[...]
> > > +
> > > +static void litex_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
> > > +{
> > > + struct litex_mmc_host *host = mmc_priv(mmc);
> > > + struct device *dev = mmc_dev(mmc);
> > > + struct mmc_command *cmd = mrq->cmd;
> > > + struct mmc_command *sbc = mrq->sbc;
> > > + struct mmc_data *data = mrq->data;
> > > + struct mmc_command *stop = mrq->stop;
> > > + unsigned int retries = cmd->retries;
> > > + unsigned int len = 0;
> > > + bool direct = false;
> > > + u32 response_len = litex_mmc_response_len(cmd);
> > > + u8 transfer = SD_CTL_DATA_XFER_NONE;
> > > +
> > > + /* First check that the card is still there */
> > > + if (!litex_mmc_get_cd(mmc)) {
> > > + cmd->error = -ENOMEDIUM;
> > > + mmc_request_done(mmc, mrq);
> > > + return;
> > > + }
> > > +
> > > + /* Send set-block-count command if needed */
> > > + if (sbc) {
> > > + sbc->error = litex_mmc_send_cmd(host, sbc->opcode, sbc->arg,
> > > + litex_mmc_response_len(sbc),
> > > + SD_CTL_DATA_XFER_NONE);
> > > + if (sbc->error) {
> > > + host->is_bus_width_set = false;
> > > + mmc_request_done(mmc, mrq);
> > > + return;
> > > + }
> > > + }
> > > +
> > > + if (data) {
> > > + /* LiteSDCard only supports 4-bit bus width; therefore, we MUST
> > > + * inject a SET_BUS_WIDTH (acmd6) before the very first data
> > > + * transfer, earlier than when the mmc subsystem would normally
> > > + * get around to it!
> >
> > This means that you may end up trying to switch bus-width, to a width
> > that isn't supported by the card, for example.
> >
> > As also stated above, I wonder how this conforms to the SD spec from
> > the initialization sequence point of view. Have you verified that this
> > isn't a problem?
>
> During litex_mmc_probe(), I have:
>
> ...
> ret = mmc_of_parse(mmc);
> if (ret)
> goto err;
>
> /* force 4-bit bus_width (only width supported by hardware) */
> mmc->caps &= ~MMC_CAP_8_BIT_DATA;
> mmc->caps |= MMC_CAP_4_BIT_DATA;
> ...
>
> This ensures no bus-width switches to anything other than 4-bit data
> should ever occur. As far as I understand the SDcard spec, it's legal
> to both send multiple redundant bus-width-set commands, and to start
> doing so before the very first data transfer request is processed
> (regardless of the fact that linux typically does a few 1-bit-wide
> data transfers during card initialization before switching to a wider
> mode, if available).
>
> This driver simply ensures that any time we ever have a data transfer,
> the bus width is set to 4 *before* said transfer is acted upon.
>
> As I mentioned earlier, if we get a "weird" SDcard that can't support
> 4-bit data transfers, its initialization should fail shortly after
> detection, and that's all there is to it, as far as I can tell.
Alright, I get the point. I guess it should work. I will have another
closer look at the corresponding code from your last submitted
version.
>
> > > + */
> > > + cmd->error = litex_mmc_set_bus_width(host);
> > > + if (cmd->error) {
> > > + dev_err(dev, "Can't set bus width!\n");
> > > + mmc_request_done(mmc, mrq);
> > > + return;
> > > + }
> > > +
> > > + litex_mmc_do_dma(host, data, &len, &direct, &transfer);
> > > + }
> > > +
> > > + do {
> > > + cmd->error = litex_mmc_send_cmd(host, cmd->opcode, cmd->arg,
> > > + response_len, transfer);
> > > + } while (cmd->error && retries-- > 0);
> > > +
> > > + if (cmd->error) {
> > > + /* card may be gone; don't assume bus width is still set */
> > > + host->is_bus_width_set = false;
> > > + }
> > > +
> > > + if (response_len == SD_CTL_RESP_SHORT) {
> > > + /* pull short response fields from appropriate host registers */
> > > + cmd->resp[0] = host->resp[3];
> > > + cmd->resp[1] = host->resp[2] & 0xFF;
> > > + } else if (response_len == SD_CTL_RESP_LONG) {
> > > + cmd->resp[0] = host->resp[0];
> > > + cmd->resp[1] = host->resp[1];
> > > + cmd->resp[2] = host->resp[2];
> > > + cmd->resp[3] = host->resp[3];
> > > + }
> > > +
> > > + /* Send stop-transmission command if required */
> > > + if (stop && (cmd->error || !sbc)) {
> > > + stop->error = litex_mmc_send_cmd(host, stop->opcode, stop->arg,
> > > + litex_mmc_response_len(stop),
> > > + SD_CTL_DATA_XFER_NONE);
> > > + if (stop->error)
> > > + host->is_bus_width_set = false;
> > > + }
> > > +
> > > + if (data) {
> > > + dma_unmap_sg(dev, data->sg, data->sg_len,
> > > + mmc_get_dma_dir(data));
> > > + }
> > > +
> > > + if (!cmd->error && transfer != SD_CTL_DATA_XFER_NONE) {
> > > + data->bytes_xfered = min(len, mmc->max_req_size);
> > > + if (transfer == SD_CTL_DATA_XFER_READ && !direct) {
> > > + sg_copy_from_buffer(data->sg, sg_nents(data->sg),
> > > + host->buffer, data->bytes_xfered);
> > > + }
> > > + }
> > > +
> > > + mmc_request_done(mmc, mrq);
> > > +}
> > > +
> >
> > [...]
> >
> > > +
> > > + mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
> >
> > I noticed that you use these hard coded values and don't really care
> > to manage voltage changes via ->set_ios().
> >
> > Rather than doing it like this, I would prefer if you can hook up a
> > fixed vmmc regulator in the DTS. Then call mmc_regulator_get_supply()
> > to fetch it from here, which will let the mmc core create the
> > mmc->ocr_avail mask, based upon the voltage level the regulator
> > supports.
> >
> > This becomes more generic and allows more flexibility for the platform
> > configuration.
>
> The LiteSDCard "hardware" (i.e., *gateware*) does not allow modification
> or selection of voltage from the software side. When a CMD8 is issued,
> the "voltage supplied" bit pattern is expected to be '0001b', which per
> the spec means "2.7-3.6V".
If you provide a range (2.7-3.6V), that means that your hardware
supports the entire range, not just one single part of it.
>
> I tried adding this to the overall DTS:
>
> vreg_mmc: vreg_mmc_3v {
> compatible = "regulator-fixed";
> regulator-min-microvolt = <3300000>;
> regulator-max-microvolt = <3300000>;
> };
>
> and then added a reference to it to the LiteSDCard "mmc0" node in DTS,
> like so:
>
> mmc0: mmc@12005000 {
> compatible = "litex,mmc";
> reg = <0x12005000 0x100>,
> <0x12003800 0x100>,
> <0x12003000 0x100>,
> <0x12004800 0x100>,
> <0x12004000 0x100>;
> reg-names = "phy", "core", "reader", "writer", "irq";
> clocks = <&sys_clk>;
> vmmc-supply = <&vreg_mmc>; /* <-------- HERE !!! */
> interrupt-parent = <&L1>;
> interrupts = <4>;
> };
>
> Finally, I replaced the hardcoded setting of `mmc->ocr_avail` with a
> call to `mmc_regulator_get_supply(mmc)`. Now, I get a bunch of timeouts
> during attempts to send e.g., CMD8 and CMD55.
> (going for 3200000 and 3400000 for min- and max-microvolt, respectively,
> -- or anything else in the allowed 2.7-3.6 range -- doesn't help either).
>
> I might be doing something subtly wrong in the way I set things up
> above, but it feels a bit overengineered, and IMHO fragile.
At a quick glance, the above looks correct to me. Maybe there is
something wrong with the code in the driver instead?
>
> OTOH, going all out and setting:
>
> /* allow for generic 2.7-3.6V range, no software tuning available */
> mmc->ocr_avail = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 |
> MMC_VDD_30_31 | MMC_VDD_31_32 | MMC_VDD_32_33 |
> MMC_VDD_33_34 | MMC_VDD_34_35 | MMC_VDD_35_36;
>
> seems to work just fine... :) Please do let me know what you think!
No, this isn't the way we want it to work. That's because it means
that we would lie to the card about what voltage range the HW actually
supports.
It's better to let the DTS file give that information about the HW.
[...]
Kind regards
Uffe
next prev parent reply other threads:[~2022-01-11 15:47 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-15 13:07 [PATCH v5 0/3] mmc: Add LiteSDCard mmc driver Gabriel Somlo
2021-12-15 13:07 ` [PATCH v5 1/3] MAINTAINERS: co-maintain LiteX platform Gabriel Somlo
2021-12-15 13:07 ` [PATCH v5 2/3] dt-bindings: mmc: Add bindings for LiteSDCard Gabriel Somlo
2021-12-15 13:07 ` [PATCH v5 3/3] mmc: Add driver for LiteX's LiteSDCard interface Gabriel Somlo
2021-12-25 16:43 ` Andy Shevchenko
2021-12-26 11:45 ` Gabriel L. Somlo
2021-12-26 13:01 ` Andy Shevchenko
2021-12-26 13:13 ` Andy Shevchenko
2021-12-26 13:36 ` Gabriel L. Somlo
2021-12-26 14:01 ` Andy Shevchenko
2021-12-26 22:37 ` Gabriel L. Somlo
2021-12-28 16:15 ` Ulf Hansson
2022-01-04 0:27 ` Gabriel L. Somlo
2022-01-06 17:08 ` Gabriel L. Somlo
2022-01-11 15:47 ` Ulf Hansson [this message]
2022-01-11 22:49 ` Gabriel L. Somlo
2022-01-12 10:24 ` Ulf Hansson
2022-01-12 18:08 ` Gabriel L. Somlo
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='CAPDyKFohOHYu_bdXsAYvDmMLqnGUW=9pG+yJDwP5-db1B6F1Dw@mail.gmail.com' \
--to=ulf.hansson@linaro.org \
--cc=david.abdurachmanov@sifive.com \
--cc=devicetree@vger.kernel.org \
--cc=florent@enjoy-digital.fr \
--cc=geert@linux-m68k.org \
--cc=gsomlo@gmail.com \
--cc=joel@jms.id.au \
--cc=kgugala@antmicro.com \
--cc=krakoczy@antmicro.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mmc@vger.kernel.org \
--cc=mdudek@internships.antmicro.com \
--cc=mholenko@antmicro.com \
--cc=paulus@ozlabs.org \
--cc=rdunlap@infradead.org \
--cc=robh+dt@kernel.org \
--cc=shorne@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).