diff mbox series

[v3,04/10] mmc: core: Add open-ended Ext memory addressing

Message ID 20240814072934.2559911-5-avri.altman@wdc.com
State Superseded
Headers show
Series Add SDUC Support | expand

Commit Message

Avri Altman Aug. 14, 2024, 7:29 a.m. UTC
For open-ended read/write - just send CMD22 before issuing the command.
While at it, make sure that the rw command arg is properly casting the
lower 32 bits, as it can be larger now.

Tested-by: Ricky WU <ricky_wu@realtek.com>
Signed-off-by: Avri Altman <avri.altman@wdc.com>
---
 drivers/mmc/core/block.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

Comments

Ulf Hansson Aug. 22, 2024, 12:23 p.m. UTC | #1
On Wed, 14 Aug 2024 at 09:31, Avri Altman <avri.altman@wdc.com> wrote:
>
> For open-ended read/write - just send CMD22 before issuing the command.
> While at it, make sure that the rw command arg is properly casting the
> lower 32 bits, as it can be larger now.
>
> Tested-by: Ricky WU <ricky_wu@realtek.com>
> Signed-off-by: Avri Altman <avri.altman@wdc.com>
> ---
>  drivers/mmc/core/block.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
> index 2c9963248fcb..1129f4e1a268 100644
> --- a/drivers/mmc/core/block.c
> +++ b/drivers/mmc/core/block.c
> @@ -180,6 +180,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
>  static void mmc_blk_hsq_req_done(struct mmc_request *mrq);
>  static int mmc_spi_err_check(struct mmc_card *card);
>  static int mmc_blk_busy_cb(void *cb_data, bool *busy);
> +static int mmc_blk_wait_for_idle(struct mmc_queue *mq, struct mmc_host *host);
>
>  static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
>  {
> @@ -1664,7 +1665,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
>
>         brq->mrq.cmd = &brq->cmd;
>
> -       brq->cmd.arg = blk_rq_pos(req);
> +       brq->cmd.arg = blk_rq_pos(req) & 0xFFFFFFFF;
>         if (!mmc_card_blockaddr(card))
>                 brq->cmd.arg <<= 9;
>         brq->cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
> @@ -1712,6 +1713,9 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
>                         (do_data_tag ? (1 << 29) : 0);
>                 brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
>                 brq->mrq.sbc = &brq->sbc;
> +       } else if (mmc_card_is_sduc(card->host)) {
> +               mmc_blk_wait_for_idle(mq, card->host);

If I understand correctly, this means the async request mechanism will
not be disabled for SDUC cards.

Maybe this is the easiest way to move this forward for now, but it's
still a bit sad if we can't keep using it for SDUC cards too.

No matter what, can you please elaborate why you have chosen this approach?

> +               mmc_send_ext_addr(card->host, blk_rq_pos(req));
>         }
>  }
>
> --
> 2.25.1
>

