[linux-sunxi] Re: [PATCH RFC 03/15] mmc: sunxi: Block signal voltage switching (CMD11)

2016-01-29 Thread Chen-Yu Tsai
On Fri, Jan 29, 2016 at 6:42 PM, Ulf Hansson  wrote:
> On 21 January 2016 at 06:26, Chen-Yu Tsai  wrote:
>> Allwinner's mmc controller supports signal voltage switching. This is
>> supported in code in Allwinner's kernel. However, publicly available
>> boards all tie it to a fixed 3.0/3.3V regulator, with options to tie
>> it to 1.8V for eMMC on some.
>>
>> Since Allwinner's kernel is an ancient 3.4, it is hard to say whether
>> adapting it's code to a modern mainline kernel would work. Block signal
>> voltage switching until someone has proper hardware to implement and
>> test this.
>>
>> This only affects SD UHS-1 modes, as eMMC switches the voltage directly
>> without any signaling.
>>
>> Signed-off-by: Chen-Yu Tsai 
>> ---
>>  drivers/mmc/host/sunxi-mmc.c | 14 ++
>>  1 file changed, 14 insertions(+)
>>
>> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
>> index 790f01662b4e..0495ae7da6d6 100644
>> --- a/drivers/mmc/host/sunxi-mmc.c
>> +++ b/drivers/mmc/host/sunxi-mmc.c
>> @@ -816,6 +816,20 @@ static void sunxi_mmc_request(struct mmc_host *mmc, 
>> struct mmc_request *mrq)
>> }
>> }
>>
>> +   /*
>> +* TODO Support signal voltage switching
>> +*
>> +* Compared to Allwinner's kernel, recent updates in the mmc core
>> +* mean this should be as easy as setting the flags in cmd_val and
>> +* imask, and waiting for it to finish. However no boards support
>> +* this so this cannot be tested. Block it for now.
>> +*/
>> +   if (cmd->opcode == SD_SWITCH_VOLTAGE) {
>> +   mrq->cmd->error = -EPERM;
>> +   mmc_request_done(mmc, mrq);
>> +   return;
>> +   }
>
> Unless some of the MMC_CAP_UHS* mode is set, this command shouldn't be sent.
>
> So, if you *really* want to protect from this, I think it's better to
> clear these caps in the ->probe() function, after mmc_of_parse() has
> been called.

OK. If we need to block these, then we need to block all the other
unsupported caps, which seems excessive and unnecessary. I'll drop
this patch.

Thanks
ChenYu

>
>> +
>> if (cmd->opcode == MMC_GO_IDLE_STATE) {
>> cmd_val |= SDXC_SEND_INIT_SEQUENCE;
>> imask |= SDXC_COMMAND_DONE;
>> --
>> 2.7.0.rc3
>>
>
> Kind regards
> Uffe

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] Re: [PATCH RFC 03/15] mmc: sunxi: Block signal voltage switching (CMD11)

2016-01-29 Thread Ulf Hansson
On 21 January 2016 at 06:26, Chen-Yu Tsai  wrote:
> Allwinner's mmc controller supports signal voltage switching. This is
> supported in code in Allwinner's kernel. However, publicly available
> boards all tie it to a fixed 3.0/3.3V regulator, with options to tie
> it to 1.8V for eMMC on some.
>
> Since Allwinner's kernel is an ancient 3.4, it is hard to say whether
> adapting it's code to a modern mainline kernel would work. Block signal
> voltage switching until someone has proper hardware to implement and
> test this.
>
> This only affects SD UHS-1 modes, as eMMC switches the voltage directly
> without any signaling.
>
> Signed-off-by: Chen-Yu Tsai 
> ---
>  drivers/mmc/host/sunxi-mmc.c | 14 ++
>  1 file changed, 14 insertions(+)
>
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index 790f01662b4e..0495ae7da6d6 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -816,6 +816,20 @@ static void sunxi_mmc_request(struct mmc_host *mmc, 
> struct mmc_request *mrq)
> }
> }
>
> +   /*
> +* TODO Support signal voltage switching
> +*
> +* Compared to Allwinner's kernel, recent updates in the mmc core
> +* mean this should be as easy as setting the flags in cmd_val and
> +* imask, and waiting for it to finish. However no boards support
> +* this so this cannot be tested. Block it for now.
> +*/
> +   if (cmd->opcode == SD_SWITCH_VOLTAGE) {
> +   mrq->cmd->error = -EPERM;
> +   mmc_request_done(mmc, mrq);
> +   return;
> +   }

