* [PATCH 01/10] pinctrl: sh-pfc: r8a7790: Implement voltage switching for SDHI
2016-03-12 9:15 [PATCH 00/10] r8a7790: add UHS-I (SDR50) support to Lager Wolfram Sang
@ 2016-03-12 9:15 ` Wolfram Sang
2016-03-14 9:47 ` Geert Uytterhoeven
2016-03-12 9:15 ` [PATCH 02/10] mmc: tmio, sh_mobile_sdhi: Pass tmio_mmc_host ptr to clk_{enable,disable} ops Wolfram Sang
` (8 subsequent siblings)
9 siblings, 1 reply; 15+ messages in thread
From: Wolfram Sang @ 2016-03-12 9:15 UTC (permalink / raw)
To: linux-renesas-soc
Cc: Wolfram Sang, linux-mmc, Dirk Behme, Ben Hutchings, linux-gpio
From: Wolfram Sang <wsa+renesas@sang-engineering.com>
All the SHDIs can operate with either 3.3V or 1.8V signals, depending
on negotiation with the card.
Implement the {get,set}_io_voltage operations and set the related
capability flag for the associated pins.
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Cc: linux-gpio@vger.kernel.org
---
Changes since RFC:
* Don't export sh_pfc_phys_to_virt but use pfc->windows->virt directly.
drivers/pinctrl/sh-pfc/pfc-r8a7790.c | 54 +++++++++++++++++++++++++++++++++++-
1 file changed, 53 insertions(+), 1 deletion(-)
diff --git a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c
index 0f4d48f9400ba0..eed8daa464cc1e 100644
--- a/drivers/pinctrl/sh-pfc/pfc-r8a7790.c
+++ b/drivers/pinctrl/sh-pfc/pfc-r8a7790.c
@@ -21,16 +21,21 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <linux/io.h>
#include <linux/kernel.h>
#include "core.h"
#include "sh_pfc.h"
+/*
+ * All pins assigned to GPIO bank 3 can be used for SD interfaces in
+ * which case they support both 3.3V and 1.8V signalling.
+ */
#define CPU_ALL_PORT(fn, sfx) \
PORT_GP_32(0, fn, sfx), \
PORT_GP_30(1, fn, sfx), \
PORT_GP_30(2, fn, sfx), \
- PORT_GP_32(3, fn, sfx), \
+ PORT_GP_CFG_32(3, fn, sfx, SH_PFC_PIN_CFG_IO_VOLTAGE), \
PORT_GP_32(4, fn, sfx), \
PORT_GP_32(5, fn, sfx)
@@ -4691,6 +4696,47 @@ static const char * const vin3_groups[] = {
"vin3_clk",
};
+#define IOCTRL6 0x8c
+
+static int r8a7790_get_io_voltage(struct sh_pfc *pfc, unsigned int pin)
+{
+ u32 data, mask;
+
+ if (WARN(pin < RCAR_GP_PIN(3, 0) || pin > RCAR_GP_PIN(3, 31), "invalid pin %#x", pin))
+ return -EINVAL;
+
+ data = ioread32(pfc->windows->virt + IOCTRL6),
+ /* Bits in IOCTRL6 are numbered in opposite order to pins */
+ mask = 0x80000000 >> (pin & 0x1f);
+
+ return (data & mask) ? 3300 : 1800;
+}
+
+static int r8a7790_set_io_voltage(struct sh_pfc *pfc, unsigned int pin, u16 mV)
+{
+ u32 data, mask;
+
+ if (WARN(pin < RCAR_GP_PIN(3, 0) || pin > RCAR_GP_PIN(3, 31), "invalid pin %#x", pin))
+ return -EINVAL;
+
+ if (mV != 1800 && mV != 3300)
+ return -EINVAL;
+
+ data = ioread32(pfc->windows->virt + IOCTRL6);
+ /* Bits in IOCTRL6 are numbered in opposite order to pins */
+ mask = 0x80000000 >> (pin & 0x1f);
+
+ if (mV == 3300)
+ data |= mask;
+ else
+ data &= ~mask;
+
+ iowrite32(~data, pfc->windows->virt); /* unlock reg */
+ iowrite32(data, pfc->windows->virt + IOCTRL6);
+
+ return 0;
+}
+
static const struct sh_pfc_function pinmux_functions[] = {
SH_PFC_FUNCTION(audio_clk),
SH_PFC_FUNCTION(avb),
@@ -5690,8 +5736,14 @@ static const struct pinmux_cfg_reg pinmux_config_regs[] = {
{ },
};
+static const struct sh_pfc_soc_operations pinmux_ops = {
+ .get_io_voltage = r8a7790_get_io_voltage,
+ .set_io_voltage = r8a7790_set_io_voltage,
+};
+
const struct sh_pfc_soc_info r8a7790_pinmux_info = {
.name = "r8a77900_pfc",
+ .ops = &pinmux_ops,
.unlock_reg = 0xe6060000, /* PMMR */
.function = { PINMUX_FUNCTION_BEGIN, PINMUX_FUNCTION_END },
--
2.7.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH 01/10] pinctrl: sh-pfc: r8a7790: Implement voltage switching for SDHI
2016-03-12 9:15 ` [PATCH 01/10] pinctrl: sh-pfc: r8a7790: Implement voltage switching for SDHI Wolfram Sang
@ 2016-03-14 9:47 ` Geert Uytterhoeven
2016-03-22 8:35 ` Wolfram Sang
0 siblings, 1 reply; 15+ messages in thread
From: Geert Uytterhoeven @ 2016-03-14 9:47 UTC (permalink / raw)
To: Wolfram Sang
Cc: linux-renesas-soc, Linux MMC List, Dirk Behme, Ben Hutchings,
linux-gpio@vger.kernel.org
On Sat, Mar 12, 2016 at 10:15 AM, Wolfram Sang <wsa@the-dreams.de> wrote:
> From: Wolfram Sang <wsa+renesas@sang-engineering.com>
>
> All the SHDIs can operate with either 3.3V or 1.8V signals, depending
> on negotiation with the card.
>
> Implement the {get,set}_io_voltage operations and set the related
> capability flag for the associated pins.
>
> Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
> Cc: linux-gpio@vger.kernel.org
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH 01/10] pinctrl: sh-pfc: r8a7790: Implement voltage switching for SDHI
2016-03-14 9:47 ` Geert Uytterhoeven
@ 2016-03-22 8:35 ` Wolfram Sang
2016-03-22 8:44 ` Geert Uytterhoeven
0 siblings, 1 reply; 15+ messages in thread
From: Wolfram Sang @ 2016-03-22 8:35 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: linux-renesas-soc, Linux MMC List, Dirk Behme, Ben Hutchings,
linux-gpio@vger.kernel.org
[-- Attachment #1: Type: text/plain, Size: 722 bytes --]
On Mon, Mar 14, 2016 at 10:47:23AM +0100, Geert Uytterhoeven wrote:
> On Sat, Mar 12, 2016 at 10:15 AM, Wolfram Sang <wsa@the-dreams.de> wrote:
> > From: Wolfram Sang <wsa+renesas@sang-engineering.com>
> >
> > All the SHDIs can operate with either 3.3V or 1.8V signals, depending
> > on negotiation with the card.
> >
> > Implement the {get,set}_io_voltage operations and set the related
> > capability flag for the associated pins.
> >
> > Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
> > Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
> > Cc: linux-gpio@vger.kernel.org
>
> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
So, can this be picked up already?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH 01/10] pinctrl: sh-pfc: r8a7790: Implement voltage switching for SDHI
2016-03-22 8:35 ` Wolfram Sang
@ 2016-03-22 8:44 ` Geert Uytterhoeven
0 siblings, 0 replies; 15+ messages in thread
From: Geert Uytterhoeven @ 2016-03-22 8:44 UTC (permalink / raw)
To: Wolfram Sang
Cc: linux-renesas-soc, Linux MMC List, Dirk Behme, Ben Hutchings,
linux-gpio@vger.kernel.org
Hi Wolfram,
On Tue, Mar 22, 2016 at 9:35 AM, Wolfram Sang <wsa@the-dreams.de> wrote:
> On Mon, Mar 14, 2016 at 10:47:23AM +0100, Geert Uytterhoeven wrote:
>> On Sat, Mar 12, 2016 at 10:15 AM, Wolfram Sang <wsa@the-dreams.de> wrote:
>> > From: Wolfram Sang <wsa+renesas@sang-engineering.com>
>> >
>> > All the SHDIs can operate with either 3.3V or 1.8V signals, depending
>> > on negotiation with the card.
>> >
>> > Implement the {get,set}_io_voltage operations and set the related
>> > capability flag for the associated pins.
>> >
>> > Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
>> > Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
>> > Cc: linux-gpio@vger.kernel.org
>>
>> Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
>
> So, can this be picked up already?
I'll add it to sh-pfc-for-v4.7, and to next renesas-drivers.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 02/10] mmc: tmio, sh_mobile_sdhi: Pass tmio_mmc_host ptr to clk_{enable,disable} ops
2016-03-12 9:15 [PATCH 00/10] r8a7790: add UHS-I (SDR50) support to Lager Wolfram Sang
2016-03-12 9:15 ` [PATCH 01/10] pinctrl: sh-pfc: r8a7790: Implement voltage switching for SDHI Wolfram Sang
@ 2016-03-12 9:15 ` Wolfram Sang
2016-03-12 9:15 ` [PATCH 03/10] mmc: tmio, sh_mobile_sdhi: Add support for variable input clock frequency Wolfram Sang
` (7 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Wolfram Sang @ 2016-03-12 9:15 UTC (permalink / raw)
To: linux-renesas-soc; +Cc: Wolfram Sang, linux-mmc, Dirk Behme, Ben Hutchings
From: Ben Hutchings <ben.hutchings@codethink.co.uk>
Change the clk_enable operation to take a pointer to the struct
tmio_mmc_host and have it set f_max. For consistency, also change the
clk_disable operation to take a pointer to struct tmio_mmc_host.
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
drivers/mmc/host/sh_mobile_sdhi.c | 12 +++++-------
drivers/mmc/host/tmio_mmc.h | 4 ++--
drivers/mmc/host/tmio_mmc_pio.c | 4 ++--
3 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 9aa147959276d0..55849350202b7d 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -131,16 +131,15 @@ static void sh_mobile_sdhi_sdbuf_width(struct tmio_mmc_host *host, int width)
sd_ctrl_write16(host, EXT_ACC, val);
}
-static int sh_mobile_sdhi_clk_enable(struct platform_device *pdev, unsigned int *f)
+static int sh_mobile_sdhi_clk_enable(struct tmio_mmc_host *host)
{
- struct mmc_host *mmc = platform_get_drvdata(pdev);
- struct tmio_mmc_host *host = mmc_priv(mmc);
+ struct mmc_host *mmc = host->mmc;
struct sh_mobile_sdhi *priv = host_to_priv(host);
int ret = clk_prepare_enable(priv->clk);
if (ret < 0)
return ret;
- *f = clk_get_rate(priv->clk);
+ mmc->f_max = clk_get_rate(priv->clk);
/* enable 16bit data access on SDBUF as default */
sh_mobile_sdhi_sdbuf_width(host, 16);
@@ -148,11 +147,10 @@ static int sh_mobile_sdhi_clk_enable(struct platform_device *pdev, unsigned int
return 0;
}
-static void sh_mobile_sdhi_clk_disable(struct platform_device *pdev)
+static void sh_mobile_sdhi_clk_disable(struct tmio_mmc_host *host)
{
- struct mmc_host *mmc = platform_get_drvdata(pdev);
- struct tmio_mmc_host *host = mmc_priv(mmc);
struct sh_mobile_sdhi *priv = host_to_priv(host);
+
clk_disable_unprepare(priv->clk);
}
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 4a597f5a53e20f..68fd8d791358c1 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -95,8 +95,8 @@ struct tmio_mmc_host {
bool sdio_irq_enabled;
int (*write16_hook)(struct tmio_mmc_host *host, int addr);
- int (*clk_enable)(struct platform_device *pdev, unsigned int *f);
- void (*clk_disable)(struct platform_device *pdev);
+ int (*clk_enable)(struct tmio_mmc_host *host);
+ void (*clk_disable)(struct tmio_mmc_host *host);
int (*multi_io_quirk)(struct mmc_card *card,
unsigned int direction, int blk_size);
};
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 03f6e74c190691..d1160156678ade 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -845,7 +845,7 @@ static int tmio_mmc_clk_update(struct tmio_mmc_host *host)
if (!host->clk_enable)
return -ENOTSUPP;
- ret = host->clk_enable(host->pdev, &mmc->f_max);
+ ret = host->clk_enable(host);
if (!ret)
mmc->f_min = mmc->f_max / 512;
@@ -1251,7 +1251,7 @@ int tmio_mmc_host_runtime_suspend(struct device *dev)
tmio_mmc_clk_stop(host);
if (host->clk_disable)
- host->clk_disable(host->pdev);
+ host->clk_disable(host);
return 0;
}
--
2.7.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 03/10] mmc: tmio, sh_mobile_sdhi: Add support for variable input clock frequency
2016-03-12 9:15 [PATCH 00/10] r8a7790: add UHS-I (SDR50) support to Lager Wolfram Sang
2016-03-12 9:15 ` [PATCH 01/10] pinctrl: sh-pfc: r8a7790: Implement voltage switching for SDHI Wolfram Sang
2016-03-12 9:15 ` [PATCH 02/10] mmc: tmio, sh_mobile_sdhi: Pass tmio_mmc_host ptr to clk_{enable,disable} ops Wolfram Sang
@ 2016-03-12 9:15 ` Wolfram Sang
2016-03-12 9:15 ` [PATCH 04/10] mmc: tmio: Add UHS-I mode support Wolfram Sang
` (6 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Wolfram Sang @ 2016-03-12 9:15 UTC (permalink / raw)
To: linux-renesas-soc; +Cc: Wolfram Sang, linux-mmc, Dirk Behme, Ben Hutchings
From: Ben Hutchings <ben.hutchings@codethink.co.uk>
Currently tmio_mmc assumes that the input clock frequency is fixed and
only its own clock divider can be changed. This is not true in the
case of sh_mobile_sdhi; we can use the clock API to change it.
In tmio_mmc:
- Delegate setting of f_min from tmio to the clk_enable operation (if
implemented), as it can be smaller than f_max / 512
- Add an optional clk_update operation called from tmio_mmc_set_clock()
that updates the input clock frequency
- Rename tmio_mmc_clk_update() to tmio_mmc_clk_enable(), to avoid
confusion with the clk_update operation
In sh_mobile_sdhi:
- Make the setting of f_max conditional; it should be set through the
max-frequency property in the device tree in future
- Set f_min based on the input clock's minimum frequency
- Implement the clk_update operation, selecting the best input clock
frequency for the bus frequency that's wanted
sh_mobile_sdhi_clk_update() is loosely based on Kuninori Morimoto's work
in sh_mmcif.
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
drivers/mmc/host/sh_mobile_sdhi.c | 56 +++++++++++++++++++++++++++++++++++++--
drivers/mmc/host/tmio_mmc.h | 2 ++
drivers/mmc/host/tmio_mmc_pio.c | 24 +++++++----------
3 files changed, 66 insertions(+), 16 deletions(-)
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 55849350202b7d..8fd1d6b29190b6 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -139,7 +139,20 @@ static int sh_mobile_sdhi_clk_enable(struct tmio_mmc_host *host)
if (ret < 0)
return ret;
- mmc->f_max = clk_get_rate(priv->clk);
+ /*
+ * The clock driver may not know what maximum frequency
+ * actually works, so it should be set with the max-frequency
+ * property which will already have been read to f_max. If it
+ * was missing, assume the current frequency is the maximum.
+ */
+ if (!mmc->f_max)
+ mmc->f_max = clk_get_rate(priv->clk);
+
+ /*
+ * Minimum frequency is the minimum input clock frequency
+ * divided by our maximum divider.
+ */
+ mmc->f_min = max(clk_round_rate(priv->clk, 1) / 512, 1L);
/* enable 16bit data access on SDBUF as default */
sh_mobile_sdhi_sdbuf_width(host, 16);
@@ -147,6 +160,44 @@ static int sh_mobile_sdhi_clk_enable(struct tmio_mmc_host *host)
return 0;
}
+static unsigned int sh_mobile_sdhi_clk_update(struct tmio_mmc_host *host,
+ unsigned int new_clock)
+{
+ struct sh_mobile_sdhi *priv = host_to_priv(host);
+ unsigned int freq, best_freq, diff_min, diff;
+ int i;
+
+ diff_min = ~0;
+ best_freq = 0;
+
+ /*
+ * We want the bus clock to be as close as possible to, but no
+ * greater than, new_clock. As we can divide by 1 << i for
+ * any i in [0, 9] we want the input clock to be as close as
+ * possible, but no greater than, new_clock << i.
+ */
+ for (i = min(9, ilog2(UINT_MAX / new_clock)); i >= 0; i--) {
+ freq = clk_round_rate(priv->clk, new_clock << i);
+ if (freq > (new_clock << i)) {
+ /* Too fast; look for a slightly slower option */
+ freq = clk_round_rate(priv->clk,
+ (new_clock << i) / 4 * 3);
+ if (freq > (new_clock << i))
+ continue;
+ }
+
+ diff = new_clock - (freq >> i);
+ if (diff <= diff_min) {
+ best_freq = freq;
+ diff_min = diff;
+ }
+ }
+
+ clk_set_rate(priv->clk, best_freq);
+
+ return best_freq;
+}
+
static void sh_mobile_sdhi_clk_disable(struct tmio_mmc_host *host)
{
struct sh_mobile_sdhi *priv = host_to_priv(host);
@@ -265,6 +316,7 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
host->dma = dma_priv;
host->write16_hook = sh_mobile_sdhi_write16_hook;
host->clk_enable = sh_mobile_sdhi_clk_enable;
+ host->clk_update = sh_mobile_sdhi_clk_update;
host->clk_disable = sh_mobile_sdhi_clk_disable;
host->multi_io_quirk = sh_mobile_sdhi_multi_io_quirk;
@@ -362,7 +414,7 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
}
}
- dev_info(&pdev->dev, "%s base at 0x%08lx clock rate %u MHz\n",
+ dev_info(&pdev->dev, "%s base at 0x%08lx max clock rate %u MHz\n",
mmc_hostname(host->mmc), (unsigned long)
(platform_get_resource(pdev, IORESOURCE_MEM, 0)->start),
host->mmc->f_max / 1000000);
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 68fd8d791358c1..b44b5890290622 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -96,6 +96,8 @@ struct tmio_mmc_host {
int (*write16_hook)(struct tmio_mmc_host *host, int addr);
int (*clk_enable)(struct tmio_mmc_host *host);
+ unsigned int (*clk_update)(struct tmio_mmc_host *host,
+ unsigned int new_clock);
void (*clk_disable)(struct tmio_mmc_host *host);
int (*multi_io_quirk)(struct mmc_card *card,
unsigned int direction, int blk_size);
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index d1160156678ade..ae81b34f17a5a5 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -160,9 +160,12 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
u32 clk = 0, clock;
if (new_clock) {
- for (clock = host->mmc->f_min, clk = 0x80000080;
- new_clock >= (clock << 1);
- clk >>= 1)
+ if (host->clk_update)
+ clock = host->clk_update(host, new_clock) / 512;
+ else
+ clock = host->mmc->f_min;
+
+ for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1)
clock <<= 1;
/* 1/1 clock is option */
@@ -837,19 +840,12 @@ fail:
pm_runtime_put_autosuspend(mmc_dev(mmc));
}
-static int tmio_mmc_clk_update(struct tmio_mmc_host *host)
+static int tmio_mmc_clk_enable(struct tmio_mmc_host *host)
{
- struct mmc_host *mmc = host->mmc;
- int ret;
-
if (!host->clk_enable)
return -ENOTSUPP;
- ret = host->clk_enable(host);
- if (!ret)
- mmc->f_min = mmc->f_max / 512;
-
- return ret;
+ return host->clk_enable(host);
}
static void tmio_mmc_power_on(struct tmio_mmc_host *host, unsigned short vdd)
@@ -1135,7 +1131,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host,
mmc->caps & MMC_CAP_NONREMOVABLE ||
mmc->slot.cd_irq >= 0);
- if (tmio_mmc_clk_update(_host) < 0) {
+ if (tmio_mmc_clk_enable(_host) < 0) {
mmc->f_max = pdata->hclk;
mmc->f_min = mmc->f_max / 512;
}
@@ -1263,7 +1259,7 @@ int tmio_mmc_host_runtime_resume(struct device *dev)
struct tmio_mmc_host *host = mmc_priv(mmc);
tmio_mmc_reset(host);
- tmio_mmc_clk_update(host);
+ tmio_mmc_clk_enable(host);
if (host->clk_cache) {
tmio_mmc_set_clock(host, host->clk_cache);
--
2.7.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 04/10] mmc: tmio: Add UHS-I mode support
2016-03-12 9:15 [PATCH 00/10] r8a7790: add UHS-I (SDR50) support to Lager Wolfram Sang
` (2 preceding siblings ...)
2016-03-12 9:15 ` [PATCH 03/10] mmc: tmio, sh_mobile_sdhi: Add support for variable input clock frequency Wolfram Sang
@ 2016-03-12 9:15 ` Wolfram Sang
2016-03-12 9:15 ` [PATCH 05/10] mmc: tmio: always start clock after frequency calculation Wolfram Sang
` (5 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Wolfram Sang @ 2016-03-12 9:15 UTC (permalink / raw)
To: linux-renesas-soc; +Cc: Wolfram Sang, linux-mmc, Dirk Behme, Ben Hutchings
From: Wolfram Sang <wsa+renesas@sang-engineering.com>
Based on work by Shinobu Uehara and Ben Dooks. This adds the voltage
switch operation needed for all UHS-I modes, but not the tuning needed
for SDR-104 which will come later.
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
Changes since RFC:
* pass whole ios instead of just signal_voltage to voltage switch function
* drop PM calls from card_busy callback
* read DAT0 instead of DAT3 for card_busy and simplify function
drivers/mmc/host/tmio_mmc.h | 2 ++
drivers/mmc/host/tmio_mmc_pio.c | 20 ++++++++++++++++++++
include/linux/mmc/tmio.h | 2 ++
3 files changed, 24 insertions(+)
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index b44b5890290622..759bf015d09b84 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -101,6 +101,8 @@ struct tmio_mmc_host {
void (*clk_disable)(struct tmio_mmc_host *host);
int (*multi_io_quirk)(struct mmc_card *card,
unsigned int direction, int blk_size);
+ int (*start_signal_voltage_switch)(struct tmio_mmc_host *host,
+ struct mmc_ios *ios);
};
struct tmio_mmc_host *tmio_mmc_host_alloc(struct platform_device *pdev);
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index ae81b34f17a5a5..4b5a7af2d2273f 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -1012,12 +1012,32 @@ static int tmio_multi_io_quirk(struct mmc_card *card,
return blk_size;
}
+static int tmio_mmc_start_signal_voltage_switch(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+
+ if (!host->start_signal_voltage_switch)
+ return 0;
+
+ return host->start_signal_voltage_switch(host, ios);
+}
+
+static int tmio_mmc_card_busy(struct mmc_host *mmc)
+{
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+
+ return !(sd_ctrl_read32(host, CTL_STATUS2) & TMIO_STATUS2_DAT0);
+}
+
static const struct mmc_host_ops tmio_mmc_ops = {
.request = tmio_mmc_request,
.set_ios = tmio_mmc_set_ios,
.get_ro = tmio_mmc_get_ro,
.get_cd = mmc_gpio_get_cd,
.enable_sdio_irq = tmio_mmc_enable_sdio_irq,
+ .start_signal_voltage_switch
+ = tmio_mmc_start_signal_voltage_switch,
+ .card_busy = tmio_mmc_card_busy,
.multi_io_quirk = tmio_multi_io_quirk,
};
diff --git a/include/linux/mmc/tmio.h b/include/linux/mmc/tmio.h
index 5f5cd80e976500..b2f28e99503383 100644
--- a/include/linux/mmc/tmio.h
+++ b/include/linux/mmc/tmio.h
@@ -63,6 +63,8 @@
#define TMIO_STAT_CMD_BUSY 0x40000000
#define TMIO_STAT_ILL_ACCESS 0x80000000
+#define TMIO_STATUS2_DAT0 BIT(7)
+
#define CLK_CTL_DIV_MASK 0xff
#define CLK_CTL_SCLKEN BIT(8)
--
2.7.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 05/10] mmc: tmio: always start clock after frequency calculation
2016-03-12 9:15 [PATCH 00/10] r8a7790: add UHS-I (SDR50) support to Lager Wolfram Sang
` (3 preceding siblings ...)
2016-03-12 9:15 ` [PATCH 04/10] mmc: tmio: Add UHS-I mode support Wolfram Sang
@ 2016-03-12 9:15 ` Wolfram Sang
2016-03-12 9:15 ` [PATCH 06/10] mmc: tmio: stop clock when 0Hz is requested Wolfram Sang
` (4 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Wolfram Sang @ 2016-03-12 9:15 UTC (permalink / raw)
To: linux-renesas-soc; +Cc: Wolfram Sang, linux-mmc, Dirk Behme, Ben Hutchings
From: Wolfram Sang <wsa+renesas@sang-engineering.com>
Starting the clock is always done after frequency change, so we can do
it directly after the clock calculation. This is the first part of doing
proper clock de-/activation at calculation time.
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
New patch, was not in RFC.
drivers/mmc/host/tmio_mmc_pio.c | 34 ++++++++++++++++------------------
1 file changed, 16 insertions(+), 18 deletions(-)
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 4b5a7af2d2273f..e773969970e51b 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -154,6 +154,18 @@ static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
}
}
+static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
+{
+ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
+ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+ msleep(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG ? 1 : 10);
+
+ if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) {
+ sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
+ msleep(10);
+ }
+}
+
static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
unsigned int new_clock)
{
@@ -182,6 +194,8 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & CLK_CTL_DIV_MASK);
if (!(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG))
msleep(10);
+
+ tmio_mmc_clk_start(host);
}
static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
@@ -196,18 +210,6 @@ static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
msleep(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG ? 5 : 10);
}
-static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
-{
- sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, CLK_CTL_SCLKEN |
- sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
- msleep(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG ? 1 : 10);
-
- if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) {
- sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
- msleep(10);
- }
-}
-
static void tmio_mmc_reset(struct tmio_mmc_host *host)
{
/* FIXME - should we set stop clock reg here */
@@ -955,14 +957,12 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
tmio_mmc_clk_stop(host);
break;
case MMC_POWER_UP:
- tmio_mmc_set_clock(host, ios->clock);
tmio_mmc_power_on(host, ios->vdd);
- tmio_mmc_clk_start(host);
+ tmio_mmc_set_clock(host, ios->clock);
tmio_mmc_set_bus_width(host, ios->bus_width);
break;
case MMC_POWER_ON:
tmio_mmc_set_clock(host, ios->clock);
- tmio_mmc_clk_start(host);
tmio_mmc_set_bus_width(host, ios->bus_width);
break;
}
@@ -1281,10 +1281,8 @@ int tmio_mmc_host_runtime_resume(struct device *dev)
tmio_mmc_reset(host);
tmio_mmc_clk_enable(host);
- if (host->clk_cache) {
+ if (host->clk_cache)
tmio_mmc_set_clock(host, host->clk_cache);
- tmio_mmc_clk_start(host);
- }
tmio_mmc_enable_dma(host, true);
--
2.7.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 06/10] mmc: tmio: stop clock when 0Hz is requested
2016-03-12 9:15 [PATCH 00/10] r8a7790: add UHS-I (SDR50) support to Lager Wolfram Sang
` (4 preceding siblings ...)
2016-03-12 9:15 ` [PATCH 05/10] mmc: tmio: always start clock after frequency calculation Wolfram Sang
@ 2016-03-12 9:15 ` Wolfram Sang
2016-03-12 9:15 ` [PATCH 07/10] mmc: host: add note that set_ios needs to handle 0Hz properly Wolfram Sang
` (3 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Wolfram Sang @ 2016-03-12 9:15 UTC (permalink / raw)
To: linux-renesas-soc; +Cc: Wolfram Sang, linux-mmc, Dirk Behme, Ben Hutchings
From: Wolfram Sang <wsa+renesas@sang-engineering.com>
Setting frequency to 0 is not enough, the clock explicitly has to be
disabled. Otherwise voltage switching (which needs SDCLK to be quiet)
fails for various cards.
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
New patch, was not in RFC.
drivers/mmc/host/tmio_mmc_pio.c | 50 +++++++++++++++++++++--------------------
1 file changed, 26 insertions(+), 24 deletions(-)
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index e773969970e51b..8dee637638c31e 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -166,25 +166,39 @@ static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
}
}
+static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
+{
+ if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) {
+ sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000);
+ msleep(10);
+ }
+
+ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
+ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+ msleep(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG ? 5 : 10);
+}
+
static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
unsigned int new_clock)
{
u32 clk = 0, clock;
- if (new_clock) {
- if (host->clk_update)
- clock = host->clk_update(host, new_clock) / 512;
- else
- clock = host->mmc->f_min;
+ if (new_clock == 0) {
+ tmio_mmc_clk_stop(host);
+ return;
+ }
- for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1)
- clock <<= 1;
+ if (host->clk_update)
+ clock = host->clk_update(host, new_clock) / 512;
+ else
+ clock = host->mmc->f_min;
- /* 1/1 clock is option */
- if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) &&
- ((clk >> 22) & 0x1))
- clk |= 0xff;
- }
+ for (clk = 0x80000080; new_clock >= (clock << 1); clk >>= 1)
+ clock <<= 1;
+
+ /* 1/1 clock is option */
+ if ((host->pdata->flags & TMIO_MMC_CLK_ACTUAL) && ((clk >> 22) & 0x1))
+ clk |= 0xff;
if (host->set_clk_div)
host->set_clk_div(host->pdev, (clk >> 22) & 1);
@@ -198,18 +212,6 @@ static void tmio_mmc_set_clock(struct tmio_mmc_host *host,
tmio_mmc_clk_start(host);
}
-static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
-{
- if (host->pdata->flags & TMIO_MMC_HAVE_HIGH_REG) {
- sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000);
- msleep(10);
- }
-
- sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~CLK_CTL_SCLKEN &
- sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
- msleep(host->pdata->flags & TMIO_MMC_FAST_CLK_CHG ? 5 : 10);
-}
-
static void tmio_mmc_reset(struct tmio_mmc_host *host)
{
/* FIXME - should we set stop clock reg here */
--
2.7.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 07/10] mmc: host: add note that set_ios needs to handle 0Hz properly
2016-03-12 9:15 [PATCH 00/10] r8a7790: add UHS-I (SDR50) support to Lager Wolfram Sang
` (5 preceding siblings ...)
2016-03-12 9:15 ` [PATCH 06/10] mmc: tmio: stop clock when 0Hz is requested Wolfram Sang
@ 2016-03-12 9:15 ` Wolfram Sang
2016-03-12 18:13 ` Sergei Shtylyov
2016-03-12 9:15 ` [PATCH 08/10] mmc: sh_mobile_sdhi: Add UHS-I mode support Wolfram Sang
` (2 subsequent siblings)
9 siblings, 1 reply; 15+ messages in thread
From: Wolfram Sang @ 2016-03-12 9:15 UTC (permalink / raw)
To: linux-renesas-soc; +Cc: Wolfram Sang, linux-mmc, Dirk Behme, Ben Hutchings
From: Wolfram Sang <wsa+renesas@sang-engineering.com>
While here, refactor the comments so that they are before the
declaration they are referring to.
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
New patch, was not in RFC.
include/linux/mmc/host.h | 31 +++++++++++++++++++++----------
1 file changed, 21 insertions(+), 10 deletions(-)
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index 8dd4d290ab0d86..85800b48241fad 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -93,28 +93,39 @@ struct mmc_host_ops {
void (*pre_req)(struct mmc_host *host, struct mmc_request *req,
bool is_first_req);
void (*request)(struct mmc_host *host, struct mmc_request *req);
+
+ /*
+ * Avoid calling the next three functions too often or in a "fast
+ * path", since underlaying controller might implement them in an
+ * expensive and/or slow way. Also note that these functions might
+ * sleep, so don't call them in the atomic contexts!
+ */
+
+ /*
+ * Notes to the set_ios callback:
+ * ios->clock might be 0. For some controllers, setting 0Hz
+ * as any other frequency works. However, some controllers
+ * explicitly need to disable the clock. Otherwise e.g. voltage
+ * switching might fail because the SDCLK is not really quiet.
+ */
+ void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);
+
/*
- * Avoid calling these three functions too often or in a "fast path",
- * since underlaying controller might implement them in an expensive
- * and/or slow way.
- *
- * Also note that these functions might sleep, so don't call them
- * in the atomic contexts!
- *
* Return values for the get_ro callback should be:
* 0 for a read/write card
* 1 for a read-only card
* -ENOSYS when not supported (equal to NULL callback)
* or a negative errno value when something bad happened
- *
+ */
+ int (*get_ro)(struct mmc_host *host);
+
+ /*
* Return values for the get_cd callback should be:
* 0 for a absent card
* 1 for a present card
* -ENOSYS when not supported (equal to NULL callback)
* or a negative errno value when something bad happened
*/
- void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);
- int (*get_ro)(struct mmc_host *host);
int (*get_cd)(struct mmc_host *host);
void (*enable_sdio_irq)(struct mmc_host *host, int enable);
--
2.7.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH 07/10] mmc: host: add note that set_ios needs to handle 0Hz properly
2016-03-12 9:15 ` [PATCH 07/10] mmc: host: add note that set_ios needs to handle 0Hz properly Wolfram Sang
@ 2016-03-12 18:13 ` Sergei Shtylyov
0 siblings, 0 replies; 15+ messages in thread
From: Sergei Shtylyov @ 2016-03-12 18:13 UTC (permalink / raw)
To: Wolfram Sang, linux-renesas-soc; +Cc: linux-mmc, Dirk Behme, Ben Hutchings
Hello.
On 03/12/2016 12:15 PM, Wolfram Sang wrote:
> From: Wolfram Sang <wsa+renesas@sang-engineering.com>
>
> While here, refactor the comments so that they are before the
> declaration they are referring to.
>
> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
> ---
>
> New patch, was not in RFC.
>
> include/linux/mmc/host.h | 31 +++++++++++++++++++++----------
> 1 file changed, 21 insertions(+), 10 deletions(-)
>
> diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
> index 8dd4d290ab0d86..85800b48241fad 100644
> --- a/include/linux/mmc/host.h
> +++ b/include/linux/mmc/host.h
> @@ -93,28 +93,39 @@ struct mmc_host_ops {
> void (*pre_req)(struct mmc_host *host, struct mmc_request *req,
> bool is_first_req);
> void (*request)(struct mmc_host *host, struct mmc_request *req);
> +
> + /*
> + * Avoid calling the next three functions too often or in a "fast
> + * path", since underlaying controller might implement them in an
Underlying.
[...]
MBR, Sergei
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 08/10] mmc: sh_mobile_sdhi: Add UHS-I mode support
2016-03-12 9:15 [PATCH 00/10] r8a7790: add UHS-I (SDR50) support to Lager Wolfram Sang
` (6 preceding siblings ...)
2016-03-12 9:15 ` [PATCH 07/10] mmc: host: add note that set_ios needs to handle 0Hz properly Wolfram Sang
@ 2016-03-12 9:15 ` Wolfram Sang
2016-03-12 9:15 ` [PATCH 09/10] ARM: shmobile: r8a7790: Set maximum frequencies for SDHI clocks Wolfram Sang
2016-03-12 9:15 ` [PATCH 10/10] ARM: shmobile: r8a7790: lager: Enable UHS-I SDR-50 Wolfram Sang
9 siblings, 0 replies; 15+ messages in thread
From: Wolfram Sang @ 2016-03-12 9:15 UTC (permalink / raw)
To: linux-renesas-soc; +Cc: Wolfram Sang, linux-mmc, Dirk Behme, Ben Hutchings
From: Wolfram Sang <wsa+renesas@sang-engineering.com>
Implement voltage switch, supporting modes up to SDR-50.
Based on work by Shinobu Uehara, Rob Taylor, William Towle and Ian Molton.
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
Changes since RFC:
* added binding docs
* use mmc_regulator_set_vqmmc instead of open coding it
* rename DT binding name and pinctrl variables to "*uhs" instead of "*1v8"
Documentation/devicetree/bindings/mmc/tmio_mmc.txt | 3 ++
drivers/mmc/host/sh_mobile_sdhi.c | 49 ++++++++++++++++++++++
2 files changed, 52 insertions(+)
diff --git a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt
index 7fb746dd1a68ca..0f610d4b5b005f 100644
--- a/Documentation/devicetree/bindings/mmc/tmio_mmc.txt
+++ b/Documentation/devicetree/bindings/mmc/tmio_mmc.txt
@@ -26,3 +26,6 @@ Required properties:
Optional properties:
- toshiba,mmc-wrprotect-disable: write-protect detection is unavailable
+- pinctrl-names: should be "default", "state_uhs"
+- pinctrl-0: should contain default/high speed pin ctrl
+- pinctrl-1: should contain uhs mode pin ctrl
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 8fd1d6b29190b6..5d2a852f17eebd 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -32,6 +32,9 @@
#include <linux/mfd/tmio.h>
#include <linux/sh_dma.h>
#include <linux/delay.h>
+#include <linux/pinctrl/consumer.h>
+#include <linux/pinctrl/pinctrl-state.h>
+#include <linux/regulator/consumer.h>
#include "tmio_mmc.h"
@@ -97,6 +100,8 @@ struct sh_mobile_sdhi {
struct clk *clk;
struct tmio_mmc_data mmc_data;
struct tmio_mmc_dma dma_priv;
+ struct pinctrl *pinctrl;
+ struct pinctrl_state *pins_default, *pins_uhs;
};
static void sh_mobile_sdhi_sdbuf_width(struct tmio_mmc_host *host, int width)
@@ -205,6 +210,43 @@ static void sh_mobile_sdhi_clk_disable(struct tmio_mmc_host *host)
clk_disable_unprepare(priv->clk);
}
+static int sh_mobile_sdhi_start_signal_voltage_switch(struct tmio_mmc_host *host,
+ struct mmc_ios *ios)
+{
+ struct sh_mobile_sdhi *priv = host_to_priv(host);
+ struct pinctrl_state *pin_state;
+ int ret;
+
+ switch (ios->signal_voltage) {
+ case MMC_SIGNAL_VOLTAGE_330:
+ pin_state = priv->pins_default;
+ break;
+ case MMC_SIGNAL_VOLTAGE_180:
+ pin_state = priv->pins_uhs;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /*
+ * If anything is missing, assume signal voltage is fixed at
+ * 3.3V and succeed/fail accordingly.
+ */
+ if (IS_ERR(priv->pinctrl) || IS_ERR(pin_state))
+ return ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330 ? 0 : -EINVAL;
+
+ ret = mmc_regulator_set_vqmmc(host->mmc, ios);
+ if (ret)
+ return ret;
+
+ ret = pinctrl_select_state(priv->pinctrl, pin_state);
+ if (ret)
+ return ret;
+
+ usleep_range(5000, 5500);
+ return 0;
+}
+
static int sh_mobile_sdhi_wait_idle(struct tmio_mmc_host *host)
{
int timeout = 1000;
@@ -296,6 +338,12 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
goto eprobe;
}
+ priv->pinctrl = devm_pinctrl_get(&pdev->dev);
+ if (!IS_ERR(priv->pinctrl)) {
+ priv->pins_default = pinctrl_lookup_state(priv->pinctrl, PINCTRL_STATE_DEFAULT);
+ priv->pins_uhs = pinctrl_lookup_state(priv->pinctrl, "state_uhs");
+ }
+
host = tmio_mmc_host_alloc(pdev);
if (!host) {
ret = -ENOMEM;
@@ -319,6 +367,7 @@ static int sh_mobile_sdhi_probe(struct platform_device *pdev)
host->clk_update = sh_mobile_sdhi_clk_update;
host->clk_disable = sh_mobile_sdhi_clk_disable;
host->multi_io_quirk = sh_mobile_sdhi_multi_io_quirk;
+ host->start_signal_voltage_switch = sh_mobile_sdhi_start_signal_voltage_switch;
/* Orginally registers were 16 bit apart, could be 32 or 64 nowadays */
if (!host->bus_shift && resource_size(res) > 0x100) /* old way to determine the shift */
--
2.7.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 09/10] ARM: shmobile: r8a7790: Set maximum frequencies for SDHI clocks
2016-03-12 9:15 [PATCH 00/10] r8a7790: add UHS-I (SDR50) support to Lager Wolfram Sang
` (7 preceding siblings ...)
2016-03-12 9:15 ` [PATCH 08/10] mmc: sh_mobile_sdhi: Add UHS-I mode support Wolfram Sang
@ 2016-03-12 9:15 ` Wolfram Sang
2016-03-12 9:15 ` [PATCH 10/10] ARM: shmobile: r8a7790: lager: Enable UHS-I SDR-50 Wolfram Sang
9 siblings, 0 replies; 15+ messages in thread
From: Wolfram Sang @ 2016-03-12 9:15 UTC (permalink / raw)
To: linux-renesas-soc; +Cc: Wolfram Sang, linux-mmc, Dirk Behme, Ben Hutchings
From: Ben Hutchings <ben.hutchings@codethink.co.uk>
Taken from the datasheet.
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
arch/arm/boot/dts/r8a7790.dtsi | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi
index 6d435e10a4de0c..318ba8129c3463 100644
--- a/arch/arm/boot/dts/r8a7790.dtsi
+++ b/arch/arm/boot/dts/r8a7790.dtsi
@@ -597,6 +597,7 @@
reg = <0 0xee100000 0 0x328>;
interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp3_clks R8A7790_CLK_SDHI0>;
+ max-frequency = <156000000>;
dmas = <&dmac1 0xcd>, <&dmac1 0xce>;
dma-names = "tx", "rx";
power-domains = <&cpg_clocks>;
@@ -608,6 +609,7 @@
reg = <0 0xee120000 0 0x328>;
interrupts = <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp3_clks R8A7790_CLK_SDHI1>;
+ max-frequency = <156000000>;
dmas = <&dmac1 0xc9>, <&dmac1 0xca>;
dma-names = "tx", "rx";
power-domains = <&cpg_clocks>;
@@ -619,6 +621,7 @@
reg = <0 0xee140000 0 0x100>;
interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp3_clks R8A7790_CLK_SDHI2>;
+ max-frequency = <97500000>;
dmas = <&dmac1 0xc1>, <&dmac1 0xc2>;
dma-names = "tx", "rx";
power-domains = <&cpg_clocks>;
@@ -630,6 +633,7 @@
reg = <0 0xee160000 0 0x100>;
interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&mstp3_clks R8A7790_CLK_SDHI3>;
+ max-frequency = <97500000>;
dmas = <&dmac1 0xd3>, <&dmac1 0xd4>;
dma-names = "tx", "rx";
power-domains = <&cpg_clocks>;
--
2.7.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* [PATCH 10/10] ARM: shmobile: r8a7790: lager: Enable UHS-I SDR-50
2016-03-12 9:15 [PATCH 00/10] r8a7790: add UHS-I (SDR50) support to Lager Wolfram Sang
` (8 preceding siblings ...)
2016-03-12 9:15 ` [PATCH 09/10] ARM: shmobile: r8a7790: Set maximum frequencies for SDHI clocks Wolfram Sang
@ 2016-03-12 9:15 ` Wolfram Sang
9 siblings, 0 replies; 15+ messages in thread
From: Wolfram Sang @ 2016-03-12 9:15 UTC (permalink / raw)
To: linux-renesas-soc; +Cc: Wolfram Sang, linux-mmc, Dirk Behme, Ben Hutchings
From: Ben Hutchings <ben.hutchings@codethink.co.uk>
Add the "1v8" pinctrl state and sd-uhs-sdr50 property to SDHI{0,2}.
Signed-off-by: Ben Hutchings <ben.hutchings@codethink.co.uk>
Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
---
Changes since RFC:
* rename DT binding name and pinctrl variables to "*uhs" instead of "*1v8"
arch/arm/boot/dts/r8a7790-lager.dts | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts
index 4972d24a609d2a..db87041617b1d8 100644
--- a/arch/arm/boot/dts/r8a7790-lager.dts
+++ b/arch/arm/boot/dts/r8a7790-lager.dts
@@ -346,11 +346,25 @@
sdhi0_pins: sd0 {
renesas,groups = "sdhi0_data4", "sdhi0_ctrl";
renesas,function = "sdhi0";
+ power-source = <3300>;
+ };
+
+ sdhi0_pins_uhs: sd0_uhs {
+ renesas,groups = "sdhi0_data4", "sdhi0_ctrl";
+ renesas,function = "sdhi0";
+ power-source = <1800>;
};
sdhi2_pins: sd2 {
renesas,groups = "sdhi2_data4", "sdhi2_ctrl";
renesas,function = "sdhi2";
+ power-source = <3300>;
+ };
+
+ sdhi2_pins_uhs: sd2_uhs {
+ renesas,groups = "sdhi2_data4", "sdhi2_ctrl";
+ renesas,function = "sdhi2";
+ power-source = <1800>;
};
mmc1_pins: mmc1 {
@@ -539,21 +553,25 @@
&sdhi0 {
pinctrl-0 = <&sdhi0_pins>;
- pinctrl-names = "default";
+ pinctrl-1 = <&sdhi0_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
vmmc-supply = <&vcc_sdhi0>;
vqmmc-supply = <&vccq_sdhi0>;
cd-gpios = <&gpio3 6 GPIO_ACTIVE_LOW>;
+ sd-uhs-sdr50;
status = "okay";
};
&sdhi2 {
pinctrl-0 = <&sdhi2_pins>;
- pinctrl-names = "default";
+ pinctrl-1 = <&sdhi2_pins_uhs>;
+ pinctrl-names = "default", "state_uhs";
vmmc-supply = <&vcc_sdhi2>;
vqmmc-supply = <&vccq_sdhi2>;
cd-gpios = <&gpio3 22 GPIO_ACTIVE_LOW>;
+ sd-uhs-sdr50;
status = "okay";
};
--
2.7.0
^ permalink raw reply related [flat|nested] 15+ messages in thread