Kind regards
Uffe
Ulf Hansson Aug. 22, 2024, 12:24 p.m. UTC | #2
On Thu, 22 Aug 2024 at 14:23, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>
> On Wed, 14 Aug 2024 at 09:31, Avri Altman <avri.altman@wdc.com> wrote:
> >
> > For open-ended read/write - just send CMD22 before issuing the command.
> > While at it, make sure that the rw command arg is properly casting the
> > lower 32 bits, as it can be larger now.
> >
> > Tested-by: Ricky WU <ricky_wu@realtek.com>
> > Signed-off-by: Avri Altman <avri.altman@wdc.com>
> > ---
> >  drivers/mmc/core/block.c | 6 +++++-
> >  1 file changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
> > index 2c9963248fcb..1129f4e1a268 100644
> > --- a/drivers/mmc/core/block.c
> > +++ b/drivers/mmc/core/block.c
> > @@ -180,6 +180,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
> >  static void mmc_blk_hsq_req_done(struct mmc_request *mrq);
> >  static int mmc_spi_err_check(struct mmc_card *card);
> >  static int mmc_blk_busy_cb(void *cb_data, bool *busy);
> > +static int mmc_blk_wait_for_idle(struct mmc_queue *mq, struct mmc_host *host);
> >
> >  static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
> >  {
> > @@ -1664,7 +1665,7 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
> >
> >         brq->mrq.cmd = &brq->cmd;
> >
> > -       brq->cmd.arg = blk_rq_pos(req);
> > +       brq->cmd.arg = blk_rq_pos(req) & 0xFFFFFFFF;
> >         if (!mmc_card_blockaddr(card))
> >                 brq->cmd.arg <<= 9;
> >         brq->cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
> > @@ -1712,6 +1713,9 @@ static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
> >                         (do_data_tag ? (1 << 29) : 0);
> >                 brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
> >                 brq->mrq.sbc = &brq->sbc;
> > +       } else if (mmc_card_is_sduc(card->host)) {
> > +               mmc_blk_wait_for_idle(mq, card->host);
>
> If I understand correctly, this means the async request mechanism will
> not be disabled for SDUC cards.

/s/will not/will

>
> Maybe this is the easiest way to move this forward for now, but it's
> still a bit sad if we can't keep using it for SDUC cards too.
>
> No matter what, can you please elaborate why you have chosen this approach?
>
> > +               mmc_send_ext_addr(card->host, blk_rq_pos(req));
> >         }
> >  }
> >
> > --
> > 2.25.1
> >
>
> Kind regards
> Uffe
Avri Altman Aug. 22, 2024, 1:43 p.m. UTC | #3
> On Thu, 22 Aug 2024 at 14:23, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> >
> > On Wed, 14 Aug 2024 at 09:31, Avri Altman <avri.altman@wdc.com>
> wrote:
> > >
> > > For open-ended read/write - just send CMD22 before issuing the
> command.
> > > While at it, make sure that the rw command arg is properly casting
> > > the lower 32 bits, as it can be larger now.
> > >
> > > Tested-by: Ricky WU <ricky_wu@realtek.com>
> > > Signed-off-by: Avri Altman <avri.altman@wdc.com>
> > > ---
> > >  drivers/mmc/core/block.c | 6 +++++-
> > >  1 file changed, 5 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
> > > index 2c9963248fcb..1129f4e1a268 100644
> > > --- a/drivers/mmc/core/block.c
> > > +++ b/drivers/mmc/core/block.c
> > > @@ -180,6 +180,7 @@ static void mmc_blk_rw_rq_prep(struct
> > > mmc_queue_req *mqrq,  static void mmc_blk_hsq_req_done(struct
> > > mmc_request *mrq);  static int mmc_spi_err_check(struct mmc_card
> > > *card);  static int mmc_blk_busy_cb(void *cb_data, bool *busy);
> > > +static int mmc_blk_wait_for_idle(struct mmc_queue *mq, struct
> > > +mmc_host *host);
> > >
> > >  static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)  { @@
> > > -1664,7 +1665,7 @@ static void mmc_blk_rw_rq_prep(struct
> > > mmc_queue_req *mqrq,
> > >
> > >         brq->mrq.cmd = &brq->cmd;
> > >
> > > -       brq->cmd.arg = blk_rq_pos(req);
> > > +       brq->cmd.arg = blk_rq_pos(req) & 0xFFFFFFFF;
> > >         if (!mmc_card_blockaddr(card))
> > >                 brq->cmd.arg <<= 9;
> > >         brq->cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 |
> MMC_CMD_ADTC;
> > > @@ -1712,6 +1713,9 @@ static void mmc_blk_rw_rq_prep(struct
> mmc_queue_req *mqrq,
> > >                         (do_data_tag ? (1 << 29) : 0);
> > >                 brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
> > >                 brq->mrq.sbc = &brq->sbc;
> > > +       } else if (mmc_card_is_sduc(card->host)) {
> > > +               mmc_blk_wait_for_idle(mq, card->host);
> >
> > If I understand correctly, this means the async request mechanism will
> > not be disabled for SDUC cards.
> 
> /s/will not/will
Originally, I wasn't waiting for idle.
I added it because on some platforms, for a series of requests,
At some point the host controller was sending the read or write before cmd22.
I thought this approach would assure the proper sequence, without quirking a bunch of hw.
I am open for other suggestions though.

Thanks,
Avri
> 
> >
> > Maybe this is the easiest way to move this forward for now, but it's
> > still a bit sad if we can't keep using it for SDUC cards too.
> >
> > No matter what, can you please elaborate why you have chosen this
> approach?
> >
> > > +               mmc_send_ext_addr(card->host, blk_rq_pos(req));
> > >         }
> > >  }
> > >
> > > --
> > > 2.25.1
> > >
> >
> > Kind regards
> > Uffe
diff mbox series

Patch

diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
index 2c9963248fcb..1129f4e1a268 100644
--- a/drivers/mmc/core/block.c
+++ b/drivers/mmc/core/block.c
@@ -180,6 +180,7 @@  static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
 static void mmc_blk_hsq_req_done(struct mmc_request *mrq);
 static int mmc_spi_err_check(struct mmc_card *card);
 static int mmc_blk_busy_cb(void *cb_data, bool *busy);
+static int mmc_blk_wait_for_idle(struct mmc_queue *mq, struct mmc_host *host);
 
 static struct mmc_blk_data *mmc_blk_get(struct gendisk *disk)
 {
@@ -1664,7 +1665,7 @@  static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
 
 	brq->mrq.cmd = &brq->cmd;
 
-	brq->cmd.arg = blk_rq_pos(req);
+	brq->cmd.arg = blk_rq_pos(req) & 0xFFFFFFFF;
 	if (!mmc_card_blockaddr(card))
 		brq->cmd.arg <<= 9;
 	brq->cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
@@ -1712,6 +1713,9 @@  static void mmc_blk_rw_rq_prep(struct mmc_queue_req *mqrq,
 			(do_data_tag ? (1 << 29) : 0);
 		brq->sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
 		brq->mrq.sbc = &brq->sbc;
+	} else if (mmc_card_is_sduc(card->host)) {
+		mmc_blk_wait_for_idle(mq, card->host);
+		mmc_send_ext_addr(card->host, blk_rq_pos(req));
 	}
 }