Unless some of the MMC_CAP_UHS* mode is set, this command shouldn't be sent.

So, if you *really* want to protect from this, I think it's better to
clear these caps in the ->probe() function, after mmc_of_parse() has
been called.

> +
> if (cmd->opcode == MMC_GO_IDLE_STATE) {
> cmd_val |= SDXC_SEND_INIT_SEQUENCE;
> imask |= SDXC_COMMAND_DONE;
> --
> 2.7.0.rc3
>

Kind regards
Uffe

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] Re: [PATCH RFC 01/15] mmc: sunxi: Document host init sequence

2016-01-29 Thread Ulf Hansson
On 21 January 2016 at 06:26, Chen-Yu Tsai  wrote:
> sunxi_mmc_init_host() originated from Allwinner kernel sources. The
> magic numbers written to various registers was never documented.
>
> Add comments for values found in Allwinner user manuals.
>
> Signed-off-by: Chen-Yu Tsai 

Thanks, applied for next!

Kind regards
Uffe

> ---
>  drivers/mmc/host/sunxi-mmc.c | 12 
>  1 file changed, 12 insertions(+)
>
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index 83de82bceafc..cce5ca540857 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -284,16 +284,28 @@ static int sunxi_mmc_init_host(struct mmc_host *mmc)
> if (sunxi_mmc_reset_host(host))
> return -EIO;
>
> +   /*
> +* Burst 8 transfers, RX trigger level: 7, TX trigger level: 8
> +*
> +* TODO: sun9i has a larger FIFO and supports higher trigger values
> +*/
> mmc_writel(host, REG_FTRGL, 0x20070008);
> +   /* Maximum timeout value */
> mmc_writel(host, REG_TMOUT, 0x);
> +   /* Unmask SDIO interrupt if needed */
> mmc_writel(host, REG_IMASK, host->sdio_imask);
> +   /* Clear all pending interrupts */
> mmc_writel(host, REG_RINTR, 0x);
> +   /* Debug register? undocumented */
> mmc_writel(host, REG_DBGC, 0xdeb);
> +   /* Enable CEATA support */
> mmc_writel(host, REG_FUNS, SDXC_CEATA_ON);
> +   /* Set DMA descriptor list base address */
> mmc_writel(host, REG_DLBA, host->sg_dma);
>
> rval = mmc_readl(host, REG_GCTRL);
> rval |= SDXC_INTERRUPT_ENABLE_BIT;
> +   /* Undocumented, but found in Allwinner code */
> rval &= ~SDXC_ACCESS_DONE_DIRECT;
> mmc_writel(host, REG_GCTRL, rval);
>
> --
> 2.7.0.rc3
>

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] Re: [PATCH RFC 04/15] mmc: sunxi: Support vqmmc regulator

2016-01-29 Thread Ulf Hansson
On 21 January 2016 at 06:26, Chen-Yu Tsai  wrote:
> eMMC chips require 2 power supplies, vmmc for internal logic, and vqmmc
> for driving output buffers. vqmmc also controls signaling voltage. Most
> boards we've seen use the same regulator for both, nevertheless the 2
> have different usages, and should be set separately.
>
> This patch adds support for vqmmc regulator supply, including voltage
> switching. The MMC core can use this to try different signaling voltages
> for eMMC.
>
> Signed-off-by: Chen-Yu Tsai 

Thanks, applied for next!

Kind regards
Uffe

