Re: Status of tmio_mmc DMA support for SDIO

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Just saw this - am I right in thinking someone has written SDIO
support for TMIO ? Im afraid I dont appear to have the preceeding
emails.

-- 
Ian Molton
Linux, Automotive, and other hacking:
http://www.mnementh.co.uk/



On 14 May 2010 09:35, Guennadi Liakhovetski <g.liakhovetski@xxxxxx> wrote:
> (added linux-mmc and tmio_mmc maintainer to CC)
>
> Hi Charles
>
> On Thu, 13 May 2010, Charles D. Krebs wrote:
>
>> Guennadi,
>>
>> I'm currently using the BSP 2.0 release (2.6.33) for the Renesas 7724
>> Ecovec platform.  I have two patches (see attached) that enable MMC
>> support and SDIO support in that version of the Kernel.
>
> Great, thanks for the patches!
>
> Regarding MMCIF, have you seen these patches:
>
> http://article.gmane.org/gmane.linux.kernel.mmc/1712
> http://article.gmane.org/gmane.linux.ports.sh.devel/7860
>
>> I've seen quite a bit of traffic lately over the linux-sh mailing list
>> regarding the addition of DMA to the tmio driver.  Unfortunately, I
>> really have no good idea as to what the status is of that development,
>> and whether or not it would apply to both MMC and SDIO modes of
>> operation.
>
> The status is: it passes my tests, as long as cache is in write-through
> mode. However, on ecovec I seem to have problems with SD: a simple
> mount-compare-overwrite-umount loop aborts even without DMA after a few
> hundreds of iterations (under 600 in one of my tests) and it happens even
> faster with DMA. However, I haven't repeated this test with the latest
> version of the patches, will do it at some point.
>
>> That said, it looks like at least patch [4/b9 v4] has a few
>> parts that accomplish both MMC and SDIO support separately.
>
> Really? I was unaware of that;) I don't think there is any SDIO specific
> code in that or in any other of my patches for tmio_mmc.
>
>> We have an SDIO based 802.11 b/g/n radio that could definitely benefit
>> from DMA support.  At this point, what patches I would need to apply,
>> and what configuration changes to the kernel are necessary to test this
>> functionality out?  Are there any known limitations to the new code for
>> SDIO support?
>
> This is the basis patch series:
>
> http://thread.gmane.org/gmane.linux.kernel.mmc/1780
>
> in which patch 4/9 you replace with these three patches:
>
> http://thread.gmane.org/gmane.linux.ports.sh.devel/8068
>
> As for SDIO, there's only one limitation: it's not implemented yet;) But
> looking at your patch, it looks like it doesn't touch data paths, only
> command paths. So, so far I don't see any reason, why DMA shouldn't work
> for you out of the box... However, you seem to have much more knowledge
> about tmio unit internals, so, maybe you can just check with your
> documentation. As for changes - do not forget to enable the shdma
> dmaengine driver. And look in /proc/interrupts during your tests to see if
> you're getting any DMA interrupts. You shall see two DMA channels, used
> per SDHI controller - for Tx and Rx.
>
>> We have a team at Redpine Signals in India that is currently working on
>> the implementation of the radio driver.  I'd like to introduce Sailaja
>> Sankabathula, Applications Engineering Manager, who is managing the
>> project.  I know that the Redpine team is eager to work through a couple
>> of issues that they are seeing with the current code that we have, and
>> that they are more than happy to help debug the new DMA enabled driver
>> code and share the results with the community via any means you think
>> best (I'd presume at least by copying the linux-sh mailing list).
>
> That right, and also the mmc list and the driver maintainer.
>
>> I'm still rather new to the community development aspect of the Linux kernel -
>> Is there somewhere I can read up about the general development procedure
>> here and how to best interface with the mailing lists?
>
> There are a couple of documents in the Linux kernel source tree, that you
> might find useful:
>
> Documentation/SubmitChecklist
> Documentation/SubmittingPatches
> Documentation/SubmittingDrivers
> Documentation/CodingStyle
> Documentation/email-clients.txt
>
>> I tend to feel a little lost in not knowing what version of the kernel
>> these patches are referenced to, if the patches are regularly checked
>> into the kernel repository, etc.
>
> Documents under
>
> Documentation/development-process/
>
> should give you an idea. In short: kernel is being developed in multiple
> topic trees, dedicated to various architectures, drivers, subsystems, etc.
> You work with one or several of those trees, relevant for your
> development, submit your patches to respective mailing lists and
> maintainers, and during the merge window (first two weeks after a final
> kernel version release) those trees get merged into the central kernel
> tree. Bug-fixes can be merged in at any time, of course.
>
> As for your patch, I think, Ian will have a good look at it, so far a
> couple of quick comments:
>
>> diff -Naur sh-2.6_bsp/arch/sh/kernel/cpu/sh4a/setup-sh7724.c sh-2.6_presdio/arch/sh/kernel/cpu/sh4a/setup-sh7724.c
>> --- sh-2.6_bsp/arch/sh/kernel/cpu/sh4a/setup-sh7724.c 2010-03-25 04:48:00.000000000 +0000
>> +++ sh-2.6_presdio/arch/sh/kernel/cpu/sh4a/setup-sh7724.c     2010-04-06 07:48:37.000000000 +0000
>> @@ -890,7 +890,7 @@
>>  static struct intc_mask_reg mask_registers[] __initdata = {
>>       { 0xa4080080, 0xa40800c0, 8, /* IMR0 / IMCR0 */
>>         { 0, TMU1_TUNI2, TMU1_TUNI1, TMU1_TUNI0,
>> -         0, DISABLED, ENABLED, ENABLED } },
>> +         0, ENABLED, ENABLED, ENABLED } },
>>       { 0xa4080084, 0xa40800c4, 8, /* IMR1 / IMCR1 */
>>         { VIO_VOU, VIO_VEU1, VIO_BEU0, VIO_CEU0,
>>           DMAC0A_DEI3, DMAC0A_DEI2, DMAC0A_DEI1, DMAC0A_DEI0 } },
>> diff -Naur sh-2.6_bsp/drivers/mfd/sh_mobile_sdhi.c sh-2.6_presdio/drivers/mfd/sh_mobile_sdhi.c
>> --- sh-2.6_bsp/drivers/mfd/sh_mobile_sdhi.c   2010-03-25 04:48:00.000000000 +0000
>> +++ sh-2.6_presdio/drivers/mfd/sh_mobile_sdhi.c       2010-04-06 07:48:37.000000000 +0000
>> @@ -97,7 +97,7 @@
>>
>>       priv->mmc_data.hclk = clk_get_rate(priv->clk);
>>       priv->mmc_data.set_pwr = sh_mobile_sdhi_set_pwr;
>> -     priv->mmc_data.capabilities = MMC_CAP_MMC_HIGHSPEED;
>> +     priv->mmc_data.capabilities = MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SDIO_IRQ;
>>
>>       memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc));
>>       priv->cell_mmc.driver_data = &priv->mmc_data;
>> diff -Naur sh-2.6_bsp/drivers/mmc/host/tmio_mmc.c sh-2.6_presdio/drivers/mmc/host/tmio_mmc.c
>> --- sh-2.6_bsp/drivers/mmc/host/tmio_mmc.c    2010-03-25 04:48:00.000000000 +0000
>> +++ sh-2.6_presdio/drivers/mmc/host/tmio_mmc.c        2010-04-06 07:48:37.000000000 +0000
>> @@ -30,6 +30,7 @@
>>  #include <linux/device.h>
>>  #include <linux/delay.h>
>>  #include <linux/mmc/host.h>
>> +#include <linux/mmc/sdio.h>
>>  #include <linux/mfd/core.h>
>>  #include <linux/mfd/tmio.h>
>>
>> @@ -146,6 +147,28 @@
>>                       c |= TRANSFER_READ;
>>       }
>>
>> +     switch (cmd->opcode) {
>> +     case SD_IO_RW_DIRECT:
>> +             sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
>> +             enable_mmc_sdio_irqs(host, TMIO_SDIO_STAT_IOIRQ);
>> +             break;
>> +     case SD_IO_RW_EXTENDED:
>> +             sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
>> +             enable_mmc_sdio_irqs(host, TMIO_SDIO_STAT_IOIRQ);
>> +             if (data->flags & MMC_DATA_READ) {
>> +                     if (data->sg->length <= 512)
>> +                             c = CMD_SD_IO_RW_EXTENDED_SREAD;
>> +                     else
>> +                             c = CMD_SD_IO_RW_EXTENDED_MREAD;
>> +             } else { /* MMC_DATA_WRITE */
>> +                     if (data->sg->length <= 512)
>> +                             c = CMD_SD_IO_RW_EXTENDED_SWRITE;
>> +                     else
>> +                             c = CMD_SD_IO_RW_EXTENDED_MWRITE;
>> +             }
>> +             break;
>> +     }
>> +
>>       enable_mmc_irqs(host, TMIO_MASK_CMD);
>>
>>       /* Fire off the command */
>> @@ -235,8 +258,13 @@
>>       if (stop) {
>>               if (stop->opcode == 12 && !stop->arg)
>>                       sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x000);
>> +#if 0
>
> I realise, this wasn't a final patch submission, but just a remark - you
> don't want commented out code in the final version
>
>> +     /* CMD_SD_IO_RW_EXTENDED_MREAD and CMD_SD_IO_RW_EXTENDED_MWRITE
>> +      * are not necessary.
>> +      */
>
> multi-line comment style is wrong. Should have been
>
> +       /*
> +        * CMD_SD_IO_RW_EXTENDED_MREAD and CMD_SD_IO_RW_EXTENDED_MWRITE
> +        * are not necessary.
> +        */
>
>>               else
>>                       BUG();
>> +#endif
>
> But essentially, maybe you can preserve this check and just replace:
>
>> -                     BUG();
>> +                     BUG_ON(host->cmd->opcode != SD_IO_RW_EXTENDED);
>
> or something similar.
>
>>       }
>>
>>       tmio_mmc_finish_request(host);
>> @@ -298,6 +326,7 @@
>>  {
>>       struct tmio_mmc_host *host = devid;
>>       unsigned int ireg, irq_mask, status;
>> +     unsigned short ireg_io, irq_mask_io, status_io;
>
> I would use u16 to explicitly specify 16-bit data.
>
>>
>>       pr_debug("MMC IRQ begin\n");
>>
>> @@ -305,15 +334,31 @@
>>       irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK);
>>       ireg = status & TMIO_MASK_IRQ & ~irq_mask;
>>
>> +     status_io = sd_ctrl_read16(host, CTL_SDIO_STATUS);
>> +     irq_mask_io = sd_ctrl_read16(host, CTL_SDIO_IRQ_MASK);
>> +     ireg_io = status_io & TMIO_SDIO_MASK_IRQ & ~irq_mask_io;
>> +
>>       pr_debug_status(status);
>>       pr_debug_status(ireg);
>>
>>       if (!ireg) {
>> +             if (ireg_io & TMIO_SDIO_STAT_IOIRQ) {
>> +                     ack_mmc_sdio_irqs(host, TMIO_SDIO_STAT_IOIRQ);
>> +                     mmc_signal_sdio_irq(host->mmc);
>> +             } else if (ireg_io & TMIO_SDIO_STAT_EXWT)
>> +                     ack_mmc_sdio_irqs(host, TMIO_SDIO_STAT_EXWT);
>> +             else if (ireg_io & TMIO_SDIO_STAT_EXPUB52)
>> +                     ack_mmc_sdio_irqs(host, TMIO_SDIO_STAT_EXPUB52);
>> +             else
>> +                     ack_mmc_sdio_irqs(host, TMIO_SDIO_STAT_RESERVE);
>> +
>> +#if 0
>>               disable_mmc_irqs(host, status & ~irq_mask);
>>
>>               pr_debug("tmio_mmc: Spurious irq, disabling! "
>>                       "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg);
>>               pr_debug_status(status);
>> +#endif
>
> Same here, I think, you can preserve this interrupt disabling, if you
> extend the test to mean "no SD and no SDIO bit is set."
>
>>
>>               goto out;
>>       }
>> @@ -321,6 +366,12 @@
>>       while (ireg) {
>>               /* Card insert / remove attempts */
>>               if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) {
>> +                     if (ireg & TMIO_STAT_CARD_REMOVE) {
>> +                             sd_ctrl_write16(host,
>> +                                     CTL_TRANSACTION_CTL, 0x0000);
>> +                             disable_mmc_sdio_irqs(host,
>> +                                     TMIO_SDIO_STAT_IOIRQ);
>> +                     }
>>                       ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT |
>>                               TMIO_STAT_CARD_REMOVE);
>>                       mmc_detect_change(host->mmc, msecs_to_jiffies(100));
>> @@ -462,10 +513,20 @@
>>       return (sd_ctrl_read16(host, CTL_STATUS) & TMIO_STAT_WRPROTECT) ? 0 : 1;
>>  }
>>
>> +static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
>> +{
>> +     struct tmio_mmc_host *host = mmc_priv(mmc);
>> +     if (enable)
>> +             enable_mmc_sdio_irqs(host, TMIO_SDIO_STAT_IOIRQ);
>> +     else
>> +             disable_mmc_sdio_irqs(host, TMIO_SDIO_STAT_IOIRQ);
>> +}
>> +
>>  static struct mmc_host_ops tmio_mmc_ops = {
>>       .request        = tmio_mmc_request,
>>       .set_ios        = tmio_mmc_set_ios,
>>       .get_ro         = tmio_mmc_get_ro,
>> +     .enable_sdio_irq = tmio_mmc_enable_sdio_irq,
>
> Don't be shy, add one more TAB to all struct members to align them
> properly;)
>
>>  };
>>
>>  #ifdef CONFIG_PM
>> diff -Naur sh-2.6_bsp/drivers/mmc/host/tmio_mmc.h sh-2.6_presdio/drivers/mmc/host/tmio_mmc.h
>> --- sh-2.6_bsp/drivers/mmc/host/tmio_mmc.h    2010-03-25 04:48:00.000000000 +0000
>> +++ sh-2.6_presdio/drivers/mmc/host/tmio_mmc.h        2010-04-06 07:48:37.000000000 +0000
>> @@ -24,6 +24,8 @@
>>  #define CTL_SD_ERROR_DETAIL_STATUS 0x2c
>>  #define CTL_SD_DATA_PORT 0x30
>>  #define CTL_TRANSACTION_CTL 0x34
>> +#define CTL_SDIO_STATUS 0x36
>> +#define CTL_SDIO_IRQ_MASK 0x38
>>  #define CTL_RESET_SD 0xe0
>>  #define CTL_SDIO_REGS 0x100
>>  #define CTL_CLK_AND_WAIT_CTL 0x138
>> @@ -62,6 +64,23 @@
>>  #define TMIO_MASK_IRQ     (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD)
>>
>>
>> +/* Definitions for values the CTRL_SDIO_STATUS register can take. */
>> +#define TMIO_SDIO_STAT_RESERVE       0x0006 /* reserve bit */
>> +#define TMIO_SDIO_STAT_IOIRQ 0x0001
>> +#define TMIO_SDIO_STAT_EXPUB52       0x4000
>> +#define TMIO_SDIO_STAT_EXWT  0x8000
>> +
>> +#define CMD_SD_IO_RW_EXTENDED_SREAD  0x1C35
>> +#define CMD_SD_IO_RW_EXTENDED_MREAD  0x7C35
>> +#define CMD_SD_IO_RW_EXTENDED_SWRITE 0x0C35
>> +#define CMD_SD_IO_RW_EXTENDED_MWRITE 0x6C35
>
> You can put these four lines in tmio_mmc.c, and maybe "SDIO" without an
> underscore?
>
>> +
>> +/* Define some SDIO IRQ masks */
>> +#define TMIO_SDIO_MASK_IRQ   (TMIO_SDIO_STAT_IOIRQ   | \
>> +                              TMIO_SDIO_STAT_EXPUB52 | \
>> +                              TMIO_SDIO_STAT_EXWT    | \
>> +                              TMIO_SDIO_STAT_RESERVE)
>> +
>>  #define enable_mmc_irqs(host, i) \
>>       do { \
>>               u32 mask;\
>> @@ -86,6 +105,29 @@
>>               sd_ctrl_write32((host), CTL_STATUS, mask); \
>>       } while (0)
>>
>> +#define enable_mmc_sdio_irqs(host, i) \
>> +     do { \
>> +             u16 mask;\
>> +             mask  = sd_ctrl_read16((host), CTL_SDIO_IRQ_MASK); \
>> +             mask &= ~((i) & TMIO_SDIO_MASK_IRQ); \
>> +             sd_ctrl_write16((host), CTL_SDIO_IRQ_MASK, mask); \
>> +     } while (0)
>> +
>> +#define disable_mmc_sdio_irqs(host, i) \
>> +     do { \
>> +             u16 mask;\
>> +             mask  = sd_ctrl_read16((host), CTL_SDIO_IRQ_MASK); \
>> +             mask |= ((i) & TMIO_SDIO_MASK_IRQ); \
>> +             sd_ctrl_write16((host), CTL_SDIO_IRQ_MASK, mask); \
>> +     } while (0)
>> +
>> +#define ack_mmc_sdio_irqs(host, i) \
>> +     do { \
>> +             u16 mask;\
>> +             mask  = sd_ctrl_read16((host), CTL_SDIO_STATUS); \
>> +             mask &= ~((i) & TMIO_SDIO_MASK_IRQ); \
>> +             sd_ctrl_write16((host), CTL_SDIO_STATUS, mask); \
>> +     } while (0)
>>
>>  struct tmio_mmc_host {
>>       void __iomem *ctl;
>
> Thanks
> Guennadi
> ---
> Guennadi Liakhovetski, Ph.D.
> Freelance Open-Source Software Developer
> http://www.open-technology.de/
>
--
To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux USB Devel]     [Linux Media]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux