Message ID | 1299844874-7605-3-git-send-email-lamiaposta71@gmail.com |
---|---|
State | Accepted |
Delegated to: | Andy Fleming |
Headers | show |
On Fri, Mar 11, 2011 at 8:01 PM, Raffaele Recalcati <lamiaposta71@gmail.com> wrote: > From: Raffaele Recalcati <raffaele.recalcati@bticino.it> > > The first SEND_OP_COND (CMD1) command added is used to ask card capabilities. > After it an AND operation is done between card capabilities and host > capabilities (at the moment only for the voltage field). > Finally the correct value is sent to the MMC, waiting that the card > exits from busy state. > > Signed-off-by: Raffaele Recalcati <raffaele.recalcati@bticino.it> > --- > drivers/mmc/mmc.c | 19 +++++++++++++++++-- > include/mmc.h | 2 ++ > 2 files changed, 19 insertions(+), 2 deletions(-) > > diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c > index fc1792a..5bea476 100644 > --- a/drivers/mmc/mmc.c > +++ b/drivers/mmc/mmc.c > @@ -351,17 +351,32 @@ sd_send_op_cond(struct mmc *mmc) > > int mmc_send_op_cond(struct mmc *mmc) > { > - int timeout = 1000; > + int timeout = 10000; > struct mmc_cmd cmd; > int err; > > /* Some cards seem to need this */ > mmc_go_idle(mmc); > > + /* Asking to the card its capabilities */ > + cmd.cmdidx = MMC_CMD_SEND_OP_COND; > + cmd.resp_type = MMC_RSP_R3; > + cmd.cmdarg = 0; > + cmd.flags = 0; > + > + err = mmc_send_cmd(mmc, &cmd, NULL); > + > + if (err) > + return err; > + > + udelay(1000); > + > do { > cmd.cmdidx = MMC_CMD_SEND_OP_COND; > cmd.resp_type = MMC_RSP_R3; > - cmd.cmdarg = OCR_HCS | mmc->voltages; > + cmd.cmdarg = ((mmc->voltages & > + (cmd.response[0] & OCR_VOLTAGE_MASK)) | > + (cmd.response[0] & OCR_ACCESS_MODE)); > cmd.flags = 0; > > err = mmc_send_cmd(mmc, &cmd, NULL); > diff --git a/include/mmc.h b/include/mmc.h > index 4ee8e1c..d18526d 100644 > --- a/include/mmc.h > +++ b/include/mmc.h > @@ -93,6 +93,8 @@ > > #define OCR_BUSY 0x80000000 > #define OCR_HCS 0x40000000 > +#define OCR_VOLTAGE_MASK 0x007FFF80 > +#define OCR_ACCESS_MODE 0x60000000 > > #define MMC_STATUS_MASK (~0x0206BF7F) > #define MMC_STATUS_RDY_FOR_DATA (1<<8) > -- > 1.7.0.4 > Works fine on Pantheon board. (armv5) Tested-by:Lei Wen <leiwen@marvell.com> Best regards, Lei
On Fri, Mar 11, 2011 at 6:01 AM, Raffaele Recalcati <lamiaposta71@gmail.com> wrote: > From: Raffaele Recalcati <raffaele.recalcati@bticino.it> > > The first SEND_OP_COND (CMD1) command added is used to ask card capabilities. > After it an AND operation is done between card capabilities and host > capabilities (at the moment only for the voltage field). > Finally the correct value is sent to the MMC, waiting that the card > exits from busy state. > > Signed-off-by: Raffaele Recalcati <raffaele.recalcati@bticino.it> > --- > drivers/mmc/mmc.c | 19 +++++++++++++++++-- > include/mmc.h | 2 ++ > 2 files changed, 19 insertions(+), 2 deletions(-) > > diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c > index fc1792a..5bea476 100644 > --- a/drivers/mmc/mmc.c > +++ b/drivers/mmc/mmc.c > @@ -351,17 +351,32 @@ sd_send_op_cond(struct mmc *mmc) > > int mmc_send_op_cond(struct mmc *mmc) > { > - int timeout = 1000; > + int timeout = 10000; > struct mmc_cmd cmd; > int err; > > /* Some cards seem to need this */ > mmc_go_idle(mmc); > > + /* Asking to the card its capabilities */ > + cmd.cmdidx = MMC_CMD_SEND_OP_COND; > + cmd.resp_type = MMC_RSP_R3; > + cmd.cmdarg = 0; > + cmd.flags = 0; > + > + err = mmc_send_cmd(mmc, &cmd, NULL); > + > + if (err) > + return err; > + > + udelay(1000); > + > do { > cmd.cmdidx = MMC_CMD_SEND_OP_COND; > cmd.resp_type = MMC_RSP_R3; > - cmd.cmdarg = OCR_HCS | mmc->voltages; > + cmd.cmdarg = ((mmc->voltages & > + (cmd.response[0] & OCR_VOLTAGE_MASK)) | > + (cmd.response[0] & OCR_ACCESS_MODE)); My concern here is that OCR_HCS has been dropped. I thought it was necessary to query the HCS abilities. I'm guessing I'm missing something, or that it's not needed, so I will apply this patch, and we'll see if anyone has issues. Andy
Hi Andy, On Wed, Apr 13, 2011 at 1:24 PM, Andy Fleming <afleming@gmail.com> wrote: > On Fri, Mar 11, 2011 at 6:01 AM, Raffaele Recalcati > <lamiaposta71@gmail.com> wrote: >> From: Raffaele Recalcati <raffaele.recalcati@bticino.it> >> >> The first SEND_OP_COND (CMD1) command added is used to ask card capabilities. >> After it an AND operation is done between card capabilities and host >> capabilities (at the moment only for the voltage field). >> Finally the correct value is sent to the MMC, waiting that the card >> exits from busy state. >> >> Signed-off-by: Raffaele Recalcati <raffaele.recalcati@bticino.it> >> --- >> drivers/mmc/mmc.c | 19 +++++++++++++++++-- >> include/mmc.h | 2 ++ >> 2 files changed, 19 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c >> index fc1792a..5bea476 100644 >> --- a/drivers/mmc/mmc.c >> +++ b/drivers/mmc/mmc.c >> @@ -351,17 +351,32 @@ sd_send_op_cond(struct mmc *mmc) >> >> int mmc_send_op_cond(struct mmc *mmc) >> { >> - int timeout = 1000; >> + int timeout = 10000; >> struct mmc_cmd cmd; >> int err; >> >> /* Some cards seem to need this */ >> mmc_go_idle(mmc); >> >> + /* Asking to the card its capabilities */ >> + cmd.cmdidx = MMC_CMD_SEND_OP_COND; >> + cmd.resp_type = MMC_RSP_R3; >> + cmd.cmdarg = 0; >> + cmd.flags = 0; >> + >> + err = mmc_send_cmd(mmc, &cmd, NULL); >> + >> + if (err) >> + return err; >> + >> + udelay(1000); >> + >> do { >> cmd.cmdidx = MMC_CMD_SEND_OP_COND; >> cmd.resp_type = MMC_RSP_R3; >> - cmd.cmdarg = OCR_HCS | mmc->voltages; >> + cmd.cmdarg = ((mmc->voltages & >> + (cmd.response[0] & OCR_VOLTAGE_MASK)) | >> + (cmd.response[0] & OCR_ACCESS_MODE)); > > > My concern here is that OCR_HCS has been dropped. I thought it was > necessary to query the HCS abilities. > > I'm guessing I'm missing something, or that it's not needed, so I will > apply this patch, and we'll see if anyone has issues. > > Andy > Thx, Raffaele
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index fc1792a..5bea476 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -351,17 +351,32 @@ sd_send_op_cond(struct mmc *mmc) int mmc_send_op_cond(struct mmc *mmc) { - int timeout = 1000; + int timeout = 10000; struct mmc_cmd cmd; int err; /* Some cards seem to need this */ mmc_go_idle(mmc); + /* Asking to the card its capabilities */ + cmd.cmdidx = MMC_CMD_SEND_OP_COND; + cmd.resp_type = MMC_RSP_R3; + cmd.cmdarg = 0; + cmd.flags = 0; + + err = mmc_send_cmd(mmc, &cmd, NULL); + + if (err) + return err; + + udelay(1000); + do { cmd.cmdidx = MMC_CMD_SEND_OP_COND; cmd.resp_type = MMC_RSP_R3; - cmd.cmdarg = OCR_HCS | mmc->voltages; + cmd.cmdarg = ((mmc->voltages & + (cmd.response[0] & OCR_VOLTAGE_MASK)) | + (cmd.response[0] & OCR_ACCESS_MODE)); cmd.flags = 0; err = mmc_send_cmd(mmc, &cmd, NULL); diff --git a/include/mmc.h b/include/mmc.h index 4ee8e1c..d18526d 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -93,6 +93,8 @@ #define OCR_BUSY 0x80000000 #define OCR_HCS 0x40000000 +#define OCR_VOLTAGE_MASK 0x007FFF80 +#define OCR_ACCESS_MODE 0x60000000 #define MMC_STATUS_MASK (~0x0206BF7F) #define MMC_STATUS_RDY_FOR_DATA (1<<8)