> ---
>  drivers/mmc/host/sunxi-mmc.c | 31 +++
>  1 file changed, 31 insertions(+)
>
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index 0495ae7da6d6..4bec87458317 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -28,6 +28,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>
>  #include 
>  #include 
> @@ -256,6 +257,9 @@ struct sunxi_mmc_host {
> struct mmc_request *mrq;
> struct mmc_request *manual_stop_mrq;
> int ferror;
> +
> +   /* vqmmc */
> +   boolvqmmc_enabled;
>  };
>
>  static int sunxi_mmc_reset_host(struct sunxi_mmc_host *host)
> @@ -716,6 +720,16 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, 
> struct mmc_ios *ios)
> if (host->ferror)
> return;
>
> +   if (!IS_ERR(mmc->supply.vqmmc)) {
> +   host->ferror = regulator_enable(mmc->supply.vqmmc);
> +   if (host->ferror) {
> +   dev_err(mmc_dev(mmc),
> +   "failed to enable vqmmc\n");
> +   return;
> +   }
> +   host->vqmmc_enabled = true;
> +   }
> +
> host->ferror = sunxi_mmc_init_host(mmc);
> if (host->ferror)
> return;
> @@ -727,6 +741,9 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, 
> struct mmc_ios *ios)
> dev_dbg(mmc_dev(mmc), "power off!\n");
> sunxi_mmc_reset_host(host);
> mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
> +   if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled)
> +   regulator_disable(mmc->supply.vqmmc);
> +   host->vqmmc_enabled = false;
> break;
> }
>
> @@ -758,6 +775,19 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, 
> struct mmc_ios *ios)
> }
>  }
>
> +static int sunxi_mmc_volt_switch(struct mmc_host *mmc, struct mmc_ios *ios)
> +{
> +   /* vqmmc regulator is available */
> +   if (!IS_ERR(mmc->supply.vqmmc))
> +   return mmc_regulator_set_vqmmc(mmc, ios);
> +
> +   /* no vqmmc regulator, assume fixed regulator at 3/3.3V */
> +   if (mmc->ios.signal_voltage == MMC_SIGNAL_VOLTAGE_330)
> +   return 0;
> +
> +   return -EINVAL;
> +}
> +
>  static void sunxi_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
>  {
> struct sunxi_mmc_host *host = mmc_priv(mmc);
> @@ -923,6 +953,7 @@ static struct mmc_host_ops sunxi_mmc_ops = {
> .get_ro  = mmc_gpio_get_ro,
> .get_cd  = mmc_gpio_get_cd,
> .enable_sdio_irq = sunxi_mmc_enable_sdio_irq,
> +   .start_signal_voltage_switch = sunxi_mmc_volt_switch,
> .hw_reset= sunxi_mmc_hw_reset,
> .card_busy   = sunxi_mmc_card_busy,
>  };
> --
> 2.7.0.rc3
>

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] Re: [PATCH RFC 02/15] mmc: sunxi: Return error on mmc_regulator_set_ocr() fail in .set_ios op

2016-01-29 Thread Ulf Hansson
On 21 January 2016 at 06:26, Chen-Yu Tsai  wrote:
> Let .set_ios() fail if mmc_regulator_set_ocr() fails to enable and set a
> proper voltage for vmmc.
>
> Signed-off-by: Chen-Yu Tsai 

Thanks, applied for next!

Kind regards
Uffe


> ---
>  drivers/mmc/host/sunxi-mmc.c | 5 -
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
> index cce5ca540857..790f01662b4e 100644
> --- a/drivers/mmc/host/sunxi-mmc.c
> +++ b/drivers/mmc/host/sunxi-mmc.c
> @@ -711,7 +711,10 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, 
> struct mmc_ios *ios)
> break;
>
> case MMC_POWER_UP:
> -   mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd);
> +   host->ferror = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc,
> +ios->vdd);
> +   if (host->ferror)
> +   return;
>
> host->ferror = sunxi_mmc_init_host(mmc);
> if (host->ferror)
> --
> 2.7.0.rc3
>

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [linux-sunxi] Ditter V21 HDMI Android TV stick - FEL mode?

2016-01-29 Thread Fabio Fumi
I'll try to set up a new Wiki page, sure. But I wanted to get useful info 
to publish, first.
Anyhow, I will start with the Wiki, as you suggest Luc.
Unfortunately, I can't get to receive the confirmation email for the wiki 
subscription... possibile?

thanks
Fabio

