* [email protected] <[email protected]> [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 <[email protected]> [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
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to