Message ID | 1466387926-3348-1-git-send-email-wenyou.yang@atmel.com |
---|---|
State | Superseded |
Delegated to: | Jaehoon Chung |
Headers | show |
Dear Pantelis, On 20.06.16 03:58, Wenyou Yang wrote: > Add the programmable clock mode for the clock generator. > this one is delegated to me, but I think it is out of my scope. Could you please have a look? Andreas > Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com> > --- > > drivers/mmc/sdhci.c | 49 +++++++++++++++++++++++++++++++++++++++---------- > include/sdhci.h | 15 +++++++++++++++ > 2 files changed, 54 insertions(+), 10 deletions(-) > > diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c > index 5c71ab8..ee6d4a1 100644 > --- a/drivers/mmc/sdhci.c > +++ b/drivers/mmc/sdhci.c > @@ -286,7 +286,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, > static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) > { > struct sdhci_host *host = mmc->priv; > - unsigned int div, clk, timeout, reg; > + unsigned int div, clk = 0, timeout, reg; > > /* Wait max 20 ms */ > timeout = 200; > @@ -310,14 +310,35 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) > return 0; > > if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) { > - /* Version 3.00 divisors must be a multiple of 2. */ > - if (mmc->cfg->f_max <= clock) > - div = 1; > - else { > - for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) { > - if ((mmc->cfg->f_max / div) <= clock) > + /* > + * Check if the Host Controller supports Programmable Clock > + * Mode. > + */ > + if (host->clk_mul) { > + for (div = 1; div <= 1024; div++) { > + if ((mmc->cfg->f_max * host->clk_mul / div) > + <= clock) > break; > } > + > + /* > + * Set Programmable Clock Mode in the Clock > + * Control register. > + */ > + clk = SDHCI_PROG_CLOCK_MODE; > + div--; > + } else { > + /* Version 3.00 divisors must be a multiple of 2. */ > + if (mmc->cfg->f_max <= clock) { > + div = 1; > + } else { > + for (div = 2; > + div < SDHCI_MAX_DIV_SPEC_300; div += 2) { > + if ((mmc->cfg->f_max / div) <= clock) > + break; > + } > + } > + div >>= 1; > } > } else { > /* Version 2.00 divisors must be a power of 2. */ > @@ -325,13 +346,13 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) > if ((mmc->cfg->f_max / div) <= clock) > break; > } > + div >>= 1; > } > - div >>= 1; > > if (host->set_clock) > host->set_clock(host->index, div); > > - clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; > + clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; > clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) > << SDHCI_DIVIDER_HI_SHIFT; > clk |= SDHCI_CLOCK_INT_EN; > @@ -480,7 +501,7 @@ static const struct mmc_ops sdhci_ops = { > > int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) > { > - unsigned int caps; > + unsigned int caps, caps_1; > > host->cfg.name = host->name; > host->cfg.ops = &sdhci_ops; > @@ -546,6 +567,14 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) > > host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; > > + /* > + * In case of Host Controller v3.00, find out whether clock > + * multiplier is supported. > + */ > + caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); > + host->clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >> > + SDHCI_CLOCK_MUL_SHIFT; > + > sdhci_reset(host, SDHCI_RESET_ALL); > > host->mmc = mmc_create(&host->cfg, host); > diff --git a/include/sdhci.h b/include/sdhci.h > index e0f6667..5abe0a2 100644 > --- a/include/sdhci.h > +++ b/include/sdhci.h > @@ -97,6 +97,7 @@ > #define SDHCI_DIV_MASK 0xFF > #define SDHCI_DIV_MASK_LEN 8 > #define SDHCI_DIV_HI_MASK 0x300 > +#define SDHCI_PROG_CLOCK_MODE 0x0020 > #define SDHCI_CLOCK_CARD_EN 0x0004 > #define SDHCI_CLOCK_INT_STABLE 0x0002 > #define SDHCI_CLOCK_INT_EN 0x0001 > @@ -166,6 +167,19 @@ > #define SDHCI_CAN_64BIT 0x10000000 > > #define SDHCI_CAPABILITIES_1 0x44 > +#define SDHCI_SUPPORT_SDR50 0x00000001 > +#define SDHCI_SUPPORT_SDR104 0x00000002 > +#define SDHCI_SUPPORT_DDR50 0x00000004 > +#define SDHCI_DRIVER_TYPE_A 0x00000010 > +#define SDHCI_DRIVER_TYPE_C 0x00000020 > +#define SDHCI_DRIVER_TYPE_D 0x00000040 > +#define SDHCI_RETUNING_TIMER_COUNT_MASK 0x00000F00 > +#define SDHCI_RETUNING_TIMER_COUNT_SHIFT 8 > +#define SDHCI_USE_SDR50_TUNING 0x00002000 > +#define SDHCI_RETUNING_MODE_MASK 0x0000C000 > +#define SDHCI_RETUNING_MODE_SHIFT 14 > +#define SDHCI_CLOCK_MUL_MASK 0x00FF0000 > +#define SDHCI_CLOCK_MUL_SHIFT 16 > > #define SDHCI_MAX_CURRENT 0x48 > > @@ -240,6 +254,7 @@ struct sdhci_host { > unsigned int quirks; > unsigned int host_caps; > unsigned int version; > + unsigned int clk_mul; /* Clock Muliplier value */ > unsigned int clock; > struct mmc *mmc; > const struct sdhci_ops *ops; >
Hi Andreas, On 08/15/2016 01:17 AM, Andreas Bießmann wrote: > Dear Pantelis, > > On 20.06.16 03:58, Wenyou Yang wrote: >> Add the programmable clock mode for the clock generator. >> > > this one is delegated to me, but I think it is out of my scope. Could > you please have a look? I will be delegated to me. I will check this patch. Thanks. Best Regards, Jaehoon Chung > > Andreas > >> Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com> >> --- >> >> drivers/mmc/sdhci.c | 49 +++++++++++++++++++++++++++++++++++++++---------- >> include/sdhci.h | 15 +++++++++++++++ >> 2 files changed, 54 insertions(+), 10 deletions(-) >> >> diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c >> index 5c71ab8..ee6d4a1 100644 >> --- a/drivers/mmc/sdhci.c >> +++ b/drivers/mmc/sdhci.c >> @@ -286,7 +286,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, >> static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) >> { >> struct sdhci_host *host = mmc->priv; >> - unsigned int div, clk, timeout, reg; >> + unsigned int div, clk = 0, timeout, reg; >> >> /* Wait max 20 ms */ >> timeout = 200; >> @@ -310,14 +310,35 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) >> return 0; >> >> if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) { >> - /* Version 3.00 divisors must be a multiple of 2. */ >> - if (mmc->cfg->f_max <= clock) >> - div = 1; >> - else { >> - for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) { >> - if ((mmc->cfg->f_max / div) <= clock) >> + /* >> + * Check if the Host Controller supports Programmable Clock >> + * Mode. >> + */ >> + if (host->clk_mul) { >> + for (div = 1; div <= 1024; div++) { >> + if ((mmc->cfg->f_max * host->clk_mul / div) >> + <= clock) >> break; >> } >> + >> + /* >> + * Set Programmable Clock Mode in the Clock >> + * Control register. >> + */ >> + clk = SDHCI_PROG_CLOCK_MODE; >> + div--; >> + } else { >> + /* Version 3.00 divisors must be a multiple of 2. */ >> + if (mmc->cfg->f_max <= clock) { >> + div = 1; >> + } else { >> + for (div = 2; >> + div < SDHCI_MAX_DIV_SPEC_300; div += 2) { >> + if ((mmc->cfg->f_max / div) <= clock) >> + break; >> + } >> + } >> + div >>= 1; >> } >> } else { >> /* Version 2.00 divisors must be a power of 2. */ >> @@ -325,13 +346,13 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) >> if ((mmc->cfg->f_max / div) <= clock) >> break; >> } >> + div >>= 1; >> } >> - div >>= 1; >> >> if (host->set_clock) >> host->set_clock(host->index, div); >> >> - clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; >> + clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; >> clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) >> << SDHCI_DIVIDER_HI_SHIFT; >> clk |= SDHCI_CLOCK_INT_EN; >> @@ -480,7 +501,7 @@ static const struct mmc_ops sdhci_ops = { >> >> int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) >> { >> - unsigned int caps; >> + unsigned int caps, caps_1; >> >> host->cfg.name = host->name; >> host->cfg.ops = &sdhci_ops; >> @@ -546,6 +567,14 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) >> >> host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; >> >> + /* >> + * In case of Host Controller v3.00, find out whether clock >> + * multiplier is supported. >> + */ >> + caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); >> + host->clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >> >> + SDHCI_CLOCK_MUL_SHIFT; >> + >> sdhci_reset(host, SDHCI_RESET_ALL); >> >> host->mmc = mmc_create(&host->cfg, host); >> diff --git a/include/sdhci.h b/include/sdhci.h >> index e0f6667..5abe0a2 100644 >> --- a/include/sdhci.h >> +++ b/include/sdhci.h >> @@ -97,6 +97,7 @@ >> #define SDHCI_DIV_MASK 0xFF >> #define SDHCI_DIV_MASK_LEN 8 >> #define SDHCI_DIV_HI_MASK 0x300 >> +#define SDHCI_PROG_CLOCK_MODE 0x0020 >> #define SDHCI_CLOCK_CARD_EN 0x0004 >> #define SDHCI_CLOCK_INT_STABLE 0x0002 >> #define SDHCI_CLOCK_INT_EN 0x0001 >> @@ -166,6 +167,19 @@ >> #define SDHCI_CAN_64BIT 0x10000000 >> >> #define SDHCI_CAPABILITIES_1 0x44 >> +#define SDHCI_SUPPORT_SDR50 0x00000001 >> +#define SDHCI_SUPPORT_SDR104 0x00000002 >> +#define SDHCI_SUPPORT_DDR50 0x00000004 >> +#define SDHCI_DRIVER_TYPE_A 0x00000010 >> +#define SDHCI_DRIVER_TYPE_C 0x00000020 >> +#define SDHCI_DRIVER_TYPE_D 0x00000040 >> +#define SDHCI_RETUNING_TIMER_COUNT_MASK 0x00000F00 >> +#define SDHCI_RETUNING_TIMER_COUNT_SHIFT 8 >> +#define SDHCI_USE_SDR50_TUNING 0x00002000 >> +#define SDHCI_RETUNING_MODE_MASK 0x0000C000 >> +#define SDHCI_RETUNING_MODE_SHIFT 14 >> +#define SDHCI_CLOCK_MUL_MASK 0x00FF0000 >> +#define SDHCI_CLOCK_MUL_SHIFT 16 >> >> #define SDHCI_MAX_CURRENT 0x48 >> >> @@ -240,6 +254,7 @@ struct sdhci_host { >> unsigned int quirks; >> unsigned int host_caps; >> unsigned int version; >> + unsigned int clk_mul; /* Clock Muliplier value */ >> unsigned int clock; >> struct mmc *mmc; >> const struct sdhci_ops *ops; >> > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot > > >
Hi Wenyou, On 08/16/2016 10:02 AM, Jaehoon Chung wrote: > Hi Andreas, > > On 08/15/2016 01:17 AM, Andreas Bießmann wrote: >> Dear Pantelis, >> >> On 20.06.16 03:58, Wenyou Yang wrote: >>> Add the programmable clock mode for the clock generator. >>> Sorry for reviewing too late. First, this patch needs to rebase on latest u-boot-mmc. Then I will check this patch on my boards.. >> >> this one is delegated to me, but I think it is out of my scope. Could >> you please have a look? > > I will be delegated to me. I will check this patch. > > Thanks. > > Best Regards, > Jaehoon Chung > >> >> Andreas >> >>> Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com> >>> --- >>> >>> drivers/mmc/sdhci.c | 49 +++++++++++++++++++++++++++++++++++++++---------- >>> include/sdhci.h | 15 +++++++++++++++ >>> 2 files changed, 54 insertions(+), 10 deletions(-) >>> >>> diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c >>> index 5c71ab8..ee6d4a1 100644 >>> --- a/drivers/mmc/sdhci.c >>> +++ b/drivers/mmc/sdhci.c >>> @@ -286,7 +286,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, >>> static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) >>> { >>> struct sdhci_host *host = mmc->priv; >>> - unsigned int div, clk, timeout, reg; >>> + unsigned int div, clk = 0, timeout, reg; >>> >>> /* Wait max 20 ms */ >>> timeout = 200; >>> @@ -310,14 +310,35 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) >>> return 0; >>> >>> if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) { >>> - /* Version 3.00 divisors must be a multiple of 2. */ >>> - if (mmc->cfg->f_max <= clock) >>> - div = 1; >>> - else { >>> - for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) { >>> - if ((mmc->cfg->f_max / div) <= clock) >>> + /* >>> + * Check if the Host Controller supports Programmable Clock >>> + * Mode. >>> + */ >>> + if (host->clk_mul) { >>> + for (div = 1; div <= 1024; div++) { >>> + if ((mmc->cfg->f_max * host->clk_mul / div) >>> + <= clock) >>> break; >>> } >>> + >>> + /* >>> + * Set Programmable Clock Mode in the Clock >>> + * Control register. >>> + */ >>> + clk = SDHCI_PROG_CLOCK_MODE; >>> + div--; >>> + } else { >>> + /* Version 3.00 divisors must be a multiple of 2. */ >>> + if (mmc->cfg->f_max <= clock) { >>> + div = 1; >>> + } else { >>> + for (div = 2; >>> + div < SDHCI_MAX_DIV_SPEC_300; div += 2) { >>> + if ((mmc->cfg->f_max / div) <= clock) >>> + break; >>> + } >>> + } >>> + div >>= 1; >>> } >>> } else { >>> /* Version 2.00 divisors must be a power of 2. */ >>> @@ -325,13 +346,13 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) >>> if ((mmc->cfg->f_max / div) <= clock) >>> break; >>> } >>> + div >>= 1; >>> } >>> - div >>= 1; >>> >>> if (host->set_clock) >>> host->set_clock(host->index, div); >>> >>> - clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; >>> + clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; >>> clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) >>> << SDHCI_DIVIDER_HI_SHIFT; >>> clk |= SDHCI_CLOCK_INT_EN; >>> @@ -480,7 +501,7 @@ static const struct mmc_ops sdhci_ops = { >>> >>> int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) >>> { >>> - unsigned int caps; >>> + unsigned int caps, caps_1; >>> >>> host->cfg.name = host->name; >>> host->cfg.ops = &sdhci_ops; >>> @@ -546,6 +567,14 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) >>> >>> host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; >>> >>> + /* >>> + * In case of Host Controller v3.00, find out whether clock >>> + * multiplier is supported. >>> + */ >>> + caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); >>> + host->clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >> >>> + SDHCI_CLOCK_MUL_SHIFT; >>> + >>> sdhci_reset(host, SDHCI_RESET_ALL); >>> >>> host->mmc = mmc_create(&host->cfg, host); >>> diff --git a/include/sdhci.h b/include/sdhci.h >>> index e0f6667..5abe0a2 100644 >>> --- a/include/sdhci.h >>> +++ b/include/sdhci.h >>> @@ -97,6 +97,7 @@ >>> #define SDHCI_DIV_MASK 0xFF >>> #define SDHCI_DIV_MASK_LEN 8 >>> #define SDHCI_DIV_HI_MASK 0x300 >>> +#define SDHCI_PROG_CLOCK_MODE 0x0020 >>> #define SDHCI_CLOCK_CARD_EN 0x0004 >>> #define SDHCI_CLOCK_INT_STABLE 0x0002 >>> #define SDHCI_CLOCK_INT_EN 0x0001 >>> @@ -166,6 +167,19 @@ >>> #define SDHCI_CAN_64BIT 0x10000000 >>> >>> #define SDHCI_CAPABILITIES_1 0x44 >>> +#define SDHCI_SUPPORT_SDR50 0x00000001 >>> +#define SDHCI_SUPPORT_SDR104 0x00000002 >>> +#define SDHCI_SUPPORT_DDR50 0x00000004 >>> +#define SDHCI_DRIVER_TYPE_A 0x00000010 >>> +#define SDHCI_DRIVER_TYPE_C 0x00000020 >>> +#define SDHCI_DRIVER_TYPE_D 0x00000040 >>> +#define SDHCI_RETUNING_TIMER_COUNT_MASK 0x00000F00 >>> +#define SDHCI_RETUNING_TIMER_COUNT_SHIFT 8 >>> +#define SDHCI_USE_SDR50_TUNING 0x00002000 >>> +#define SDHCI_RETUNING_MODE_MASK 0x0000C000 >>> +#define SDHCI_RETUNING_MODE_SHIFT 14 >>> +#define SDHCI_CLOCK_MUL_MASK 0x00FF0000 >>> +#define SDHCI_CLOCK_MUL_SHIFT 16 >>> >>> #define SDHCI_MAX_CURRENT 0x48 >>> >>> @@ -240,6 +254,7 @@ struct sdhci_host { >>> unsigned int quirks; >>> unsigned int host_caps; >>> unsigned int version; >>> + unsigned int clk_mul; /* Clock Muliplier value */ s/Muliplier/Multiplier Best Regards, Jaehoon Chung >>> unsigned int clock; >>> struct mmc *mmc; >>> const struct sdhci_ops *ops; >>> >> _______________________________________________ >> U-Boot mailing list >> U-Boot@lists.denx.de >> http://lists.denx.de/mailman/listinfo/u-boot >> >> >> > > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > http://lists.denx.de/mailman/listinfo/u-boot > > >
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 5c71ab8..ee6d4a1 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -286,7 +286,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) { struct sdhci_host *host = mmc->priv; - unsigned int div, clk, timeout, reg; + unsigned int div, clk = 0, timeout, reg; /* Wait max 20 ms */ timeout = 200; @@ -310,14 +310,35 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) return 0; if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) { - /* Version 3.00 divisors must be a multiple of 2. */ - if (mmc->cfg->f_max <= clock) - div = 1; - else { - for (div = 2; div < SDHCI_MAX_DIV_SPEC_300; div += 2) { - if ((mmc->cfg->f_max / div) <= clock) + /* + * Check if the Host Controller supports Programmable Clock + * Mode. + */ + if (host->clk_mul) { + for (div = 1; div <= 1024; div++) { + if ((mmc->cfg->f_max * host->clk_mul / div) + <= clock) break; } + + /* + * Set Programmable Clock Mode in the Clock + * Control register. + */ + clk = SDHCI_PROG_CLOCK_MODE; + div--; + } else { + /* Version 3.00 divisors must be a multiple of 2. */ + if (mmc->cfg->f_max <= clock) { + div = 1; + } else { + for (div = 2; + div < SDHCI_MAX_DIV_SPEC_300; div += 2) { + if ((mmc->cfg->f_max / div) <= clock) + break; + } + } + div >>= 1; } } else { /* Version 2.00 divisors must be a power of 2. */ @@ -325,13 +346,13 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock) if ((mmc->cfg->f_max / div) <= clock) break; } + div >>= 1; } - div >>= 1; if (host->set_clock) host->set_clock(host->index, div); - clk = (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; + clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT; clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN) << SDHCI_DIVIDER_HI_SHIFT; clk |= SDHCI_CLOCK_INT_EN; @@ -480,7 +501,7 @@ static const struct mmc_ops sdhci_ops = { int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) { - unsigned int caps; + unsigned int caps, caps_1; host->cfg.name = host->name; host->cfg.ops = &sdhci_ops; @@ -546,6 +567,14 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk) host->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; + /* + * In case of Host Controller v3.00, find out whether clock + * multiplier is supported. + */ + caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1); + host->clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >> + SDHCI_CLOCK_MUL_SHIFT; + sdhci_reset(host, SDHCI_RESET_ALL); host->mmc = mmc_create(&host->cfg, host); diff --git a/include/sdhci.h b/include/sdhci.h index e0f6667..5abe0a2 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -97,6 +97,7 @@ #define SDHCI_DIV_MASK 0xFF #define SDHCI_DIV_MASK_LEN 8 #define SDHCI_DIV_HI_MASK 0x300 +#define SDHCI_PROG_CLOCK_MODE 0x0020 #define SDHCI_CLOCK_CARD_EN 0x0004 #define SDHCI_CLOCK_INT_STABLE 0x0002 #define SDHCI_CLOCK_INT_EN 0x0001 @@ -166,6 +167,19 @@ #define SDHCI_CAN_64BIT 0x10000000 #define SDHCI_CAPABILITIES_1 0x44 +#define SDHCI_SUPPORT_SDR50 0x00000001 +#define SDHCI_SUPPORT_SDR104 0x00000002 +#define SDHCI_SUPPORT_DDR50 0x00000004 +#define SDHCI_DRIVER_TYPE_A 0x00000010 +#define SDHCI_DRIVER_TYPE_C 0x00000020 +#define SDHCI_DRIVER_TYPE_D 0x00000040 +#define SDHCI_RETUNING_TIMER_COUNT_MASK 0x00000F00 +#define SDHCI_RETUNING_TIMER_COUNT_SHIFT 8 +#define SDHCI_USE_SDR50_TUNING 0x00002000 +#define SDHCI_RETUNING_MODE_MASK 0x0000C000 +#define SDHCI_RETUNING_MODE_SHIFT 14 +#define SDHCI_CLOCK_MUL_MASK 0x00FF0000 +#define SDHCI_CLOCK_MUL_SHIFT 16 #define SDHCI_MAX_CURRENT 0x48 @@ -240,6 +254,7 @@ struct sdhci_host { unsigned int quirks; unsigned int host_caps; unsigned int version; + unsigned int clk_mul; /* Clock Muliplier value */ unsigned int clock; struct mmc *mmc; const struct sdhci_ops *ops;
Add the programmable clock mode for the clock generator. Signed-off-by: Wenyou Yang <wenyou.yang@atmel.com> --- drivers/mmc/sdhci.c | 49 +++++++++++++++++++++++++++++++++++++++---------- include/sdhci.h | 15 +++++++++++++++ 2 files changed, 54 insertions(+), 10 deletions(-)