On Thursday, 28 January 2016 20:45:41 UTC+1, Luc Verhaegen wrote:
>
> On Thu, Jan 28, 2016 at 07:41:52AM -0800, Fabio Fumi wrote: 
> > This is the info from Android /system/build.prop, which should help 
> > identifying the device: 
>
> This is pretty pointless. 
>
> Create a device page, and follow the new device howto. 
>
> Luc Verhaegen. 
>

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [linux-sunxi] Problem with Allwinner H3 clocks

2016-01-29 Thread Chen-Yu Tsai
On Fri, Jan 29, 2016 at 2:25 PM, Hans de Goede  wrote:
> Hi,
>
> On 01/28/2016 08:29 PM, Maxime Ripard wrote:
>>
>> On Thu, Jan 28, 2016 at 05:59:18PM +0100, Jean-Francois Moine wrote:
>
>
> 
>
>>> The A23/A33/H3 (and surely some other SoCs) documentations about
>>> the peripheral/periph/periph0/periph1 PLLs say:
>>>
>>> Note: The PLL Output should be fixed to 600MHz, it is not
>>> recommended to vary this value arbitrarily.
>>
>>
>> I don't know if it's worth it at this point. The pll6 seems to work
>> fine at other rates. Have you experienced any breakage when running at
>> another frequency?
>
>
> Hmm, are we actually changing the freq of pll6 on any SoCs? I know we've
> the code to it, but given that it is shared between many pheripherals,
> I assume we end up never changing it. I assume / hope that the clock
> framework protects against reclocking a clock with multiple users ...

No we're not. And none of the children of pll6 have CLK_SET_RATE_PARENT
set, so they won't change pll6. I think the point is pll6 itself _can_
be changed, but that would screw up all the peripherals depending on it.

There's also SATA and USB that might be driven by it.

ChenYu

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH 0/3] mmc: sunxi: Support eMMC DDR modes

2016-01-29 Thread Chen-Yu Tsai
Hi everyone,

This was "mmc: sunxi: Support vqmmc regulator and eMMC DDR modes". vqmmc
support and DT patches were merged even though it was an RFC series, to
my suprise.

These are the remaining patches that add eMMC HS-DDR support to sunxi.

Patch 1 adds timing delays for MMC_DDR52 mode.

Patch 2 adds support for 8 bit eMMC DDR52 mode. Under this mode, the
controller must run at twice the card clock, and different timing delays
are needed.

Patch 3 enables eMMC HS-DDR for sunxi-mmc.


Changes since RFC:

  - Dropped patches that are merged

  - Dropped "mmc: sunxi: Block signal voltage switching (CMD11)".
According to Ulf, the mmc core won't send this command unless the UHS
capabilities are set. We don't.

  - Increased f_max to 52 MHz. Clock rate range for 50 MHz timing delay
also increased to match. See patch 1.


Regards
ChenYu


Chen-Yu Tsai (3):
  mmc: sunxi: Support MMC_DDR52 timing modes
  mmc: sunxi: Support 8 bit eMMC DDR transfer modes
  mmc: sunxi: Enable eMMC HS-DDR (MMC_CAP_1_8V_DDR) support

 drivers/mmc/host/sunxi-mmc.c | 42 --
 1 file changed, 32 insertions(+), 10 deletions(-)

-- 
2.7.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH 3/3] mmc: sunxi: Enable eMMC HS-DDR (MMC_CAP_1_8V_DDR) support

2016-01-29 Thread Chen-Yu Tsai
Now that clock delay settings for 8 bit DDR are correct, and vqmmc
support is available, we can enable MMC_CAP_1_8V_DDR support. This
enables MMC HS-DDR at up to 52 MHz, even if signal voltage switching
is not available.

Signed-off-by: Chen-Yu Tsai 
---

There was discussion about an alternative: setting this capability
in the DT to preserve DT backwards compatibility. However just setting
it in the DT without the driver updates also breaks it. Furthermore,
Maxime's latest "clk: sunxi: Refactor A31 PLL6 so that it can be reused"
patch will break DT compatility. Given the above, I see no reason to
try and maintain compatibility only to fail.

