From: Tony Lindgren <tony@atomide.com>
To: Ladislav Michl <ladis@linux-mips.org>
Cc: linux-omap@vger.kernel.org, juha.yrjola@nokia.com
Subject: Re: mmci-omap regressions
Date: Thu, 22 Oct 2009 15:01:54 -0700 [thread overview]
Message-ID: <20091022220154.GZ16230@atomide.com> (raw)
In-Reply-To: <20091021211506.GA6498@localhost.localdomain>
* Ladislav.Michl@seznam.cz <Ladislav.Michl@seznam.cz> [091021 12:15]:
> Hmm, it seems noone is going to fix it for me, so let's move on...
>
> On Mon, Jan 12, 2009 at 12:42:43PM +0200, Tony Lindgren wrote:
> > Hi,
> >
> > * Ladislav Michl <ladis@linux-mips.org> [090112 11:19]:
> > > Last time I used MMC card with linux-2.6.15-omap2 and it worked pretty well on
> > > my custom 5910 based board. Current git nor linux-2.6.22-omap1 (currently used
> > > for production) doesn't work at all. Inspecting diff between 2.6.15-omap2 and
> > > 2.6.22-omap1 showed that
> > > --- a/drivers/mmc/host/omap.c 2009-01-12 09:32:23.000000000 +0100
> > > +++ b/drivers/mmc/host/omap.c 2009-01-12 09:46:26.000000000 +0100
> > > @@ -974,7 +974,7 @@
> > > * Writing to the CON register twice seems to do the trick. */
> > > for (i = 0; i < 2; i++)
> > > OMAP_MMC_WRITE(host, CON, dsor);
> > > - if (ios->power_mode == MMC_POWER_ON) {
> > > + if (ios->power_mode == MMC_POWER_UP) {
> > > /* Send clock cycles, poll completion */
> > > OMAP_MMC_WRITE(host, IE, 0);
> > > OMAP_MMC_WRITE(host, STAT, 0xffff);
> > > did the trick.
> > >
> > > With above patch applied to 2.6.22-omap1 I got
> > > # modprobe omap
> > > mmci-omap mmci-omap.1: command timeout, CMD 8
> > > mmcblk0: mmc0:0001 127104KiB
> > > mmcblk0: p1
> > > while there is no command timeout with 2.6.15-omap2, but at least it works.
> >
> > OK, well at least that's a good start on figuring out what has broken
> > it. It does not seem like the right fix though as the MMC_POWER_UP
> > should just power up the slot, and clocks should not get turned on
> > until in MMC_POWER_ON.
> >
> > > Doing the same modification in current git doesn't help. Moreover removing
> > > omap.ko and inserting again behaves differently than inserting for first
> > > time:
> > > # modprobe omap
> > > mmci-omap mmci-omap.0: command timeout (CMD8)
> > > mmci-omap mmci-omap.0: command timeout (CMD5)
> > > mmci-omap mmci-omap.0: command timeout (CMD5)
> > > mmci-omap mmci-omap.0: command timeout (CMD5)
> > > mmci-omap mmci-omap.0: command timeout (CMD5)
> > > mmci-omap mmci-omap.0: command timeout (CMD55)
> > > mmci-omap mmci-omap.0: command timeout (CMD55)
> > > mmci-omap mmci-omap.0: command timeout (CMD55)
> > > mmci-omap mmci-omap.0: command timeout (CMD55)
> > > mmc0: error -22 whilst initialising MMC card
> > > # rmmod omap
> > > # modprobe omap
> > > mmci-omap: probe of mmci-omap.0 failed with error -16
> >
> > Looks like the current git head does goto exit after MMC_POWER_UP before
> > you even get to that code.
> >
> > > I'll happily send any requested debug informations and test any patches
> >
> > Can you maybe try to debug by applying your patch and commenting out
> > the goto exit?
>
> Here is somehow working version. It seems sending init stream multiple times
> is not good idea. Please note I have no clue how is MMC supposed to work
> (except very basic knowledge).
>
> So with the patch (complete patch, see mmc driver fixes I posted earlier today)
> below, output looks like:
>
> # modprobe omap
> MMC_POWER_OFF
> MMC dsor: 0
> MMC_POWER_UP
> MMC_POWER_ON
> MMC dsor: 878
> time elapsed: 254us
> MMC_POWER_ON
> MMC dsor: 878
> MMC_POWER_ON
> MMC dsor: 878
> mmci-omap mmci-omap.0: command timeout (CMD8)
> mmci-omap mmci-omap.0: command timeout (CMD5)
> mmci-omap mmci-omap.0: command timeout (CMD5)
> mmci-omap mmci-omap.0: command timeout (CMD5)
> mmci-omap mmci-omap.0: command timeout (CMD5)
> mmci-omap mmci-omap.0: command timeout (CMD55)
> mmci-omap mmci-omap.0: command timeout (CMD55)
> mmci-omap mmci-omap.0: command timeout (CMD55)
> mmci-omap mmci-omap.0: command timeout (CMD55)
> MMC_POWER_ON
> MMC dsor: 878
> MMC_POWER_ON
> MMC dsor: 878
> MMC_POWER_ON
> MMC dsor: 878
> MMC_POWER_ON
> MMC dsor: 878
> MMC_POWER_ON
> MMC dsor: 803
> mmc0: new MMC card at address 0001
> mmcblk0: mmc0:0001 D0601 122 MiB
> mmcblk0:
> p1
>
> Note, that "command timeout" is still there, but at least it detect card and
> also note that "worst case at 400kHz, 80 cycles makes 200 microsecs" took
> actually more than 200us.
Good to hear. Can you please resend this too to the mmc list?
Regards,
Tony
> diff --git a/drivers/mmc/host/omap.c b/drivers/mmc/host/omap.c
> index 5d773b8..0bcd6b0 100644
> --- a/drivers/mmc/host/omap.c
> +++ b/drivers/mmc/host/omap.c
> @@ -123,15 +123,16 @@ struct mmc_omap_host {
> struct mmc_data * data;
> struct mmc_host * mmc;
> struct device * dev;
> - unsigned char id; /* 16xx chips have 2 MMC blocks */
> struct clk * iclk;
> struct clk * fclk;
> struct resource *mem_res;
> void __iomem *virt_base;
> unsigned int phys_base;
> int irq;
> + unsigned char id; /* 16xx chips have 2 MMC blocks */
> unsigned char bus_mode;
> unsigned char hw_bus_mode;
> + unsigned char power_mode;
>
> struct work_struct cmd_abort_work;
> unsigned abort:1;
> @@ -1233,7 +1234,7 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> struct mmc_omap_slot *slot = mmc_priv(mmc);
> struct mmc_omap_host *host = slot->host;
> int i, dsor;
> - int clk_enabled;
> + int clk_enabled, init_stream;
>
> mmc_omap_select_slot(slot, 0);
>
> @@ -1243,20 +1244,27 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> slot->vdd = ios->vdd;
>
> clk_enabled = 0;
> + init_stream = 0;
> switch (ios->power_mode) {
> case MMC_POWER_OFF:
> + printk("MMC_POWER_OFF\n");
> mmc_omap_set_power(slot, 0, ios->vdd);
> break;
> case MMC_POWER_UP:
> + printk("MMC_POWER_UP\n");
> /* Cannot touch dsor yet, just power up MMC */
> mmc_omap_set_power(slot, 1, ios->vdd);
> + host->power_mode = ios->power_mode;
> goto exit;
> case MMC_POWER_ON:
> + printk("MMC_POWER_ON\n");
> mmc_omap_fclk_enable(host, 1);
> clk_enabled = 1;
> - dsor |= 1 << 11;
> + if (host->power_mode != MMC_POWER_ON)
> + init_stream = 1;
> break;
> }
> + host->power_mode = ios->power_mode;
>
> if (slot->bus_mode != ios->bus_mode) {
> if (slot->pdata->set_bus_mode != NULL)
> @@ -1269,12 +1277,15 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> * goes somehow out of sync, and the POW bit is not being set,
> * which results in the while loop below getting stuck.
> * Writing to the CON register twice seems to do the trick. */
> + if (ios->power_mode == MMC_POWER_ON)
> + dsor |= 1 << 11;
> + printk("MMC dsor: %x\n", dsor);
> for (i = 0; i < 2; i++)
> OMAP_MMC_WRITE(host, CON, dsor);
> slot->saved_con = dsor;
> - if (ios->power_mode == MMC_POWER_ON) {
> + if (init_stream) {
> /* worst case at 400kHz, 80 cycles makes 200 microsecs */
> - int usecs = 250;
> + int usecs = 512;
>
> /* Send clock cycles, poll completion */
> OMAP_MMC_WRITE(host, IE, 0);
> @@ -1285,8 +1296,8 @@ static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> usecs--;
> }
> OMAP_MMC_WRITE(host, STAT, 1);
> + printk("time elapsed: %dus\n", 512 - usecs);
> }
> -
> exit:
> mmc_omap_release_slot(slot, clk_enabled);
> }
> @@ -1445,6 +1456,7 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
> platform_set_drvdata(pdev, host);
>
> host->id = pdev->id;
> + host->power_mode = -1;
> host->mem_res = res;
> host->irq = irq;
>
> @@ -1459,8 +1471,10 @@ static int __init mmc_omap_probe(struct platform_device *pdev)
> goto err_ioremap;
>
> host->iclk = clk_get(&pdev->dev, "ick");
> - if (IS_ERR(host->iclk))
> + if (IS_ERR(host->iclk)) {
> + ret = PTR_ERR(host->iclk);
> goto err_free_mmc_host;
> + }
> clk_enable(host->iclk);
>
> host->fclk = clk_get(&pdev->dev, "fck");
> @@ -1500,10 +1514,8 @@ err_free_irq:
> err_free_fclk:
> clk_put(host->fclk);
> err_free_iclk:
> - if (host->iclk != NULL) {
> - clk_disable(host->iclk);
> - clk_put(host->iclk);
> - }
> + clk_disable(host->iclk);
> + clk_put(host->iclk);
> err_free_mmc_host:
> iounmap(host->virt_base);
> err_ioremap:
> @@ -1529,6 +1541,7 @@ static int mmc_omap_remove(struct platform_device *pdev)
> host->pdata->cleanup(&pdev->dev);
>
> mmc_omap_fclk_enable(host, 0);
> + free_irq(host->irq, host);
> clk_put(host->fclk);
> clk_disable(host->iclk);
> clk_put(host->iclk);
>
> Hints and ideas welcome and appreciated :-)
>
> Thanks,
> ladis
next prev parent reply other threads:[~2009-10-22 22:01 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-01-12 9:17 mmci-omap regressions Ladislav Michl
2009-01-12 10:42 ` Tony Lindgren
2009-01-12 11:35 ` Ladislav Michl
2009-10-21 21:15 ` Ladislav.Michl
2009-10-22 22:01 ` Tony Lindgren [this message]
2009-01-20 1:10 ` Måns Rullgård
2009-01-20 9:36 ` andrzej zaborowski
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=20091022220154.GZ16230@atomide.com \
--to=tony@atomide.com \
--cc=juha.yrjola@nokia.com \
--cc=ladis@linux-mips.org \
--cc=linux-omap@vger.kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox