lkml.org 
[lkml]   [2010]   [Jul]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    SubjectRe: [PATCH] mmc: MMC 4.4 DDR support
    From
    On Sat, Jul 10, 2010 at 2:28 PM, Kyungmin Park <kmpark@infradead.org> wrote:
    > Hi,
    >
    > Looks good to me except where's use the MMC_DDR_MODE. why do you set
    > brq.data.flags |= MMC_DDR_MODE?
    >
    > Now my SDHCI host don't support eMMC 4.4 but the end of july I can test it.
    Fixing eMMC 4.4 means DDR features at host.
    >
    > Thank you,
    > Kyungmin Park
    >
    > On Fri, Jul 9, 2010 at 3:59 PM, Hanumath Prasad
    > <hanumath.prasad@stericsson.com> wrote:
    >> Add support for Dual Data Rate MMC cards as defined in the 4.4
    >> specification.
    >>
    >> Cc: linux-mmc@vger.kernel.org
    >> Acked-by: Linus Walleij <linus.walleij@stericsson.com>
    >> Signed-off-by: Hanumath Prasad <hanumath.prasad@stericsson.com>
    >> ---
    >>  drivers/mmc/card/block.c |   10 +++++++---
    >>  drivers/mmc/core/mmc.c   |   37 +++++++++++++++++++++++++++++++++++--
    >>  include/linux/mmc/card.h |    5 +++++
    >>  include/linux/mmc/core.h |    1 +
    >>  include/linux/mmc/host.h |    4 ++++
    >>  include/linux/mmc/mmc.h  |   11 +++++++++--
    >>  6 files changed, 61 insertions(+), 7 deletions(-)
    >>
    >> diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
    >> index cb9fbc8..4eb84eb 100644
    >> --- a/drivers/mmc/card/block.c
    >> +++ b/drivers/mmc/card/block.c
    >> @@ -299,7 +299,8 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
    >>                        readcmd = MMC_READ_SINGLE_BLOCK;
    >>                        writecmd = MMC_WRITE_BLOCK;
    >>                }
    >> -
    >> +               if (mmc_card_ddr_mode(card))
    >> +                       brq.data.flags |= MMC_DDR_MODE;
    >>                if (rq_data_dir(req) == READ) {
    >>                        brq.cmd.opcode = readcmd;
    >>                        brq.data.flags |= MMC_DATA_READ;
    >> @@ -569,8 +570,11 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
    >>        struct mmc_command cmd;
    >>        int err;
    >>
    >> -       /* Block-addressed cards ignore MMC_SET_BLOCKLEN. */
    >> -       if (mmc_card_blockaddr(card))
    >> +       /*
    >> +        * Block-addressed and ddr mode supported cards
    >> +        * ignore MMC_SET_BLOCKLEN.
    >> +        */
    >> +       if (mmc_card_blockaddr(card) || mmc_card_ddr_mode(card))
    >>                return 0;
    >>
    >>        mmc_claim_host(card->host);
    >> diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
    >> index 89f7a25..1d33503 100644
    >> --- a/drivers/mmc/core/mmc.c
    >> +++ b/drivers/mmc/core/mmc.c
    >> @@ -227,6 +227,21 @@ static int mmc_read_ext_csd(struct mmc_card *card)
    >>        }
    >>
    >>        switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
    >> +       case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 |
    >> +            EXT_CSD_CARD_TYPE_26:
    >> +               card->ext_csd.hs_max_dtr = 52000000;
    >> +               card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_52;
    >> +               break;
    >> +       case EXT_CSD_CARD_TYPE_DDR_1_2V | EXT_CSD_CARD_TYPE_52 |
    >> +            EXT_CSD_CARD_TYPE_26:
    >> +               card->ext_csd.hs_max_dtr = 52000000;
    >> +               card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_2V;
    >> +               break;
    >> +       case EXT_CSD_CARD_TYPE_DDR_1_8V | EXT_CSD_CARD_TYPE_52 |
    >> +            EXT_CSD_CARD_TYPE_26:
    >> +               card->ext_csd.hs_max_dtr = 52000000;
    >> +               card->ext_csd.card_type = EXT_CSD_CARD_TYPE_DDR_1_8V;
    >> +               break;
    >>        case EXT_CSD_CARD_TYPE_52 | EXT_CSD_CARD_TYPE_26:
    >>                card->ext_csd.hs_max_dtr = 52000000;
    >>                break;
    >> @@ -444,6 +459,18 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
    >>        mmc_set_clock(host, max_dtr);
    >>
    >>        /*
    >> +        * Activate DDR50 mode (if supported).
    >> +        */
    >> +       if (mmc_card_highspeed(card)) {
    >> +               if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V)
    >> +                       && (host->caps & (MMC_CAP_1_8V_DDR)))
    >> +                               mmc_card_set_ddr_mode(card);
    >> +               else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V)
    >> +                       && (host->caps & (MMC_CAP_1_2V_DDR)))
    >> +                               mmc_card_set_ddr_mode(card);
    >> +       }
    >> +
    >> +       /*
    >>         * Activate wide bus (if supported).
    >>         */
    >>        if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
    >> @@ -451,10 +478,16 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
    >>                unsigned ext_csd_bit, bus_width;
    >>
    >>                if (host->caps & MMC_CAP_8_BIT_DATA) {
    >> -                       ext_csd_bit = EXT_CSD_BUS_WIDTH_8;
    >> +                       if (mmc_card_ddr_mode(card))
    >> +                               ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_8;
    >> +                       else
    >> +                               ext_csd_bit = EXT_CSD_BUS_WIDTH_8;
    >>                        bus_width = MMC_BUS_WIDTH_8;
    >>                } else {
    >> -                       ext_csd_bit = EXT_CSD_BUS_WIDTH_4;
    >> +                       if (mmc_card_ddr_mode(card))
    >> +                               ext_csd_bit = EXT_CSD_DDR_BUS_WIDTH_4;
    >> +                       else
    >> +                               ext_csd_bit = EXT_CSD_BUS_WIDTH_4;
    >>                        bus_width = MMC_BUS_WIDTH_4;
    >>                }
    >>
    >> diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
    >> index d02d2c6..7d0aca8 100644
    >> --- a/include/linux/mmc/card.h
    >> +++ b/include/linux/mmc/card.h
    >> @@ -44,6 +44,7 @@ struct mmc_ext_csd {
    >>        unsigned int            sa_timeout;             /* Units: 100ns */
    >>        unsigned int            hs_max_dtr;
    >>        unsigned int            sectors;
    >> +       unsigned int            card_type;
    >>  };
    >>
    >>  struct sd_scr {
    >> @@ -97,6 +98,8 @@ struct mmc_card {
    >>  #define MMC_STATE_READONLY     (1<<1)          /* card is read-only */
    >>  #define MMC_STATE_HIGHSPEED    (1<<2)          /* card is in high speed mode */
    >>  #define MMC_STATE_BLOCKADDR    (1<<3)          /* card uses block-addressing */
    >> +#define MMC_STATE_HIGHSPEED_DDR (1<<4)          /* card is in high speed */
    >> +                                               /* dual data rate mode */
    >>        unsigned int            quirks;         /* card quirks */
    >>  #define MMC_QUIRK_LENIENT_FN0  (1<<0)          /* allow SDIO FN0 writes outside of the VS CCCR range */
    >>  #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1)   /* use func->cur_blksize */
    >> @@ -129,11 +132,13 @@ struct mmc_card {
    >>  #define mmc_card_present(c)    ((c)->state & MMC_STATE_PRESENT)
    >>  #define mmc_card_readonly(c)   ((c)->state & MMC_STATE_READONLY)
    >>  #define mmc_card_highspeed(c)  ((c)->state & MMC_STATE_HIGHSPEED)
    >> +#define mmc_card_ddr_mode(c)   ((c)->state & MMC_STATE_HIGHSPEED_DDR)
    >>  #define mmc_card_blockaddr(c)  ((c)->state & MMC_STATE_BLOCKADDR)
    >>
    >>  #define mmc_card_set_present(c)        ((c)->state |= MMC_STATE_PRESENT)
    >>  #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
    >>  #define mmc_card_set_highspeed(c) ((c)->state |= MMC_STATE_HIGHSPEED)
    >> +#define mmc_card_set_ddr_mode(c) ((c)->state |= MMC_STATE_HIGHSPEED_DDR)
    >>  #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR)
    >>
    >>  static inline int mmc_card_lenient_fn0(const struct mmc_card *c)
    >> diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
    >> index e4898e9..b31e47a 100644
    >> --- a/include/linux/mmc/core.h
    >> +++ b/include/linux/mmc/core.h
    >> @@ -107,6 +107,7 @@ struct mmc_data {
    >>  #define MMC_DATA_WRITE (1 << 8)
    >>  #define MMC_DATA_READ  (1 << 9)
    >>  #define MMC_DATA_STREAM        (1 << 10)
    >> +#define MMC_DDR_MODE    (1 << 11)
    >>
    >>        unsigned int            bytes_xfered;
    >>
    >> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
    >> index f65913c..c775290 100644
    >> --- a/include/linux/mmc/host.h
    >> +++ b/include/linux/mmc/host.h
    >> @@ -155,6 +155,10 @@ struct mmc_host {
    >>  #define MMC_CAP_DISABLE                (1 << 7)        /* Can the host be disabled */
    >>  #define MMC_CAP_NONREMOVABLE   (1 << 8)        /* Nonremovable e.g. eMMC */
    >>  #define MMC_CAP_WAIT_WHILE_BUSY        (1 << 9)        /* Waits while card is busy */
    >> +#define MMC_CAP_1_8V_DDR        (1 << 10)       /* can support */
    >> +                                               /* DDR mode at 1.8V */
    >> +#define MMC_CAP_1_2V_DDR        (1 << 11)       /* can support */
    >> +                                               /* DDR mode at 1.2V */
    >>
    >>        mmc_pm_flag_t           pm_caps;        /* supported pm features */
    >>
    >> diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
    >> index 8a49cbf..fc446de 100644
    >> --- a/include/linux/mmc/mmc.h
    >> +++ b/include/linux/mmc/mmc.h
    >> @@ -268,11 +268,18 @@ struct _mmc_csd {
    >>
    >>  #define EXT_CSD_CARD_TYPE_26   (1<<0)  /* Card can run at 26MHz */
    >>  #define EXT_CSD_CARD_TYPE_52   (1<<1)  /* Card can run at 52MHz */
    >> -#define EXT_CSD_CARD_TYPE_MASK 0x3     /* Mask out reserved and DDR bits */
    >> +#define EXT_CSD_CARD_TYPE_MASK 0xF     /* Mask out reserved bits */
    >> +#define EXT_CSD_CARD_TYPE_DDR_1_8V  (1<<2)   /* Card can run at 52MHz */
    >> +                                            /* DDR mode @1.8V or 3V I/O */
    >> +#define EXT_CSD_CARD_TYPE_DDR_1_2V  (1<<3)   /* Card can run at 52MHz */
    >> +                                            /* DDR mode @1.2V I/O */
    >> +#define EXT_CSD_CARD_TYPE_DDR_52       (EXT_CSD_CARD_TYPE_DDR_1_8V  \
    >> +                                       | EXT_CSD_CARD_TYPE_DDR_1_2V)
    >>
    >> -#define EXT_CSD_BUS_WIDTH_1    0       /* Card is in 1 bit mode */
    >>  #define EXT_CSD_BUS_WIDTH_4    1       /* Card is in 4 bit mode */
    >>  #define EXT_CSD_BUS_WIDTH_8    2       /* Card is in 8 bit mode */
    >> +#define EXT_CSD_DDR_BUS_WIDTH_4    5    /* Card is in 4 bit DDR mode */
    >> +#define EXT_CSD_DDR_BUS_WIDTH_8    6    /* Card is in 8 bit DDR mode */
    >>
    >>  /*
    >>  * MMC_SWITCH access modes
    >> --
    >> 1.6.3.3
    >>
    >> --
    >> To unsubscribe from this list: send the line "unsubscribe linux-mmc" in
    >> the body of a message to majordomo@vger.kernel.org
    >> More majordomo info at  http://vger.kernel.org/majordomo-info.html
    >>
    >
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2010-07-10 07:33    [W:3.980 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site