---
 drivers/mmc/host/sunxi-mmc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index bb4592696046..2aee17cd85ae 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -1131,6 +1131,7 @@ static int sunxi_mmc_probe(struct platform_device *pdev)
mmc->f_min  =   40;
mmc->f_max  = 5200;
mmc->caps  |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
+ MMC_CAP_1_8V_DDR |
  MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ;
 
ret = mmc_of_parse(mmc);
-- 
2.7.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH 2/3] mmc: sunxi: Support 8 bit eMMC DDR transfer modes

2016-01-29 Thread Chen-Yu Tsai
Allwinner's MMC controller needs to run at double the card clock rate
for 8 bit DDR transfer modes. Interestingly, this is not needed for
4 bit DDR transfers.

Different clock delays are needed for 8 bit eMMC DDR, due to the
increased module clock rate. For the A80 though, the same values for
4 bit and 8 bit are shared. The new values for the other SoCs were from
A83T user manual's "new timing mode" default values, which describes
them in clock phase, rather than delay periods. These values were used
without any modification. They may not be correct, but they work.

Signed-off-by: Chen-Yu Tsai 
---
 drivers/mmc/host/sunxi-mmc.c | 33 ++---
 1 file changed, 26 insertions(+), 7 deletions(-)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index fe6c171fd135..bb4592696046 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -215,6 +215,7 @@
 #define SDXC_CLK_25M   1
 #define SDXC_CLK_50M   2
 #define SDXC_CLK_50M_DDR   3
+#define SDXC_CLK_50M_DDR_8BIT  4
 
 struct sunxi_mmc_clk_delay {
u32 output;
@@ -656,11 +657,17 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host 
*host,
  struct mmc_ios *ios)
 {
u32 rate, oclk_dly, rval, sclk_dly;
+   u32 clock = ios->clock;
int ret;
 
-   rate = clk_round_rate(host->clk_mmc, ios->clock);
+   /* 8 bit DDR requires a higher module clock */
+   if (ios->timing == MMC_TIMING_MMC_DDR52 &&
+   ios->bus_width == MMC_BUS_WIDTH_8)
+   clock <<= 1;
+
+   rate = clk_round_rate(host->clk_mmc, clock);
dev_dbg(mmc_dev(host->mmc), "setting clk to %d, rounded %d\n",
-   ios->clock, rate);
+   clock, rate);
 
/* setting clock rate */
ret = clk_set_rate(host->clk_mmc, rate);
@@ -677,6 +684,12 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host 
*host,
/* clear internal divider */
rval = mmc_readl(host, REG_CLKCR);
rval &= ~0xff;
+   /* set internal divider for 8 bit eMMC DDR, so card clock is right */
+   if (ios->timing == MMC_TIMING_MMC_DDR52 &&
+   ios->bus_width == MMC_BUS_WIDTH_8) {
+   rval |= 1;
+   rate >>= 1;
+   }
mmc_writel(host, REG_CLKCR, rval);
 
