* [U-Boot] [PATCH] mmc: sdhci: Add the programmable clock mode support
@ 2016-06-20 1:58 Wenyou Yang
2016-08-14 16:17 ` Andreas Bießmann
0 siblings, 1 reply; 4+ messages in thread
From: Wenyou Yang @ 2016-06-20 1:58 UTC (permalink / raw)
To: u-boot
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(-)
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;
--
2.7.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH] mmc: sdhci: Add the programmable clock mode support
2016-06-20 1:58 [U-Boot] [PATCH] mmc: sdhci: Add the programmable clock mode support Wenyou Yang
@ 2016-08-14 16:17 ` Andreas Bießmann
2016-08-16 1:02 ` Jaehoon Chung
0 siblings, 1 reply; 4+ messages in thread
From: Andreas Bießmann @ 2016-08-14 16:17 UTC (permalink / raw)
To: u-boot
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;
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH] mmc: sdhci: Add the programmable clock mode support
2016-08-14 16:17 ` Andreas Bießmann
@ 2016-08-16 1:02 ` Jaehoon Chung
2016-08-22 2:24 ` Jaehoon Chung
0 siblings, 1 reply; 4+ messages in thread
From: Jaehoon Chung @ 2016-08-16 1:02 UTC (permalink / raw)
To: u-boot
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 at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* [U-Boot] [PATCH] mmc: sdhci: Add the programmable clock mode support
2016-08-16 1:02 ` Jaehoon Chung
@ 2016-08-22 2:24 ` Jaehoon Chung
0 siblings, 0 replies; 4+ messages in thread
From: Jaehoon Chung @ 2016-08-22 2:24 UTC (permalink / raw)
To: 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 at lists.denx.de
>> http://lists.denx.de/mailman/listinfo/u-boot
>>
>>
>>
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot
>
>
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-08-22 2:24 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-20 1:58 [U-Boot] [PATCH] mmc: sdhci: Add the programmable clock mode support Wenyou Yang
2016-08-14 16:17 ` Andreas Bießmann
2016-08-16 1:02 ` Jaehoon Chung
2016-08-22 2:24 ` Jaehoon Chung
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.