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.y...@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
> 
> 
> 

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to