/* determine delays */
@@ -687,13 +700,16 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host 
*host,
oclk_dly = host->clk_delays[SDXC_CLK_25M].output;
sclk_dly = host->clk_delays[SDXC_CLK_25M].sample;
} else if (rate <= 5200) {
-   if (ios->timing == MMC_TIMING_UHS_DDR50 ||
-   ios->timing == MMC_TIMING_MMC_DDR52) {
-   oclk_dly = host->clk_delays[SDXC_CLK_50M_DDR].output;
-   sclk_dly = host->clk_delays[SDXC_CLK_50M_DDR].sample;
-   } else {
+   if (ios->timing != MMC_TIMING_UHS_DDR50 &&
+   ios->timing != MMC_TIMING_MMC_DDR52) {
oclk_dly = host->clk_delays[SDXC_CLK_50M].output;
sclk_dly = host->clk_delays[SDXC_CLK_50M].sample;
+   } else if (ios->bus_width == MMC_BUS_WIDTH_8) {
+   oclk_dly = 
host->clk_delays[SDXC_CLK_50M_DDR_8BIT].output;
+   sclk_dly = 
host->clk_delays[SDXC_CLK_50M_DDR_8BIT].sample;
+   } else {
+   oclk_dly = host->clk_delays[SDXC_CLK_50M_DDR].output;
+   sclk_dly = host->clk_delays[SDXC_CLK_50M_DDR].sample;
}
} else {
return -EINVAL;
@@ -951,6 +967,8 @@ static const struct sunxi_mmc_clk_delay 
sunxi_mmc_clk_delays[] = {
[SDXC_CLK_25M]  = { .output = 180, .sample =  75 },
[SDXC_CLK_50M]  = { .output =  90, .sample = 120 },
[SDXC_CLK_50M_DDR]  = { .output =  60, .sample = 120 },
+   /* Value from A83T "new timing mode". Works but might not be right. */
+   [SDXC_CLK_50M_DDR_8BIT] = { .output =  90, .sample = 180 },
 };
 
 static const struct sunxi_mmc_clk_delay sun9i_mmc_clk_delays[] = {
@@ -958,6 +976,7 @@ static const struct sunxi_mmc_clk_delay 
sun9i_mmc_clk_delays[] = {
[SDXC_CLK_25M]  = { .output = 180, .sample =  75 },
[SDXC_CLK_50M]  = { .output = 150, .sample = 120 },
[SDXC_CLK_50M_DDR]  = { .output =  90, .sample = 120 },
+   [SDXC_CLK_50M_DDR_8BIT] = { .output =  90, .sample = 120 },
 };
 
 static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host,
-- 
2.7.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH 1/3] mmc: sunxi: Support MMC_DDR52 timing modes

2016-01-29 Thread Chen-Yu Tsai
DDR transfer modes include UHS-1 DDR50 and MMC HS-DDR (or MMC_DDR52).
Consider MMC_DDR52 when setting clock delays.

Since MMC high speed mode goes up to 52 MHz instead of 50 MHz for SD,
and this number is visible in the capability macro, increase the
clock rate upper limit to 52 MHz.

Signed-off-by: Chen-Yu Tsai 
---
 drivers/mmc/host/sunxi-mmc.c | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c
index 765dfb9f77ec..fe6c171fd135 100644
--- a/drivers/mmc/host/sunxi-mmc.c
+++ b/drivers/mmc/host/sunxi-mmc.c
@@ -686,8 +686,9 @@ static int sunxi_mmc_clk_set_rate(struct sunxi_mmc_host 
*host,
} else if (rate <= 2500) {
oclk_dly = host->clk_delays[SDXC_CLK_25M].output;
sclk_dly = host->clk_delays[SDXC_CLK_25M].sample;
-   } else if (rate <= 5000) {
-   if (ios->timing == MMC_TIMING_UHS_DDR50) {
+   } else if (rate <= 5200) {
+   if (ios->timing == MMC_TIMING_UHS_DDR50 ||
+   ios->timing == MMC_TIMING_MMC_DDR52) {
oclk_dly = host->clk_delays[SDXC_CLK_50M_DDR].output;
sclk_dly = host->clk_delays[SDXC_CLK_50M_DDR].sample;
} else {
@@ -762,7 +763,8 @@ static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
 
/* set ddr mode */
rval = mmc_readl(host, REG_GCTRL);
-   if (ios->timing == MMC_TIMING_UHS_DDR50)
+   if (ios->timing == MMC_TIMING_UHS_DDR50 ||
+   ios->timing == MMC_TIMING_MMC_DDR52)
rval |= SDXC_DDR_MODE;
else
rval &= ~SDXC_DDR_MODE;
@@ -1106,9 +1108,9 @@ static int sunxi_mmc_probe(struct platform_device *pdev)
mmc->max_segs   = PAGE_SIZE / sizeof(struct sunxi_idma_des);
mmc->max_seg_size   = (1 << host->idma_des_size_bits);
mmc->max_req_size   = mmc->max_seg_size * mmc->max_segs;
-   /* 400kHz ~ 50MHz */
+   /* 400kHz ~ 52MHz */
mmc->f_min  =   40;
-   mmc->f_max  = 5000;
+   mmc->f_max  = 5200;
mmc->caps  |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED |
  MMC_CAP_ERASE | MMC_CAP_SDIO_IRQ;
 
-- 
2.7.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.