All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] mmc: Add OMAP SDHCI driver
@ 2017-08-21  7:41 ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel, Kishon Vijay Abraham I

This is the first step in deprecating omap_hsmmc driver completely
and moving to sdhci-omap driver which uses the sdhci library.

This series adds a new SDHCI quirk to indicate MMC_RSP_136 has CRC (since
sdhci in OMAP has CRC)

Apart from the quirk, sdhci-omap has it's own callbacks
to set_clock (clock divider programming is different from generic sdhci)
, set_power, set_bus_width, set_bus_mode and platform_send_init_74_clocks.
These callback functions are implemented based on omap_hsmmc driver.

The sdhci-omap driver supports only the high speed mode and UHS/HS200
mode will be added in a later series.

It has been tested only in boards having DRA7 SoCs like dra7-evm, dra72-evm,
am571x-idk, am572x-idk, am57xx-evm. (Tested only eMMC and SD.
SDIO support will be added later). The plan is to fully convert DRA7
SoC to use SDHCI driver and then convert other legacy platforms to use
SDHCI.

Next Steps:
*) Add UHS support to sdhci-omap
*) Add SDIO support
*) Add support for older TI platforms

Changes from v1:
*) Remove the quirks and instead use sdhci_omap specific callbacks for
   set_power, set_busmode etc.
*) Add a patch from Adrian to tidy reading 136-bit responses

I've also pushed the entire series along with dependent dt patches @
https://github.com/kishon/linux-wip.git sdhci_omap_v1 (in case someone
wants to test)

Adrian Hunter (1):
  mmc: sdhci: Tidy reading 136-bit responses

Kishon Vijay Abraham I (4):
  mmc: sdhci: Add quirk to indicate MMC_RSP_136 has CRC
  dt-bindings: ti-omap-hsmmc: Document new compatible for sdhci omap
  mmc: sdhci-omap: Add OMAP SDHCI driver
  MAINTAINERS: Add TI OMAP SDHCI Maintainer

 .../devicetree/bindings/mmc/ti-omap-hsmmc.txt      |   1 +
 MAINTAINERS                                        |   6 +
 drivers/mmc/host/Kconfig                           |  12 +
 drivers/mmc/host/Makefile                          |   1 +
 drivers/mmc/host/sdhci-omap.c                      | 629 +++++++++++++++++++++
 drivers/mmc/host/sdhci.c                           |  31 +-
 drivers/mmc/host/sdhci.h                           |   2 +
 7 files changed, 672 insertions(+), 10 deletions(-)
 create mode 100644 drivers/mmc/host/sdhci-omap.c

-- 
2.11.0

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH 0/5] mmc: Add OMAP SDHCI driver
@ 2017-08-21  7:41 ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel, Kishon Vijay Abraham I

This is the first step in deprecating omap_hsmmc driver completely
and moving to sdhci-omap driver which uses the sdhci library.

This series adds a new SDHCI quirk to indicate MMC_RSP_136 has CRC (since
sdhci in OMAP has CRC)

Apart from the quirk, sdhci-omap has it's own callbacks
to set_clock (clock divider programming is different from generic sdhci)
, set_power, set_bus_width, set_bus_mode and platform_send_init_74_clocks.
These callback functions are implemented based on omap_hsmmc driver.

The sdhci-omap driver supports only the high speed mode and UHS/HS200
mode will be added in a later series.

It has been tested only in boards having DRA7 SoCs like dra7-evm, dra72-evm,
am571x-idk, am572x-idk, am57xx-evm. (Tested only eMMC and SD.
SDIO support will be added later). The plan is to fully convert DRA7
SoC to use SDHCI driver and then convert other legacy platforms to use
SDHCI.

Next Steps:
*) Add UHS support to sdhci-omap
*) Add SDIO support
*) Add support for older TI platforms

Changes from v1:
*) Remove the quirks and instead use sdhci_omap specific callbacks for
   set_power, set_busmode etc.
*) Add a patch from Adrian to tidy reading 136-bit responses

I've also pushed the entire series along with dependent dt patches @
https://github.com/kishon/linux-wip.git sdhci_omap_v1 (in case someone
wants to test)

Adrian Hunter (1):
  mmc: sdhci: Tidy reading 136-bit responses

Kishon Vijay Abraham I (4):
  mmc: sdhci: Add quirk to indicate MMC_RSP_136 has CRC
  dt-bindings: ti-omap-hsmmc: Document new compatible for sdhci omap
  mmc: sdhci-omap: Add OMAP SDHCI driver
  MAINTAINERS: Add TI OMAP SDHCI Maintainer

 .../devicetree/bindings/mmc/ti-omap-hsmmc.txt      |   1 +
 MAINTAINERS                                        |   6 +
 drivers/mmc/host/Kconfig                           |  12 +
 drivers/mmc/host/Makefile                          |   1 +
 drivers/mmc/host/sdhci-omap.c                      | 629 +++++++++++++++++++++
 drivers/mmc/host/sdhci.c                           |  31 +-
 drivers/mmc/host/sdhci.h                           |   2 +
 7 files changed, 672 insertions(+), 10 deletions(-)
 create mode 100644 drivers/mmc/host/sdhci-omap.c

-- 
2.11.0


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH 0/5] mmc: Add OMAP SDHCI driver
@ 2017-08-21  7:41 ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: linux-arm-kernel

This is the first step in deprecating omap_hsmmc driver completely
and moving to sdhci-omap driver which uses the sdhci library.

This series adds a new SDHCI quirk to indicate MMC_RSP_136 has CRC (since
sdhci in OMAP has CRC)

Apart from the quirk, sdhci-omap has it's own callbacks
to set_clock (clock divider programming is different from generic sdhci)
, set_power, set_bus_width, set_bus_mode and platform_send_init_74_clocks.
These callback functions are implemented based on omap_hsmmc driver.

The sdhci-omap driver supports only the high speed mode and UHS/HS200
mode will be added in a later series.

It has been tested only in boards having DRA7 SoCs like dra7-evm, dra72-evm,
am571x-idk, am572x-idk, am57xx-evm. (Tested only eMMC and SD.
SDIO support will be added later). The plan is to fully convert DRA7
SoC to use SDHCI driver and then convert other legacy platforms to use
SDHCI.

Next Steps:
*) Add UHS support to sdhci-omap
*) Add SDIO support
*) Add support for older TI platforms

Changes from v1:
*) Remove the quirks and instead use sdhci_omap specific callbacks for
   set_power, set_busmode etc.
*) Add a patch from Adrian to tidy reading 136-bit responses

I've also pushed the entire series along with dependent dt patches @
https://github.com/kishon/linux-wip.git sdhci_omap_v1 (in case someone
wants to test)

Adrian Hunter (1):
  mmc: sdhci: Tidy reading 136-bit responses

Kishon Vijay Abraham I (4):
  mmc: sdhci: Add quirk to indicate MMC_RSP_136 has CRC
  dt-bindings: ti-omap-hsmmc: Document new compatible for sdhci omap
  mmc: sdhci-omap: Add OMAP SDHCI driver
  MAINTAINERS: Add TI OMAP SDHCI Maintainer

 .../devicetree/bindings/mmc/ti-omap-hsmmc.txt      |   1 +
 MAINTAINERS                                        |   6 +
 drivers/mmc/host/Kconfig                           |  12 +
 drivers/mmc/host/Makefile                          |   1 +
 drivers/mmc/host/sdhci-omap.c                      | 629 +++++++++++++++++++++
 drivers/mmc/host/sdhci.c                           |  31 +-
 drivers/mmc/host/sdhci.h                           |   2 +
 7 files changed, 672 insertions(+), 10 deletions(-)
 create mode 100644 drivers/mmc/host/sdhci-omap.c

-- 
2.11.0

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH 1/5] mmc: sdhci: Tidy reading 136-bit responses
  2017-08-21  7:41 ` Kishon Vijay Abraham I
  (?)
@ 2017-08-21  7:41   ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel, Kishon Vijay Abraham I

From: Adrian Hunter <adrian.hunter@intel.com>

Read each register only once and move the code to a separate function so
that it is not jammed against the 80 column margin.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/sdhci.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index a1ad2ddadca1..ba639b7851cb 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1173,24 +1173,32 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
 }
 EXPORT_SYMBOL_GPL(sdhci_send_command);
 
+static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
+{
+	int i, reg;
+
+	for (i = 0; i < 4; i++) {
+		reg = SDHCI_RESPONSE + (3 - i) * 4;
+		cmd->resp[i] = sdhci_readl(host, reg);
+	}
+
+	/* CRC is stripped so we need to do some shifting */
+	for (i = 0; i < 4; i++) {
+		cmd->resp[i] <<= 8;
+		if (i != 3)
+			cmd->resp[i] |= cmd->resp[i + 1] >> 24;
+	}
+}
+
 static void sdhci_finish_command(struct sdhci_host *host)
 {
 	struct mmc_command *cmd = host->cmd;
-	int i;
 
 	host->cmd = NULL;
 
 	if (cmd->flags & MMC_RSP_PRESENT) {
 		if (cmd->flags & MMC_RSP_136) {
-			/* CRC is stripped so we need to do some shifting. */
-			for (i = 0;i < 4;i++) {
-				cmd->resp[i] = sdhci_readl(host,
-					SDHCI_RESPONSE + (3-i)*4) << 8;
-				if (i != 3)
-					cmd->resp[i] |=
-						sdhci_readb(host,
-						SDHCI_RESPONSE + (3-i)*4-1);
-			}
+			sdhci_read_rsp_136(host, cmd);
 		} else {
 			cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
 		}
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH 1/5] mmc: sdhci: Tidy reading 136-bit responses
@ 2017-08-21  7:41   ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel, Kishon Vijay Abraham I

From: Adrian Hunter <adrian.hunter@intel.com>

Read each register only once and move the code to a separate function so
that it is not jammed against the 80 column margin.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/sdhci.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index a1ad2ddadca1..ba639b7851cb 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1173,24 +1173,32 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
 }
 EXPORT_SYMBOL_GPL(sdhci_send_command);
 
+static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
+{
+	int i, reg;
+
+	for (i = 0; i < 4; i++) {
+		reg = SDHCI_RESPONSE + (3 - i) * 4;
+		cmd->resp[i] = sdhci_readl(host, reg);
+	}
+
+	/* CRC is stripped so we need to do some shifting */
+	for (i = 0; i < 4; i++) {
+		cmd->resp[i] <<= 8;
+		if (i != 3)
+			cmd->resp[i] |= cmd->resp[i + 1] >> 24;
+	}
+}
+
 static void sdhci_finish_command(struct sdhci_host *host)
 {
 	struct mmc_command *cmd = host->cmd;
-	int i;
 
 	host->cmd = NULL;
 
 	if (cmd->flags & MMC_RSP_PRESENT) {
 		if (cmd->flags & MMC_RSP_136) {
-			/* CRC is stripped so we need to do some shifting. */
-			for (i = 0;i < 4;i++) {
-				cmd->resp[i] = sdhci_readl(host,
-					SDHCI_RESPONSE + (3-i)*4) << 8;
-				if (i != 3)
-					cmd->resp[i] |=
-						sdhci_readb(host,
-						SDHCI_RESPONSE + (3-i)*4-1);
-			}
+			sdhci_read_rsp_136(host, cmd);
 		} else {
 			cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
 		}
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH 1/5] mmc: sdhci: Tidy reading 136-bit responses
@ 2017-08-21  7:41   ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: linux-arm-kernel

From: Adrian Hunter <adrian.hunter@intel.com>

Read each register only once and move the code to a separate function so
that it is not jammed against the 80 column margin.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/sdhci.c | 28 ++++++++++++++++++----------
 1 file changed, 18 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index a1ad2ddadca1..ba639b7851cb 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1173,24 +1173,32 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
 }
 EXPORT_SYMBOL_GPL(sdhci_send_command);
 
+static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
+{
+	int i, reg;
+
+	for (i = 0; i < 4; i++) {
+		reg = SDHCI_RESPONSE + (3 - i) * 4;
+		cmd->resp[i] = sdhci_readl(host, reg);
+	}
+
+	/* CRC is stripped so we need to do some shifting */
+	for (i = 0; i < 4; i++) {
+		cmd->resp[i] <<= 8;
+		if (i != 3)
+			cmd->resp[i] |= cmd->resp[i + 1] >> 24;
+	}
+}
+
 static void sdhci_finish_command(struct sdhci_host *host)
 {
 	struct mmc_command *cmd = host->cmd;
-	int i;
 
 	host->cmd = NULL;
 
 	if (cmd->flags & MMC_RSP_PRESENT) {
 		if (cmd->flags & MMC_RSP_136) {
-			/* CRC is stripped so we need to do some shifting. */
-			for (i = 0;i < 4;i++) {
-				cmd->resp[i] = sdhci_readl(host,
-					SDHCI_RESPONSE + (3-i)*4) << 8;
-				if (i != 3)
-					cmd->resp[i] |=
-						sdhci_readb(host,
-						SDHCI_RESPONSE + (3-i)*4-1);
-			}
+			sdhci_read_rsp_136(host, cmd);
 		} else {
 			cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
 		}
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH 2/5] mmc: sdhci: Add quirk to indicate MMC_RSP_136 has CRC
  2017-08-21  7:41 ` Kishon Vijay Abraham I
  (?)
@ 2017-08-21  7:41   ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel, Kishon Vijay Abraham I

TI's implementation of sdhci controller used in DRA7 SoC's has
CRC in responses with length 136 bits. Add quirk to indicate
the controller has CRC in MMC_RSP_136. If this quirk is
set sdhci library shouldn't shift the response present in
SDHCI_RESPONSE register.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/sdhci.c | 3 +++
 drivers/mmc/host/sdhci.h | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index ba639b7851cb..9c8d7428df3c 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1182,6 +1182,9 @@ static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
 		cmd->resp[i] = sdhci_readl(host, reg);
 	}
 
+	if (host->quirks2 & SDHCI_QUIRK2_RSP_136_HAS_CRC)
+		return;
+
 	/* CRC is stripped so we need to do some shifting */
 	for (i = 0; i < 4; i++) {
 		cmd->resp[i] <<= 8;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 399edc681623..54bc444c317f 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -435,6 +435,8 @@ struct sdhci_host {
 #define SDHCI_QUIRK2_ACMD23_BROKEN			(1<<14)
 /* Broken Clock divider zero in controller */
 #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN		(1<<15)
+/* Controller has CRC in 136 bit Command Response */
+#define SDHCI_QUIRK2_RSP_136_HAS_CRC			(1<<16)
 
 	int irq;		/* Device IRQ */
 	void __iomem *ioaddr;	/* Mapped address */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH 2/5] mmc: sdhci: Add quirk to indicate MMC_RSP_136 has CRC
@ 2017-08-21  7:41   ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel, Kishon Vijay Abraham I

TI's implementation of sdhci controller used in DRA7 SoC's has
CRC in responses with length 136 bits. Add quirk to indicate
the controller has CRC in MMC_RSP_136. If this quirk is
set sdhci library shouldn't shift the response present in
SDHCI_RESPONSE register.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/sdhci.c | 3 +++
 drivers/mmc/host/sdhci.h | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index ba639b7851cb..9c8d7428df3c 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1182,6 +1182,9 @@ static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
 		cmd->resp[i] = sdhci_readl(host, reg);
 	}
 
+	if (host->quirks2 & SDHCI_QUIRK2_RSP_136_HAS_CRC)
+		return;
+
 	/* CRC is stripped so we need to do some shifting */
 	for (i = 0; i < 4; i++) {
 		cmd->resp[i] <<= 8;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 399edc681623..54bc444c317f 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -435,6 +435,8 @@ struct sdhci_host {
 #define SDHCI_QUIRK2_ACMD23_BROKEN			(1<<14)
 /* Broken Clock divider zero in controller */
 #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN		(1<<15)
+/* Controller has CRC in 136 bit Command Response */
+#define SDHCI_QUIRK2_RSP_136_HAS_CRC			(1<<16)
 
 	int irq;		/* Device IRQ */
 	void __iomem *ioaddr;	/* Mapped address */
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH 2/5] mmc: sdhci: Add quirk to indicate MMC_RSP_136 has CRC
@ 2017-08-21  7:41   ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: linux-arm-kernel

TI's implementation of sdhci controller used in DRA7 SoC's has
CRC in responses with length 136 bits. Add quirk to indicate
the controller has CRC in MMC_RSP_136. If this quirk is
set sdhci library shouldn't shift the response present in
SDHCI_RESPONSE register.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/sdhci.c | 3 +++
 drivers/mmc/host/sdhci.h | 2 ++
 2 files changed, 5 insertions(+)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index ba639b7851cb..9c8d7428df3c 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1182,6 +1182,9 @@ static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
 		cmd->resp[i] = sdhci_readl(host, reg);
 	}
 
+	if (host->quirks2 & SDHCI_QUIRK2_RSP_136_HAS_CRC)
+		return;
+
 	/* CRC is stripped so we need to do some shifting */
 	for (i = 0; i < 4; i++) {
 		cmd->resp[i] <<= 8;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 399edc681623..54bc444c317f 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -435,6 +435,8 @@ struct sdhci_host {
 #define SDHCI_QUIRK2_ACMD23_BROKEN			(1<<14)
 /* Broken Clock divider zero in controller */
 #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN		(1<<15)
+/* Controller has CRC in 136 bit Command Response */
+#define SDHCI_QUIRK2_RSP_136_HAS_CRC			(1<<16)
 
 	int irq;		/* Device IRQ */
 	void __iomem *ioaddr;	/* Mapped address */
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH 3/5] dt-bindings: ti-omap-hsmmc: Document new compatible for sdhci omap
  2017-08-21  7:41 ` Kishon Vijay Abraham I
  (?)
@ 2017-08-21  7:41   ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel, Kishon Vijay Abraham I

Document the new compatible string "ti,dra7-sdhci" to be used for
MMC controllers in DRA7 and DRA72 SoCs.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
index 0e026c151c1c..db80fdfd05d7 100644
--- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
+++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
@@ -13,6 +13,7 @@ Required properties:
  Should be "ti,omap3-pre-es3-hsmmc" for OMAP3 controllers pre ES3.0
  Should be "ti,omap4-hsmmc", for OMAP4 controllers
  Should be "ti,am33xx-hsmmc", for AM335x controllers
+ Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
 - ti,hwmods: Must be "mmc<n>", n is controller instance starting 1
 
 Optional properties:
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH 3/5] dt-bindings: ti-omap-hsmmc: Document new compatible for sdhci omap
@ 2017-08-21  7:41   ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel, Kishon Vijay Abraham I

Document the new compatible string "ti,dra7-sdhci" to be used for
MMC controllers in DRA7 and DRA72 SoCs.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
index 0e026c151c1c..db80fdfd05d7 100644
--- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
+++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
@@ -13,6 +13,7 @@ Required properties:
  Should be "ti,omap3-pre-es3-hsmmc" for OMAP3 controllers pre ES3.0
  Should be "ti,omap4-hsmmc", for OMAP4 controllers
  Should be "ti,am33xx-hsmmc", for AM335x controllers
+ Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
 - ti,hwmods: Must be "mmc<n>", n is controller instance starting 1
 
 Optional properties:
-- 
2.11.0


^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH 3/5] dt-bindings: ti-omap-hsmmc: Document new compatible for sdhci omap
@ 2017-08-21  7:41   ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: linux-arm-kernel

Document the new compatible string "ti,dra7-sdhci" to be used for
MMC controllers in DRA7 and DRA72 SoCs.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
index 0e026c151c1c..db80fdfd05d7 100644
--- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
+++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
@@ -13,6 +13,7 @@ Required properties:
  Should be "ti,omap3-pre-es3-hsmmc" for OMAP3 controllers pre ES3.0
  Should be "ti,omap4-hsmmc", for OMAP4 controllers
  Should be "ti,am33xx-hsmmc", for AM335x controllers
+ Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
 - ti,hwmods: Must be "mmc<n>", n is controller instance starting 1
 
 Optional properties:
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH 4/5] mmc: sdhci-omap: Add OMAP SDHCI driver
  2017-08-21  7:41 ` Kishon Vijay Abraham I
  (?)
@ 2017-08-21  7:41   ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel, Kishon Vijay Abraham I

Create a new sdhci-omap driver to configure the eMMC/SD/SDIO controller
in TI's OMAP SoCs making use of the SDHCI core library. For OMAP specific
configurations, populate sdhci_ops with OMAP specific callbacks and use
SDHCI quirks.
Enable only high speed mode for both SD and eMMC here and add other
UHS mode support later.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/Kconfig      |  12 +
 drivers/mmc/host/Makefile     |   1 +
 drivers/mmc/host/sdhci-omap.c | 629 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 642 insertions(+)
 create mode 100644 drivers/mmc/host/sdhci-omap.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 60f90d49e7a9..60d50843e165 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -899,3 +899,15 @@ config MMC_SDHCI_XENON
 	  This selects Marvell Xenon eMMC/SD/SDIO SDHCI.
 	  If you have a controller with this interface, say Y or M here.
 	  If unsure, say N.
+
+config MMC_SDHCI_OMAP
+	tristate "TI SDHCI Controller Support"
+	depends on MMC_SDHCI_PLTFM
+	help
+	  This selects the Secure Digital Host Controller Interface (SDHCI)
+	  support present in TI's DRA7 SOCs. The controller supports
+	  SD/MMC/SDIO devices.
+
+	  If you have a controller with this interface, say Y or M here.
+
+	  If unsure, say N.
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 8c46766c000c..33181df88a10 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_MMC_SDHCI_MSM)		+= sdhci-msm.o
 obj-$(CONFIG_MMC_SDHCI_ST)		+= sdhci-st.o
 obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32)	+= sdhci-pic32.o
 obj-$(CONFIG_MMC_SDHCI_BRCMSTB)		+= sdhci-brcmstb.o
+obj-$(CONFIG_MMC_SDHCI_OMAP)		+= sdhci-omap.o
 
 ifeq ($(CONFIG_CB710_DEBUG),y)
 	CFLAGS-cb710-mmc	+= -DDEBUG
diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c
new file mode 100644
index 000000000000..73ee3b4a400c
--- /dev/null
+++ b/drivers/mmc/host/sdhci-omap.c
@@ -0,0 +1,629 @@
+/**
+ * SDHCI Controller driver for TI's OMAP SoCs
+ *
+ * Copyright (C) 2017 Texas Instruments
+ * Author: Kishon Vijay Abraham I <kishon@ti.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 of
+ * the License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/delay.h>
+#include <linux/mmc/slot-gpio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+
+#include "sdhci-pltfm.h"
+
+#define SDHCI_OMAP_CON		0x12c
+#define CON_DW8			BIT(5)
+#define CON_DMA_MASTER		BIT(20)
+#define CON_INIT		BIT(1)
+#define CON_OD			BIT(0)
+
+#define SDHCI_OMAP_CMD		0x20c
+
+#define SDHCI_OMAP_HCTL		0x228
+#define HCTL_SDBP		BIT(8)
+#define HCTL_SDVS_SHIFT		9
+#define HCTL_SDVS_MASK		(0x7 << HCTL_SDVS_SHIFT)
+#define HCTL_SDVS_33		(0x7 << HCTL_SDVS_SHIFT)
+#define HCTL_SDVS_30		(0x6 << HCTL_SDVS_SHIFT)
+#define HCTL_SDVS_18		(0x5 << HCTL_SDVS_SHIFT)
+
+#define SDHCI_OMAP_SYSCTL	0x22c
+#define SYSCTL_CEN		BIT(2)
+#define SYSCTL_CLKD_SHIFT	6
+#define SYSCTL_CLKD_MASK	0x3ff
+
+#define SDHCI_OMAP_STAT		0x230
+
+#define SDHCI_OMAP_IE		0x234
+#define INT_CC_EN		BIT(0)
+
+#define SDHCI_OMAP_AC12		0x23c
+#define AC12_V1V8_SIGEN		BIT(19)
+
+#define SDHCI_OMAP_CAPA		0x240
+#define CAPA_VS33		BIT(24)
+#define CAPA_VS30		BIT(25)
+#define CAPA_VS18		BIT(26)
+
+#define MMC_TIMEOUT		1		/* 1 msec */
+
+#define SYSCTL_CLKD_MAX		0x3FF
+
+#define IOV_1V8			1800000		/* 180000 uV */
+#define IOV_3V0			3000000		/* 300000 uV */
+#define IOV_3V3			3300000		/* 330000 uV */
+
+struct sdhci_omap_data {
+	u32 offset;
+};
+
+struct sdhci_omap_host {
+	void __iomem		*base;
+	struct device		*dev;
+	struct	regulator	*pbias;
+	bool			pbias_enabled;
+	struct sdhci_host	*host;
+	unsigned int		flags;
+
+#define SDHCI_OMAP_SUPPORTS_DUAL_VOLT	BIT(0)
+#define SDHCI_OMAP_NO_1_8_V		BIT(1)
+
+	u8			bus_mode;
+	u8			power_mode;
+	bool			io_3_3v_support;
+};
+
+static inline u32 sdhci_omap_readl(struct sdhci_omap_host *host,
+				   unsigned int offset)
+{
+	return readl(host->base + offset);
+}
+
+static inline void sdhci_omap_writel(struct sdhci_omap_host *host,
+				     unsigned int offset, u32 data)
+{
+	writel(data, host->base + offset);
+}
+
+static int sdhci_omap_set_pbias(struct sdhci_omap_host *omap_host,
+				bool power_on, unsigned int iov)
+{
+	int ret;
+	struct device *dev = omap_host->dev;
+
+	if (IS_ERR(omap_host->pbias))
+		return 0;
+
+	if (power_on) {
+		ret = regulator_set_voltage(omap_host->pbias, iov, iov);
+		if (ret) {
+			dev_err(dev, "pbias set voltage failed\n");
+			return ret;
+		}
+
+		if (omap_host->pbias_enabled)
+			return 0;
+
+		ret = regulator_enable(omap_host->pbias);
+		if (ret) {
+			dev_err(dev, "pbias reg enable fail\n");
+			return ret;
+		}
+
+		omap_host->pbias_enabled = true;
+	} else {
+		if (!omap_host->pbias_enabled)
+			return 0;
+
+		ret = regulator_disable(omap_host->pbias);
+		if (ret) {
+			dev_err(dev, "pbias reg disable fail\n");
+			return ret;
+		}
+		omap_host->pbias_enabled = false;
+	}
+
+	return 0;
+}
+
+static int sdhci_omap_enable_iov(struct sdhci_omap_host *omap_host,
+				 unsigned int iov)
+{
+	int ret;
+	struct sdhci_host *host = omap_host->host;
+	struct mmc_host *mmc = host->mmc;
+
+	ret = sdhci_omap_set_pbias(omap_host, false, 0);
+	if (ret)
+		return ret;
+
+	if (!IS_ERR(mmc->supply.vqmmc)) {
+		ret = regulator_set_voltage(mmc->supply.vqmmc, iov, iov);
+		if (ret) {
+			dev_err(mmc_dev(mmc), "vqmmc set voltage failed\n");
+			return ret;
+		}
+	}
+
+	ret = sdhci_omap_set_pbias(omap_host, true, iov);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void sdhci_omap_conf_bus_power(struct sdhci_omap_host *omap_host,
+				      unsigned char signal_voltage)
+{
+	u32 reg;
+	ktime_t timeout;
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL);
+	reg &= ~HCTL_SDVS_MASK;
+
+	if (signal_voltage == MMC_SIGNAL_VOLTAGE_180)
+		reg |= HCTL_SDVS_18;
+	else if (omap_host->io_3_3v_support)
+		reg |= HCTL_SDVS_33;
+	else
+		reg |= HCTL_SDVS_30;
+
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
+
+	reg |= HCTL_SDBP;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
+
+	/* wait 1ms */
+	timeout = ktime_add_ms(ktime_get(), MMC_TIMEOUT);
+	while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL) & HCTL_SDBP)) {
+		if (WARN_ON(ktime_after(ktime_get(), timeout)))
+			return;
+		usleep_range(5, 10);
+	}
+}
+
+static int sdhci_omap_start_signal_voltage_switch(struct mmc_host *mmc,
+						  struct mmc_ios *ios)
+{
+	u32 reg;
+	int ret;
+	unsigned int iov;
+	struct sdhci_host *host = mmc_priv(mmc);
+	struct sdhci_pltfm_host *pltfm_host;
+	struct sdhci_omap_host *omap_host;
+	struct device *dev;
+
+	pltfm_host = sdhci_priv(host);
+	omap_host = sdhci_pltfm_priv(pltfm_host);
+	dev = omap_host->dev;
+
+	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
+		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
+		if (!(reg & (CAPA_VS33 | CAPA_VS30)))
+			return -EOPNOTSUPP;
+
+		sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
+
+		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
+		reg &= ~AC12_V1V8_SIGEN;
+		sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
+
+		if (omap_host->io_3_3v_support)
+			iov = IOV_3V3;
+		else
+			iov = IOV_3V0;
+	} else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
+		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
+		if (!(reg & CAPA_VS18))
+			return -EOPNOTSUPP;
+
+		sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
+
+		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
+		reg |= AC12_V1V8_SIGEN;
+		sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
+
+		iov = IOV_1V8;
+	} else {
+		return -EOPNOTSUPP;
+	}
+
+	ret = sdhci_omap_enable_iov(omap_host, iov);
+	if (ret) {
+		dev_err(dev, "failed to switch IO voltage to %dmV\n", iov);
+		return ret;
+	}
+
+	dev_dbg(dev, "IO voltage switched to %dmV\n", iov);
+	return 0;
+}
+
+static void sdhci_omap_set_bus_mode(struct sdhci_omap_host *omap_host,
+				    unsigned int mode)
+{
+	u32 reg;
+
+	if (omap_host->bus_mode == mode)
+		return;
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
+	if (mode == MMC_BUSMODE_OPENDRAIN)
+		reg |= CON_OD;
+	else
+		reg &= ~CON_OD;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
+
+	omap_host->bus_mode = mode;
+}
+
+void sdhci_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	struct sdhci_pltfm_host *pltfm_host;
+	struct sdhci_omap_host *omap_host;
+
+	pltfm_host = sdhci_priv(host);
+	omap_host = sdhci_pltfm_priv(pltfm_host);
+
+	sdhci_omap_set_bus_mode(omap_host, ios->bus_mode);
+	sdhci_set_ios(mmc, ios);
+}
+
+static void sdhci_omap_set_capabilities(struct sdhci_omap_host *omap_host)
+{
+	u32 reg;
+
+	/* voltage capabilities might be set by boot loader, clear it */
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
+	reg &= ~(CAPA_VS18 | CAPA_VS30 | CAPA_VS33);
+
+	if (omap_host->flags & SDHCI_OMAP_SUPPORTS_DUAL_VOLT) {
+		if (omap_host->io_3_3v_support)
+			reg |= (CAPA_VS33 | CAPA_VS18);
+		else
+			reg |= (CAPA_VS30 | CAPA_VS18);
+	} else if (omap_host->flags & SDHCI_OMAP_NO_1_8_V) {
+		if (omap_host->io_3_3v_support)
+			reg |= CAPA_VS33;
+		else
+			reg |= CAPA_VS30;
+	} else {
+		reg |= CAPA_VS18;
+	}
+
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CAPA, reg);
+}
+
+static u16 sdhci_omap_calc_divisor(struct sdhci_pltfm_host *host,
+				   unsigned int clock)
+{
+	u16 dsor;
+
+	dsor = DIV_ROUND_UP(clk_get_rate(host->clk), clock);
+	if (dsor > SYSCTL_CLKD_MAX)
+		dsor = SYSCTL_CLKD_MAX;
+
+	return dsor;
+}
+
+static void sdhci_omap_start_clock(struct sdhci_omap_host *omap_host)
+{
+	u32 reg;
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
+	reg |= SYSCTL_CEN;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
+}
+
+static void sdhci_omap_stop_clock(struct sdhci_omap_host *omap_host)
+{
+	u32 reg;
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
+	reg &= ~SYSCTL_CEN;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
+}
+
+static void sdhci_omap_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
+	unsigned long clkdiv;
+
+	if (!clock)
+		return;
+
+	sdhci_omap_stop_clock(omap_host);
+
+	clkdiv = sdhci_omap_calc_divisor(pltfm_host, clock);
+	clkdiv = (clkdiv & SYSCTL_CLKD_MASK) << SYSCTL_CLKD_SHIFT;
+	sdhci_enable_clk(host, clkdiv);
+
+	sdhci_omap_start_clock(omap_host);
+}
+
+void sdhci_omap_set_power(struct sdhci_host *host, unsigned char mode,
+			  unsigned short vdd)
+{
+	struct mmc_host *mmc = host->mmc;
+
+	mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+}
+
+static int sdhci_omap_enable_dma(struct sdhci_host *host)
+{
+	u32 reg;
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
+	reg |= CON_DMA_MASTER;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
+
+	return 0;
+}
+
+unsigned int sdhci_omap_get_min_clock(struct sdhci_host *host)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+	return clk_get_rate(pltfm_host->clk) / SYSCTL_CLKD_MAX;
+}
+
+static void sdhci_omap_set_bus_width(struct sdhci_host *host, int width)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
+	u32 reg;
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
+	if (width == MMC_BUS_WIDTH_8)
+		reg |= CON_DW8;
+	else
+		reg &= ~CON_DW8;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
+
+	sdhci_set_bus_width(host, width);
+}
+
+static void sdhci_omap_init_74_clocks(struct sdhci_host *host, u8 power_mode)
+{
+	u32 reg;
+	ktime_t timeout;
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
+
+	if (omap_host->power_mode == power_mode)
+		return;
+
+	if (power_mode != MMC_POWER_ON)
+		return;
+
+	disable_irq(host->irq);
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
+	reg |= CON_INIT;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CMD, 0x0);
+
+	/* wait 1ms */
+	timeout = ktime_add_ms(ktime_get(), MMC_TIMEOUT);
+	while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_STAT) & INT_CC_EN)) {
+		if (WARN_ON(ktime_after(ktime_get(), timeout)))
+			return;
+		usleep_range(5, 10);
+	}
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
+	reg &= ~CON_INIT;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_STAT, INT_CC_EN);
+
+	enable_irq(host->irq);
+
+	omap_host->power_mode = power_mode;
+}
+
+static struct sdhci_ops sdhci_omap_ops = {
+	.set_clock = sdhci_omap_set_clock,
+	.set_power = sdhci_omap_set_power,
+	.enable_dma = sdhci_omap_enable_dma,
+	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
+	.get_min_clock = sdhci_omap_get_min_clock,
+	.set_bus_width = sdhci_omap_set_bus_width,
+	.platform_send_init_74_clocks = sdhci_omap_init_74_clocks,
+	.reset = sdhci_reset,
+	.set_uhs_signaling = sdhci_set_uhs_signaling,
+};
+
+void sdhci_omap_get_of_property(struct sdhci_omap_host *omap_host)
+{
+	struct device *dev = omap_host->dev;
+	struct sdhci_host *host = omap_host->host;
+	struct mmc_host *mmc = host->mmc;
+
+	if (device_property_read_bool(dev, "ti,dual-volt"))
+		omap_host->flags |= SDHCI_OMAP_SUPPORTS_DUAL_VOLT;
+
+	if (device_property_read_bool(dev, "no-1-8-v"))
+		omap_host->flags |= SDHCI_OMAP_NO_1_8_V;
+
+	if (device_property_read_bool(dev, "ti,non-removable"))
+		mmc->caps |= MMC_CAP_NONREMOVABLE;
+}
+
+static const struct sdhci_pltfm_data sdhci_omap_pdata = {
+	.quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
+		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
+		  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
+		  SDHCI_QUIRK_NO_HISPD_BIT |
+		  SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC,
+	.quirks2 = SDHCI_QUIRK2_NO_1_8_V |
+		   SDHCI_QUIRK2_ACMD23_BROKEN |
+		   SDHCI_QUIRK2_RSP_136_HAS_CRC,
+	.ops = &sdhci_omap_ops,
+};
+
+static const struct sdhci_omap_data dra7_data = {
+	.offset = 0x200,
+};
+
+static const struct of_device_id omap_sdhci_match[] = {
+	{ .compatible = "ti,dra7-sdhci", .data = &dra7_data },
+	{},
+};
+MODULE_DEVICE_TABLE(of, omap_sdhci_match);
+
+static int sdhci_omap_probe(struct platform_device *pdev)
+{
+	int ret;
+	u32 offset;
+	struct device *dev = &pdev->dev;
+	struct sdhci_host *host;
+	struct sdhci_pltfm_host *pltfm_host;
+	struct sdhci_omap_host *omap_host;
+	struct mmc_host *mmc;
+	const struct of_device_id *match;
+	struct sdhci_omap_data *data;
+
+	match = of_match_device(omap_sdhci_match, dev);
+	if (!match)
+		return -EINVAL;
+
+	data = (struct sdhci_omap_data *)match->data;
+	if (!data) {
+		dev_err(dev, "no sdhci omap data\n");
+		return -EINVAL;
+	}
+
+	offset = data->offset;
+
+	host = sdhci_pltfm_init(pdev, &sdhci_omap_pdata,
+				sizeof(*omap_host));
+	if (IS_ERR(host)) {
+		dev_err(dev, "Failed sdhci_pltfm_init\n");
+		return PTR_ERR(host);
+	}
+
+	pltfm_host = sdhci_priv(host);
+	omap_host = sdhci_pltfm_priv(pltfm_host);
+	omap_host->host = host;
+	omap_host->base = host->ioaddr;
+	omap_host->dev = dev;
+	sdhci_omap_get_of_property(omap_host);
+
+	host->ioaddr += offset;
+
+	mmc = host->mmc;
+	ret = mmc_of_parse(mmc);
+	if (ret)
+		goto err_of_parse;
+
+	pltfm_host->clk = devm_clk_get(dev, "fck");
+	if (IS_ERR(pltfm_host->clk)) {
+		ret = PTR_ERR(pltfm_host->clk);
+		goto err_of_parse;
+	}
+
+	ret = clk_set_rate(pltfm_host->clk, mmc->f_max);
+	if (ret) {
+		dev_err(dev, "failed to set clock to %d\n", mmc->f_max);
+		goto err_of_parse;
+	}
+
+	omap_host->pbias = devm_regulator_get_optional(dev, "pbias");
+	if (IS_ERR(omap_host->pbias)) {
+		ret = PTR_ERR(omap_host->pbias);
+		if (ret != -ENODEV) {
+			dev_err(dev, "CONFIG_REGULATOR_PBIAS not enabled??\n");
+			return ret;
+		}
+		dev_dbg(dev, "unable to get pbias regulator %ld\n",
+			PTR_ERR(omap_host->pbias));
+	} else {
+		if (regulator_is_supported_voltage(omap_host->pbias, IOV_3V3,
+						   IOV_3V3))
+			omap_host->io_3_3v_support = true;
+		dev_vdbg(dev, "Max PBIAS support Voltage: %dmv\n",
+			 omap_host->io_3_3v_support ? IOV_3V3 : IOV_3V0);
+	}
+	omap_host->pbias_enabled = false;
+
+	/* Enable main Func clock, interface clock and program SYSCONFIG */
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0) {
+		dev_err(dev, "pm_runtime_get_sync failed\n");
+		goto err_get_sync;
+	}
+
+	sdhci_omap_set_capabilities(omap_host);
+
+	host->mmc_host_ops.get_ro = mmc_gpio_get_ro;
+	host->mmc_host_ops.start_signal_voltage_switch =
+					sdhci_omap_start_signal_voltage_switch;
+	host->mmc_host_ops.set_ios = sdhci_omap_set_ios;
+
+	sdhci_read_caps(host);
+	host->caps |= SDHCI_CAN_DO_ADMA2;
+
+	ret = sdhci_add_host(host);
+	if (ret)
+		goto err_get_sync;
+
+	return 0;
+
+err_get_sync:
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+
+err_of_parse:
+	sdhci_pltfm_free(pdev);
+	return ret;
+}
+
+static int sdhci_omap_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+
+	sdhci_remove_host(host, true);
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+	sdhci_pltfm_free(pdev);
+
+	return 0;
+}
+
+static struct platform_driver sdhci_omap_driver = {
+	.probe = sdhci_omap_probe,
+	.remove = sdhci_omap_remove,
+	.driver = {
+		   .name = "sdhci-omap",
+		   .of_match_table = of_match_ptr(omap_sdhci_match),
+		  },
+};
+
+module_platform_driver(sdhci_omap_driver);
+
+MODULE_DESCRIPTION("SDHCI driver for OMAP SoCs");
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("OMAP SDHCI Driver");
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH 4/5] mmc: sdhci-omap: Add OMAP SDHCI driver
@ 2017-08-21  7:41   ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel, Kishon Vijay Abraham I

Create a new sdhci-omap driver to configure the eMMC/SD/SDIO controller
in TI's OMAP SoCs making use of the SDHCI core library. For OMAP specific
configurations, populate sdhci_ops with OMAP specific callbacks and use
SDHCI quirks.
Enable only high speed mode for both SD and eMMC here and add other
UHS mode support later.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/Kconfig      |  12 +
 drivers/mmc/host/Makefile     |   1 +
 drivers/mmc/host/sdhci-omap.c | 629 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 642 insertions(+)
 create mode 100644 drivers/mmc/host/sdhci-omap.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 60f90d49e7a9..60d50843e165 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -899,3 +899,15 @@ config MMC_SDHCI_XENON
 	  This selects Marvell Xenon eMMC/SD/SDIO SDHCI.
 	  If you have a controller with this interface, say Y or M here.
 	  If unsure, say N.
+
+config MMC_SDHCI_OMAP
+	tristate "TI SDHCI Controller Support"
+	depends on MMC_SDHCI_PLTFM
+	help
+	  This selects the Secure Digital Host Controller Interface (SDHCI)
+	  support present in TI's DRA7 SOCs. The controller supports
+	  SD/MMC/SDIO devices.
+
+	  If you have a controller with this interface, say Y or M here.
+
+	  If unsure, say N.
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 8c46766c000c..33181df88a10 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_MMC_SDHCI_MSM)		+= sdhci-msm.o
 obj-$(CONFIG_MMC_SDHCI_ST)		+= sdhci-st.o
 obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32)	+= sdhci-pic32.o
 obj-$(CONFIG_MMC_SDHCI_BRCMSTB)		+= sdhci-brcmstb.o
+obj-$(CONFIG_MMC_SDHCI_OMAP)		+= sdhci-omap.o
 
 ifeq ($(CONFIG_CB710_DEBUG),y)
 	CFLAGS-cb710-mmc	+= -DDEBUG
diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c
new file mode 100644
index 000000000000..73ee3b4a400c
--- /dev/null
+++ b/drivers/mmc/host/sdhci-omap.c
@@ -0,0 +1,629 @@
+/**
+ * SDHCI Controller driver for TI's OMAP SoCs
+ *
+ * Copyright (C) 2017 Texas Instruments
+ * Author: Kishon Vijay Abraham I <kishon@ti.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 of
+ * the License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/delay.h>
+#include <linux/mmc/slot-gpio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+
+#include "sdhci-pltfm.h"
+
+#define SDHCI_OMAP_CON		0x12c
+#define CON_DW8			BIT(5)
+#define CON_DMA_MASTER		BIT(20)
+#define CON_INIT		BIT(1)
+#define CON_OD			BIT(0)
+
+#define SDHCI_OMAP_CMD		0x20c
+
+#define SDHCI_OMAP_HCTL		0x228
+#define HCTL_SDBP		BIT(8)
+#define HCTL_SDVS_SHIFT		9
+#define HCTL_SDVS_MASK		(0x7 << HCTL_SDVS_SHIFT)
+#define HCTL_SDVS_33		(0x7 << HCTL_SDVS_SHIFT)
+#define HCTL_SDVS_30		(0x6 << HCTL_SDVS_SHIFT)
+#define HCTL_SDVS_18		(0x5 << HCTL_SDVS_SHIFT)
+
+#define SDHCI_OMAP_SYSCTL	0x22c
+#define SYSCTL_CEN		BIT(2)
+#define SYSCTL_CLKD_SHIFT	6
+#define SYSCTL_CLKD_MASK	0x3ff
+
+#define SDHCI_OMAP_STAT		0x230
+
+#define SDHCI_OMAP_IE		0x234
+#define INT_CC_EN		BIT(0)
+
+#define SDHCI_OMAP_AC12		0x23c
+#define AC12_V1V8_SIGEN		BIT(19)
+
+#define SDHCI_OMAP_CAPA		0x240
+#define CAPA_VS33		BIT(24)
+#define CAPA_VS30		BIT(25)
+#define CAPA_VS18		BIT(26)
+
+#define MMC_TIMEOUT		1		/* 1 msec */
+
+#define SYSCTL_CLKD_MAX		0x3FF
+
+#define IOV_1V8			1800000		/* 180000 uV */
+#define IOV_3V0			3000000		/* 300000 uV */
+#define IOV_3V3			3300000		/* 330000 uV */
+
+struct sdhci_omap_data {
+	u32 offset;
+};
+
+struct sdhci_omap_host {
+	void __iomem		*base;
+	struct device		*dev;
+	struct	regulator	*pbias;
+	bool			pbias_enabled;
+	struct sdhci_host	*host;
+	unsigned int		flags;
+
+#define SDHCI_OMAP_SUPPORTS_DUAL_VOLT	BIT(0)
+#define SDHCI_OMAP_NO_1_8_V		BIT(1)
+
+	u8			bus_mode;
+	u8			power_mode;
+	bool			io_3_3v_support;
+};
+
+static inline u32 sdhci_omap_readl(struct sdhci_omap_host *host,
+				   unsigned int offset)
+{
+	return readl(host->base + offset);
+}
+
+static inline void sdhci_omap_writel(struct sdhci_omap_host *host,
+				     unsigned int offset, u32 data)
+{
+	writel(data, host->base + offset);
+}
+
+static int sdhci_omap_set_pbias(struct sdhci_omap_host *omap_host,
+				bool power_on, unsigned int iov)
+{
+	int ret;
+	struct device *dev = omap_host->dev;
+
+	if (IS_ERR(omap_host->pbias))
+		return 0;
+
+	if (power_on) {
+		ret = regulator_set_voltage(omap_host->pbias, iov, iov);
+		if (ret) {
+			dev_err(dev, "pbias set voltage failed\n");
+			return ret;
+		}
+
+		if (omap_host->pbias_enabled)
+			return 0;
+
+		ret = regulator_enable(omap_host->pbias);
+		if (ret) {
+			dev_err(dev, "pbias reg enable fail\n");
+			return ret;
+		}
+
+		omap_host->pbias_enabled = true;
+	} else {
+		if (!omap_host->pbias_enabled)
+			return 0;
+
+		ret = regulator_disable(omap_host->pbias);
+		if (ret) {
+			dev_err(dev, "pbias reg disable fail\n");
+			return ret;
+		}
+		omap_host->pbias_enabled = false;
+	}
+
+	return 0;
+}
+
+static int sdhci_omap_enable_iov(struct sdhci_omap_host *omap_host,
+				 unsigned int iov)
+{
+	int ret;
+	struct sdhci_host *host = omap_host->host;
+	struct mmc_host *mmc = host->mmc;
+
+	ret = sdhci_omap_set_pbias(omap_host, false, 0);
+	if (ret)
+		return ret;
+
+	if (!IS_ERR(mmc->supply.vqmmc)) {
+		ret = regulator_set_voltage(mmc->supply.vqmmc, iov, iov);
+		if (ret) {
+			dev_err(mmc_dev(mmc), "vqmmc set voltage failed\n");
+			return ret;
+		}
+	}
+
+	ret = sdhci_omap_set_pbias(omap_host, true, iov);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void sdhci_omap_conf_bus_power(struct sdhci_omap_host *omap_host,
+				      unsigned char signal_voltage)
+{
+	u32 reg;
+	ktime_t timeout;
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL);
+	reg &= ~HCTL_SDVS_MASK;
+
+	if (signal_voltage == MMC_SIGNAL_VOLTAGE_180)
+		reg |= HCTL_SDVS_18;
+	else if (omap_host->io_3_3v_support)
+		reg |= HCTL_SDVS_33;
+	else
+		reg |= HCTL_SDVS_30;
+
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
+
+	reg |= HCTL_SDBP;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
+
+	/* wait 1ms */
+	timeout = ktime_add_ms(ktime_get(), MMC_TIMEOUT);
+	while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL) & HCTL_SDBP)) {
+		if (WARN_ON(ktime_after(ktime_get(), timeout)))
+			return;
+		usleep_range(5, 10);
+	}
+}
+
+static int sdhci_omap_start_signal_voltage_switch(struct mmc_host *mmc,
+						  struct mmc_ios *ios)
+{
+	u32 reg;
+	int ret;
+	unsigned int iov;
+	struct sdhci_host *host = mmc_priv(mmc);
+	struct sdhci_pltfm_host *pltfm_host;
+	struct sdhci_omap_host *omap_host;
+	struct device *dev;
+
+	pltfm_host = sdhci_priv(host);
+	omap_host = sdhci_pltfm_priv(pltfm_host);
+	dev = omap_host->dev;
+
+	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
+		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
+		if (!(reg & (CAPA_VS33 | CAPA_VS30)))
+			return -EOPNOTSUPP;
+
+		sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
+
+		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
+		reg &= ~AC12_V1V8_SIGEN;
+		sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
+
+		if (omap_host->io_3_3v_support)
+			iov = IOV_3V3;
+		else
+			iov = IOV_3V0;
+	} else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
+		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
+		if (!(reg & CAPA_VS18))
+			return -EOPNOTSUPP;
+
+		sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
+
+		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
+		reg |= AC12_V1V8_SIGEN;
+		sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
+
+		iov = IOV_1V8;
+	} else {
+		return -EOPNOTSUPP;
+	}
+
+	ret = sdhci_omap_enable_iov(omap_host, iov);
+	if (ret) {
+		dev_err(dev, "failed to switch IO voltage to %dmV\n", iov);
+		return ret;
+	}
+
+	dev_dbg(dev, "IO voltage switched to %dmV\n", iov);
+	return 0;
+}
+
+static void sdhci_omap_set_bus_mode(struct sdhci_omap_host *omap_host,
+				    unsigned int mode)
+{
+	u32 reg;
+
+	if (omap_host->bus_mode == mode)
+		return;
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
+	if (mode == MMC_BUSMODE_OPENDRAIN)
+		reg |= CON_OD;
+	else
+		reg &= ~CON_OD;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
+
+	omap_host->bus_mode = mode;
+}
+
+void sdhci_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	struct sdhci_pltfm_host *pltfm_host;
+	struct sdhci_omap_host *omap_host;
+
+	pltfm_host = sdhci_priv(host);
+	omap_host = sdhci_pltfm_priv(pltfm_host);
+
+	sdhci_omap_set_bus_mode(omap_host, ios->bus_mode);
+	sdhci_set_ios(mmc, ios);
+}
+
+static void sdhci_omap_set_capabilities(struct sdhci_omap_host *omap_host)
+{
+	u32 reg;
+
+	/* voltage capabilities might be set by boot loader, clear it */
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
+	reg &= ~(CAPA_VS18 | CAPA_VS30 | CAPA_VS33);
+
+	if (omap_host->flags & SDHCI_OMAP_SUPPORTS_DUAL_VOLT) {
+		if (omap_host->io_3_3v_support)
+			reg |= (CAPA_VS33 | CAPA_VS18);
+		else
+			reg |= (CAPA_VS30 | CAPA_VS18);
+	} else if (omap_host->flags & SDHCI_OMAP_NO_1_8_V) {
+		if (omap_host->io_3_3v_support)
+			reg |= CAPA_VS33;
+		else
+			reg |= CAPA_VS30;
+	} else {
+		reg |= CAPA_VS18;
+	}
+
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CAPA, reg);
+}
+
+static u16 sdhci_omap_calc_divisor(struct sdhci_pltfm_host *host,
+				   unsigned int clock)
+{
+	u16 dsor;
+
+	dsor = DIV_ROUND_UP(clk_get_rate(host->clk), clock);
+	if (dsor > SYSCTL_CLKD_MAX)
+		dsor = SYSCTL_CLKD_MAX;
+
+	return dsor;
+}
+
+static void sdhci_omap_start_clock(struct sdhci_omap_host *omap_host)
+{
+	u32 reg;
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
+	reg |= SYSCTL_CEN;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
+}
+
+static void sdhci_omap_stop_clock(struct sdhci_omap_host *omap_host)
+{
+	u32 reg;
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
+	reg &= ~SYSCTL_CEN;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
+}
+
+static void sdhci_omap_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
+	unsigned long clkdiv;
+
+	if (!clock)
+		return;
+
+	sdhci_omap_stop_clock(omap_host);
+
+	clkdiv = sdhci_omap_calc_divisor(pltfm_host, clock);
+	clkdiv = (clkdiv & SYSCTL_CLKD_MASK) << SYSCTL_CLKD_SHIFT;
+	sdhci_enable_clk(host, clkdiv);
+
+	sdhci_omap_start_clock(omap_host);
+}
+
+void sdhci_omap_set_power(struct sdhci_host *host, unsigned char mode,
+			  unsigned short vdd)
+{
+	struct mmc_host *mmc = host->mmc;
+
+	mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+}
+
+static int sdhci_omap_enable_dma(struct sdhci_host *host)
+{
+	u32 reg;
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
+	reg |= CON_DMA_MASTER;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
+
+	return 0;
+}
+
+unsigned int sdhci_omap_get_min_clock(struct sdhci_host *host)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+	return clk_get_rate(pltfm_host->clk) / SYSCTL_CLKD_MAX;
+}
+
+static void sdhci_omap_set_bus_width(struct sdhci_host *host, int width)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
+	u32 reg;
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
+	if (width == MMC_BUS_WIDTH_8)
+		reg |= CON_DW8;
+	else
+		reg &= ~CON_DW8;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
+
+	sdhci_set_bus_width(host, width);
+}
+
+static void sdhci_omap_init_74_clocks(struct sdhci_host *host, u8 power_mode)
+{
+	u32 reg;
+	ktime_t timeout;
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
+
+	if (omap_host->power_mode == power_mode)
+		return;
+
+	if (power_mode != MMC_POWER_ON)
+		return;
+
+	disable_irq(host->irq);
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
+	reg |= CON_INIT;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CMD, 0x0);
+
+	/* wait 1ms */
+	timeout = ktime_add_ms(ktime_get(), MMC_TIMEOUT);
+	while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_STAT) & INT_CC_EN)) {
+		if (WARN_ON(ktime_after(ktime_get(), timeout)))
+			return;
+		usleep_range(5, 10);
+	}
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
+	reg &= ~CON_INIT;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_STAT, INT_CC_EN);
+
+	enable_irq(host->irq);
+
+	omap_host->power_mode = power_mode;
+}
+
+static struct sdhci_ops sdhci_omap_ops = {
+	.set_clock = sdhci_omap_set_clock,
+	.set_power = sdhci_omap_set_power,
+	.enable_dma = sdhci_omap_enable_dma,
+	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
+	.get_min_clock = sdhci_omap_get_min_clock,
+	.set_bus_width = sdhci_omap_set_bus_width,
+	.platform_send_init_74_clocks = sdhci_omap_init_74_clocks,
+	.reset = sdhci_reset,
+	.set_uhs_signaling = sdhci_set_uhs_signaling,
+};
+
+void sdhci_omap_get_of_property(struct sdhci_omap_host *omap_host)
+{
+	struct device *dev = omap_host->dev;
+	struct sdhci_host *host = omap_host->host;
+	struct mmc_host *mmc = host->mmc;
+
+	if (device_property_read_bool(dev, "ti,dual-volt"))
+		omap_host->flags |= SDHCI_OMAP_SUPPORTS_DUAL_VOLT;
+
+	if (device_property_read_bool(dev, "no-1-8-v"))
+		omap_host->flags |= SDHCI_OMAP_NO_1_8_V;
+
+	if (device_property_read_bool(dev, "ti,non-removable"))
+		mmc->caps |= MMC_CAP_NONREMOVABLE;
+}
+
+static const struct sdhci_pltfm_data sdhci_omap_pdata = {
+	.quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
+		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
+		  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
+		  SDHCI_QUIRK_NO_HISPD_BIT |
+		  SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC,
+	.quirks2 = SDHCI_QUIRK2_NO_1_8_V |
+		   SDHCI_QUIRK2_ACMD23_BROKEN |
+		   SDHCI_QUIRK2_RSP_136_HAS_CRC,
+	.ops = &sdhci_omap_ops,
+};
+
+static const struct sdhci_omap_data dra7_data = {
+	.offset = 0x200,
+};
+
+static const struct of_device_id omap_sdhci_match[] = {
+	{ .compatible = "ti,dra7-sdhci", .data = &dra7_data },
+	{},
+};
+MODULE_DEVICE_TABLE(of, omap_sdhci_match);
+
+static int sdhci_omap_probe(struct platform_device *pdev)
+{
+	int ret;
+	u32 offset;
+	struct device *dev = &pdev->dev;
+	struct sdhci_host *host;
+	struct sdhci_pltfm_host *pltfm_host;
+	struct sdhci_omap_host *omap_host;
+	struct mmc_host *mmc;
+	const struct of_device_id *match;
+	struct sdhci_omap_data *data;
+
+	match = of_match_device(omap_sdhci_match, dev);
+	if (!match)
+		return -EINVAL;
+
+	data = (struct sdhci_omap_data *)match->data;
+	if (!data) {
+		dev_err(dev, "no sdhci omap data\n");
+		return -EINVAL;
+	}
+
+	offset = data->offset;
+
+	host = sdhci_pltfm_init(pdev, &sdhci_omap_pdata,
+				sizeof(*omap_host));
+	if (IS_ERR(host)) {
+		dev_err(dev, "Failed sdhci_pltfm_init\n");
+		return PTR_ERR(host);
+	}
+
+	pltfm_host = sdhci_priv(host);
+	omap_host = sdhci_pltfm_priv(pltfm_host);
+	omap_host->host = host;
+	omap_host->base = host->ioaddr;
+	omap_host->dev = dev;
+	sdhci_omap_get_of_property(omap_host);
+
+	host->ioaddr += offset;
+
+	mmc = host->mmc;
+	ret = mmc_of_parse(mmc);
+	if (ret)
+		goto err_of_parse;
+
+	pltfm_host->clk = devm_clk_get(dev, "fck");
+	if (IS_ERR(pltfm_host->clk)) {
+		ret = PTR_ERR(pltfm_host->clk);
+		goto err_of_parse;
+	}
+
+	ret = clk_set_rate(pltfm_host->clk, mmc->f_max);
+	if (ret) {
+		dev_err(dev, "failed to set clock to %d\n", mmc->f_max);
+		goto err_of_parse;
+	}
+
+	omap_host->pbias = devm_regulator_get_optional(dev, "pbias");
+	if (IS_ERR(omap_host->pbias)) {
+		ret = PTR_ERR(omap_host->pbias);
+		if (ret != -ENODEV) {
+			dev_err(dev, "CONFIG_REGULATOR_PBIAS not enabled??\n");
+			return ret;
+		}
+		dev_dbg(dev, "unable to get pbias regulator %ld\n",
+			PTR_ERR(omap_host->pbias));
+	} else {
+		if (regulator_is_supported_voltage(omap_host->pbias, IOV_3V3,
+						   IOV_3V3))
+			omap_host->io_3_3v_support = true;
+		dev_vdbg(dev, "Max PBIAS support Voltage: %dmv\n",
+			 omap_host->io_3_3v_support ? IOV_3V3 : IOV_3V0);
+	}
+	omap_host->pbias_enabled = false;
+
+	/* Enable main Func clock, interface clock and program SYSCONFIG */
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0) {
+		dev_err(dev, "pm_runtime_get_sync failed\n");
+		goto err_get_sync;
+	}
+
+	sdhci_omap_set_capabilities(omap_host);
+
+	host->mmc_host_ops.get_ro = mmc_gpio_get_ro;
+	host->mmc_host_ops.start_signal_voltage_switch =
+					sdhci_omap_start_signal_voltage_switch;
+	host->mmc_host_ops.set_ios = sdhci_omap_set_ios;
+
+	sdhci_read_caps(host);
+	host->caps |= SDHCI_CAN_DO_ADMA2;
+
+	ret = sdhci_add_host(host);
+	if (ret)
+		goto err_get_sync;
+
+	return 0;
+
+err_get_sync:
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+
+err_of_parse:
+	sdhci_pltfm_free(pdev);
+	return ret;
+}
+
+static int sdhci_omap_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+
+	sdhci_remove_host(host, true);
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+	sdhci_pltfm_free(pdev);
+
+	return 0;
+}
+
+static struct platform_driver sdhci_omap_driver = {
+	.probe = sdhci_omap_probe,
+	.remove = sdhci_omap_remove,
+	.driver = {
+		   .name = "sdhci-omap",
+		   .of_match_table = of_match_ptr(omap_sdhci_match),
+		  },
+};
+
+module_platform_driver(sdhci_omap_driver);
+
+MODULE_DESCRIPTION("SDHCI driver for OMAP SoCs");
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("OMAP SDHCI Driver");
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH 4/5] mmc: sdhci-omap: Add OMAP SDHCI driver
@ 2017-08-21  7:41   ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: linux-arm-kernel

Create a new sdhci-omap driver to configure the eMMC/SD/SDIO controller
in TI's OMAP SoCs making use of the SDHCI core library. For OMAP specific
configurations, populate sdhci_ops with OMAP specific callbacks and use
SDHCI quirks.
Enable only high speed mode for both SD and eMMC here and add other
UHS mode support later.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 drivers/mmc/host/Kconfig      |  12 +
 drivers/mmc/host/Makefile     |   1 +
 drivers/mmc/host/sdhci-omap.c | 629 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 642 insertions(+)
 create mode 100644 drivers/mmc/host/sdhci-omap.c

diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 60f90d49e7a9..60d50843e165 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -899,3 +899,15 @@ config MMC_SDHCI_XENON
 	  This selects Marvell Xenon eMMC/SD/SDIO SDHCI.
 	  If you have a controller with this interface, say Y or M here.
 	  If unsure, say N.
+
+config MMC_SDHCI_OMAP
+	tristate "TI SDHCI Controller Support"
+	depends on MMC_SDHCI_PLTFM
+	help
+	  This selects the Secure Digital Host Controller Interface (SDHCI)
+	  support present in TI's DRA7 SOCs. The controller supports
+	  SD/MMC/SDIO devices.
+
+	  If you have a controller with this interface, say Y or M here.
+
+	  If unsure, say N.
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 8c46766c000c..33181df88a10 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -88,6 +88,7 @@ obj-$(CONFIG_MMC_SDHCI_MSM)		+= sdhci-msm.o
 obj-$(CONFIG_MMC_SDHCI_ST)		+= sdhci-st.o
 obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32)	+= sdhci-pic32.o
 obj-$(CONFIG_MMC_SDHCI_BRCMSTB)		+= sdhci-brcmstb.o
+obj-$(CONFIG_MMC_SDHCI_OMAP)		+= sdhci-omap.o
 
 ifeq ($(CONFIG_CB710_DEBUG),y)
 	CFLAGS-cb710-mmc	+= -DDEBUG
diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c
new file mode 100644
index 000000000000..73ee3b4a400c
--- /dev/null
+++ b/drivers/mmc/host/sdhci-omap.c
@@ -0,0 +1,629 @@
+/**
+ * SDHCI Controller driver for TI's OMAP SoCs
+ *
+ * Copyright (C) 2017 Texas Instruments
+ * Author: Kishon Vijay Abraham I <kishon@ti.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 of
+ * the License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/delay.h>
+#include <linux/mmc/slot-gpio.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+
+#include "sdhci-pltfm.h"
+
+#define SDHCI_OMAP_CON		0x12c
+#define CON_DW8			BIT(5)
+#define CON_DMA_MASTER		BIT(20)
+#define CON_INIT		BIT(1)
+#define CON_OD			BIT(0)
+
+#define SDHCI_OMAP_CMD		0x20c
+
+#define SDHCI_OMAP_HCTL		0x228
+#define HCTL_SDBP		BIT(8)
+#define HCTL_SDVS_SHIFT		9
+#define HCTL_SDVS_MASK		(0x7 << HCTL_SDVS_SHIFT)
+#define HCTL_SDVS_33		(0x7 << HCTL_SDVS_SHIFT)
+#define HCTL_SDVS_30		(0x6 << HCTL_SDVS_SHIFT)
+#define HCTL_SDVS_18		(0x5 << HCTL_SDVS_SHIFT)
+
+#define SDHCI_OMAP_SYSCTL	0x22c
+#define SYSCTL_CEN		BIT(2)
+#define SYSCTL_CLKD_SHIFT	6
+#define SYSCTL_CLKD_MASK	0x3ff
+
+#define SDHCI_OMAP_STAT		0x230
+
+#define SDHCI_OMAP_IE		0x234
+#define INT_CC_EN		BIT(0)
+
+#define SDHCI_OMAP_AC12		0x23c
+#define AC12_V1V8_SIGEN		BIT(19)
+
+#define SDHCI_OMAP_CAPA		0x240
+#define CAPA_VS33		BIT(24)
+#define CAPA_VS30		BIT(25)
+#define CAPA_VS18		BIT(26)
+
+#define MMC_TIMEOUT		1		/* 1 msec */
+
+#define SYSCTL_CLKD_MAX		0x3FF
+
+#define IOV_1V8			1800000		/* 180000 uV */
+#define IOV_3V0			3000000		/* 300000 uV */
+#define IOV_3V3			3300000		/* 330000 uV */
+
+struct sdhci_omap_data {
+	u32 offset;
+};
+
+struct sdhci_omap_host {
+	void __iomem		*base;
+	struct device		*dev;
+	struct	regulator	*pbias;
+	bool			pbias_enabled;
+	struct sdhci_host	*host;
+	unsigned int		flags;
+
+#define SDHCI_OMAP_SUPPORTS_DUAL_VOLT	BIT(0)
+#define SDHCI_OMAP_NO_1_8_V		BIT(1)
+
+	u8			bus_mode;
+	u8			power_mode;
+	bool			io_3_3v_support;
+};
+
+static inline u32 sdhci_omap_readl(struct sdhci_omap_host *host,
+				   unsigned int offset)
+{
+	return readl(host->base + offset);
+}
+
+static inline void sdhci_omap_writel(struct sdhci_omap_host *host,
+				     unsigned int offset, u32 data)
+{
+	writel(data, host->base + offset);
+}
+
+static int sdhci_omap_set_pbias(struct sdhci_omap_host *omap_host,
+				bool power_on, unsigned int iov)
+{
+	int ret;
+	struct device *dev = omap_host->dev;
+
+	if (IS_ERR(omap_host->pbias))
+		return 0;
+
+	if (power_on) {
+		ret = regulator_set_voltage(omap_host->pbias, iov, iov);
+		if (ret) {
+			dev_err(dev, "pbias set voltage failed\n");
+			return ret;
+		}
+
+		if (omap_host->pbias_enabled)
+			return 0;
+
+		ret = regulator_enable(omap_host->pbias);
+		if (ret) {
+			dev_err(dev, "pbias reg enable fail\n");
+			return ret;
+		}
+
+		omap_host->pbias_enabled = true;
+	} else {
+		if (!omap_host->pbias_enabled)
+			return 0;
+
+		ret = regulator_disable(omap_host->pbias);
+		if (ret) {
+			dev_err(dev, "pbias reg disable fail\n");
+			return ret;
+		}
+		omap_host->pbias_enabled = false;
+	}
+
+	return 0;
+}
+
+static int sdhci_omap_enable_iov(struct sdhci_omap_host *omap_host,
+				 unsigned int iov)
+{
+	int ret;
+	struct sdhci_host *host = omap_host->host;
+	struct mmc_host *mmc = host->mmc;
+
+	ret = sdhci_omap_set_pbias(omap_host, false, 0);
+	if (ret)
+		return ret;
+
+	if (!IS_ERR(mmc->supply.vqmmc)) {
+		ret = regulator_set_voltage(mmc->supply.vqmmc, iov, iov);
+		if (ret) {
+			dev_err(mmc_dev(mmc), "vqmmc set voltage failed\n");
+			return ret;
+		}
+	}
+
+	ret = sdhci_omap_set_pbias(omap_host, true, iov);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+
+static void sdhci_omap_conf_bus_power(struct sdhci_omap_host *omap_host,
+				      unsigned char signal_voltage)
+{
+	u32 reg;
+	ktime_t timeout;
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL);
+	reg &= ~HCTL_SDVS_MASK;
+
+	if (signal_voltage == MMC_SIGNAL_VOLTAGE_180)
+		reg |= HCTL_SDVS_18;
+	else if (omap_host->io_3_3v_support)
+		reg |= HCTL_SDVS_33;
+	else
+		reg |= HCTL_SDVS_30;
+
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
+
+	reg |= HCTL_SDBP;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
+
+	/* wait 1ms */
+	timeout = ktime_add_ms(ktime_get(), MMC_TIMEOUT);
+	while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL) & HCTL_SDBP)) {
+		if (WARN_ON(ktime_after(ktime_get(), timeout)))
+			return;
+		usleep_range(5, 10);
+	}
+}
+
+static int sdhci_omap_start_signal_voltage_switch(struct mmc_host *mmc,
+						  struct mmc_ios *ios)
+{
+	u32 reg;
+	int ret;
+	unsigned int iov;
+	struct sdhci_host *host = mmc_priv(mmc);
+	struct sdhci_pltfm_host *pltfm_host;
+	struct sdhci_omap_host *omap_host;
+	struct device *dev;
+
+	pltfm_host = sdhci_priv(host);
+	omap_host = sdhci_pltfm_priv(pltfm_host);
+	dev = omap_host->dev;
+
+	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
+		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
+		if (!(reg & (CAPA_VS33 | CAPA_VS30)))
+			return -EOPNOTSUPP;
+
+		sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
+
+		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
+		reg &= ~AC12_V1V8_SIGEN;
+		sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
+
+		if (omap_host->io_3_3v_support)
+			iov = IOV_3V3;
+		else
+			iov = IOV_3V0;
+	} else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
+		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
+		if (!(reg & CAPA_VS18))
+			return -EOPNOTSUPP;
+
+		sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
+
+		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
+		reg |= AC12_V1V8_SIGEN;
+		sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
+
+		iov = IOV_1V8;
+	} else {
+		return -EOPNOTSUPP;
+	}
+
+	ret = sdhci_omap_enable_iov(omap_host, iov);
+	if (ret) {
+		dev_err(dev, "failed to switch IO voltage to %dmV\n", iov);
+		return ret;
+	}
+
+	dev_dbg(dev, "IO voltage switched to %dmV\n", iov);
+	return 0;
+}
+
+static void sdhci_omap_set_bus_mode(struct sdhci_omap_host *omap_host,
+				    unsigned int mode)
+{
+	u32 reg;
+
+	if (omap_host->bus_mode == mode)
+		return;
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
+	if (mode == MMC_BUSMODE_OPENDRAIN)
+		reg |= CON_OD;
+	else
+		reg &= ~CON_OD;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
+
+	omap_host->bus_mode = mode;
+}
+
+void sdhci_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+	struct sdhci_host *host = mmc_priv(mmc);
+	struct sdhci_pltfm_host *pltfm_host;
+	struct sdhci_omap_host *omap_host;
+
+	pltfm_host = sdhci_priv(host);
+	omap_host = sdhci_pltfm_priv(pltfm_host);
+
+	sdhci_omap_set_bus_mode(omap_host, ios->bus_mode);
+	sdhci_set_ios(mmc, ios);
+}
+
+static void sdhci_omap_set_capabilities(struct sdhci_omap_host *omap_host)
+{
+	u32 reg;
+
+	/* voltage capabilities might be set by boot loader, clear it */
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
+	reg &= ~(CAPA_VS18 | CAPA_VS30 | CAPA_VS33);
+
+	if (omap_host->flags & SDHCI_OMAP_SUPPORTS_DUAL_VOLT) {
+		if (omap_host->io_3_3v_support)
+			reg |= (CAPA_VS33 | CAPA_VS18);
+		else
+			reg |= (CAPA_VS30 | CAPA_VS18);
+	} else if (omap_host->flags & SDHCI_OMAP_NO_1_8_V) {
+		if (omap_host->io_3_3v_support)
+			reg |= CAPA_VS33;
+		else
+			reg |= CAPA_VS30;
+	} else {
+		reg |= CAPA_VS18;
+	}
+
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CAPA, reg);
+}
+
+static u16 sdhci_omap_calc_divisor(struct sdhci_pltfm_host *host,
+				   unsigned int clock)
+{
+	u16 dsor;
+
+	dsor = DIV_ROUND_UP(clk_get_rate(host->clk), clock);
+	if (dsor > SYSCTL_CLKD_MAX)
+		dsor = SYSCTL_CLKD_MAX;
+
+	return dsor;
+}
+
+static void sdhci_omap_start_clock(struct sdhci_omap_host *omap_host)
+{
+	u32 reg;
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
+	reg |= SYSCTL_CEN;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
+}
+
+static void sdhci_omap_stop_clock(struct sdhci_omap_host *omap_host)
+{
+	u32 reg;
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
+	reg &= ~SYSCTL_CEN;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
+}
+
+static void sdhci_omap_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
+	unsigned long clkdiv;
+
+	if (!clock)
+		return;
+
+	sdhci_omap_stop_clock(omap_host);
+
+	clkdiv = sdhci_omap_calc_divisor(pltfm_host, clock);
+	clkdiv = (clkdiv & SYSCTL_CLKD_MASK) << SYSCTL_CLKD_SHIFT;
+	sdhci_enable_clk(host, clkdiv);
+
+	sdhci_omap_start_clock(omap_host);
+}
+
+void sdhci_omap_set_power(struct sdhci_host *host, unsigned char mode,
+			  unsigned short vdd)
+{
+	struct mmc_host *mmc = host->mmc;
+
+	mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
+}
+
+static int sdhci_omap_enable_dma(struct sdhci_host *host)
+{
+	u32 reg;
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
+	reg |= CON_DMA_MASTER;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
+
+	return 0;
+}
+
+unsigned int sdhci_omap_get_min_clock(struct sdhci_host *host)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+	return clk_get_rate(pltfm_host->clk) / SYSCTL_CLKD_MAX;
+}
+
+static void sdhci_omap_set_bus_width(struct sdhci_host *host, int width)
+{
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
+	u32 reg;
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
+	if (width == MMC_BUS_WIDTH_8)
+		reg |= CON_DW8;
+	else
+		reg &= ~CON_DW8;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
+
+	sdhci_set_bus_width(host, width);
+}
+
+static void sdhci_omap_init_74_clocks(struct sdhci_host *host, u8 power_mode)
+{
+	u32 reg;
+	ktime_t timeout;
+	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
+
+	if (omap_host->power_mode == power_mode)
+		return;
+
+	if (power_mode != MMC_POWER_ON)
+		return;
+
+	disable_irq(host->irq);
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
+	reg |= CON_INIT;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CMD, 0x0);
+
+	/* wait 1ms */
+	timeout = ktime_add_ms(ktime_get(), MMC_TIMEOUT);
+	while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_STAT) & INT_CC_EN)) {
+		if (WARN_ON(ktime_after(ktime_get(), timeout)))
+			return;
+		usleep_range(5, 10);
+	}
+
+	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
+	reg &= ~CON_INIT;
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
+	sdhci_omap_writel(omap_host, SDHCI_OMAP_STAT, INT_CC_EN);
+
+	enable_irq(host->irq);
+
+	omap_host->power_mode = power_mode;
+}
+
+static struct sdhci_ops sdhci_omap_ops = {
+	.set_clock = sdhci_omap_set_clock,
+	.set_power = sdhci_omap_set_power,
+	.enable_dma = sdhci_omap_enable_dma,
+	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
+	.get_min_clock = sdhci_omap_get_min_clock,
+	.set_bus_width = sdhci_omap_set_bus_width,
+	.platform_send_init_74_clocks = sdhci_omap_init_74_clocks,
+	.reset = sdhci_reset,
+	.set_uhs_signaling = sdhci_set_uhs_signaling,
+};
+
+void sdhci_omap_get_of_property(struct sdhci_omap_host *omap_host)
+{
+	struct device *dev = omap_host->dev;
+	struct sdhci_host *host = omap_host->host;
+	struct mmc_host *mmc = host->mmc;
+
+	if (device_property_read_bool(dev, "ti,dual-volt"))
+		omap_host->flags |= SDHCI_OMAP_SUPPORTS_DUAL_VOLT;
+
+	if (device_property_read_bool(dev, "no-1-8-v"))
+		omap_host->flags |= SDHCI_OMAP_NO_1_8_V;
+
+	if (device_property_read_bool(dev, "ti,non-removable"))
+		mmc->caps |= MMC_CAP_NONREMOVABLE;
+}
+
+static const struct sdhci_pltfm_data sdhci_omap_pdata = {
+	.quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
+		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
+		  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
+		  SDHCI_QUIRK_NO_HISPD_BIT |
+		  SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC,
+	.quirks2 = SDHCI_QUIRK2_NO_1_8_V |
+		   SDHCI_QUIRK2_ACMD23_BROKEN |
+		   SDHCI_QUIRK2_RSP_136_HAS_CRC,
+	.ops = &sdhci_omap_ops,
+};
+
+static const struct sdhci_omap_data dra7_data = {
+	.offset = 0x200,
+};
+
+static const struct of_device_id omap_sdhci_match[] = {
+	{ .compatible = "ti,dra7-sdhci", .data = &dra7_data },
+	{},
+};
+MODULE_DEVICE_TABLE(of, omap_sdhci_match);
+
+static int sdhci_omap_probe(struct platform_device *pdev)
+{
+	int ret;
+	u32 offset;
+	struct device *dev = &pdev->dev;
+	struct sdhci_host *host;
+	struct sdhci_pltfm_host *pltfm_host;
+	struct sdhci_omap_host *omap_host;
+	struct mmc_host *mmc;
+	const struct of_device_id *match;
+	struct sdhci_omap_data *data;
+
+	match = of_match_device(omap_sdhci_match, dev);
+	if (!match)
+		return -EINVAL;
+
+	data = (struct sdhci_omap_data *)match->data;
+	if (!data) {
+		dev_err(dev, "no sdhci omap data\n");
+		return -EINVAL;
+	}
+
+	offset = data->offset;
+
+	host = sdhci_pltfm_init(pdev, &sdhci_omap_pdata,
+				sizeof(*omap_host));
+	if (IS_ERR(host)) {
+		dev_err(dev, "Failed sdhci_pltfm_init\n");
+		return PTR_ERR(host);
+	}
+
+	pltfm_host = sdhci_priv(host);
+	omap_host = sdhci_pltfm_priv(pltfm_host);
+	omap_host->host = host;
+	omap_host->base = host->ioaddr;
+	omap_host->dev = dev;
+	sdhci_omap_get_of_property(omap_host);
+
+	host->ioaddr += offset;
+
+	mmc = host->mmc;
+	ret = mmc_of_parse(mmc);
+	if (ret)
+		goto err_of_parse;
+
+	pltfm_host->clk = devm_clk_get(dev, "fck");
+	if (IS_ERR(pltfm_host->clk)) {
+		ret = PTR_ERR(pltfm_host->clk);
+		goto err_of_parse;
+	}
+
+	ret = clk_set_rate(pltfm_host->clk, mmc->f_max);
+	if (ret) {
+		dev_err(dev, "failed to set clock to %d\n", mmc->f_max);
+		goto err_of_parse;
+	}
+
+	omap_host->pbias = devm_regulator_get_optional(dev, "pbias");
+	if (IS_ERR(omap_host->pbias)) {
+		ret = PTR_ERR(omap_host->pbias);
+		if (ret != -ENODEV) {
+			dev_err(dev, "CONFIG_REGULATOR_PBIAS not enabled??\n");
+			return ret;
+		}
+		dev_dbg(dev, "unable to get pbias regulator %ld\n",
+			PTR_ERR(omap_host->pbias));
+	} else {
+		if (regulator_is_supported_voltage(omap_host->pbias, IOV_3V3,
+						   IOV_3V3))
+			omap_host->io_3_3v_support = true;
+		dev_vdbg(dev, "Max PBIAS support Voltage: %dmv\n",
+			 omap_host->io_3_3v_support ? IOV_3V3 : IOV_3V0);
+	}
+	omap_host->pbias_enabled = false;
+
+	/* Enable main Func clock, interface clock and program SYSCONFIG */
+	pm_runtime_enable(dev);
+	ret = pm_runtime_get_sync(dev);
+	if (ret < 0) {
+		dev_err(dev, "pm_runtime_get_sync failed\n");
+		goto err_get_sync;
+	}
+
+	sdhci_omap_set_capabilities(omap_host);
+
+	host->mmc_host_ops.get_ro = mmc_gpio_get_ro;
+	host->mmc_host_ops.start_signal_voltage_switch =
+					sdhci_omap_start_signal_voltage_switch;
+	host->mmc_host_ops.set_ios = sdhci_omap_set_ios;
+
+	sdhci_read_caps(host);
+	host->caps |= SDHCI_CAN_DO_ADMA2;
+
+	ret = sdhci_add_host(host);
+	if (ret)
+		goto err_get_sync;
+
+	return 0;
+
+err_get_sync:
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+
+err_of_parse:
+	sdhci_pltfm_free(pdev);
+	return ret;
+}
+
+static int sdhci_omap_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct sdhci_host *host = platform_get_drvdata(pdev);
+
+	sdhci_remove_host(host, true);
+	pm_runtime_put_sync(dev);
+	pm_runtime_disable(dev);
+	sdhci_pltfm_free(pdev);
+
+	return 0;
+}
+
+static struct platform_driver sdhci_omap_driver = {
+	.probe = sdhci_omap_probe,
+	.remove = sdhci_omap_remove,
+	.driver = {
+		   .name = "sdhci-omap",
+		   .of_match_table = of_match_ptr(omap_sdhci_match),
+		  },
+};
+
+module_platform_driver(sdhci_omap_driver);
+
+MODULE_DESCRIPTION("SDHCI driver for OMAP SoCs");
+MODULE_AUTHOR("Texas Instruments Inc.");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("OMAP SDHCI Driver");
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH 5/5] MAINTAINERS: Add TI OMAP SDHCI Maintainer
  2017-08-21  7:41 ` Kishon Vijay Abraham I
  (?)
@ 2017-08-21  7:41   ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel, Kishon Vijay Abraham I

Add Maintainer for the TI OMAP SDHCI driver.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 44cb004c765d..c9871351c16f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11777,6 +11777,12 @@ L:	linux-mmc@vger.kernel.org
 S:	Maintained
 F:	drivers/mmc/host/sdhci-spear.c
 
+SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) TI OMAP DRIVER
+M:	Kishon Vijay Abraham I <kishon@ti.com>
+L:	linux-mmc@vger.kernel.org
+S:	Maintained
+F:	drivers/mmc/host/sdhci-omap.c
+
 SECURE ENCRYPTING DEVICE (SED) OPAL DRIVER
 M:	Scott Bauer <scott.bauer@intel.com>
 M:	Jonathan Derrick <jonathan.derrick@intel.com>
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH 5/5] MAINTAINERS: Add TI OMAP SDHCI Maintainer
@ 2017-08-21  7:41   ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel, Kishon Vijay Abraham I

Add Maintainer for the TI OMAP SDHCI driver.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 44cb004c765d..c9871351c16f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11777,6 +11777,12 @@ L:	linux-mmc@vger.kernel.org
 S:	Maintained
 F:	drivers/mmc/host/sdhci-spear.c
 
+SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) TI OMAP DRIVER
+M:	Kishon Vijay Abraham I <kishon@ti.com>
+L:	linux-mmc@vger.kernel.org
+S:	Maintained
+F:	drivers/mmc/host/sdhci-omap.c
+
 SECURE ENCRYPTING DEVICE (SED) OPAL DRIVER
 M:	Scott Bauer <scott.bauer@intel.com>
 M:	Jonathan Derrick <jonathan.derrick@intel.com>
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH 5/5] MAINTAINERS: Add TI OMAP SDHCI Maintainer
@ 2017-08-21  7:41   ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-21  7:41 UTC (permalink / raw)
  To: linux-arm-kernel

Add Maintainer for the TI OMAP SDHCI driver.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 44cb004c765d..c9871351c16f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11777,6 +11777,12 @@ L:	linux-mmc at vger.kernel.org
 S:	Maintained
 F:	drivers/mmc/host/sdhci-spear.c
 
+SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) TI OMAP DRIVER
+M:	Kishon Vijay Abraham I <kishon@ti.com>
+L:	linux-mmc at vger.kernel.org
+S:	Maintained
+F:	drivers/mmc/host/sdhci-omap.c
+
 SECURE ENCRYPTING DEVICE (SED) OPAL DRIVER
 M:	Scott Bauer <scott.bauer@intel.com>
 M:	Jonathan Derrick <jonathan.derrick@intel.com>
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* Re: [PATCH 3/5] dt-bindings: ti-omap-hsmmc: Document new compatible for sdhci omap
  2017-08-21  7:41   ` Kishon Vijay Abraham I
@ 2017-08-21 14:21     ` Tony Lindgren
  -1 siblings, 0 replies; 86+ messages in thread
From: Tony Lindgren @ 2017-08-21 14:21 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Ulf Hansson, Adrian Hunter, Rob Herring, Sekhar Nori,
	Russell King, Ravikumar Kattekola, linux-mmc, devicetree,
	linux-kernel, linux-omap, linux-arm-kernel

* Kishon Vijay Abraham I <kishon@ti.com> [170821 00:42]:
> Document the new compatible string "ti,dra7-sdhci" to be used for
> MMC controllers in DRA7 and DRA72 SoCs.

I suggest that you add a new one sdhci-omap.txt instead.
We are not currently parsing the all the hsmmc properties for
sdhci.

Then eventually when they are fully compatible, we can just
change ti-omap-hsmmc.txt to point to the sdhci-omap.txt.

Regards,

Tony

> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
>  Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
> index 0e026c151c1c..db80fdfd05d7 100644
> --- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
> +++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
> @@ -13,6 +13,7 @@ Required properties:
>   Should be "ti,omap3-pre-es3-hsmmc" for OMAP3 controllers pre ES3.0
>   Should be "ti,omap4-hsmmc", for OMAP4 controllers
>   Should be "ti,am33xx-hsmmc", for AM335x controllers
> + Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
>  - ti,hwmods: Must be "mmc<n>", n is controller instance starting 1
>  
>  Optional properties:
> -- 
> 2.11.0
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH 3/5] dt-bindings: ti-omap-hsmmc: Document new compatible for sdhci omap
@ 2017-08-21 14:21     ` Tony Lindgren
  0 siblings, 0 replies; 86+ messages in thread
From: Tony Lindgren @ 2017-08-21 14:21 UTC (permalink / raw)
  To: linux-arm-kernel

* Kishon Vijay Abraham I <kishon@ti.com> [170821 00:42]:
> Document the new compatible string "ti,dra7-sdhci" to be used for
> MMC controllers in DRA7 and DRA72 SoCs.

I suggest that you add a new one sdhci-omap.txt instead.
We are not currently parsing the all the hsmmc properties for
sdhci.

Then eventually when they are fully compatible, we can just
change ti-omap-hsmmc.txt to point to the sdhci-omap.txt.

Regards,

Tony

> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
>  Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
> index 0e026c151c1c..db80fdfd05d7 100644
> --- a/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
> +++ b/Documentation/devicetree/bindings/mmc/ti-omap-hsmmc.txt
> @@ -13,6 +13,7 @@ Required properties:
>   Should be "ti,omap3-pre-es3-hsmmc" for OMAP3 controllers pre ES3.0
>   Should be "ti,omap4-hsmmc", for OMAP4 controllers
>   Should be "ti,am33xx-hsmmc", for AM335x controllers
> + Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
>  - ti,hwmods: Must be "mmc<n>", n is controller instance starting 1
>  
>  Optional properties:
> -- 
> 2.11.0
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v2 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
  2017-08-21 14:21     ` Tony Lindgren
  (?)
@ 2017-08-22 13:39       ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-22 13:39 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter, Rob Herring, Tony Lindgren
  Cc: Sekhar Nori, Russell King, Ravikumar Kattekola, linux-mmc,
	devicetree, linux-kernel, linux-omap, linux-arm-kernel,
	Kishon Vijay Abraham I

Add binding for the TI's sdhci-omap controller. This now includes only
a subset of properties documented in ti-omap-hsmmc.txt but will eventually
include all the properties.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
Changes from v1:
*) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
   of using the ti-omap-hsmmc.txt as suggested by Tony
 .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt

diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
new file mode 100644
index 000000000000..139695ad2d58
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
@@ -0,0 +1,22 @@
+* TI OMAP SDHCI Controller
+
+Refer to mmc.txt for standard MMC bindings.
+
+Required properties:
+- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
+- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
+
+Optional properties:
+- ti,dual-volt: boolean, supports dual voltage cards
+- ti,non-removable: non-removable slot (like eMMC)
+
+Example:
+	mmc1: mmc@0x4809c000 {
+		compatible = "ti,omap4-hsmmc";
+		reg = <0x4809c000 0x400>;
+		ti,hwmods = "mmc1";
+		ti,dual-volt;
+		bus-width = <4>;
+		vmmc-supply = <&vmmc>; /* phandle to regulator node */
+		ti,non-removable;
+	};
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-22 13:39       ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-22 13:39 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter, Rob Herring, Tony Lindgren
  Cc: devicetree, Kishon Vijay Abraham I, Sekhar Nori, linux-mmc,
	linux-kernel, Russell King, Ravikumar Kattekola, linux-omap,
	linux-arm-kernel

Add binding for the TI's sdhci-omap controller. This now includes only
a subset of properties documented in ti-omap-hsmmc.txt but will eventually
include all the properties.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
Changes from v1:
*) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
   of using the ti-omap-hsmmc.txt as suggested by Tony
 .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt

diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
new file mode 100644
index 000000000000..139695ad2d58
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
@@ -0,0 +1,22 @@
+* TI OMAP SDHCI Controller
+
+Refer to mmc.txt for standard MMC bindings.
+
+Required properties:
+- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
+- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
+
+Optional properties:
+- ti,dual-volt: boolean, supports dual voltage cards
+- ti,non-removable: non-removable slot (like eMMC)
+
+Example:
+	mmc1: mmc@0x4809c000 {
+		compatible = "ti,omap4-hsmmc";
+		reg = <0x4809c000 0x400>;
+		ti,hwmods = "mmc1";
+		ti,dual-volt;
+		bus-width = <4>;
+		vmmc-supply = <&vmmc>; /* phandle to regulator node */
+		ti,non-removable;
+	};
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v2 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-22 13:39       ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-22 13:39 UTC (permalink / raw)
  To: linux-arm-kernel

Add binding for the TI's sdhci-omap controller. This now includes only
a subset of properties documented in ti-omap-hsmmc.txt but will eventually
include all the properties.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
Changes from v1:
*) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
   of using the ti-omap-hsmmc.txt as suggested by Tony
 .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt

diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
new file mode 100644
index 000000000000..139695ad2d58
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
@@ -0,0 +1,22 @@
+* TI OMAP SDHCI Controller
+
+Refer to mmc.txt for standard MMC bindings.
+
+Required properties:
+- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
+- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
+
+Optional properties:
+- ti,dual-volt: boolean, supports dual voltage cards
+- ti,non-removable: non-removable slot (like eMMC)
+
+Example:
+	mmc1: mmc at 0x4809c000 {
+		compatible = "ti,omap4-hsmmc";
+		reg = <0x4809c000 0x400>;
+		ti,hwmods = "mmc1";
+		ti,dual-volt;
+		bus-width = <4>;
+		vmmc-supply = <&vmmc>; /* phandle to regulator node */
+		ti,non-removable;
+	};
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* Re: [PATCH v2 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
  2017-08-22 13:39       ` Kishon Vijay Abraham I
@ 2017-08-22 17:39         ` Tony Lindgren
  -1 siblings, 0 replies; 86+ messages in thread
From: Tony Lindgren @ 2017-08-22 17:39 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Ulf Hansson, Adrian Hunter, Rob Herring, Sekhar Nori,
	Russell King, Ravikumar Kattekola, linux-mmc, devicetree,
	linux-kernel, linux-omap, linux-arm-kernel

* Kishon Vijay Abraham I <kishon@ti.com> [170822 06:39]:
> Add binding for the TI's sdhci-omap controller. This now includes only
> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
> include all the properties.
>
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
> Changes from v1:
> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>    of using the ti-omap-hsmmc.txt as suggested by Tony

Works for me thanks, just one typo below..

>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> 
> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> new file mode 100644
> index 000000000000..139695ad2d58
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> @@ -0,0 +1,22 @@
> +* TI OMAP SDHCI Controller
> +
> +Refer to mmc.txt for standard MMC bindings.
> +
> +Required properties:
> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
> +
> +Optional properties:
> +- ti,dual-volt: boolean, supports dual voltage cards
> +- ti,non-removable: non-removable slot (like eMMC)
> +
> +Example:
> +	mmc1: mmc@0x4809c000 {
> +		compatible = "ti,omap4-hsmmc";

The compatible in the example here is still using hsmmc :)

Tony

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v2 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-22 17:39         ` Tony Lindgren
  0 siblings, 0 replies; 86+ messages in thread
From: Tony Lindgren @ 2017-08-22 17:39 UTC (permalink / raw)
  To: linux-arm-kernel

* Kishon Vijay Abraham I <kishon@ti.com> [170822 06:39]:
> Add binding for the TI's sdhci-omap controller. This now includes only
> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
> include all the properties.
>
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
> Changes from v1:
> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>    of using the ti-omap-hsmmc.txt as suggested by Tony

Works for me thanks, just one typo below..

>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> 
> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> new file mode 100644
> index 000000000000..139695ad2d58
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> @@ -0,0 +1,22 @@
> +* TI OMAP SDHCI Controller
> +
> +Refer to mmc.txt for standard MMC bindings.
> +
> +Required properties:
> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
> +
> +Optional properties:
> +- ti,dual-volt: boolean, supports dual voltage cards
> +- ti,non-removable: non-removable slot (like eMMC)
> +
> +Example:
> +	mmc1: mmc at 0x4809c000 {
> +		compatible = "ti,omap4-hsmmc";

The compatible in the example here is still using hsmmc :)

Tony

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
  2017-08-21 14:21     ` Tony Lindgren
  (?)
@ 2017-08-23  5:42       ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-23  5:42 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter, Rob Herring, Tony Lindgren
  Cc: Sekhar Nori, Russell King, Ravikumar Kattekola, linux-mmc,
	devicetree, linux-kernel, linux-omap, linux-arm-kernel,
	Kishon Vijay Abraham I

Add binding for the TI's sdhci-omap controller. This now includes only
a subset of properties documented in ti-omap-hsmmc.txt but will eventually
include all the properties.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
Changes from v2:
*) Fixed example to use the updated compatible

Changes from v1:
*) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
   of using the ti-omap-hsmmc.txt as suggested by Tony
 .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt

diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
new file mode 100644
index 000000000000..139695ad2d58
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
@@ -0,0 +1,22 @@
+* TI OMAP SDHCI Controller
+
+Refer to mmc.txt for standard MMC bindings.
+
+Required properties:
+- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
+- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
+
+Optional properties:
+- ti,dual-volt: boolean, supports dual voltage cards
+- ti,non-removable: non-removable slot (like eMMC)
+
+Example:
+	mmc1: mmc@0x4809c000 {
+		compatible = "ti,dra7-sdhci";
+		reg = <0x4809c000 0x400>;
+		ti,hwmods = "mmc1";
+		ti,dual-volt;
+		bus-width = <4>;
+		vmmc-supply = <&vmmc>; /* phandle to regulator node */
+		ti,non-removable;
+	};
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-23  5:42       ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-23  5:42 UTC (permalink / raw)
  To: Ulf Hansson, Adrian Hunter, Rob Herring, Tony Lindgren
  Cc: devicetree, Kishon Vijay Abraham I, Sekhar Nori, linux-mmc,
	linux-kernel, Russell King, Ravikumar Kattekola, linux-omap,
	linux-arm-kernel

Add binding for the TI's sdhci-omap controller. This now includes only
a subset of properties documented in ti-omap-hsmmc.txt but will eventually
include all the properties.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
Changes from v2:
*) Fixed example to use the updated compatible

Changes from v1:
*) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
   of using the ti-omap-hsmmc.txt as suggested by Tony
 .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt

diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
new file mode 100644
index 000000000000..139695ad2d58
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
@@ -0,0 +1,22 @@
+* TI OMAP SDHCI Controller
+
+Refer to mmc.txt for standard MMC bindings.
+
+Required properties:
+- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
+- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
+
+Optional properties:
+- ti,dual-volt: boolean, supports dual voltage cards
+- ti,non-removable: non-removable slot (like eMMC)
+
+Example:
+	mmc1: mmc@0x4809c000 {
+		compatible = "ti,dra7-sdhci";
+		reg = <0x4809c000 0x400>;
+		ti,hwmods = "mmc1";
+		ti,dual-volt;
+		bus-width = <4>;
+		vmmc-supply = <&vmmc>; /* phandle to regulator node */
+		ti,non-removable;
+	};
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-23  5:42       ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-23  5:42 UTC (permalink / raw)
  To: linux-arm-kernel

Add binding for the TI's sdhci-omap controller. This now includes only
a subset of properties documented in ti-omap-hsmmc.txt but will eventually
include all the properties.

Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
---
Changes from v2:
*) Fixed example to use the updated compatible

Changes from v1:
*) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
   of using the ti-omap-hsmmc.txt as suggested by Tony
 .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt

diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
new file mode 100644
index 000000000000..139695ad2d58
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
@@ -0,0 +1,22 @@
+* TI OMAP SDHCI Controller
+
+Refer to mmc.txt for standard MMC bindings.
+
+Required properties:
+- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
+- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
+
+Optional properties:
+- ti,dual-volt: boolean, supports dual voltage cards
+- ti,non-removable: non-removable slot (like eMMC)
+
+Example:
+	mmc1: mmc at 0x4809c000 {
+		compatible = "ti,dra7-sdhci";
+		reg = <0x4809c000 0x400>;
+		ti,hwmods = "mmc1";
+		ti,dual-volt;
+		bus-width = <4>;
+		vmmc-supply = <&vmmc>; /* phandle to regulator node */
+		ti,non-removable;
+	};
-- 
2.11.0

^ permalink raw reply related	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-23 13:07         ` Ulf Hansson
  0 siblings, 0 replies; 86+ messages in thread
From: Ulf Hansson @ 2017-08-23 13:07 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Adrian Hunter, Rob Herring, Tony Lindgren, Sekhar Nori,
	Russell King, Ravikumar Kattekola, linux-mmc, devicetree,
	linux-kernel, linux-omap, linux-arm-kernel

On 23 August 2017 at 07:42, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> Add binding for the TI's sdhci-omap controller. This now includes only
> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
> include all the properties.
>
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
> Changes from v2:
> *) Fixed example to use the updated compatible
>
> Changes from v1:
> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>    of using the ti-omap-hsmmc.txt as suggested by Tony
>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>
> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> new file mode 100644
> index 000000000000..139695ad2d58
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> @@ -0,0 +1,22 @@
> +* TI OMAP SDHCI Controller
> +
> +Refer to mmc.txt for standard MMC bindings.
> +
> +Required properties:
> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
> +
> +Optional properties:
> +- ti,dual-volt: boolean, supports dual voltage cards
> +- ti,non-removable: non-removable slot (like eMMC)
> +
> +Example:
> +       mmc1: mmc@0x4809c000 {
> +               compatible = "ti,dra7-sdhci";
> +               reg = <0x4809c000 0x400>;
> +               ti,hwmods = "mmc1";
> +               ti,dual-volt;
> +               bus-width = <4>;
> +               vmmc-supply = <&vmmc>; /* phandle to regulator node */
> +               ti,non-removable;
> +       };
> --
> 2.11.0
>

I am wondering a bit on the long term plan here.

Ideally at some point in future, we would like to remove the old
omap_hsmmc driver, but from compatible string point of view, that
means we first needs to deprecate the old ones for a while. Right?

That said, what is then the reason to why we should bring over the
existing omap_hsmmc bindings to the sdhci-omap bindings?

For example, "ti,dual-volt" can likely be replaced with something
better that already exists (either a common mmc binding or an sdhci
binding). For "ti,non-removable", we already have a common mmc binding
"non-removable" for this.

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-23 13:07         ` Ulf Hansson
  0 siblings, 0 replies; 86+ messages in thread
From: Ulf Hansson @ 2017-08-23 13:07 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Adrian Hunter, Rob Herring, Tony Lindgren, Sekhar Nori,
	Russell King, Ravikumar Kattekola,
	linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-omap,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On 23 August 2017 at 07:42, Kishon Vijay Abraham I <kishon-l0cyMroinI0@public.gmane.org> wrote:
> Add binding for the TI's sdhci-omap controller. This now includes only
> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
> include all the properties.
>
> Signed-off-by: Kishon Vijay Abraham I <kishon-l0cyMroinI0@public.gmane.org>
> ---
> Changes from v2:
> *) Fixed example to use the updated compatible
>
> Changes from v1:
> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>    of using the ti-omap-hsmmc.txt as suggested by Tony
>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>
> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> new file mode 100644
> index 000000000000..139695ad2d58
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> @@ -0,0 +1,22 @@
> +* TI OMAP SDHCI Controller
> +
> +Refer to mmc.txt for standard MMC bindings.
> +
> +Required properties:
> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
> +
> +Optional properties:
> +- ti,dual-volt: boolean, supports dual voltage cards
> +- ti,non-removable: non-removable slot (like eMMC)
> +
> +Example:
> +       mmc1: mmc@0x4809c000 {
> +               compatible = "ti,dra7-sdhci";
> +               reg = <0x4809c000 0x400>;
> +               ti,hwmods = "mmc1";
> +               ti,dual-volt;
> +               bus-width = <4>;
> +               vmmc-supply = <&vmmc>; /* phandle to regulator node */
> +               ti,non-removable;
> +       };
> --
> 2.11.0
>

I am wondering a bit on the long term plan here.

Ideally at some point in future, we would like to remove the old
omap_hsmmc driver, but from compatible string point of view, that
means we first needs to deprecate the old ones for a while. Right?

That said, what is then the reason to why we should bring over the
existing omap_hsmmc bindings to the sdhci-omap bindings?

For example, "ti,dual-volt" can likely be replaced with something
better that already exists (either a common mmc binding or an sdhci
binding). For "ti,non-removable", we already have a common mmc binding
"non-removable" for this.

Kind regards
Uffe
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-23 13:07         ` Ulf Hansson
  0 siblings, 0 replies; 86+ messages in thread
From: Ulf Hansson @ 2017-08-23 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

On 23 August 2017 at 07:42, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> Add binding for the TI's sdhci-omap controller. This now includes only
> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
> include all the properties.
>
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
> Changes from v2:
> *) Fixed example to use the updated compatible
>
> Changes from v1:
> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>    of using the ti-omap-hsmmc.txt as suggested by Tony
>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>
> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> new file mode 100644
> index 000000000000..139695ad2d58
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> @@ -0,0 +1,22 @@
> +* TI OMAP SDHCI Controller
> +
> +Refer to mmc.txt for standard MMC bindings.
> +
> +Required properties:
> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
> +
> +Optional properties:
> +- ti,dual-volt: boolean, supports dual voltage cards
> +- ti,non-removable: non-removable slot (like eMMC)
> +
> +Example:
> +       mmc1: mmc at 0x4809c000 {
> +               compatible = "ti,dra7-sdhci";
> +               reg = <0x4809c000 0x400>;
> +               ti,hwmods = "mmc1";
> +               ti,dual-volt;
> +               bus-width = <4>;
> +               vmmc-supply = <&vmmc>; /* phandle to regulator node */
> +               ti,non-removable;
> +       };
> --
> 2.11.0
>

I am wondering a bit on the long term plan here.

Ideally at some point in future, we would like to remove the old
omap_hsmmc driver, but from compatible string point of view, that
means we first needs to deprecate the old ones for a while. Right?

That said, what is then the reason to why we should bring over the
existing omap_hsmmc bindings to the sdhci-omap bindings?

For example, "ti,dual-volt" can likely be replaced with something
better that already exists (either a common mmc binding or an sdhci
binding). For "ti,non-removable", we already have a common mmc binding
"non-removable" for this.

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
  2017-08-23 13:07         ` Ulf Hansson
  (?)
@ 2017-08-23 13:56           ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-23 13:56 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Adrian Hunter, Rob Herring, Tony Lindgren, Sekhar Nori,
	Russell King, Ravikumar Kattekola, linux-mmc, devicetree,
	linux-kernel, linux-omap, linux-arm-kernel

Hi Uffe,

On Wednesday 23 August 2017 06:37 PM, Ulf Hansson wrote:
> On 23 August 2017 at 07:42, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>> Add binding for the TI's sdhci-omap controller. This now includes only
>> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
>> include all the properties.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>> Changes from v2:
>> *) Fixed example to use the updated compatible
>>
>> Changes from v1:
>> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>>    of using the ti-omap-hsmmc.txt as suggested by Tony
>>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>>  1 file changed, 22 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>> new file mode 100644
>> index 000000000000..139695ad2d58
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>> @@ -0,0 +1,22 @@
>> +* TI OMAP SDHCI Controller
>> +
>> +Refer to mmc.txt for standard MMC bindings.
>> +
>> +Required properties:
>> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
>> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
>> +
>> +Optional properties:
>> +- ti,dual-volt: boolean, supports dual voltage cards
>> +- ti,non-removable: non-removable slot (like eMMC)
>> +
>> +Example:
>> +       mmc1: mmc@0x4809c000 {
>> +               compatible = "ti,dra7-sdhci";
>> +               reg = <0x4809c000 0x400>;
>> +               ti,hwmods = "mmc1";
>> +               ti,dual-volt;
>> +               bus-width = <4>;
>> +               vmmc-supply = <&vmmc>; /* phandle to regulator node */
>> +               ti,non-removable;
>> +       };
>> --
>> 2.11.0
>>
> 
> I am wondering a bit on the long term plan here.
> 
> Ideally at some point in future, we would like to remove the old
> omap_hsmmc driver, but from compatible string point of view, that
> means we first needs to deprecate the old ones for a while. Right?

right but sdhci-omap is still lacking features that was present in omap_hsmmc
like context save/restore, SDIO support etc. I think we should deprecate
omap_hsmmc compatible once we add all the features in sdhci-omap?
> 
> That said, what is then the reason to why we should bring over the
> existing omap_hsmmc bindings to the sdhci-omap bindings?

This is mainly for old dt compatibility. Even after removing the omap_hsmmc
driver, users should still be able to use newer kernel with their existing dtbs.

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-23 13:56           ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-23 13:56 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Adrian Hunter, Rob Herring, Tony Lindgren, Sekhar Nori,
	Russell King, Ravikumar Kattekola, linux-mmc, devicetree,
	linux-kernel, linux-omap, linux-arm-kernel

Hi Uffe,

On Wednesday 23 August 2017 06:37 PM, Ulf Hansson wrote:
> On 23 August 2017 at 07:42, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>> Add binding for the TI's sdhci-omap controller. This now includes only
>> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
>> include all the properties.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>> Changes from v2:
>> *) Fixed example to use the updated compatible
>>
>> Changes from v1:
>> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>>    of using the ti-omap-hsmmc.txt as suggested by Tony
>>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>>  1 file changed, 22 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>> new file mode 100644
>> index 000000000000..139695ad2d58
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>> @@ -0,0 +1,22 @@
>> +* TI OMAP SDHCI Controller
>> +
>> +Refer to mmc.txt for standard MMC bindings.
>> +
>> +Required properties:
>> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
>> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
>> +
>> +Optional properties:
>> +- ti,dual-volt: boolean, supports dual voltage cards
>> +- ti,non-removable: non-removable slot (like eMMC)
>> +
>> +Example:
>> +       mmc1: mmc@0x4809c000 {
>> +               compatible = "ti,dra7-sdhci";
>> +               reg = <0x4809c000 0x400>;
>> +               ti,hwmods = "mmc1";
>> +               ti,dual-volt;
>> +               bus-width = <4>;
>> +               vmmc-supply = <&vmmc>; /* phandle to regulator node */
>> +               ti,non-removable;
>> +       };
>> --
>> 2.11.0
>>
> 
> I am wondering a bit on the long term plan here.
> 
> Ideally at some point in future, we would like to remove the old
> omap_hsmmc driver, but from compatible string point of view, that
> means we first needs to deprecate the old ones for a while. Right?

right but sdhci-omap is still lacking features that was present in omap_hsmmc
like context save/restore, SDIO support etc. I think we should deprecate
omap_hsmmc compatible once we add all the features in sdhci-omap?
> 
> That said, what is then the reason to why we should bring over the
> existing omap_hsmmc bindings to the sdhci-omap bindings?

This is mainly for old dt compatibility. Even after removing the omap_hsmmc
driver, users should still be able to use newer kernel with their existing dtbs.

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-23 13:56           ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-23 13:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uffe,

On Wednesday 23 August 2017 06:37 PM, Ulf Hansson wrote:
> On 23 August 2017 at 07:42, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>> Add binding for the TI's sdhci-omap controller. This now includes only
>> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
>> include all the properties.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>> Changes from v2:
>> *) Fixed example to use the updated compatible
>>
>> Changes from v1:
>> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>>    of using the ti-omap-hsmmc.txt as suggested by Tony
>>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>>  1 file changed, 22 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>> new file mode 100644
>> index 000000000000..139695ad2d58
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>> @@ -0,0 +1,22 @@
>> +* TI OMAP SDHCI Controller
>> +
>> +Refer to mmc.txt for standard MMC bindings.
>> +
>> +Required properties:
>> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
>> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
>> +
>> +Optional properties:
>> +- ti,dual-volt: boolean, supports dual voltage cards
>> +- ti,non-removable: non-removable slot (like eMMC)
>> +
>> +Example:
>> +       mmc1: mmc at 0x4809c000 {
>> +               compatible = "ti,dra7-sdhci";
>> +               reg = <0x4809c000 0x400>;
>> +               ti,hwmods = "mmc1";
>> +               ti,dual-volt;
>> +               bus-width = <4>;
>> +               vmmc-supply = <&vmmc>; /* phandle to regulator node */
>> +               ti,non-removable;
>> +       };
>> --
>> 2.11.0
>>
> 
> I am wondering a bit on the long term plan here.
> 
> Ideally at some point in future, we would like to remove the old
> omap_hsmmc driver, but from compatible string point of view, that
> means we first needs to deprecate the old ones for a while. Right?

right but sdhci-omap is still lacking features that was present in omap_hsmmc
like context save/restore, SDIO support etc. I think we should deprecate
omap_hsmmc compatible once we add all the features in sdhci-omap?
> 
> That said, what is then the reason to why we should bring over the
> existing omap_hsmmc bindings to the sdhci-omap bindings?

This is mainly for old dt compatibility. Even after removing the omap_hsmmc
driver, users should still be able to use newer kernel with their existing dtbs.

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
  2017-08-23 13:56           ` Kishon Vijay Abraham I
  (?)
@ 2017-08-24 11:29             ` Ulf Hansson
  -1 siblings, 0 replies; 86+ messages in thread
From: Ulf Hansson @ 2017-08-24 11:29 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Adrian Hunter, Rob Herring, Tony Lindgren, Sekhar Nori,
	Russell King, Ravikumar Kattekola, linux-mmc, devicetree,
	linux-kernel, linux-omap, linux-arm-kernel

On 23 August 2017 at 15:56, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> Hi Uffe,
>
> On Wednesday 23 August 2017 06:37 PM, Ulf Hansson wrote:
>> On 23 August 2017 at 07:42, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>>> Add binding for the TI's sdhci-omap controller. This now includes only
>>> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
>>> include all the properties.
>>>
>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>> ---
>>> Changes from v2:
>>> *) Fixed example to use the updated compatible
>>>
>>> Changes from v1:
>>> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>>>    of using the ti-omap-hsmmc.txt as suggested by Tony
>>>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>>>  1 file changed, 22 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>> new file mode 100644
>>> index 000000000000..139695ad2d58
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>> @@ -0,0 +1,22 @@
>>> +* TI OMAP SDHCI Controller
>>> +
>>> +Refer to mmc.txt for standard MMC bindings.
>>> +
>>> +Required properties:
>>> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
>>> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
>>> +
>>> +Optional properties:
>>> +- ti,dual-volt: boolean, supports dual voltage cards
>>> +- ti,non-removable: non-removable slot (like eMMC)
>>> +
>>> +Example:
>>> +       mmc1: mmc@0x4809c000 {
>>> +               compatible = "ti,dra7-sdhci";
>>> +               reg = <0x4809c000 0x400>;
>>> +               ti,hwmods = "mmc1";
>>> +               ti,dual-volt;
>>> +               bus-width = <4>;
>>> +               vmmc-supply = <&vmmc>; /* phandle to regulator node */
>>> +               ti,non-removable;
>>> +       };
>>> --
>>> 2.11.0
>>>
>>
>> I am wondering a bit on the long term plan here.
>>
>> Ideally at some point in future, we would like to remove the old
>> omap_hsmmc driver, but from compatible string point of view, that
>> means we first needs to deprecate the old ones for a while. Right?
>
> right but sdhci-omap is still lacking features that was present in omap_hsmmc
> like context save/restore, SDIO support etc. I think we should deprecate
> omap_hsmmc compatible once we add all the features in sdhci-omap?
>>
>> That said, what is then the reason to why we should bring over the
>> existing omap_hsmmc bindings to the sdhci-omap bindings?
>
> This is mainly for old dt compatibility. Even after removing the omap_hsmmc
> driver, users should still be able to use newer kernel with their existing dtbs.

I guess we have two options.

1) Allow us to invent and use new bindings - and a new compatible.
When everything is implemented in sdhci-omap, we can deprecate the old
omap_hsmmc driver and its corresponding compatible/bindings. At some
point later we can remove the legacy driver/bindings altogether - of
course that might take a while. This option allows us to re-think some
of the old bindings and really clean up some if its related code. For
example, I think "ti,dual-volt" is a bad binding. Instead it would be
better to use the existing mmc bindings about which speed mode the
controller/board supports (as the voltage level comes with it).

2) Invent only a new compatible, but stick to use the old omap hsmmc
bindings and thus also deploy the similar code dealing with them. When
everything is implemented move the old omap_hsmmc compatibles into the
new sdhci-omap driver and them remove the old omap_hsmmc driver. At
that point we could also deprecate the old omap hsmmc compatibles, but
to me that is rather pointless.

The two options has different advantages, feel free to pick any of them!

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-24 11:29             ` Ulf Hansson
  0 siblings, 0 replies; 86+ messages in thread
From: Ulf Hansson @ 2017-08-24 11:29 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Adrian Hunter, Rob Herring, Tony Lindgren, Sekhar Nori,
	Russell King, Ravikumar Kattekola, linux-mmc, devicetree,
	linux-kernel, linux-omap, linux-arm-kernel

On 23 August 2017 at 15:56, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> Hi Uffe,
>
> On Wednesday 23 August 2017 06:37 PM, Ulf Hansson wrote:
>> On 23 August 2017 at 07:42, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>>> Add binding for the TI's sdhci-omap controller. This now includes only
>>> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
>>> include all the properties.
>>>
>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>> ---
>>> Changes from v2:
>>> *) Fixed example to use the updated compatible
>>>
>>> Changes from v1:
>>> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>>>    of using the ti-omap-hsmmc.txt as suggested by Tony
>>>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>>>  1 file changed, 22 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>> new file mode 100644
>>> index 000000000000..139695ad2d58
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>> @@ -0,0 +1,22 @@
>>> +* TI OMAP SDHCI Controller
>>> +
>>> +Refer to mmc.txt for standard MMC bindings.
>>> +
>>> +Required properties:
>>> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
>>> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
>>> +
>>> +Optional properties:
>>> +- ti,dual-volt: boolean, supports dual voltage cards
>>> +- ti,non-removable: non-removable slot (like eMMC)
>>> +
>>> +Example:
>>> +       mmc1: mmc@0x4809c000 {
>>> +               compatible = "ti,dra7-sdhci";
>>> +               reg = <0x4809c000 0x400>;
>>> +               ti,hwmods = "mmc1";
>>> +               ti,dual-volt;
>>> +               bus-width = <4>;
>>> +               vmmc-supply = <&vmmc>; /* phandle to regulator node */
>>> +               ti,non-removable;
>>> +       };
>>> --
>>> 2.11.0
>>>
>>
>> I am wondering a bit on the long term plan here.
>>
>> Ideally at some point in future, we would like to remove the old
>> omap_hsmmc driver, but from compatible string point of view, that
>> means we first needs to deprecate the old ones for a while. Right?
>
> right but sdhci-omap is still lacking features that was present in omap_hsmmc
> like context save/restore, SDIO support etc. I think we should deprecate
> omap_hsmmc compatible once we add all the features in sdhci-omap?
>>
>> That said, what is then the reason to why we should bring over the
>> existing omap_hsmmc bindings to the sdhci-omap bindings?
>
> This is mainly for old dt compatibility. Even after removing the omap_hsmmc
> driver, users should still be able to use newer kernel with their existing dtbs.

I guess we have two options.

1) Allow us to invent and use new bindings - and a new compatible.
When everything is implemented in sdhci-omap, we can deprecate the old
omap_hsmmc driver and its corresponding compatible/bindings. At some
point later we can remove the legacy driver/bindings altogether - of
course that might take a while. This option allows us to re-think some
of the old bindings and really clean up some if its related code. For
example, I think "ti,dual-volt" is a bad binding. Instead it would be
better to use the existing mmc bindings about which speed mode the
controller/board supports (as the voltage level comes with it).

2) Invent only a new compatible, but stick to use the old omap hsmmc
bindings and thus also deploy the similar code dealing with them. When
everything is implemented move the old omap_hsmmc compatibles into the
new sdhci-omap driver and them remove the old omap_hsmmc driver. At
that point we could also deprecate the old omap hsmmc compatibles, but
to me that is rather pointless.

The two options has different advantages, feel free to pick any of them!

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-24 11:29             ` Ulf Hansson
  0 siblings, 0 replies; 86+ messages in thread
From: Ulf Hansson @ 2017-08-24 11:29 UTC (permalink / raw)
  To: linux-arm-kernel

On 23 August 2017 at 15:56, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> Hi Uffe,
>
> On Wednesday 23 August 2017 06:37 PM, Ulf Hansson wrote:
>> On 23 August 2017 at 07:42, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>>> Add binding for the TI's sdhci-omap controller. This now includes only
>>> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
>>> include all the properties.
>>>
>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>> ---
>>> Changes from v2:
>>> *) Fixed example to use the updated compatible
>>>
>>> Changes from v1:
>>> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>>>    of using the ti-omap-hsmmc.txt as suggested by Tony
>>>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>>>  1 file changed, 22 insertions(+)
>>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>> new file mode 100644
>>> index 000000000000..139695ad2d58
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>> @@ -0,0 +1,22 @@
>>> +* TI OMAP SDHCI Controller
>>> +
>>> +Refer to mmc.txt for standard MMC bindings.
>>> +
>>> +Required properties:
>>> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
>>> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
>>> +
>>> +Optional properties:
>>> +- ti,dual-volt: boolean, supports dual voltage cards
>>> +- ti,non-removable: non-removable slot (like eMMC)
>>> +
>>> +Example:
>>> +       mmc1: mmc at 0x4809c000 {
>>> +               compatible = "ti,dra7-sdhci";
>>> +               reg = <0x4809c000 0x400>;
>>> +               ti,hwmods = "mmc1";
>>> +               ti,dual-volt;
>>> +               bus-width = <4>;
>>> +               vmmc-supply = <&vmmc>; /* phandle to regulator node */
>>> +               ti,non-removable;
>>> +       };
>>> --
>>> 2.11.0
>>>
>>
>> I am wondering a bit on the long term plan here.
>>
>> Ideally at some point in future, we would like to remove the old
>> omap_hsmmc driver, but from compatible string point of view, that
>> means we first needs to deprecate the old ones for a while. Right?
>
> right but sdhci-omap is still lacking features that was present in omap_hsmmc
> like context save/restore, SDIO support etc. I think we should deprecate
> omap_hsmmc compatible once we add all the features in sdhci-omap?
>>
>> That said, what is then the reason to why we should bring over the
>> existing omap_hsmmc bindings to the sdhci-omap bindings?
>
> This is mainly for old dt compatibility. Even after removing the omap_hsmmc
> driver, users should still be able to use newer kernel with their existing dtbs.

I guess we have two options.

1) Allow us to invent and use new bindings - and a new compatible.
When everything is implemented in sdhci-omap, we can deprecate the old
omap_hsmmc driver and its corresponding compatible/bindings. At some
point later we can remove the legacy driver/bindings altogether - of
course that might take a while. This option allows us to re-think some
of the old bindings and really clean up some if its related code. For
example, I think "ti,dual-volt" is a bad binding. Instead it would be
better to use the existing mmc bindings about which speed mode the
controller/board supports (as the voltage level comes with it).

2) Invent only a new compatible, but stick to use the old omap hsmmc
bindings and thus also deploy the similar code dealing with them. When
everything is implemented move the old omap_hsmmc compatibles into the
new sdhci-omap driver and them remove the old omap_hsmmc driver. At
that point we could also deprecate the old omap hsmmc compatibles, but
to me that is rather pointless.

The two options has different advantages, feel free to pick any of them!

Kind regards
Uffe

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH 2/5] mmc: sdhci: Add quirk to indicate MMC_RSP_136 has CRC
  2017-08-21  7:41   ` Kishon Vijay Abraham I
@ 2017-08-28  7:57     ` Adrian Hunter
  -1 siblings, 0 replies; 86+ messages in thread
From: Adrian Hunter @ 2017-08-28  7:57 UTC (permalink / raw)
  To: Kishon Vijay Abraham I, Ulf Hansson
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel

On 21/08/17 10:41, Kishon Vijay Abraham I wrote:
> TI's implementation of sdhci controller used in DRA7 SoC's has
> CRC in responses with length 136 bits. Add quirk to indicate
> the controller has CRC in MMC_RSP_136. If this quirk is
> set sdhci library shouldn't shift the response present in
> SDHCI_RESPONSE register.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

Acked-by: Adrian Hunter <adrian.hunter@intel.com>

> ---
>  drivers/mmc/host/sdhci.c | 3 +++
>  drivers/mmc/host/sdhci.h | 2 ++
>  2 files changed, 5 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index ba639b7851cb..9c8d7428df3c 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1182,6 +1182,9 @@ static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
>  		cmd->resp[i] = sdhci_readl(host, reg);
>  	}
>  
> +	if (host->quirks2 & SDHCI_QUIRK2_RSP_136_HAS_CRC)
> +		return;
> +
>  	/* CRC is stripped so we need to do some shifting */
>  	for (i = 0; i < 4; i++) {
>  		cmd->resp[i] <<= 8;
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 399edc681623..54bc444c317f 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -435,6 +435,8 @@ struct sdhci_host {
>  #define SDHCI_QUIRK2_ACMD23_BROKEN			(1<<14)
>  /* Broken Clock divider zero in controller */
>  #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN		(1<<15)
> +/* Controller has CRC in 136 bit Command Response */
> +#define SDHCI_QUIRK2_RSP_136_HAS_CRC			(1<<16)
>  
>  	int irq;		/* Device IRQ */
>  	void __iomem *ioaddr;	/* Mapped address */
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH 2/5] mmc: sdhci: Add quirk to indicate MMC_RSP_136 has CRC
@ 2017-08-28  7:57     ` Adrian Hunter
  0 siblings, 0 replies; 86+ messages in thread
From: Adrian Hunter @ 2017-08-28  7:57 UTC (permalink / raw)
  To: linux-arm-kernel

On 21/08/17 10:41, Kishon Vijay Abraham I wrote:
> TI's implementation of sdhci controller used in DRA7 SoC's has
> CRC in responses with length 136 bits. Add quirk to indicate
> the controller has CRC in MMC_RSP_136. If this quirk is
> set sdhci library shouldn't shift the response present in
> SDHCI_RESPONSE register.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

Acked-by: Adrian Hunter <adrian.hunter@intel.com>

> ---
>  drivers/mmc/host/sdhci.c | 3 +++
>  drivers/mmc/host/sdhci.h | 2 ++
>  2 files changed, 5 insertions(+)
> 
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index ba639b7851cb..9c8d7428df3c 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1182,6 +1182,9 @@ static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
>  		cmd->resp[i] = sdhci_readl(host, reg);
>  	}
>  
> +	if (host->quirks2 & SDHCI_QUIRK2_RSP_136_HAS_CRC)
> +		return;
> +
>  	/* CRC is stripped so we need to do some shifting */
>  	for (i = 0; i < 4; i++) {
>  		cmd->resp[i] <<= 8;
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 399edc681623..54bc444c317f 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -435,6 +435,8 @@ struct sdhci_host {
>  #define SDHCI_QUIRK2_ACMD23_BROKEN			(1<<14)
>  /* Broken Clock divider zero in controller */
>  #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN		(1<<15)
> +/* Controller has CRC in 136 bit Command Response */
> +#define SDHCI_QUIRK2_RSP_136_HAS_CRC			(1<<16)
>  
>  	int irq;		/* Device IRQ */
>  	void __iomem *ioaddr;	/* Mapped address */
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH 4/5] mmc: sdhci-omap: Add OMAP SDHCI driver
  2017-08-21  7:41   ` Kishon Vijay Abraham I
@ 2017-08-28  9:06     ` Adrian Hunter
  -1 siblings, 0 replies; 86+ messages in thread
From: Adrian Hunter @ 2017-08-28  9:06 UTC (permalink / raw)
  To: Kishon Vijay Abraham I, Ulf Hansson
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel

On 21/08/17 10:41, Kishon Vijay Abraham I wrote:
> Create a new sdhci-omap driver to configure the eMMC/SD/SDIO controller
> in TI's OMAP SoCs making use of the SDHCI core library. For OMAP specific
> configurations, populate sdhci_ops with OMAP specific callbacks and use
> SDHCI quirks.
> Enable only high speed mode for both SD and eMMC here and add other
> UHS mode support later.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

There are a few minor comments below.

> ---
>  drivers/mmc/host/Kconfig      |  12 +
>  drivers/mmc/host/Makefile     |   1 +
>  drivers/mmc/host/sdhci-omap.c | 629 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 642 insertions(+)
>  create mode 100644 drivers/mmc/host/sdhci-omap.c
> 
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 60f90d49e7a9..60d50843e165 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -899,3 +899,15 @@ config MMC_SDHCI_XENON
>  	  This selects Marvell Xenon eMMC/SD/SDIO SDHCI.
>  	  If you have a controller with this interface, say Y or M here.
>  	  If unsure, say N.
> +
> +config MMC_SDHCI_OMAP
> +	tristate "TI SDHCI Controller Support"
> +	depends on MMC_SDHCI_PLTFM
> +	help
> +	  This selects the Secure Digital Host Controller Interface (SDHCI)
> +	  support present in TI's DRA7 SOCs. The controller supports
> +	  SD/MMC/SDIO devices.
> +
> +	  If you have a controller with this interface, say Y or M here.
> +
> +	  If unsure, say N.
> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
> index 8c46766c000c..33181df88a10 100644
> --- a/drivers/mmc/host/Makefile
> +++ b/drivers/mmc/host/Makefile
> @@ -88,6 +88,7 @@ obj-$(CONFIG_MMC_SDHCI_MSM)		+= sdhci-msm.o
>  obj-$(CONFIG_MMC_SDHCI_ST)		+= sdhci-st.o
>  obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32)	+= sdhci-pic32.o
>  obj-$(CONFIG_MMC_SDHCI_BRCMSTB)		+= sdhci-brcmstb.o
> +obj-$(CONFIG_MMC_SDHCI_OMAP)		+= sdhci-omap.o
>  
>  ifeq ($(CONFIG_CB710_DEBUG),y)
>  	CFLAGS-cb710-mmc	+= -DDEBUG
> diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c
> new file mode 100644
> index 000000000000..73ee3b4a400c
> --- /dev/null
> +++ b/drivers/mmc/host/sdhci-omap.c
> @@ -0,0 +1,629 @@
> +/**
> + * SDHCI Controller driver for TI's OMAP SoCs
> + *
> + * Copyright (C) 2017 Texas Instruments
> + * Author: Kishon Vijay Abraham I <kishon@ti.com>
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 of
> + * the License as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/mmc/slot-gpio.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regulator/consumer.h>
> +
> +#include "sdhci-pltfm.h"
> +
> +#define SDHCI_OMAP_CON		0x12c
> +#define CON_DW8			BIT(5)
> +#define CON_DMA_MASTER		BIT(20)
> +#define CON_INIT		BIT(1)
> +#define CON_OD			BIT(0)
> +
> +#define SDHCI_OMAP_CMD		0x20c
> +
> +#define SDHCI_OMAP_HCTL		0x228
> +#define HCTL_SDBP		BIT(8)
> +#define HCTL_SDVS_SHIFT		9
> +#define HCTL_SDVS_MASK		(0x7 << HCTL_SDVS_SHIFT)
> +#define HCTL_SDVS_33		(0x7 << HCTL_SDVS_SHIFT)
> +#define HCTL_SDVS_30		(0x6 << HCTL_SDVS_SHIFT)
> +#define HCTL_SDVS_18		(0x5 << HCTL_SDVS_SHIFT)
> +
> +#define SDHCI_OMAP_SYSCTL	0x22c
> +#define SYSCTL_CEN		BIT(2)
> +#define SYSCTL_CLKD_SHIFT	6
> +#define SYSCTL_CLKD_MASK	0x3ff
> +
> +#define SDHCI_OMAP_STAT		0x230
> +
> +#define SDHCI_OMAP_IE		0x234
> +#define INT_CC_EN		BIT(0)
> +
> +#define SDHCI_OMAP_AC12		0x23c
> +#define AC12_V1V8_SIGEN		BIT(19)
> +
> +#define SDHCI_OMAP_CAPA		0x240
> +#define CAPA_VS33		BIT(24)
> +#define CAPA_VS30		BIT(25)
> +#define CAPA_VS18		BIT(26)
> +
> +#define MMC_TIMEOUT		1		/* 1 msec */

As before, SDHCI_OMAP_TIMEOUT is a better name

> +
> +#define SYSCTL_CLKD_MAX		0x3FF
> +
> +#define IOV_1V8			1800000		/* 180000 uV */
> +#define IOV_3V0			3000000		/* 300000 uV */
> +#define IOV_3V3			3300000		/* 330000 uV */
> +
> +struct sdhci_omap_data {
> +	u32 offset;
> +};
> +
> +struct sdhci_omap_host {
> +	void __iomem		*base;
> +	struct device		*dev;
> +	struct	regulator	*pbias;
> +	bool			pbias_enabled;
> +	struct sdhci_host	*host;
> +	unsigned int		flags;
> +
> +#define SDHCI_OMAP_SUPPORTS_DUAL_VOLT	BIT(0)
> +#define SDHCI_OMAP_NO_1_8_V		BIT(1)
> +
> +	u8			bus_mode;
> +	u8			power_mode;
> +	bool			io_3_3v_support;
> +};
> +
> +static inline u32 sdhci_omap_readl(struct sdhci_omap_host *host,
> +				   unsigned int offset)
> +{
> +	return readl(host->base + offset);
> +}
> +
> +static inline void sdhci_omap_writel(struct sdhci_omap_host *host,
> +				     unsigned int offset, u32 data)
> +{
> +	writel(data, host->base + offset);
> +}
> +
> +static int sdhci_omap_set_pbias(struct sdhci_omap_host *omap_host,
> +				bool power_on, unsigned int iov)
> +{
> +	int ret;
> +	struct device *dev = omap_host->dev;
> +
> +	if (IS_ERR(omap_host->pbias))
> +		return 0;
> +
> +	if (power_on) {
> +		ret = regulator_set_voltage(omap_host->pbias, iov, iov);
> +		if (ret) {
> +			dev_err(dev, "pbias set voltage failed\n");
> +			return ret;
> +		}
> +
> +		if (omap_host->pbias_enabled)
> +			return 0;
> +
> +		ret = regulator_enable(omap_host->pbias);
> +		if (ret) {
> +			dev_err(dev, "pbias reg enable fail\n");
> +			return ret;
> +		}
> +
> +		omap_host->pbias_enabled = true;
> +	} else {
> +		if (!omap_host->pbias_enabled)
> +			return 0;
> +
> +		ret = regulator_disable(omap_host->pbias);
> +		if (ret) {
> +			dev_err(dev, "pbias reg disable fail\n");
> +			return ret;
> +		}
> +		omap_host->pbias_enabled = false;
> +	}
> +
> +	return 0;
> +}
> +
> +static int sdhci_omap_enable_iov(struct sdhci_omap_host *omap_host,
> +				 unsigned int iov)
> +{
> +	int ret;
> +	struct sdhci_host *host = omap_host->host;
> +	struct mmc_host *mmc = host->mmc;
> +
> +	ret = sdhci_omap_set_pbias(omap_host, false, 0);
> +	if (ret)
> +		return ret;
> +
> +	if (!IS_ERR(mmc->supply.vqmmc)) {
> +		ret = regulator_set_voltage(mmc->supply.vqmmc, iov, iov);
> +		if (ret) {
> +			dev_err(mmc_dev(mmc), "vqmmc set voltage failed\n");
> +			return ret;
> +		}
> +	}
> +
> +	ret = sdhci_omap_set_pbias(omap_host, true, iov);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static void sdhci_omap_conf_bus_power(struct sdhci_omap_host *omap_host,
> +				      unsigned char signal_voltage)
> +{
> +	u32 reg;
> +	ktime_t timeout;
> +
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL);
> +	reg &= ~HCTL_SDVS_MASK;
> +
> +	if (signal_voltage == MMC_SIGNAL_VOLTAGE_180)
> +		reg |= HCTL_SDVS_18;
> +	else if (omap_host->io_3_3v_support)
> +		reg |= HCTL_SDVS_33;
> +	else
> +		reg |= HCTL_SDVS_30;
> +
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
> +
> +	reg |= HCTL_SDBP;
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
> +
> +	/* wait 1ms */
> +	timeout = ktime_add_ms(ktime_get(), MMC_TIMEOUT);
> +	while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL) & HCTL_SDBP)) {
> +		if (WARN_ON(ktime_after(ktime_get(), timeout)))
> +			return;
> +		usleep_range(5, 10);
> +	}
> +}
> +
> +static int sdhci_omap_start_signal_voltage_switch(struct mmc_host *mmc,
> +						  struct mmc_ios *ios)
> +{
> +	u32 reg;
> +	int ret;
> +	unsigned int iov;
> +	struct sdhci_host *host = mmc_priv(mmc);
> +	struct sdhci_pltfm_host *pltfm_host;
> +	struct sdhci_omap_host *omap_host;
> +	struct device *dev;
> +
> +	pltfm_host = sdhci_priv(host);
> +	omap_host = sdhci_pltfm_priv(pltfm_host);
> +	dev = omap_host->dev;
> +
> +	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
> +		if (!(reg & (CAPA_VS33 | CAPA_VS30)))
> +			return -EOPNOTSUPP;
> +
> +		sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
> +
> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
> +		reg &= ~AC12_V1V8_SIGEN;
> +		sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
> +
> +		if (omap_host->io_3_3v_support)
> +			iov = IOV_3V3;
> +		else
> +			iov = IOV_3V0;
> +	} else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
> +		if (!(reg & CAPA_VS18))
> +			return -EOPNOTSUPP;
> +
> +		sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
> +
> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
> +		reg |= AC12_V1V8_SIGEN;
> +		sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
> +
> +		iov = IOV_1V8;
> +	} else {
> +		return -EOPNOTSUPP;
> +	}
> +
> +	ret = sdhci_omap_enable_iov(omap_host, iov);
> +	if (ret) {
> +		dev_err(dev, "failed to switch IO voltage to %dmV\n", iov);
> +		return ret;
> +	}
> +
> +	dev_dbg(dev, "IO voltage switched to %dmV\n", iov);
> +	return 0;
> +}
> +
> +static void sdhci_omap_set_bus_mode(struct sdhci_omap_host *omap_host,
> +				    unsigned int mode)
> +{
> +	u32 reg;
> +
> +	if (omap_host->bus_mode == mode)
> +		return;
> +
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
> +	if (mode == MMC_BUSMODE_OPENDRAIN)
> +		reg |= CON_OD;
> +	else
> +		reg &= ~CON_OD;
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
> +
> +	omap_host->bus_mode = mode;
> +}
> +
> +void sdhci_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> +{
> +	struct sdhci_host *host = mmc_priv(mmc);
> +	struct sdhci_pltfm_host *pltfm_host;
> +	struct sdhci_omap_host *omap_host;
> +
> +	pltfm_host = sdhci_priv(host);
> +	omap_host = sdhci_pltfm_priv(pltfm_host);
> +
> +	sdhci_omap_set_bus_mode(omap_host, ios->bus_mode);
> +	sdhci_set_ios(mmc, ios);
> +}
> +
> +static void sdhci_omap_set_capabilities(struct sdhci_omap_host *omap_host)
> +{
> +	u32 reg;
> +
> +	/* voltage capabilities might be set by boot loader, clear it */
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
> +	reg &= ~(CAPA_VS18 | CAPA_VS30 | CAPA_VS33);
> +
> +	if (omap_host->flags & SDHCI_OMAP_SUPPORTS_DUAL_VOLT) {
> +		if (omap_host->io_3_3v_support)
> +			reg |= (CAPA_VS33 | CAPA_VS18);
> +		else
> +			reg |= (CAPA_VS30 | CAPA_VS18);
> +	} else if (omap_host->flags & SDHCI_OMAP_NO_1_8_V) {
> +		if (omap_host->io_3_3v_support)
> +			reg |= CAPA_VS33;
> +		else
> +			reg |= CAPA_VS30;
> +	} else {
> +		reg |= CAPA_VS18;
> +	}
> +
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CAPA, reg);
> +}
> +
> +static u16 sdhci_omap_calc_divisor(struct sdhci_pltfm_host *host,
> +				   unsigned int clock)
> +{
> +	u16 dsor;
> +
> +	dsor = DIV_ROUND_UP(clk_get_rate(host->clk), clock);
> +	if (dsor > SYSCTL_CLKD_MAX)
> +		dsor = SYSCTL_CLKD_MAX;
> +
> +	return dsor;
> +}
> +
> +static void sdhci_omap_start_clock(struct sdhci_omap_host *omap_host)
> +{
> +	u32 reg;
> +
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
> +	reg |= SYSCTL_CEN;
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
> +}
> +
> +static void sdhci_omap_stop_clock(struct sdhci_omap_host *omap_host)
> +{
> +	u32 reg;
> +
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
> +	reg &= ~SYSCTL_CEN;
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
> +}
> +
> +static void sdhci_omap_set_clock(struct sdhci_host *host, unsigned int clock)
> +{
> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
> +	unsigned long clkdiv;
> +
> +	if (!clock)
> +		return;

Are you sure you don't want to stop the clock.

> +
> +	sdhci_omap_stop_clock(omap_host);
> +
> +	clkdiv = sdhci_omap_calc_divisor(pltfm_host, clock);
> +	clkdiv = (clkdiv & SYSCTL_CLKD_MASK) << SYSCTL_CLKD_SHIFT;
> +	sdhci_enable_clk(host, clkdiv);
> +
> +	sdhci_omap_start_clock(omap_host);
> +}
> +
> +void sdhci_omap_set_power(struct sdhci_host *host, unsigned char mode,
> +			  unsigned short vdd)
> +{
> +	struct mmc_host *mmc = host->mmc;
> +
> +	mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
> +}
> +
> +static int sdhci_omap_enable_dma(struct sdhci_host *host)
> +{
> +	u32 reg;
> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
> +
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
> +	reg |= CON_DMA_MASTER;
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
> +
> +	return 0;
> +}
> +
> +unsigned int sdhci_omap_get_min_clock(struct sdhci_host *host)
> +{
> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +
> +	return clk_get_rate(pltfm_host->clk) / SYSCTL_CLKD_MAX;
> +}
> +
> +static void sdhci_omap_set_bus_width(struct sdhci_host *host, int width)
> +{
> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
> +	u32 reg;
> +
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
> +	if (width == MMC_BUS_WIDTH_8)
> +		reg |= CON_DW8;
> +	else
> +		reg &= ~CON_DW8;
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
> +
> +	sdhci_set_bus_width(host, width);
> +}
> +
> +static void sdhci_omap_init_74_clocks(struct sdhci_host *host, u8 power_mode)
> +{
> +	u32 reg;
> +	ktime_t timeout;
> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
> +
> +	if (omap_host->power_mode == power_mode)
> +		return;
> +
> +	if (power_mode != MMC_POWER_ON)
> +		return;
> +
> +	disable_irq(host->irq);
> +
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
> +	reg |= CON_INIT;
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CMD, 0x0);
> +
> +	/* wait 1ms */
> +	timeout = ktime_add_ms(ktime_get(), MMC_TIMEOUT);
> +	while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_STAT) & INT_CC_EN)) {
> +		if (WARN_ON(ktime_after(ktime_get(), timeout)))
> +			return;
> +		usleep_range(5, 10);
> +	}
> +
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
> +	reg &= ~CON_INIT;
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_STAT, INT_CC_EN);
> +
> +	enable_irq(host->irq);
> +
> +	omap_host->power_mode = power_mode;
> +}
> +
> +static struct sdhci_ops sdhci_omap_ops = {
> +	.set_clock = sdhci_omap_set_clock,
> +	.set_power = sdhci_omap_set_power,
> +	.enable_dma = sdhci_omap_enable_dma,
> +	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
> +	.get_min_clock = sdhci_omap_get_min_clock,
> +	.set_bus_width = sdhci_omap_set_bus_width,
> +	.platform_send_init_74_clocks = sdhci_omap_init_74_clocks,
> +	.reset = sdhci_reset,
> +	.set_uhs_signaling = sdhci_set_uhs_signaling,
> +};
> +
> +void sdhci_omap_get_of_property(struct sdhci_omap_host *omap_host)
> +{
> +	struct device *dev = omap_host->dev;
> +	struct sdhci_host *host = omap_host->host;
> +	struct mmc_host *mmc = host->mmc;
> +
> +	if (device_property_read_bool(dev, "ti,dual-volt"))
> +		omap_host->flags |= SDHCI_OMAP_SUPPORTS_DUAL_VOLT;
> +
> +	if (device_property_read_bool(dev, "no-1-8-v"))
> +		omap_host->flags |= SDHCI_OMAP_NO_1_8_V;
> +
> +	if (device_property_read_bool(dev, "ti,non-removable"))
> +		mmc->caps |= MMC_CAP_NONREMOVABLE;
> +}
> +
> +static const struct sdhci_pltfm_data sdhci_omap_pdata = {
> +	.quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
> +		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
> +		  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
> +		  SDHCI_QUIRK_NO_HISPD_BIT |
> +		  SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC,
> +	.quirks2 = SDHCI_QUIRK2_NO_1_8_V |
> +		   SDHCI_QUIRK2_ACMD23_BROKEN |
> +		   SDHCI_QUIRK2_RSP_136_HAS_CRC,
> +	.ops = &sdhci_omap_ops,
> +};
> +
> +static const struct sdhci_omap_data dra7_data = {
> +	.offset = 0x200,
> +};
> +
> +static const struct of_device_id omap_sdhci_match[] = {
> +	{ .compatible = "ti,dra7-sdhci", .data = &dra7_data },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, omap_sdhci_match);
> +
> +static int sdhci_omap_probe(struct platform_device *pdev)
> +{
> +	int ret;
> +	u32 offset;
> +	struct device *dev = &pdev->dev;
> +	struct sdhci_host *host;
> +	struct sdhci_pltfm_host *pltfm_host;
> +	struct sdhci_omap_host *omap_host;
> +	struct mmc_host *mmc;
> +	const struct of_device_id *match;
> +	struct sdhci_omap_data *data;
> +
> +	match = of_match_device(omap_sdhci_match, dev);
> +	if (!match)
> +		return -EINVAL;
> +
> +	data = (struct sdhci_omap_data *)match->data;
> +	if (!data) {
> +		dev_err(dev, "no sdhci omap data\n");
> +		return -EINVAL;
> +	}
> +
> +	offset = data->offset;
> +
> +	host = sdhci_pltfm_init(pdev, &sdhci_omap_pdata,
> +				sizeof(*omap_host));
> +	if (IS_ERR(host)) {
> +		dev_err(dev, "Failed sdhci_pltfm_init\n");
> +		return PTR_ERR(host);
> +	}
> +
> +	pltfm_host = sdhci_priv(host);
> +	omap_host = sdhci_pltfm_priv(pltfm_host);
> +	omap_host->host = host;
> +	omap_host->base = host->ioaddr;
> +	omap_host->dev = dev;
> +	sdhci_omap_get_of_property(omap_host);
> +
> +	host->ioaddr += offset;
> +
> +	mmc = host->mmc;
> +	ret = mmc_of_parse(mmc);
> +	if (ret)
> +		goto err_of_parse;
> +
> +	pltfm_host->clk = devm_clk_get(dev, "fck");
> +	if (IS_ERR(pltfm_host->clk)) {
> +		ret = PTR_ERR(pltfm_host->clk);
> +		goto err_of_parse;
> +	}
> +
> +	ret = clk_set_rate(pltfm_host->clk, mmc->f_max);
> +	if (ret) {
> +		dev_err(dev, "failed to set clock to %d\n", mmc->f_max);
> +		goto err_of_parse;
> +	}
> +
> +	omap_host->pbias = devm_regulator_get_optional(dev, "pbias");
> +	if (IS_ERR(omap_host->pbias)) {
> +		ret = PTR_ERR(omap_host->pbias);
> +		if (ret != -ENODEV) {
> +			dev_err(dev, "CONFIG_REGULATOR_PBIAS not enabled??\n");
> +			return ret;
> +		}
> +		dev_dbg(dev, "unable to get pbias regulator %ld\n",
> +			PTR_ERR(omap_host->pbias));
> +	} else {
> +		if (regulator_is_supported_voltage(omap_host->pbias, IOV_3V3,
> +						   IOV_3V3))
> +			omap_host->io_3_3v_support = true;
> +		dev_vdbg(dev, "Max PBIAS support Voltage: %dmv\n",
> +			 omap_host->io_3_3v_support ? IOV_3V3 : IOV_3V0);
> +	}
> +	omap_host->pbias_enabled = false;
> +
> +	/* Enable main Func clock, interface clock and program SYSCONFIG */

Maybe also mention that the PM domain does those things.  Out of curiousity,
what happens if CONFIG_PM is not set?

> +	pm_runtime_enable(dev);
> +	ret = pm_runtime_get_sync(dev);
> +	if (ret < 0) {
> +		dev_err(dev, "pm_runtime_get_sync failed\n");
> +		goto err_get_sync;

The correct "undo" function for pm_runtime_get_sync() failing is
pm_runtime_put_noidle() not pm_runtime_put_sync().  So:

		pm_runtime_put_noidle(dev);
		goto err_rpm_disable;

> +	}
> +
> +	sdhci_omap_set_capabilities(omap_host);
> +
> +	host->mmc_host_ops.get_ro = mmc_gpio_get_ro;
> +	host->mmc_host_ops.start_signal_voltage_switch =
> +					sdhci_omap_start_signal_voltage_switch;
> +	host->mmc_host_ops.set_ios = sdhci_omap_set_ios;
> +
> +	sdhci_read_caps(host);
> +	host->caps |= SDHCI_CAN_DO_ADMA2;
> +
> +	ret = sdhci_add_host(host);
> +	if (ret)
> +		goto err_get_sync;
> +
> +	return 0;
> +
> +err_get_sync:

It is more usual for error labels to describe what they will do rather than
what failed. i.e. this would be err_put_sync:

> +	pm_runtime_put_sync(dev);

err_rpm_disable:

> +	pm_runtime_disable(dev);
> +
> +err_of_parse:

err_pltfm_free:

> +	sdhci_pltfm_free(pdev);
> +	return ret;
> +}
> +
> +static int sdhci_omap_remove(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct sdhci_host *host = platform_get_drvdata(pdev);
> +
> +	sdhci_remove_host(host, true);
> +	pm_runtime_put_sync(dev);
> +	pm_runtime_disable(dev);
> +	sdhci_pltfm_free(pdev);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver sdhci_omap_driver = {
> +	.probe = sdhci_omap_probe,
> +	.remove = sdhci_omap_remove,
> +	.driver = {
> +		   .name = "sdhci-omap",
> +		   .of_match_table = of_match_ptr(omap_sdhci_match),

Don't you need #ifdef CONFIG_OF around the table if you use of_match_ptr()?

> +		  },
> +};
> +
> +module_platform_driver(sdhci_omap_driver);
> +
> +MODULE_DESCRIPTION("SDHCI driver for OMAP SoCs");
> +MODULE_AUTHOR("Texas Instruments Inc.");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("OMAP SDHCI Driver");

A module alias with spaces in it looks strange.  Is that the intention?

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH 4/5] mmc: sdhci-omap: Add OMAP SDHCI driver
@ 2017-08-28  9:06     ` Adrian Hunter
  0 siblings, 0 replies; 86+ messages in thread
From: Adrian Hunter @ 2017-08-28  9:06 UTC (permalink / raw)
  To: linux-arm-kernel

On 21/08/17 10:41, Kishon Vijay Abraham I wrote:
> Create a new sdhci-omap driver to configure the eMMC/SD/SDIO controller
> in TI's OMAP SoCs making use of the SDHCI core library. For OMAP specific
> configurations, populate sdhci_ops with OMAP specific callbacks and use
> SDHCI quirks.
> Enable only high speed mode for both SD and eMMC here and add other
> UHS mode support later.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

There are a few minor comments below.

> ---
>  drivers/mmc/host/Kconfig      |  12 +
>  drivers/mmc/host/Makefile     |   1 +
>  drivers/mmc/host/sdhci-omap.c | 629 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 642 insertions(+)
>  create mode 100644 drivers/mmc/host/sdhci-omap.c
> 
> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
> index 60f90d49e7a9..60d50843e165 100644
> --- a/drivers/mmc/host/Kconfig
> +++ b/drivers/mmc/host/Kconfig
> @@ -899,3 +899,15 @@ config MMC_SDHCI_XENON
>  	  This selects Marvell Xenon eMMC/SD/SDIO SDHCI.
>  	  If you have a controller with this interface, say Y or M here.
>  	  If unsure, say N.
> +
> +config MMC_SDHCI_OMAP
> +	tristate "TI SDHCI Controller Support"
> +	depends on MMC_SDHCI_PLTFM
> +	help
> +	  This selects the Secure Digital Host Controller Interface (SDHCI)
> +	  support present in TI's DRA7 SOCs. The controller supports
> +	  SD/MMC/SDIO devices.
> +
> +	  If you have a controller with this interface, say Y or M here.
> +
> +	  If unsure, say N.
> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
> index 8c46766c000c..33181df88a10 100644
> --- a/drivers/mmc/host/Makefile
> +++ b/drivers/mmc/host/Makefile
> @@ -88,6 +88,7 @@ obj-$(CONFIG_MMC_SDHCI_MSM)		+= sdhci-msm.o
>  obj-$(CONFIG_MMC_SDHCI_ST)		+= sdhci-st.o
>  obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32)	+= sdhci-pic32.o
>  obj-$(CONFIG_MMC_SDHCI_BRCMSTB)		+= sdhci-brcmstb.o
> +obj-$(CONFIG_MMC_SDHCI_OMAP)		+= sdhci-omap.o
>  
>  ifeq ($(CONFIG_CB710_DEBUG),y)
>  	CFLAGS-cb710-mmc	+= -DDEBUG
> diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c
> new file mode 100644
> index 000000000000..73ee3b4a400c
> --- /dev/null
> +++ b/drivers/mmc/host/sdhci-omap.c
> @@ -0,0 +1,629 @@
> +/**
> + * SDHCI Controller driver for TI's OMAP SoCs
> + *
> + * Copyright (C) 2017 Texas Instruments
> + * Author: Kishon Vijay Abraham I <kishon@ti.com>
> + *
> + * This program is free software: you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 of
> + * the License as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/mmc/slot-gpio.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/regulator/consumer.h>
> +
> +#include "sdhci-pltfm.h"
> +
> +#define SDHCI_OMAP_CON		0x12c
> +#define CON_DW8			BIT(5)
> +#define CON_DMA_MASTER		BIT(20)
> +#define CON_INIT		BIT(1)
> +#define CON_OD			BIT(0)
> +
> +#define SDHCI_OMAP_CMD		0x20c
> +
> +#define SDHCI_OMAP_HCTL		0x228
> +#define HCTL_SDBP		BIT(8)
> +#define HCTL_SDVS_SHIFT		9
> +#define HCTL_SDVS_MASK		(0x7 << HCTL_SDVS_SHIFT)
> +#define HCTL_SDVS_33		(0x7 << HCTL_SDVS_SHIFT)
> +#define HCTL_SDVS_30		(0x6 << HCTL_SDVS_SHIFT)
> +#define HCTL_SDVS_18		(0x5 << HCTL_SDVS_SHIFT)
> +
> +#define SDHCI_OMAP_SYSCTL	0x22c
> +#define SYSCTL_CEN		BIT(2)
> +#define SYSCTL_CLKD_SHIFT	6
> +#define SYSCTL_CLKD_MASK	0x3ff
> +
> +#define SDHCI_OMAP_STAT		0x230
> +
> +#define SDHCI_OMAP_IE		0x234
> +#define INT_CC_EN		BIT(0)
> +
> +#define SDHCI_OMAP_AC12		0x23c
> +#define AC12_V1V8_SIGEN		BIT(19)
> +
> +#define SDHCI_OMAP_CAPA		0x240
> +#define CAPA_VS33		BIT(24)
> +#define CAPA_VS30		BIT(25)
> +#define CAPA_VS18		BIT(26)
> +
> +#define MMC_TIMEOUT		1		/* 1 msec */

As before, SDHCI_OMAP_TIMEOUT is a better name

> +
> +#define SYSCTL_CLKD_MAX		0x3FF
> +
> +#define IOV_1V8			1800000		/* 180000 uV */
> +#define IOV_3V0			3000000		/* 300000 uV */
> +#define IOV_3V3			3300000		/* 330000 uV */
> +
> +struct sdhci_omap_data {
> +	u32 offset;
> +};
> +
> +struct sdhci_omap_host {
> +	void __iomem		*base;
> +	struct device		*dev;
> +	struct	regulator	*pbias;
> +	bool			pbias_enabled;
> +	struct sdhci_host	*host;
> +	unsigned int		flags;
> +
> +#define SDHCI_OMAP_SUPPORTS_DUAL_VOLT	BIT(0)
> +#define SDHCI_OMAP_NO_1_8_V		BIT(1)
> +
> +	u8			bus_mode;
> +	u8			power_mode;
> +	bool			io_3_3v_support;
> +};
> +
> +static inline u32 sdhci_omap_readl(struct sdhci_omap_host *host,
> +				   unsigned int offset)
> +{
> +	return readl(host->base + offset);
> +}
> +
> +static inline void sdhci_omap_writel(struct sdhci_omap_host *host,
> +				     unsigned int offset, u32 data)
> +{
> +	writel(data, host->base + offset);
> +}
> +
> +static int sdhci_omap_set_pbias(struct sdhci_omap_host *omap_host,
> +				bool power_on, unsigned int iov)
> +{
> +	int ret;
> +	struct device *dev = omap_host->dev;
> +
> +	if (IS_ERR(omap_host->pbias))
> +		return 0;
> +
> +	if (power_on) {
> +		ret = regulator_set_voltage(omap_host->pbias, iov, iov);
> +		if (ret) {
> +			dev_err(dev, "pbias set voltage failed\n");
> +			return ret;
> +		}
> +
> +		if (omap_host->pbias_enabled)
> +			return 0;
> +
> +		ret = regulator_enable(omap_host->pbias);
> +		if (ret) {
> +			dev_err(dev, "pbias reg enable fail\n");
> +			return ret;
> +		}
> +
> +		omap_host->pbias_enabled = true;
> +	} else {
> +		if (!omap_host->pbias_enabled)
> +			return 0;
> +
> +		ret = regulator_disable(omap_host->pbias);
> +		if (ret) {
> +			dev_err(dev, "pbias reg disable fail\n");
> +			return ret;
> +		}
> +		omap_host->pbias_enabled = false;
> +	}
> +
> +	return 0;
> +}
> +
> +static int sdhci_omap_enable_iov(struct sdhci_omap_host *omap_host,
> +				 unsigned int iov)
> +{
> +	int ret;
> +	struct sdhci_host *host = omap_host->host;
> +	struct mmc_host *mmc = host->mmc;
> +
> +	ret = sdhci_omap_set_pbias(omap_host, false, 0);
> +	if (ret)
> +		return ret;
> +
> +	if (!IS_ERR(mmc->supply.vqmmc)) {
> +		ret = regulator_set_voltage(mmc->supply.vqmmc, iov, iov);
> +		if (ret) {
> +			dev_err(mmc_dev(mmc), "vqmmc set voltage failed\n");
> +			return ret;
> +		}
> +	}
> +
> +	ret = sdhci_omap_set_pbias(omap_host, true, iov);
> +	if (ret)
> +		return ret;
> +
> +	return 0;
> +}
> +
> +static void sdhci_omap_conf_bus_power(struct sdhci_omap_host *omap_host,
> +				      unsigned char signal_voltage)
> +{
> +	u32 reg;
> +	ktime_t timeout;
> +
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL);
> +	reg &= ~HCTL_SDVS_MASK;
> +
> +	if (signal_voltage == MMC_SIGNAL_VOLTAGE_180)
> +		reg |= HCTL_SDVS_18;
> +	else if (omap_host->io_3_3v_support)
> +		reg |= HCTL_SDVS_33;
> +	else
> +		reg |= HCTL_SDVS_30;
> +
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
> +
> +	reg |= HCTL_SDBP;
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
> +
> +	/* wait 1ms */
> +	timeout = ktime_add_ms(ktime_get(), MMC_TIMEOUT);
> +	while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL) & HCTL_SDBP)) {
> +		if (WARN_ON(ktime_after(ktime_get(), timeout)))
> +			return;
> +		usleep_range(5, 10);
> +	}
> +}
> +
> +static int sdhci_omap_start_signal_voltage_switch(struct mmc_host *mmc,
> +						  struct mmc_ios *ios)
> +{
> +	u32 reg;
> +	int ret;
> +	unsigned int iov;
> +	struct sdhci_host *host = mmc_priv(mmc);
> +	struct sdhci_pltfm_host *pltfm_host;
> +	struct sdhci_omap_host *omap_host;
> +	struct device *dev;
> +
> +	pltfm_host = sdhci_priv(host);
> +	omap_host = sdhci_pltfm_priv(pltfm_host);
> +	dev = omap_host->dev;
> +
> +	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
> +		if (!(reg & (CAPA_VS33 | CAPA_VS30)))
> +			return -EOPNOTSUPP;
> +
> +		sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
> +
> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
> +		reg &= ~AC12_V1V8_SIGEN;
> +		sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
> +
> +		if (omap_host->io_3_3v_support)
> +			iov = IOV_3V3;
> +		else
> +			iov = IOV_3V0;
> +	} else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
> +		if (!(reg & CAPA_VS18))
> +			return -EOPNOTSUPP;
> +
> +		sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
> +
> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
> +		reg |= AC12_V1V8_SIGEN;
> +		sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
> +
> +		iov = IOV_1V8;
> +	} else {
> +		return -EOPNOTSUPP;
> +	}
> +
> +	ret = sdhci_omap_enable_iov(omap_host, iov);
> +	if (ret) {
> +		dev_err(dev, "failed to switch IO voltage to %dmV\n", iov);
> +		return ret;
> +	}
> +
> +	dev_dbg(dev, "IO voltage switched to %dmV\n", iov);
> +	return 0;
> +}
> +
> +static void sdhci_omap_set_bus_mode(struct sdhci_omap_host *omap_host,
> +				    unsigned int mode)
> +{
> +	u32 reg;
> +
> +	if (omap_host->bus_mode == mode)
> +		return;
> +
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
> +	if (mode == MMC_BUSMODE_OPENDRAIN)
> +		reg |= CON_OD;
> +	else
> +		reg &= ~CON_OD;
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
> +
> +	omap_host->bus_mode = mode;
> +}
> +
> +void sdhci_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
> +{
> +	struct sdhci_host *host = mmc_priv(mmc);
> +	struct sdhci_pltfm_host *pltfm_host;
> +	struct sdhci_omap_host *omap_host;
> +
> +	pltfm_host = sdhci_priv(host);
> +	omap_host = sdhci_pltfm_priv(pltfm_host);
> +
> +	sdhci_omap_set_bus_mode(omap_host, ios->bus_mode);
> +	sdhci_set_ios(mmc, ios);
> +}
> +
> +static void sdhci_omap_set_capabilities(struct sdhci_omap_host *omap_host)
> +{
> +	u32 reg;
> +
> +	/* voltage capabilities might be set by boot loader, clear it */
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
> +	reg &= ~(CAPA_VS18 | CAPA_VS30 | CAPA_VS33);
> +
> +	if (omap_host->flags & SDHCI_OMAP_SUPPORTS_DUAL_VOLT) {
> +		if (omap_host->io_3_3v_support)
> +			reg |= (CAPA_VS33 | CAPA_VS18);
> +		else
> +			reg |= (CAPA_VS30 | CAPA_VS18);
> +	} else if (omap_host->flags & SDHCI_OMAP_NO_1_8_V) {
> +		if (omap_host->io_3_3v_support)
> +			reg |= CAPA_VS33;
> +		else
> +			reg |= CAPA_VS30;
> +	} else {
> +		reg |= CAPA_VS18;
> +	}
> +
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CAPA, reg);
> +}
> +
> +static u16 sdhci_omap_calc_divisor(struct sdhci_pltfm_host *host,
> +				   unsigned int clock)
> +{
> +	u16 dsor;
> +
> +	dsor = DIV_ROUND_UP(clk_get_rate(host->clk), clock);
> +	if (dsor > SYSCTL_CLKD_MAX)
> +		dsor = SYSCTL_CLKD_MAX;
> +
> +	return dsor;
> +}
> +
> +static void sdhci_omap_start_clock(struct sdhci_omap_host *omap_host)
> +{
> +	u32 reg;
> +
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
> +	reg |= SYSCTL_CEN;
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
> +}
> +
> +static void sdhci_omap_stop_clock(struct sdhci_omap_host *omap_host)
> +{
> +	u32 reg;
> +
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
> +	reg &= ~SYSCTL_CEN;
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
> +}
> +
> +static void sdhci_omap_set_clock(struct sdhci_host *host, unsigned int clock)
> +{
> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
> +	unsigned long clkdiv;
> +
> +	if (!clock)
> +		return;

Are you sure you don't want to stop the clock.

> +
> +	sdhci_omap_stop_clock(omap_host);
> +
> +	clkdiv = sdhci_omap_calc_divisor(pltfm_host, clock);
> +	clkdiv = (clkdiv & SYSCTL_CLKD_MASK) << SYSCTL_CLKD_SHIFT;
> +	sdhci_enable_clk(host, clkdiv);
> +
> +	sdhci_omap_start_clock(omap_host);
> +}
> +
> +void sdhci_omap_set_power(struct sdhci_host *host, unsigned char mode,
> +			  unsigned short vdd)
> +{
> +	struct mmc_host *mmc = host->mmc;
> +
> +	mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
> +}
> +
> +static int sdhci_omap_enable_dma(struct sdhci_host *host)
> +{
> +	u32 reg;
> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
> +
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
> +	reg |= CON_DMA_MASTER;
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
> +
> +	return 0;
> +}
> +
> +unsigned int sdhci_omap_get_min_clock(struct sdhci_host *host)
> +{
> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +
> +	return clk_get_rate(pltfm_host->clk) / SYSCTL_CLKD_MAX;
> +}
> +
> +static void sdhci_omap_set_bus_width(struct sdhci_host *host, int width)
> +{
> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
> +	u32 reg;
> +
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
> +	if (width == MMC_BUS_WIDTH_8)
> +		reg |= CON_DW8;
> +	else
> +		reg &= ~CON_DW8;
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
> +
> +	sdhci_set_bus_width(host, width);
> +}
> +
> +static void sdhci_omap_init_74_clocks(struct sdhci_host *host, u8 power_mode)
> +{
> +	u32 reg;
> +	ktime_t timeout;
> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
> +
> +	if (omap_host->power_mode == power_mode)
> +		return;
> +
> +	if (power_mode != MMC_POWER_ON)
> +		return;
> +
> +	disable_irq(host->irq);
> +
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
> +	reg |= CON_INIT;
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CMD, 0x0);
> +
> +	/* wait 1ms */
> +	timeout = ktime_add_ms(ktime_get(), MMC_TIMEOUT);
> +	while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_STAT) & INT_CC_EN)) {
> +		if (WARN_ON(ktime_after(ktime_get(), timeout)))
> +			return;
> +		usleep_range(5, 10);
> +	}
> +
> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
> +	reg &= ~CON_INIT;
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_STAT, INT_CC_EN);
> +
> +	enable_irq(host->irq);
> +
> +	omap_host->power_mode = power_mode;
> +}
> +
> +static struct sdhci_ops sdhci_omap_ops = {
> +	.set_clock = sdhci_omap_set_clock,
> +	.set_power = sdhci_omap_set_power,
> +	.enable_dma = sdhci_omap_enable_dma,
> +	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
> +	.get_min_clock = sdhci_omap_get_min_clock,
> +	.set_bus_width = sdhci_omap_set_bus_width,
> +	.platform_send_init_74_clocks = sdhci_omap_init_74_clocks,
> +	.reset = sdhci_reset,
> +	.set_uhs_signaling = sdhci_set_uhs_signaling,
> +};
> +
> +void sdhci_omap_get_of_property(struct sdhci_omap_host *omap_host)
> +{
> +	struct device *dev = omap_host->dev;
> +	struct sdhci_host *host = omap_host->host;
> +	struct mmc_host *mmc = host->mmc;
> +
> +	if (device_property_read_bool(dev, "ti,dual-volt"))
> +		omap_host->flags |= SDHCI_OMAP_SUPPORTS_DUAL_VOLT;
> +
> +	if (device_property_read_bool(dev, "no-1-8-v"))
> +		omap_host->flags |= SDHCI_OMAP_NO_1_8_V;
> +
> +	if (device_property_read_bool(dev, "ti,non-removable"))
> +		mmc->caps |= MMC_CAP_NONREMOVABLE;
> +}
> +
> +static const struct sdhci_pltfm_data sdhci_omap_pdata = {
> +	.quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
> +		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
> +		  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
> +		  SDHCI_QUIRK_NO_HISPD_BIT |
> +		  SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC,
> +	.quirks2 = SDHCI_QUIRK2_NO_1_8_V |
> +		   SDHCI_QUIRK2_ACMD23_BROKEN |
> +		   SDHCI_QUIRK2_RSP_136_HAS_CRC,
> +	.ops = &sdhci_omap_ops,
> +};
> +
> +static const struct sdhci_omap_data dra7_data = {
> +	.offset = 0x200,
> +};
> +
> +static const struct of_device_id omap_sdhci_match[] = {
> +	{ .compatible = "ti,dra7-sdhci", .data = &dra7_data },
> +	{},
> +};
> +MODULE_DEVICE_TABLE(of, omap_sdhci_match);
> +
> +static int sdhci_omap_probe(struct platform_device *pdev)
> +{
> +	int ret;
> +	u32 offset;
> +	struct device *dev = &pdev->dev;
> +	struct sdhci_host *host;
> +	struct sdhci_pltfm_host *pltfm_host;
> +	struct sdhci_omap_host *omap_host;
> +	struct mmc_host *mmc;
> +	const struct of_device_id *match;
> +	struct sdhci_omap_data *data;
> +
> +	match = of_match_device(omap_sdhci_match, dev);
> +	if (!match)
> +		return -EINVAL;
> +
> +	data = (struct sdhci_omap_data *)match->data;
> +	if (!data) {
> +		dev_err(dev, "no sdhci omap data\n");
> +		return -EINVAL;
> +	}
> +
> +	offset = data->offset;
> +
> +	host = sdhci_pltfm_init(pdev, &sdhci_omap_pdata,
> +				sizeof(*omap_host));
> +	if (IS_ERR(host)) {
> +		dev_err(dev, "Failed sdhci_pltfm_init\n");
> +		return PTR_ERR(host);
> +	}
> +
> +	pltfm_host = sdhci_priv(host);
> +	omap_host = sdhci_pltfm_priv(pltfm_host);
> +	omap_host->host = host;
> +	omap_host->base = host->ioaddr;
> +	omap_host->dev = dev;
> +	sdhci_omap_get_of_property(omap_host);
> +
> +	host->ioaddr += offset;
> +
> +	mmc = host->mmc;
> +	ret = mmc_of_parse(mmc);
> +	if (ret)
> +		goto err_of_parse;
> +
> +	pltfm_host->clk = devm_clk_get(dev, "fck");
> +	if (IS_ERR(pltfm_host->clk)) {
> +		ret = PTR_ERR(pltfm_host->clk);
> +		goto err_of_parse;
> +	}
> +
> +	ret = clk_set_rate(pltfm_host->clk, mmc->f_max);
> +	if (ret) {
> +		dev_err(dev, "failed to set clock to %d\n", mmc->f_max);
> +		goto err_of_parse;
> +	}
> +
> +	omap_host->pbias = devm_regulator_get_optional(dev, "pbias");
> +	if (IS_ERR(omap_host->pbias)) {
> +		ret = PTR_ERR(omap_host->pbias);
> +		if (ret != -ENODEV) {
> +			dev_err(dev, "CONFIG_REGULATOR_PBIAS not enabled??\n");
> +			return ret;
> +		}
> +		dev_dbg(dev, "unable to get pbias regulator %ld\n",
> +			PTR_ERR(omap_host->pbias));
> +	} else {
> +		if (regulator_is_supported_voltage(omap_host->pbias, IOV_3V3,
> +						   IOV_3V3))
> +			omap_host->io_3_3v_support = true;
> +		dev_vdbg(dev, "Max PBIAS support Voltage: %dmv\n",
> +			 omap_host->io_3_3v_support ? IOV_3V3 : IOV_3V0);
> +	}
> +	omap_host->pbias_enabled = false;
> +
> +	/* Enable main Func clock, interface clock and program SYSCONFIG */

Maybe also mention that the PM domain does those things.  Out of curiousity,
what happens if CONFIG_PM is not set?

> +	pm_runtime_enable(dev);
> +	ret = pm_runtime_get_sync(dev);
> +	if (ret < 0) {
> +		dev_err(dev, "pm_runtime_get_sync failed\n");
> +		goto err_get_sync;

The correct "undo" function for pm_runtime_get_sync() failing is
pm_runtime_put_noidle() not pm_runtime_put_sync().  So:

		pm_runtime_put_noidle(dev);
		goto err_rpm_disable;

> +	}
> +
> +	sdhci_omap_set_capabilities(omap_host);
> +
> +	host->mmc_host_ops.get_ro = mmc_gpio_get_ro;
> +	host->mmc_host_ops.start_signal_voltage_switch =
> +					sdhci_omap_start_signal_voltage_switch;
> +	host->mmc_host_ops.set_ios = sdhci_omap_set_ios;
> +
> +	sdhci_read_caps(host);
> +	host->caps |= SDHCI_CAN_DO_ADMA2;
> +
> +	ret = sdhci_add_host(host);
> +	if (ret)
> +		goto err_get_sync;
> +
> +	return 0;
> +
> +err_get_sync:

It is more usual for error labels to describe what they will do rather than
what failed. i.e. this would be err_put_sync:

> +	pm_runtime_put_sync(dev);

err_rpm_disable:

> +	pm_runtime_disable(dev);
> +
> +err_of_parse:

err_pltfm_free:

> +	sdhci_pltfm_free(pdev);
> +	return ret;
> +}
> +
> +static int sdhci_omap_remove(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct sdhci_host *host = platform_get_drvdata(pdev);
> +
> +	sdhci_remove_host(host, true);
> +	pm_runtime_put_sync(dev);
> +	pm_runtime_disable(dev);
> +	sdhci_pltfm_free(pdev);
> +
> +	return 0;
> +}
> +
> +static struct platform_driver sdhci_omap_driver = {
> +	.probe = sdhci_omap_probe,
> +	.remove = sdhci_omap_remove,
> +	.driver = {
> +		   .name = "sdhci-omap",
> +		   .of_match_table = of_match_ptr(omap_sdhci_match),

Don't you need #ifdef CONFIG_OF around the table if you use of_match_ptr()?

> +		  },
> +};
> +
> +module_platform_driver(sdhci_omap_driver);
> +
> +MODULE_DESCRIPTION("SDHCI driver for OMAP SoCs");
> +MODULE_AUTHOR("Texas Instruments Inc.");
> +MODULE_LICENSE("GPL v2");
> +MODULE_ALIAS("OMAP SDHCI Driver");

A module alias with spaces in it looks strange.  Is that the intention?

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH 5/5] MAINTAINERS: Add TI OMAP SDHCI Maintainer
  2017-08-21  7:41   ` Kishon Vijay Abraham I
@ 2017-08-28  9:07     ` Adrian Hunter
  -1 siblings, 0 replies; 86+ messages in thread
From: Adrian Hunter @ 2017-08-28  9:07 UTC (permalink / raw)
  To: Kishon Vijay Abraham I, Ulf Hansson
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel

On 21/08/17 10:41, Kishon Vijay Abraham I wrote:
> Add Maintainer for the TI OMAP SDHCI driver.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

Acked-by: Adrian Hunter <adrian.hunter@intel.com>

> ---
>  MAINTAINERS | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 44cb004c765d..c9871351c16f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11777,6 +11777,12 @@ L:	linux-mmc@vger.kernel.org
>  S:	Maintained
>  F:	drivers/mmc/host/sdhci-spear.c
>  
> +SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) TI OMAP DRIVER
> +M:	Kishon Vijay Abraham I <kishon@ti.com>
> +L:	linux-mmc@vger.kernel.org
> +S:	Maintained
> +F:	drivers/mmc/host/sdhci-omap.c
> +
>  SECURE ENCRYPTING DEVICE (SED) OPAL DRIVER
>  M:	Scott Bauer <scott.bauer@intel.com>
>  M:	Jonathan Derrick <jonathan.derrick@intel.com>
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH 5/5] MAINTAINERS: Add TI OMAP SDHCI Maintainer
@ 2017-08-28  9:07     ` Adrian Hunter
  0 siblings, 0 replies; 86+ messages in thread
From: Adrian Hunter @ 2017-08-28  9:07 UTC (permalink / raw)
  To: linux-arm-kernel

On 21/08/17 10:41, Kishon Vijay Abraham I wrote:
> Add Maintainer for the TI OMAP SDHCI driver.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

Acked-by: Adrian Hunter <adrian.hunter@intel.com>

> ---
>  MAINTAINERS | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 44cb004c765d..c9871351c16f 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11777,6 +11777,12 @@ L:	linux-mmc at vger.kernel.org
>  S:	Maintained
>  F:	drivers/mmc/host/sdhci-spear.c
>  
> +SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) TI OMAP DRIVER
> +M:	Kishon Vijay Abraham I <kishon@ti.com>
> +L:	linux-mmc at vger.kernel.org
> +S:	Maintained
> +F:	drivers/mmc/host/sdhci-omap.c
> +
>  SECURE ENCRYPTING DEVICE (SED) OPAL DRIVER
>  M:	Scott Bauer <scott.bauer@intel.com>
>  M:	Jonathan Derrick <jonathan.derrick@intel.com>
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
  2017-08-24 11:29             ` Ulf Hansson
  (?)
@ 2017-08-29 11:20               ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-29 11:20 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Adrian Hunter, Rob Herring, Tony Lindgren, Sekhar Nori,
	Russell King, Ravikumar Kattekola, linux-mmc, devicetree,
	linux-kernel, linux-omap, linux-arm-kernel

Hi Uffe,

On Thursday 24 August 2017 04:59 PM, Ulf Hansson wrote:
> On 23 August 2017 at 15:56, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>> Hi Uffe,
>>
>> On Wednesday 23 August 2017 06:37 PM, Ulf Hansson wrote:
>>> On 23 August 2017 at 07:42, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>>>> Add binding for the TI's sdhci-omap controller. This now includes only
>>>> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
>>>> include all the properties.
>>>>
>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>>> ---
>>>> Changes from v2:
>>>> *) Fixed example to use the updated compatible
>>>>
>>>> Changes from v1:
>>>> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>>>>    of using the ti-omap-hsmmc.txt as suggested by Tony
>>>>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>>>>  1 file changed, 22 insertions(+)
>>>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>>> new file mode 100644
>>>> index 000000000000..139695ad2d58
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>>> @@ -0,0 +1,22 @@
>>>> +* TI OMAP SDHCI Controller
>>>> +
>>>> +Refer to mmc.txt for standard MMC bindings.
>>>> +
>>>> +Required properties:
>>>> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
>>>> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
>>>> +
>>>> +Optional properties:
>>>> +- ti,dual-volt: boolean, supports dual voltage cards
>>>> +- ti,non-removable: non-removable slot (like eMMC)
>>>> +
>>>> +Example:
>>>> +       mmc1: mmc@0x4809c000 {
>>>> +               compatible = "ti,dra7-sdhci";
>>>> +               reg = <0x4809c000 0x400>;
>>>> +               ti,hwmods = "mmc1";
>>>> +               ti,dual-volt;
>>>> +               bus-width = <4>;
>>>> +               vmmc-supply = <&vmmc>; /* phandle to regulator node */
>>>> +               ti,non-removable;
>>>> +       };
>>>> --
>>>> 2.11.0
>>>>
>>>
>>> I am wondering a bit on the long term plan here.
>>>
>>> Ideally at some point in future, we would like to remove the old
>>> omap_hsmmc driver, but from compatible string point of view, that
>>> means we first needs to deprecate the old ones for a while. Right?
>>
>> right but sdhci-omap is still lacking features that was present in omap_hsmmc
>> like context save/restore, SDIO support etc. I think we should deprecate
>> omap_hsmmc compatible once we add all the features in sdhci-omap?
>>>
>>> That said, what is then the reason to why we should bring over the
>>> existing omap_hsmmc bindings to the sdhci-omap bindings?
>>
>> This is mainly for old dt compatibility. Even after removing the omap_hsmmc
>> driver, users should still be able to use newer kernel with their existing dtbs.
> 
> I guess we have two options.
> 
> 1) Allow us to invent and use new bindings - and a new compatible.
> When everything is implemented in sdhci-omap, we can deprecate the old
> omap_hsmmc driver and its corresponding compatible/bindings. At some
> point later we can remove the legacy driver/bindings altogether - of
> course that might take a while. This option allows us to re-think some
> of the old bindings and really clean up some if its related code. For
> example, I think "ti,dual-volt" is a bad binding. Instead it would be
> better to use the existing mmc bindings about which speed mode the
> controller/board supports (as the voltage level comes with it).
> 
> 2) Invent only a new compatible, but stick to use the old omap hsmmc
> bindings and thus also deploy the similar code dealing with them. When
> everything is implemented move the old omap_hsmmc compatibles into the
> new sdhci-omap driver and them remove the old omap_hsmmc driver. At
> that point we could also deprecate the old omap hsmmc compatibles, but
> to me that is rather pointless.
> 
> The two options has different advantages, feel free to pick any of them!

Okay. I'll send a new version with option '1' (new compatible/new bindings).

And when we deprecate the omap_hsmmc driver (some time later), we'll add
support for the legacy bindings in sdhci-omap driver (so that old dtbs continue
to work). Tony, are you okay with this?

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-29 11:20               ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-29 11:20 UTC (permalink / raw)
  To: Ulf Hansson
  Cc: Adrian Hunter, Rob Herring, Tony Lindgren, Sekhar Nori,
	Russell King, Ravikumar Kattekola, linux-mmc, devicetree,
	linux-kernel, linux-omap, linux-arm-kernel

Hi Uffe,

On Thursday 24 August 2017 04:59 PM, Ulf Hansson wrote:
> On 23 August 2017 at 15:56, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>> Hi Uffe,
>>
>> On Wednesday 23 August 2017 06:37 PM, Ulf Hansson wrote:
>>> On 23 August 2017 at 07:42, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>>>> Add binding for the TI's sdhci-omap controller. This now includes only
>>>> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
>>>> include all the properties.
>>>>
>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>>> ---
>>>> Changes from v2:
>>>> *) Fixed example to use the updated compatible
>>>>
>>>> Changes from v1:
>>>> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>>>>    of using the ti-omap-hsmmc.txt as suggested by Tony
>>>>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>>>>  1 file changed, 22 insertions(+)
>>>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>>> new file mode 100644
>>>> index 000000000000..139695ad2d58
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>>> @@ -0,0 +1,22 @@
>>>> +* TI OMAP SDHCI Controller
>>>> +
>>>> +Refer to mmc.txt for standard MMC bindings.
>>>> +
>>>> +Required properties:
>>>> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
>>>> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
>>>> +
>>>> +Optional properties:
>>>> +- ti,dual-volt: boolean, supports dual voltage cards
>>>> +- ti,non-removable: non-removable slot (like eMMC)
>>>> +
>>>> +Example:
>>>> +       mmc1: mmc@0x4809c000 {
>>>> +               compatible = "ti,dra7-sdhci";
>>>> +               reg = <0x4809c000 0x400>;
>>>> +               ti,hwmods = "mmc1";
>>>> +               ti,dual-volt;
>>>> +               bus-width = <4>;
>>>> +               vmmc-supply = <&vmmc>; /* phandle to regulator node */
>>>> +               ti,non-removable;
>>>> +       };
>>>> --
>>>> 2.11.0
>>>>
>>>
>>> I am wondering a bit on the long term plan here.
>>>
>>> Ideally at some point in future, we would like to remove the old
>>> omap_hsmmc driver, but from compatible string point of view, that
>>> means we first needs to deprecate the old ones for a while. Right?
>>
>> right but sdhci-omap is still lacking features that was present in omap_hsmmc
>> like context save/restore, SDIO support etc. I think we should deprecate
>> omap_hsmmc compatible once we add all the features in sdhci-omap?
>>>
>>> That said, what is then the reason to why we should bring over the
>>> existing omap_hsmmc bindings to the sdhci-omap bindings?
>>
>> This is mainly for old dt compatibility. Even after removing the omap_hsmmc
>> driver, users should still be able to use newer kernel with their existing dtbs.
> 
> I guess we have two options.
> 
> 1) Allow us to invent and use new bindings - and a new compatible.
> When everything is implemented in sdhci-omap, we can deprecate the old
> omap_hsmmc driver and its corresponding compatible/bindings. At some
> point later we can remove the legacy driver/bindings altogether - of
> course that might take a while. This option allows us to re-think some
> of the old bindings and really clean up some if its related code. For
> example, I think "ti,dual-volt" is a bad binding. Instead it would be
> better to use the existing mmc bindings about which speed mode the
> controller/board supports (as the voltage level comes with it).
> 
> 2) Invent only a new compatible, but stick to use the old omap hsmmc
> bindings and thus also deploy the similar code dealing with them. When
> everything is implemented move the old omap_hsmmc compatibles into the
> new sdhci-omap driver and them remove the old omap_hsmmc driver. At
> that point we could also deprecate the old omap hsmmc compatibles, but
> to me that is rather pointless.
> 
> The two options has different advantages, feel free to pick any of them!

Okay. I'll send a new version with option '1' (new compatible/new bindings).

And when we deprecate the omap_hsmmc driver (some time later), we'll add
support for the legacy bindings in sdhci-omap driver (so that old dtbs continue
to work). Tony, are you okay with this?

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-29 11:20               ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-29 11:20 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uffe,

On Thursday 24 August 2017 04:59 PM, Ulf Hansson wrote:
> On 23 August 2017 at 15:56, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>> Hi Uffe,
>>
>> On Wednesday 23 August 2017 06:37 PM, Ulf Hansson wrote:
>>> On 23 August 2017 at 07:42, Kishon Vijay Abraham I <kishon@ti.com> wrote:
>>>> Add binding for the TI's sdhci-omap controller. This now includes only
>>>> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
>>>> include all the properties.
>>>>
>>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>>>> ---
>>>> Changes from v2:
>>>> *) Fixed example to use the updated compatible
>>>>
>>>> Changes from v1:
>>>> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>>>>    of using the ti-omap-hsmmc.txt as suggested by Tony
>>>>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>>>>  1 file changed, 22 insertions(+)
>>>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>>> new file mode 100644
>>>> index 000000000000..139695ad2d58
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>>> @@ -0,0 +1,22 @@
>>>> +* TI OMAP SDHCI Controller
>>>> +
>>>> +Refer to mmc.txt for standard MMC bindings.
>>>> +
>>>> +Required properties:
>>>> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
>>>> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
>>>> +
>>>> +Optional properties:
>>>> +- ti,dual-volt: boolean, supports dual voltage cards
>>>> +- ti,non-removable: non-removable slot (like eMMC)
>>>> +
>>>> +Example:
>>>> +       mmc1: mmc at 0x4809c000 {
>>>> +               compatible = "ti,dra7-sdhci";
>>>> +               reg = <0x4809c000 0x400>;
>>>> +               ti,hwmods = "mmc1";
>>>> +               ti,dual-volt;
>>>> +               bus-width = <4>;
>>>> +               vmmc-supply = <&vmmc>; /* phandle to regulator node */
>>>> +               ti,non-removable;
>>>> +       };
>>>> --
>>>> 2.11.0
>>>>
>>>
>>> I am wondering a bit on the long term plan here.
>>>
>>> Ideally at some point in future, we would like to remove the old
>>> omap_hsmmc driver, but from compatible string point of view, that
>>> means we first needs to deprecate the old ones for a while. Right?
>>
>> right but sdhci-omap is still lacking features that was present in omap_hsmmc
>> like context save/restore, SDIO support etc. I think we should deprecate
>> omap_hsmmc compatible once we add all the features in sdhci-omap?
>>>
>>> That said, what is then the reason to why we should bring over the
>>> existing omap_hsmmc bindings to the sdhci-omap bindings?
>>
>> This is mainly for old dt compatibility. Even after removing the omap_hsmmc
>> driver, users should still be able to use newer kernel with their existing dtbs.
> 
> I guess we have two options.
> 
> 1) Allow us to invent and use new bindings - and a new compatible.
> When everything is implemented in sdhci-omap, we can deprecate the old
> omap_hsmmc driver and its corresponding compatible/bindings. At some
> point later we can remove the legacy driver/bindings altogether - of
> course that might take a while. This option allows us to re-think some
> of the old bindings and really clean up some if its related code. For
> example, I think "ti,dual-volt" is a bad binding. Instead it would be
> better to use the existing mmc bindings about which speed mode the
> controller/board supports (as the voltage level comes with it).
> 
> 2) Invent only a new compatible, but stick to use the old omap hsmmc
> bindings and thus also deploy the similar code dealing with them. When
> everything is implemented move the old omap_hsmmc compatibles into the
> new sdhci-omap driver and them remove the old omap_hsmmc driver. At
> that point we could also deprecate the old omap hsmmc compatibles, but
> to me that is rather pointless.
> 
> The two options has different advantages, feel free to pick any of them!

Okay. I'll send a new version with option '1' (new compatible/new bindings).

And when we deprecate the omap_hsmmc driver (some time later), we'll add
support for the legacy bindings in sdhci-omap driver (so that old dtbs continue
to work). Tony, are you okay with this?

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-29 11:50                 ` Sebastian Reichel
  0 siblings, 0 replies; 86+ messages in thread
From: Sebastian Reichel @ 2017-08-29 11:50 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Ulf Hansson, Adrian Hunter, Rob Herring, Tony Lindgren,
	Sekhar Nori, Russell King, Ravikumar Kattekola, linux-mmc,
	devicetree, linux-kernel, linux-omap, linux-arm-kernel

[-- Attachment #1: Type: text/plain, Size: 5155 bytes --]

Hi,

On Tue, Aug 29, 2017 at 04:50:22PM +0530, Kishon Vijay Abraham I wrote:
> Hi Uffe,
> 
> On Thursday 24 August 2017 04:59 PM, Ulf Hansson wrote:
> > On 23 August 2017 at 15:56, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> >> Hi Uffe,
> >>
> >> On Wednesday 23 August 2017 06:37 PM, Ulf Hansson wrote:
> >>> On 23 August 2017 at 07:42, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> >>>> Add binding for the TI's sdhci-omap controller. This now includes only
> >>>> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
> >>>> include all the properties.
> >>>>
> >>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> >>>> ---
> >>>> Changes from v2:
> >>>> *) Fixed example to use the updated compatible
> >>>>
> >>>> Changes from v1:
> >>>> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
> >>>>    of using the ti-omap-hsmmc.txt as suggested by Tony
> >>>>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
> >>>>  1 file changed, 22 insertions(+)
> >>>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> >>>>
> >>>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> >>>> new file mode 100644
> >>>> index 000000000000..139695ad2d58
> >>>> --- /dev/null
> >>>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> >>>> @@ -0,0 +1,22 @@
> >>>> +* TI OMAP SDHCI Controller
> >>>> +
> >>>> +Refer to mmc.txt for standard MMC bindings.
> >>>> +
> >>>> +Required properties:
> >>>> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
> >>>> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
> >>>> +
> >>>> +Optional properties:
> >>>> +- ti,dual-volt: boolean, supports dual voltage cards
> >>>> +- ti,non-removable: non-removable slot (like eMMC)
> >>>> +
> >>>> +Example:
> >>>> +       mmc1: mmc@0x4809c000 {
> >>>> +               compatible = "ti,dra7-sdhci";
> >>>> +               reg = <0x4809c000 0x400>;
> >>>> +               ti,hwmods = "mmc1";
> >>>> +               ti,dual-volt;
> >>>> +               bus-width = <4>;
> >>>> +               vmmc-supply = <&vmmc>; /* phandle to regulator node */
> >>>> +               ti,non-removable;
> >>>> +       };
> >>>> --
> >>>> 2.11.0
> >>>>
> >>>
> >>> I am wondering a bit on the long term plan here.
> >>>
> >>> Ideally at some point in future, we would like to remove the old
> >>> omap_hsmmc driver, but from compatible string point of view, that
> >>> means we first needs to deprecate the old ones for a while. Right?
> >>
> >> right but sdhci-omap is still lacking features that was present in omap_hsmmc
> >> like context save/restore, SDIO support etc. I think we should deprecate
> >> omap_hsmmc compatible once we add all the features in sdhci-omap?
> >>>
> >>> That said, what is then the reason to why we should bring over the
> >>> existing omap_hsmmc bindings to the sdhci-omap bindings?
> >>
> >> This is mainly for old dt compatibility. Even after removing the omap_hsmmc
> >> driver, users should still be able to use newer kernel with their existing dtbs.
> > 
> > I guess we have two options.
> > 
> > 1) Allow us to invent and use new bindings - and a new compatible.
> > When everything is implemented in sdhci-omap, we can deprecate the old
> > omap_hsmmc driver and its corresponding compatible/bindings. At some
> > point later we can remove the legacy driver/bindings altogether - of
> > course that might take a while. This option allows us to re-think some
> > of the old bindings and really clean up some if its related code. For
> > example, I think "ti,dual-volt" is a bad binding. Instead it would be
> > better to use the existing mmc bindings about which speed mode the
> > controller/board supports (as the voltage level comes with it).
> > 
> > 2) Invent only a new compatible, but stick to use the old omap hsmmc
> > bindings and thus also deploy the similar code dealing with them. When
> > everything is implemented move the old omap_hsmmc compatibles into the
> > new sdhci-omap driver and them remove the old omap_hsmmc driver. At
> > that point we could also deprecate the old omap hsmmc compatibles, but
> > to me that is rather pointless.
> > 
> > The two options has different advantages, feel free to pick any of them!
> 
> Okay. I'll send a new version with option '1' (new compatible/new bindings).
> 
> And when we deprecate the omap_hsmmc driver (some time later), we'll add
> support for the legacy bindings in sdhci-omap driver (so that old dtbs continue
> to work). Tony, are you okay with this?

I think you should Cc Rob Herring and Mark Rutland (DT binding
maintainers). This sounds like "I use DT to describe driver
behaviour" instead of "I use DT to describe hardware".

I would expect the conversion to look like the one done for UART,
see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
same compatible value and you can choose using kernel configuration.

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-29 11:50                 ` Sebastian Reichel
  0 siblings, 0 replies; 86+ messages in thread
From: Sebastian Reichel @ 2017-08-29 11:50 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Ulf Hansson, Adrian Hunter, Rob Herring, Tony Lindgren,
	Sekhar Nori, Russell King, Ravikumar Kattekola,
	linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-omap,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

[-- Attachment #1: Type: text/plain, Size: 5221 bytes --]

Hi,

On Tue, Aug 29, 2017 at 04:50:22PM +0530, Kishon Vijay Abraham I wrote:
> Hi Uffe,
> 
> On Thursday 24 August 2017 04:59 PM, Ulf Hansson wrote:
> > On 23 August 2017 at 15:56, Kishon Vijay Abraham I <kishon-l0cyMroinI0@public.gmane.org> wrote:
> >> Hi Uffe,
> >>
> >> On Wednesday 23 August 2017 06:37 PM, Ulf Hansson wrote:
> >>> On 23 August 2017 at 07:42, Kishon Vijay Abraham I <kishon-l0cyMroinI0@public.gmane.org> wrote:
> >>>> Add binding for the TI's sdhci-omap controller. This now includes only
> >>>> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
> >>>> include all the properties.
> >>>>
> >>>> Signed-off-by: Kishon Vijay Abraham I <kishon-l0cyMroinI0@public.gmane.org>
> >>>> ---
> >>>> Changes from v2:
> >>>> *) Fixed example to use the updated compatible
> >>>>
> >>>> Changes from v1:
> >>>> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
> >>>>    of using the ti-omap-hsmmc.txt as suggested by Tony
> >>>>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
> >>>>  1 file changed, 22 insertions(+)
> >>>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> >>>>
> >>>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> >>>> new file mode 100644
> >>>> index 000000000000..139695ad2d58
> >>>> --- /dev/null
> >>>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> >>>> @@ -0,0 +1,22 @@
> >>>> +* TI OMAP SDHCI Controller
> >>>> +
> >>>> +Refer to mmc.txt for standard MMC bindings.
> >>>> +
> >>>> +Required properties:
> >>>> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
> >>>> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
> >>>> +
> >>>> +Optional properties:
> >>>> +- ti,dual-volt: boolean, supports dual voltage cards
> >>>> +- ti,non-removable: non-removable slot (like eMMC)
> >>>> +
> >>>> +Example:
> >>>> +       mmc1: mmc@0x4809c000 {
> >>>> +               compatible = "ti,dra7-sdhci";
> >>>> +               reg = <0x4809c000 0x400>;
> >>>> +               ti,hwmods = "mmc1";
> >>>> +               ti,dual-volt;
> >>>> +               bus-width = <4>;
> >>>> +               vmmc-supply = <&vmmc>; /* phandle to regulator node */
> >>>> +               ti,non-removable;
> >>>> +       };
> >>>> --
> >>>> 2.11.0
> >>>>
> >>>
> >>> I am wondering a bit on the long term plan here.
> >>>
> >>> Ideally at some point in future, we would like to remove the old
> >>> omap_hsmmc driver, but from compatible string point of view, that
> >>> means we first needs to deprecate the old ones for a while. Right?
> >>
> >> right but sdhci-omap is still lacking features that was present in omap_hsmmc
> >> like context save/restore, SDIO support etc. I think we should deprecate
> >> omap_hsmmc compatible once we add all the features in sdhci-omap?
> >>>
> >>> That said, what is then the reason to why we should bring over the
> >>> existing omap_hsmmc bindings to the sdhci-omap bindings?
> >>
> >> This is mainly for old dt compatibility. Even after removing the omap_hsmmc
> >> driver, users should still be able to use newer kernel with their existing dtbs.
> > 
> > I guess we have two options.
> > 
> > 1) Allow us to invent and use new bindings - and a new compatible.
> > When everything is implemented in sdhci-omap, we can deprecate the old
> > omap_hsmmc driver and its corresponding compatible/bindings. At some
> > point later we can remove the legacy driver/bindings altogether - of
> > course that might take a while. This option allows us to re-think some
> > of the old bindings and really clean up some if its related code. For
> > example, I think "ti,dual-volt" is a bad binding. Instead it would be
> > better to use the existing mmc bindings about which speed mode the
> > controller/board supports (as the voltage level comes with it).
> > 
> > 2) Invent only a new compatible, but stick to use the old omap hsmmc
> > bindings and thus also deploy the similar code dealing with them. When
> > everything is implemented move the old omap_hsmmc compatibles into the
> > new sdhci-omap driver and them remove the old omap_hsmmc driver. At
> > that point we could also deprecate the old omap hsmmc compatibles, but
> > to me that is rather pointless.
> > 
> > The two options has different advantages, feel free to pick any of them!
> 
> Okay. I'll send a new version with option '1' (new compatible/new bindings).
> 
> And when we deprecate the omap_hsmmc driver (some time later), we'll add
> support for the legacy bindings in sdhci-omap driver (so that old dtbs continue
> to work). Tony, are you okay with this?

I think you should Cc Rob Herring and Mark Rutland (DT binding
maintainers). This sounds like "I use DT to describe driver
behaviour" instead of "I use DT to describe hardware".

I would expect the conversion to look like the one done for UART,
see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
same compatible value and you can choose using kernel configuration.

-- Sebastian

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-29 11:50                 ` Sebastian Reichel
  0 siblings, 0 replies; 86+ messages in thread
From: Sebastian Reichel @ 2017-08-29 11:50 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tue, Aug 29, 2017 at 04:50:22PM +0530, Kishon Vijay Abraham I wrote:
> Hi Uffe,
> 
> On Thursday 24 August 2017 04:59 PM, Ulf Hansson wrote:
> > On 23 August 2017 at 15:56, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> >> Hi Uffe,
> >>
> >> On Wednesday 23 August 2017 06:37 PM, Ulf Hansson wrote:
> >>> On 23 August 2017 at 07:42, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> >>>> Add binding for the TI's sdhci-omap controller. This now includes only
> >>>> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
> >>>> include all the properties.
> >>>>
> >>>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> >>>> ---
> >>>> Changes from v2:
> >>>> *) Fixed example to use the updated compatible
> >>>>
> >>>> Changes from v1:
> >>>> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
> >>>>    of using the ti-omap-hsmmc.txt as suggested by Tony
> >>>>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
> >>>>  1 file changed, 22 insertions(+)
> >>>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> >>>>
> >>>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> >>>> new file mode 100644
> >>>> index 000000000000..139695ad2d58
> >>>> --- /dev/null
> >>>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> >>>> @@ -0,0 +1,22 @@
> >>>> +* TI OMAP SDHCI Controller
> >>>> +
> >>>> +Refer to mmc.txt for standard MMC bindings.
> >>>> +
> >>>> +Required properties:
> >>>> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
> >>>> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
> >>>> +
> >>>> +Optional properties:
> >>>> +- ti,dual-volt: boolean, supports dual voltage cards
> >>>> +- ti,non-removable: non-removable slot (like eMMC)
> >>>> +
> >>>> +Example:
> >>>> +       mmc1: mmc at 0x4809c000 {
> >>>> +               compatible = "ti,dra7-sdhci";
> >>>> +               reg = <0x4809c000 0x400>;
> >>>> +               ti,hwmods = "mmc1";
> >>>> +               ti,dual-volt;
> >>>> +               bus-width = <4>;
> >>>> +               vmmc-supply = <&vmmc>; /* phandle to regulator node */
> >>>> +               ti,non-removable;
> >>>> +       };
> >>>> --
> >>>> 2.11.0
> >>>>
> >>>
> >>> I am wondering a bit on the long term plan here.
> >>>
> >>> Ideally at some point in future, we would like to remove the old
> >>> omap_hsmmc driver, but from compatible string point of view, that
> >>> means we first needs to deprecate the old ones for a while. Right?
> >>
> >> right but sdhci-omap is still lacking features that was present in omap_hsmmc
> >> like context save/restore, SDIO support etc. I think we should deprecate
> >> omap_hsmmc compatible once we add all the features in sdhci-omap?
> >>>
> >>> That said, what is then the reason to why we should bring over the
> >>> existing omap_hsmmc bindings to the sdhci-omap bindings?
> >>
> >> This is mainly for old dt compatibility. Even after removing the omap_hsmmc
> >> driver, users should still be able to use newer kernel with their existing dtbs.
> > 
> > I guess we have two options.
> > 
> > 1) Allow us to invent and use new bindings - and a new compatible.
> > When everything is implemented in sdhci-omap, we can deprecate the old
> > omap_hsmmc driver and its corresponding compatible/bindings. At some
> > point later we can remove the legacy driver/bindings altogether - of
> > course that might take a while. This option allows us to re-think some
> > of the old bindings and really clean up some if its related code. For
> > example, I think "ti,dual-volt" is a bad binding. Instead it would be
> > better to use the existing mmc bindings about which speed mode the
> > controller/board supports (as the voltage level comes with it).
> > 
> > 2) Invent only a new compatible, but stick to use the old omap hsmmc
> > bindings and thus also deploy the similar code dealing with them. When
> > everything is implemented move the old omap_hsmmc compatibles into the
> > new sdhci-omap driver and them remove the old omap_hsmmc driver. At
> > that point we could also deprecate the old omap hsmmc compatibles, but
> > to me that is rather pointless.
> > 
> > The two options has different advantages, feel free to pick any of them!
> 
> Okay. I'll send a new version with option '1' (new compatible/new bindings).
> 
> And when we deprecate the omap_hsmmc driver (some time later), we'll add
> support for the legacy bindings in sdhci-omap driver (so that old dtbs continue
> to work). Tony, are you okay with this?

I think you should Cc Rob Herring and Mark Rutland (DT binding
maintainers). This sounds like "I use DT to describe driver
behaviour" instead of "I use DT to describe hardware".

I would expect the conversion to look like the one done for UART,
see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
same compatible value and you can choose using kernel configuration.

-- Sebastian
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20170829/1b8c8c06/attachment.sig>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
  2017-08-29 11:50                 ` Sebastian Reichel
  (?)
@ 2017-08-29 13:58                   ` Tony Lindgren
  -1 siblings, 0 replies; 86+ messages in thread
From: Tony Lindgren @ 2017-08-29 13:58 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Kishon Vijay Abraham I, Ulf Hansson, Adrian Hunter, Rob Herring,
	Sekhar Nori, Russell King, Ravikumar Kattekola, linux-mmc,
	devicetree, linux-kernel, linux-omap, linux-arm-kernel

* Sebastian Reichel <sebastian.reichel@collabora.co.uk> [170829 04:51]:
> On Tue, Aug 29, 2017 at 04:50:22PM +0530, Kishon Vijay Abraham I wrote:
> > On Thursday 24 August 2017 04:59 PM, Ulf Hansson wrote:
> > > I guess we have two options.
> > > 
> > > 1) Allow us to invent and use new bindings - and a new compatible.
> > > When everything is implemented in sdhci-omap, we can deprecate the old
> > > omap_hsmmc driver and its corresponding compatible/bindings. At some
> > > point later we can remove the legacy driver/bindings altogether - of
> > > course that might take a while. This option allows us to re-think some
> > > of the old bindings and really clean up some if its related code. For
> > > example, I think "ti,dual-volt" is a bad binding. Instead it would be
> > > better to use the existing mmc bindings about which speed mode the
> > > controller/board supports (as the voltage level comes with it).
> > > 
> > > 2) Invent only a new compatible, but stick to use the old omap hsmmc
> > > bindings and thus also deploy the similar code dealing with them. When
> > > everything is implemented move the old omap_hsmmc compatibles into the
> > > new sdhci-omap driver and them remove the old omap_hsmmc driver. At
> > > that point we could also deprecate the old omap hsmmc compatibles, but
> > > to me that is rather pointless.
> > > 
> > > The two options has different advantages, feel free to pick any of them!
> > 
> > Okay. I'll send a new version with option '1' (new compatible/new bindings).

Agreed.

> > And when we deprecate the omap_hsmmc driver (some time later), we'll add
> > support for the legacy bindings in sdhci-omap driver (so that old dtbs continue
> > to work). Tony, are you okay with this?
> 
> I think you should Cc Rob Herring and Mark Rutland (DT binding
> maintainers). This sounds like "I use DT to describe driver
> behaviour" instead of "I use DT to describe hardware".

Yes please.

> I would expect the conversion to look like the one done for UART,
> see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
> same compatible value and you can choose using kernel configuration.

That does not work unfortunately :( We are now stuck in a situation
where two drivers are attempting to probe with the same compatible
and we can't enable 8250_OMAP because of the user space breakage
with the device names. And I'm actuallly thinking we should add a
new compatible for 8250-omap to be able to start enabling it one
board at a time.

It's best to enable devices to use the new compatible as things are
tested rather than hope for some magic "flag day" flip that might
never happen. Having two days attempting to probe with the same
binding just won't work.

So yeah, I agree with Kishon that we should stick with generic
and sdhci bindings. And then we can start already using it for
boards that can use it, then eventually when we're ready, start
parsing also the legacy bindings and maybe drop the old driver.

Regards,

Tony

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-29 13:58                   ` Tony Lindgren
  0 siblings, 0 replies; 86+ messages in thread
From: Tony Lindgren @ 2017-08-29 13:58 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Kishon Vijay Abraham I, Ulf Hansson, Adrian Hunter, Rob Herring,
	Sekhar Nori, Russell King, Ravikumar Kattekola, linux-mmc,
	devicetree, linux-kernel, linux-omap, linux-arm-kernel

* Sebastian Reichel <sebastian.reichel@collabora.co.uk> [170829 04:51]:
> On Tue, Aug 29, 2017 at 04:50:22PM +0530, Kishon Vijay Abraham I wrote:
> > On Thursday 24 August 2017 04:59 PM, Ulf Hansson wrote:
> > > I guess we have two options.
> > > 
> > > 1) Allow us to invent and use new bindings - and a new compatible.
> > > When everything is implemented in sdhci-omap, we can deprecate the old
> > > omap_hsmmc driver and its corresponding compatible/bindings. At some
> > > point later we can remove the legacy driver/bindings altogether - of
> > > course that might take a while. This option allows us to re-think some
> > > of the old bindings and really clean up some if its related code. For
> > > example, I think "ti,dual-volt" is a bad binding. Instead it would be
> > > better to use the existing mmc bindings about which speed mode the
> > > controller/board supports (as the voltage level comes with it).
> > > 
> > > 2) Invent only a new compatible, but stick to use the old omap hsmmc
> > > bindings and thus also deploy the similar code dealing with them. When
> > > everything is implemented move the old omap_hsmmc compatibles into the
> > > new sdhci-omap driver and them remove the old omap_hsmmc driver. At
> > > that point we could also deprecate the old omap hsmmc compatibles, but
> > > to me that is rather pointless.
> > > 
> > > The two options has different advantages, feel free to pick any of them!
> > 
> > Okay. I'll send a new version with option '1' (new compatible/new bindings).

Agreed.

> > And when we deprecate the omap_hsmmc driver (some time later), we'll add
> > support for the legacy bindings in sdhci-omap driver (so that old dtbs continue
> > to work). Tony, are you okay with this?
> 
> I think you should Cc Rob Herring and Mark Rutland (DT binding
> maintainers). This sounds like "I use DT to describe driver
> behaviour" instead of "I use DT to describe hardware".

Yes please.

> I would expect the conversion to look like the one done for UART,
> see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
> same compatible value and you can choose using kernel configuration.

That does not work unfortunately :( We are now stuck in a situation
where two drivers are attempting to probe with the same compatible
and we can't enable 8250_OMAP because of the user space breakage
with the device names. And I'm actuallly thinking we should add a
new compatible for 8250-omap to be able to start enabling it one
board at a time.

It's best to enable devices to use the new compatible as things are
tested rather than hope for some magic "flag day" flip that might
never happen. Having two days attempting to probe with the same
binding just won't work.

So yeah, I agree with Kishon that we should stick with generic
and sdhci bindings. And then we can start already using it for
boards that can use it, then eventually when we're ready, start
parsing also the legacy bindings and maybe drop the old driver.

Regards,

Tony


^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-29 13:58                   ` Tony Lindgren
  0 siblings, 0 replies; 86+ messages in thread
From: Tony Lindgren @ 2017-08-29 13:58 UTC (permalink / raw)
  To: linux-arm-kernel

* Sebastian Reichel <sebastian.reichel@collabora.co.uk> [170829 04:51]:
> On Tue, Aug 29, 2017 at 04:50:22PM +0530, Kishon Vijay Abraham I wrote:
> > On Thursday 24 August 2017 04:59 PM, Ulf Hansson wrote:
> > > I guess we have two options.
> > > 
> > > 1) Allow us to invent and use new bindings - and a new compatible.
> > > When everything is implemented in sdhci-omap, we can deprecate the old
> > > omap_hsmmc driver and its corresponding compatible/bindings. At some
> > > point later we can remove the legacy driver/bindings altogether - of
> > > course that might take a while. This option allows us to re-think some
> > > of the old bindings and really clean up some if its related code. For
> > > example, I think "ti,dual-volt" is a bad binding. Instead it would be
> > > better to use the existing mmc bindings about which speed mode the
> > > controller/board supports (as the voltage level comes with it).
> > > 
> > > 2) Invent only a new compatible, but stick to use the old omap hsmmc
> > > bindings and thus also deploy the similar code dealing with them. When
> > > everything is implemented move the old omap_hsmmc compatibles into the
> > > new sdhci-omap driver and them remove the old omap_hsmmc driver. At
> > > that point we could also deprecate the old omap hsmmc compatibles, but
> > > to me that is rather pointless.
> > > 
> > > The two options has different advantages, feel free to pick any of them!
> > 
> > Okay. I'll send a new version with option '1' (new compatible/new bindings).

Agreed.

> > And when we deprecate the omap_hsmmc driver (some time later), we'll add
> > support for the legacy bindings in sdhci-omap driver (so that old dtbs continue
> > to work). Tony, are you okay with this?
> 
> I think you should Cc Rob Herring and Mark Rutland (DT binding
> maintainers). This sounds like "I use DT to describe driver
> behaviour" instead of "I use DT to describe hardware".

Yes please.

> I would expect the conversion to look like the one done for UART,
> see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
> same compatible value and you can choose using kernel configuration.

That does not work unfortunately :( We are now stuck in a situation
where two drivers are attempting to probe with the same compatible
and we can't enable 8250_OMAP because of the user space breakage
with the device names. And I'm actuallly thinking we should add a
new compatible for 8250-omap to be able to start enabling it one
board at a time.

It's best to enable devices to use the new compatible as things are
tested rather than hope for some magic "flag day" flip that might
never happen. Having two days attempting to probe with the same
binding just won't work.

So yeah, I agree with Kishon that we should stick with generic
and sdhci bindings. And then we can start already using it for
boards that can use it, then eventually when we're ready, start
parsing also the legacy bindings and maybe drop the old driver.

Regards,

Tony

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
  2017-08-29 13:58                   ` Tony Lindgren
  (?)
@ 2017-08-29 14:43                     ` Tony Lindgren
  -1 siblings, 0 replies; 86+ messages in thread
From: Tony Lindgren @ 2017-08-29 14:43 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Kishon Vijay Abraham I, Ulf Hansson, Adrian Hunter, Rob Herring,
	Sekhar Nori, Russell King, Ravikumar Kattekola, linux-mmc,
	devicetree, linux-kernel, linux-omap, linux-arm-kernel

* Tony Lindgren <tony@atomide.com> [170829 06:58]:
> It's best to enable devices to use the new compatible as things are
> tested rather than hope for some magic "flag day" flip that might
> never happen. Having two days attempting to probe with the same
> binding just won't work.

Hehe I mean "Having two drivers attempting to probe with the same
binding" above.

Tony

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-29 14:43                     ` Tony Lindgren
  0 siblings, 0 replies; 86+ messages in thread
From: Tony Lindgren @ 2017-08-29 14:43 UTC (permalink / raw)
  To: Sebastian Reichel
  Cc: Kishon Vijay Abraham I, Ulf Hansson, Adrian Hunter, Rob Herring,
	Sekhar Nori, Russell King, Ravikumar Kattekola, linux-mmc,
	devicetree, linux-kernel, linux-omap, linux-arm-kernel

* Tony Lindgren <tony@atomide.com> [170829 06:58]:
> It's best to enable devices to use the new compatible as things are
> tested rather than hope for some magic "flag day" flip that might
> never happen. Having two days attempting to probe with the same
> binding just won't work.

Hehe I mean "Having two drivers attempting to probe with the same
binding" above.

Tony

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-29 14:43                     ` Tony Lindgren
  0 siblings, 0 replies; 86+ messages in thread
From: Tony Lindgren @ 2017-08-29 14:43 UTC (permalink / raw)
  To: linux-arm-kernel

* Tony Lindgren <tony@atomide.com> [170829 06:58]:
> It's best to enable devices to use the new compatible as things are
> tested rather than hope for some magic "flag day" flip that might
> never happen. Having two days attempting to probe with the same
> binding just won't work.

Hehe I mean "Having two drivers attempting to probe with the same
binding" above.

Tony

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-29 17:09                     ` Rob Herring
  0 siblings, 0 replies; 86+ messages in thread
From: Rob Herring @ 2017-08-29 17:09 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Sebastian Reichel, Kishon Vijay Abraham I, Ulf Hansson,
	Adrian Hunter, Sekhar Nori, Russell King, Ravikumar Kattekola,
	linux-mmc, devicetree, linux-kernel, linux-omap,
	linux-arm-kernel

On Tue, Aug 29, 2017 at 06:58:23AM -0700, Tony Lindgren wrote:
> * Sebastian Reichel <sebastian.reichel@collabora.co.uk> [170829 04:51]:
> > On Tue, Aug 29, 2017 at 04:50:22PM +0530, Kishon Vijay Abraham I wrote:
> > > On Thursday 24 August 2017 04:59 PM, Ulf Hansson wrote:
> > > > I guess we have two options.
> > > > 
> > > > 1) Allow us to invent and use new bindings - and a new compatible.
> > > > When everything is implemented in sdhci-omap, we can deprecate the old
> > > > omap_hsmmc driver and its corresponding compatible/bindings. At some
> > > > point later we can remove the legacy driver/bindings altogether - of
> > > > course that might take a while. This option allows us to re-think some
> > > > of the old bindings and really clean up some if its related code. For
> > > > example, I think "ti,dual-volt" is a bad binding. Instead it would be
> > > > better to use the existing mmc bindings about which speed mode the
> > > > controller/board supports (as the voltage level comes with it).
> > > > 
> > > > 2) Invent only a new compatible, but stick to use the old omap hsmmc
> > > > bindings and thus also deploy the similar code dealing with them. When
> > > > everything is implemented move the old omap_hsmmc compatibles into the
> > > > new sdhci-omap driver and them remove the old omap_hsmmc driver. At
> > > > that point we could also deprecate the old omap hsmmc compatibles, but
> > > > to me that is rather pointless.
> > > > 
> > > > The two options has different advantages, feel free to pick any of them!
> > > 
> > > Okay. I'll send a new version with option '1' (new compatible/new bindings).
> 
> Agreed.
> 
> > > And when we deprecate the omap_hsmmc driver (some time later), we'll add
> > > support for the legacy bindings in sdhci-omap driver (so that old dtbs continue
> > > to work). Tony, are you okay with this?
> > 
> > I think you should Cc Rob Herring and Mark Rutland (DT binding
> > maintainers). This sounds like "I use DT to describe driver
> > behaviour" instead of "I use DT to describe hardware".

Indeed...

> 
> Yes please.
> 
> > I would expect the conversion to look like the one done for UART,
> > see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
> > same compatible value and you can choose using kernel configuration.
> 
> That does not work unfortunately :( We are now stuck in a situation
> where two drivers are attempting to probe with the same compatible
> and we can't enable 8250_OMAP because of the user space breakage
> with the device names. And I'm actuallly thinking we should add a
> new compatible for 8250-omap to be able to start enabling it one
> board at a time.

Is that the only problem? Presumably, the SD driver doesn't have a 
userspace facing issue.

> It's best to enable devices to use the new compatible as things are
> tested rather than hope for some magic "flag day" flip that might
> never happen. Having two days attempting to probe with the same
> binding just won't work.

Aren't you just picking whether the flag day is in DT or the kernel? I 
guess you're assuming one kernel build and it would be switching all 
boards at one. 

> So yeah, I agree with Kishon that we should stick with generic
> and sdhci bindings. And then we can start already using it for
> boards that can use it, then eventually when we're ready, start
> parsing also the legacy bindings and maybe drop the old driver.

I assume there are some other common properties you would switch to in 
the transition?  You could make the legacy driver bail from probe based 
on presence or absence of other properties. Or you could just blacklist 
converted platforms in the legacy driver. The point is that the problems 
are solvable in the kernel.

But if your really want a new compatible, I don't really care. It's 
only one device.

Rob

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-29 17:09                     ` Rob Herring
  0 siblings, 0 replies; 86+ messages in thread
From: Rob Herring @ 2017-08-29 17:09 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: Sebastian Reichel, Kishon Vijay Abraham I, Ulf Hansson,
	Adrian Hunter, Sekhar Nori, Russell King, Ravikumar Kattekola,
	linux-mmc-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-omap,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r

On Tue, Aug 29, 2017 at 06:58:23AM -0700, Tony Lindgren wrote:
> * Sebastian Reichel <sebastian.reichel-ZGY8ohtN/8pPYcu2f3hruQ@public.gmane.org> [170829 04:51]:
> > On Tue, Aug 29, 2017 at 04:50:22PM +0530, Kishon Vijay Abraham I wrote:
> > > On Thursday 24 August 2017 04:59 PM, Ulf Hansson wrote:
> > > > I guess we have two options.
> > > > 
> > > > 1) Allow us to invent and use new bindings - and a new compatible.
> > > > When everything is implemented in sdhci-omap, we can deprecate the old
> > > > omap_hsmmc driver and its corresponding compatible/bindings. At some
> > > > point later we can remove the legacy driver/bindings altogether - of
> > > > course that might take a while. This option allows us to re-think some
> > > > of the old bindings and really clean up some if its related code. For
> > > > example, I think "ti,dual-volt" is a bad binding. Instead it would be
> > > > better to use the existing mmc bindings about which speed mode the
> > > > controller/board supports (as the voltage level comes with it).
> > > > 
> > > > 2) Invent only a new compatible, but stick to use the old omap hsmmc
> > > > bindings and thus also deploy the similar code dealing with them. When
> > > > everything is implemented move the old omap_hsmmc compatibles into the
> > > > new sdhci-omap driver and them remove the old omap_hsmmc driver. At
> > > > that point we could also deprecate the old omap hsmmc compatibles, but
> > > > to me that is rather pointless.
> > > > 
> > > > The two options has different advantages, feel free to pick any of them!
> > > 
> > > Okay. I'll send a new version with option '1' (new compatible/new bindings).
> 
> Agreed.
> 
> > > And when we deprecate the omap_hsmmc driver (some time later), we'll add
> > > support for the legacy bindings in sdhci-omap driver (so that old dtbs continue
> > > to work). Tony, are you okay with this?
> > 
> > I think you should Cc Rob Herring and Mark Rutland (DT binding
> > maintainers). This sounds like "I use DT to describe driver
> > behaviour" instead of "I use DT to describe hardware".

Indeed...

> 
> Yes please.
> 
> > I would expect the conversion to look like the one done for UART,
> > see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
> > same compatible value and you can choose using kernel configuration.
> 
> That does not work unfortunately :( We are now stuck in a situation
> where two drivers are attempting to probe with the same compatible
> and we can't enable 8250_OMAP because of the user space breakage
> with the device names. And I'm actuallly thinking we should add a
> new compatible for 8250-omap to be able to start enabling it one
> board at a time.

Is that the only problem? Presumably, the SD driver doesn't have a 
userspace facing issue.

> It's best to enable devices to use the new compatible as things are
> tested rather than hope for some magic "flag day" flip that might
> never happen. Having two days attempting to probe with the same
> binding just won't work.

Aren't you just picking whether the flag day is in DT or the kernel? I 
guess you're assuming one kernel build and it would be switching all 
boards at one. 

> So yeah, I agree with Kishon that we should stick with generic
> and sdhci bindings. And then we can start already using it for
> boards that can use it, then eventually when we're ready, start
> parsing also the legacy bindings and maybe drop the old driver.

I assume there are some other common properties you would switch to in 
the transition?  You could make the legacy driver bail from probe based 
on presence or absence of other properties. Or you could just blacklist 
converted platforms in the legacy driver. The point is that the problems 
are solvable in the kernel.

But if your really want a new compatible, I don't really care. It's 
only one device.

Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-29 17:09                     ` Rob Herring
  0 siblings, 0 replies; 86+ messages in thread
From: Rob Herring @ 2017-08-29 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Aug 29, 2017 at 06:58:23AM -0700, Tony Lindgren wrote:
> * Sebastian Reichel <sebastian.reichel@collabora.co.uk> [170829 04:51]:
> > On Tue, Aug 29, 2017 at 04:50:22PM +0530, Kishon Vijay Abraham I wrote:
> > > On Thursday 24 August 2017 04:59 PM, Ulf Hansson wrote:
> > > > I guess we have two options.
> > > > 
> > > > 1) Allow us to invent and use new bindings - and a new compatible.
> > > > When everything is implemented in sdhci-omap, we can deprecate the old
> > > > omap_hsmmc driver and its corresponding compatible/bindings. At some
> > > > point later we can remove the legacy driver/bindings altogether - of
> > > > course that might take a while. This option allows us to re-think some
> > > > of the old bindings and really clean up some if its related code. For
> > > > example, I think "ti,dual-volt" is a bad binding. Instead it would be
> > > > better to use the existing mmc bindings about which speed mode the
> > > > controller/board supports (as the voltage level comes with it).
> > > > 
> > > > 2) Invent only a new compatible, but stick to use the old omap hsmmc
> > > > bindings and thus also deploy the similar code dealing with them. When
> > > > everything is implemented move the old omap_hsmmc compatibles into the
> > > > new sdhci-omap driver and them remove the old omap_hsmmc driver. At
> > > > that point we could also deprecate the old omap hsmmc compatibles, but
> > > > to me that is rather pointless.
> > > > 
> > > > The two options has different advantages, feel free to pick any of them!
> > > 
> > > Okay. I'll send a new version with option '1' (new compatible/new bindings).
> 
> Agreed.
> 
> > > And when we deprecate the omap_hsmmc driver (some time later), we'll add
> > > support for the legacy bindings in sdhci-omap driver (so that old dtbs continue
> > > to work). Tony, are you okay with this?
> > 
> > I think you should Cc Rob Herring and Mark Rutland (DT binding
> > maintainers). This sounds like "I use DT to describe driver
> > behaviour" instead of "I use DT to describe hardware".

Indeed...

> 
> Yes please.
> 
> > I would expect the conversion to look like the one done for UART,
> > see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
> > same compatible value and you can choose using kernel configuration.
> 
> That does not work unfortunately :( We are now stuck in a situation
> where two drivers are attempting to probe with the same compatible
> and we can't enable 8250_OMAP because of the user space breakage
> with the device names. And I'm actuallly thinking we should add a
> new compatible for 8250-omap to be able to start enabling it one
> board at a time.

Is that the only problem? Presumably, the SD driver doesn't have a 
userspace facing issue.

> It's best to enable devices to use the new compatible as things are
> tested rather than hope for some magic "flag day" flip that might
> never happen. Having two days attempting to probe with the same
> binding just won't work.

Aren't you just picking whether the flag day is in DT or the kernel? I 
guess you're assuming one kernel build and it would be switching all 
boards at one. 

> So yeah, I agree with Kishon that we should stick with generic
> and sdhci bindings. And then we can start already using it for
> boards that can use it, then eventually when we're ready, start
> parsing also the legacy bindings and maybe drop the old driver.

I assume there are some other common properties you would switch to in 
the transition?  You could make the legacy driver bail from probe based 
on presence or absence of other properties. Or you could just blacklist 
converted platforms in the legacy driver. The point is that the problems 
are solvable in the kernel.

But if your really want a new compatible, I don't really care. It's 
only one device.

Rob

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
  2017-08-23  5:42       ` Kishon Vijay Abraham I
@ 2017-08-29 17:11         ` Rob Herring
  -1 siblings, 0 replies; 86+ messages in thread
From: Rob Herring @ 2017-08-29 17:11 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Ulf Hansson, Adrian Hunter, Tony Lindgren, Sekhar Nori,
	Russell King, Ravikumar Kattekola, linux-mmc, devicetree,
	linux-kernel, linux-omap, linux-arm-kernel

On Wed, Aug 23, 2017 at 11:12:46AM +0530, Kishon Vijay Abraham I wrote:
> Add binding for the TI's sdhci-omap controller. This now includes only
> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
> include all the properties.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
> Changes from v2:
> *) Fixed example to use the updated compatible
> 
> Changes from v1:
> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>    of using the ti-omap-hsmmc.txt as suggested by Tony
>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> 
> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> new file mode 100644
> index 000000000000..139695ad2d58
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> @@ -0,0 +1,22 @@
> +* TI OMAP SDHCI Controller
> +
> +Refer to mmc.txt for standard MMC bindings.
> +
> +Required properties:
> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
> +
> +Optional properties:
> +- ti,dual-volt: boolean, supports dual voltage cards
> +- ti,non-removable: non-removable slot (like eMMC)

Well, if you are doing a new compatible, then why aren't you using 
common properties?

> +
> +Example:
> +	mmc1: mmc@0x4809c000 {

Drop the '0x'.

> +		compatible = "ti,dra7-sdhci";
> +		reg = <0x4809c000 0x400>;
> +		ti,hwmods = "mmc1";
> +		ti,dual-volt;
> +		bus-width = <4>;
> +		vmmc-supply = <&vmmc>; /* phandle to regulator node */
> +		ti,non-removable;
> +	};
> -- 
> 2.11.0
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-29 17:11         ` Rob Herring
  0 siblings, 0 replies; 86+ messages in thread
From: Rob Herring @ 2017-08-29 17:11 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Aug 23, 2017 at 11:12:46AM +0530, Kishon Vijay Abraham I wrote:
> Add binding for the TI's sdhci-omap controller. This now includes only
> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
> include all the properties.
> 
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
> Changes from v2:
> *) Fixed example to use the updated compatible
> 
> Changes from v1:
> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>    of using the ti-omap-hsmmc.txt as suggested by Tony
>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> 
> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> new file mode 100644
> index 000000000000..139695ad2d58
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
> @@ -0,0 +1,22 @@
> +* TI OMAP SDHCI Controller
> +
> +Refer to mmc.txt for standard MMC bindings.
> +
> +Required properties:
> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
> +
> +Optional properties:
> +- ti,dual-volt: boolean, supports dual voltage cards
> +- ti,non-removable: non-removable slot (like eMMC)

Well, if you are doing a new compatible, then why aren't you using 
common properties?

> +
> +Example:
> +	mmc1: mmc at 0x4809c000 {

Drop the '0x'.

> +		compatible = "ti,dra7-sdhci";
> +		reg = <0x4809c000 0x400>;
> +		ti,hwmods = "mmc1";
> +		ti,dual-volt;
> +		bus-width = <4>;
> +		vmmc-supply = <&vmmc>; /* phandle to regulator node */
> +		ti,non-removable;
> +	};
> -- 
> 2.11.0
> 

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
  2017-08-29 17:09                     ` Rob Herring
  (?)
@ 2017-08-29 17:39                       ` Tony Lindgren
  -1 siblings, 0 replies; 86+ messages in thread
From: Tony Lindgren @ 2017-08-29 17:39 UTC (permalink / raw)
  To: Rob Herring
  Cc: Sebastian Reichel, Kishon Vijay Abraham I, Ulf Hansson,
	Adrian Hunter, Sekhar Nori, Russell King, Ravikumar Kattekola,
	linux-mmc, devicetree, linux-kernel, linux-omap,
	linux-arm-kernel

* Rob Herring <robh@kernel.org> [170829 10:09]:
> On Tue, Aug 29, 2017 at 06:58:23AM -0700, Tony Lindgren wrote:
> > * Sebastian Reichel <sebastian.reichel@collabora.co.uk> [170829 04:51]:
> > > I would expect the conversion to look like the one done for UART,
> > > see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
> > > same compatible value and you can choose using kernel configuration.
> > 
> > That does not work unfortunately :( We are now stuck in a situation
> > where two drivers are attempting to probe with the same compatible
> > and we can't enable 8250_OMAP because of the user space breakage
> > with the device names. And I'm actuallly thinking we should add a
> > new compatible for 8250-omap to be able to start enabling it one
> > board at a time.
> 
> Is that the only problem? Presumably, the SD driver doesn't have a 
> userspace facing issue.

No userspace issue with the sdhci-omap. But the sdhci-omap driver
still has the issue of trying enable it for everything at once and
expect everything to work. The sdhci-omap driver can already be
used for boards that don't need power management for example, but
will break things for devices running on batteries.

> > It's best to enable devices to use the new compatible as things are
> > tested rather than hope for some magic "flag day" flip that might
> > never happen. Having two days attempting to probe with the same
> > binding just won't work.
> 
> Aren't you just picking whether the flag day is in DT or the kernel? I 
> guess you're assuming one kernel build and it would be switching all 
> boards at one. 

Right, this would be risky and would take unnecessarily long
to use the new driver on boards that can already use it. While
power management won't work yet, I'd expect the sdhci-omap be
faster on SoCs that can do ADMA.

> > So yeah, I agree with Kishon that we should stick with generic
> > and sdhci bindings. And then we can start already using it for
> > boards that can use it, then eventually when we're ready, start
> > parsing also the legacy bindings and maybe drop the old driver.
> 
> I assume there are some other common properties you would switch to in 
> the transition?  You could make the legacy driver bail from probe based 
> on presence or absence of other properties. Or you could just blacklist 
> converted platforms in the legacy driver. The point is that the problems 
> are solvable in the kernel.

Yes this could be done too. But let's enable it on per-board
basis rather than attempt to flip it on at once.

> But if your really want a new compatible, I don't really care. It's 
> only one device.

Both a new compatible or a check for some resource work just fine
for me as long as the driver can be selected on per-board basis.

Regards,

Tony

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-29 17:39                       ` Tony Lindgren
  0 siblings, 0 replies; 86+ messages in thread
From: Tony Lindgren @ 2017-08-29 17:39 UTC (permalink / raw)
  To: Rob Herring
  Cc: Sebastian Reichel, Kishon Vijay Abraham I, Ulf Hansson,
	Adrian Hunter, Sekhar Nori, Russell King, Ravikumar Kattekola,
	linux-mmc, devicetree, linux-kernel, linux-omap,
	linux-arm-kernel

* Rob Herring <robh@kernel.org> [170829 10:09]:
> On Tue, Aug 29, 2017 at 06:58:23AM -0700, Tony Lindgren wrote:
> > * Sebastian Reichel <sebastian.reichel@collabora.co.uk> [170829 04:51]:
> > > I would expect the conversion to look like the one done for UART,
> > > see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
> > > same compatible value and you can choose using kernel configuration.
> > 
> > That does not work unfortunately :( We are now stuck in a situation
> > where two drivers are attempting to probe with the same compatible
> > and we can't enable 8250_OMAP because of the user space breakage
> > with the device names. And I'm actuallly thinking we should add a
> > new compatible for 8250-omap to be able to start enabling it one
> > board at a time.
> 
> Is that the only problem? Presumably, the SD driver doesn't have a 
> userspace facing issue.

No userspace issue with the sdhci-omap. But the sdhci-omap driver
still has the issue of trying enable it for everything at once and
expect everything to work. The sdhci-omap driver can already be
used for boards that don't need power management for example, but
will break things for devices running on batteries.

> > It's best to enable devices to use the new compatible as things are
> > tested rather than hope for some magic "flag day" flip that might
> > never happen. Having two days attempting to probe with the same
> > binding just won't work.
> 
> Aren't you just picking whether the flag day is in DT or the kernel? I 
> guess you're assuming one kernel build and it would be switching all 
> boards at one. 

Right, this would be risky and would take unnecessarily long
to use the new driver on boards that can already use it. While
power management won't work yet, I'd expect the sdhci-omap be
faster on SoCs that can do ADMA.

> > So yeah, I agree with Kishon that we should stick with generic
> > and sdhci bindings. And then we can start already using it for
> > boards that can use it, then eventually when we're ready, start
> > parsing also the legacy bindings and maybe drop the old driver.
> 
> I assume there are some other common properties you would switch to in 
> the transition?  You could make the legacy driver bail from probe based 
> on presence or absence of other properties. Or you could just blacklist 
> converted platforms in the legacy driver. The point is that the problems 
> are solvable in the kernel.

Yes this could be done too. But let's enable it on per-board
basis rather than attempt to flip it on at once.

> But if your really want a new compatible, I don't really care. It's 
> only one device.

Both a new compatible or a check for some resource work just fine
for me as long as the driver can be selected on per-board basis.

Regards,

Tony

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-08-29 17:39                       ` Tony Lindgren
  0 siblings, 0 replies; 86+ messages in thread
From: Tony Lindgren @ 2017-08-29 17:39 UTC (permalink / raw)
  To: linux-arm-kernel

* Rob Herring <robh@kernel.org> [170829 10:09]:
> On Tue, Aug 29, 2017 at 06:58:23AM -0700, Tony Lindgren wrote:
> > * Sebastian Reichel <sebastian.reichel@collabora.co.uk> [170829 04:51]:
> > > I would expect the conversion to look like the one done for UART,
> > > see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
> > > same compatible value and you can choose using kernel configuration.
> > 
> > That does not work unfortunately :( We are now stuck in a situation
> > where two drivers are attempting to probe with the same compatible
> > and we can't enable 8250_OMAP because of the user space breakage
> > with the device names. And I'm actuallly thinking we should add a
> > new compatible for 8250-omap to be able to start enabling it one
> > board at a time.
> 
> Is that the only problem? Presumably, the SD driver doesn't have a 
> userspace facing issue.

No userspace issue with the sdhci-omap. But the sdhci-omap driver
still has the issue of trying enable it for everything at once and
expect everything to work. The sdhci-omap driver can already be
used for boards that don't need power management for example, but
will break things for devices running on batteries.

> > It's best to enable devices to use the new compatible as things are
> > tested rather than hope for some magic "flag day" flip that might
> > never happen. Having two days attempting to probe with the same
> > binding just won't work.
> 
> Aren't you just picking whether the flag day is in DT or the kernel? I 
> guess you're assuming one kernel build and it would be switching all 
> boards at one. 

Right, this would be risky and would take unnecessarily long
to use the new driver on boards that can already use it. While
power management won't work yet, I'd expect the sdhci-omap be
faster on SoCs that can do ADMA.

> > So yeah, I agree with Kishon that we should stick with generic
> > and sdhci bindings. And then we can start already using it for
> > boards that can use it, then eventually when we're ready, start
> > parsing also the legacy bindings and maybe drop the old driver.
> 
> I assume there are some other common properties you would switch to in 
> the transition?  You could make the legacy driver bail from probe based 
> on presence or absence of other properties. Or you could just blacklist 
> converted platforms in the legacy driver. The point is that the problems 
> are solvable in the kernel.

Yes this could be done too. But let's enable it on per-board
basis rather than attempt to flip it on at once.

> But if your really want a new compatible, I don't really care. It's 
> only one device.

Both a new compatible or a check for some resource work just fine
for me as long as the driver can be selected on per-board basis.

Regards,

Tony

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH 1/5] mmc: sdhci: Tidy reading 136-bit responses
  2017-08-21  7:41   ` Kishon Vijay Abraham I
  (?)
@ 2017-08-30 13:13     ` Ulf Hansson
  -1 siblings, 0 replies; 86+ messages in thread
From: Ulf Hansson @ 2017-08-30 13:13 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Adrian Hunter, Rob Herring, Tony Lindgren, Sekhar Nori,
	Russell King, Ravikumar Kattekola, linux-mmc, devicetree,
	linux-kernel, linux-omap, linux-arm-kernel

On 21 August 2017 at 09:41, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> From: Adrian Hunter <adrian.hunter@intel.com>
>
> Read each register only once and move the code to a separate function so
> that it is not jammed against the 80 column margin.
>
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

Thanks, applied for next!

Kind regards
Uffe

> ---
>  drivers/mmc/host/sdhci.c | 28 ++++++++++++++++++----------
>  1 file changed, 18 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index a1ad2ddadca1..ba639b7851cb 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1173,24 +1173,32 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
>  }
>  EXPORT_SYMBOL_GPL(sdhci_send_command);
>
> +static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
> +{
> +       int i, reg;
> +
> +       for (i = 0; i < 4; i++) {
> +               reg = SDHCI_RESPONSE + (3 - i) * 4;
> +               cmd->resp[i] = sdhci_readl(host, reg);
> +       }
> +
> +       /* CRC is stripped so we need to do some shifting */
> +       for (i = 0; i < 4; i++) {
> +               cmd->resp[i] <<= 8;
> +               if (i != 3)
> +                       cmd->resp[i] |= cmd->resp[i + 1] >> 24;
> +       }
> +}
> +
>  static void sdhci_finish_command(struct sdhci_host *host)
>  {
>         struct mmc_command *cmd = host->cmd;
> -       int i;
>
>         host->cmd = NULL;
>
>         if (cmd->flags & MMC_RSP_PRESENT) {
>                 if (cmd->flags & MMC_RSP_136) {
> -                       /* CRC is stripped so we need to do some shifting. */
> -                       for (i = 0;i < 4;i++) {
> -                               cmd->resp[i] = sdhci_readl(host,
> -                                       SDHCI_RESPONSE + (3-i)*4) << 8;
> -                               if (i != 3)
> -                                       cmd->resp[i] |=
> -                                               sdhci_readb(host,
> -                                               SDHCI_RESPONSE + (3-i)*4-1);
> -                       }
> +                       sdhci_read_rsp_136(host, cmd);
>                 } else {
>                         cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
>                 }
> --
> 2.11.0
>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH 1/5] mmc: sdhci: Tidy reading 136-bit responses
@ 2017-08-30 13:13     ` Ulf Hansson
  0 siblings, 0 replies; 86+ messages in thread
From: Ulf Hansson @ 2017-08-30 13:13 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Adrian Hunter, Rob Herring, Tony Lindgren, Sekhar Nori,
	Russell King, Ravikumar Kattekola, linux-mmc, devicetree,
	linux-kernel, linux-omap, linux-arm-kernel

On 21 August 2017 at 09:41, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> From: Adrian Hunter <adrian.hunter@intel.com>
>
> Read each register only once and move the code to a separate function so
> that it is not jammed against the 80 column margin.
>
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

Thanks, applied for next!

Kind regards
Uffe

> ---
>  drivers/mmc/host/sdhci.c | 28 ++++++++++++++++++----------
>  1 file changed, 18 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index a1ad2ddadca1..ba639b7851cb 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1173,24 +1173,32 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
>  }
>  EXPORT_SYMBOL_GPL(sdhci_send_command);
>
> +static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
> +{
> +       int i, reg;
> +
> +       for (i = 0; i < 4; i++) {
> +               reg = SDHCI_RESPONSE + (3 - i) * 4;
> +               cmd->resp[i] = sdhci_readl(host, reg);
> +       }
> +
> +       /* CRC is stripped so we need to do some shifting */
> +       for (i = 0; i < 4; i++) {
> +               cmd->resp[i] <<= 8;
> +               if (i != 3)
> +                       cmd->resp[i] |= cmd->resp[i + 1] >> 24;
> +       }
> +}
> +
>  static void sdhci_finish_command(struct sdhci_host *host)
>  {
>         struct mmc_command *cmd = host->cmd;
> -       int i;
>
>         host->cmd = NULL;
>
>         if (cmd->flags & MMC_RSP_PRESENT) {
>                 if (cmd->flags & MMC_RSP_136) {
> -                       /* CRC is stripped so we need to do some shifting. */
> -                       for (i = 0;i < 4;i++) {
> -                               cmd->resp[i] = sdhci_readl(host,
> -                                       SDHCI_RESPONSE + (3-i)*4) << 8;
> -                               if (i != 3)
> -                                       cmd->resp[i] |=
> -                                               sdhci_readb(host,
> -                                               SDHCI_RESPONSE + (3-i)*4-1);
> -                       }
> +                       sdhci_read_rsp_136(host, cmd);
>                 } else {
>                         cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
>                 }
> --
> 2.11.0
>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH 1/5] mmc: sdhci: Tidy reading 136-bit responses
@ 2017-08-30 13:13     ` Ulf Hansson
  0 siblings, 0 replies; 86+ messages in thread
From: Ulf Hansson @ 2017-08-30 13:13 UTC (permalink / raw)
  To: linux-arm-kernel

On 21 August 2017 at 09:41, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> From: Adrian Hunter <adrian.hunter@intel.com>
>
> Read each register only once and move the code to a separate function so
> that it is not jammed against the 80 column margin.
>
> Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

Thanks, applied for next!

Kind regards
Uffe

> ---
>  drivers/mmc/host/sdhci.c | 28 ++++++++++++++++++----------
>  1 file changed, 18 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index a1ad2ddadca1..ba639b7851cb 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1173,24 +1173,32 @@ void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
>  }
>  EXPORT_SYMBOL_GPL(sdhci_send_command);
>
> +static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
> +{
> +       int i, reg;
> +
> +       for (i = 0; i < 4; i++) {
> +               reg = SDHCI_RESPONSE + (3 - i) * 4;
> +               cmd->resp[i] = sdhci_readl(host, reg);
> +       }
> +
> +       /* CRC is stripped so we need to do some shifting */
> +       for (i = 0; i < 4; i++) {
> +               cmd->resp[i] <<= 8;
> +               if (i != 3)
> +                       cmd->resp[i] |= cmd->resp[i + 1] >> 24;
> +       }
> +}
> +
>  static void sdhci_finish_command(struct sdhci_host *host)
>  {
>         struct mmc_command *cmd = host->cmd;
> -       int i;
>
>         host->cmd = NULL;
>
>         if (cmd->flags & MMC_RSP_PRESENT) {
>                 if (cmd->flags & MMC_RSP_136) {
> -                       /* CRC is stripped so we need to do some shifting. */
> -                       for (i = 0;i < 4;i++) {
> -                               cmd->resp[i] = sdhci_readl(host,
> -                                       SDHCI_RESPONSE + (3-i)*4) << 8;
> -                               if (i != 3)
> -                                       cmd->resp[i] |=
> -                                               sdhci_readb(host,
> -                                               SDHCI_RESPONSE + (3-i)*4-1);
> -                       }
> +                       sdhci_read_rsp_136(host, cmd);
>                 } else {
>                         cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
>                 }
> --
> 2.11.0
>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH 2/5] mmc: sdhci: Add quirk to indicate MMC_RSP_136 has CRC
  2017-08-21  7:41   ` Kishon Vijay Abraham I
  (?)
@ 2017-08-30 13:13     ` Ulf Hansson
  -1 siblings, 0 replies; 86+ messages in thread
From: Ulf Hansson @ 2017-08-30 13:13 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Adrian Hunter, Rob Herring, Tony Lindgren, Sekhar Nori,
	Russell King, Ravikumar Kattekola, linux-mmc, devicetree,
	linux-kernel, linux-omap, linux-arm-kernel

On 21 August 2017 at 09:41, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> TI's implementation of sdhci controller used in DRA7 SoC's has
> CRC in responses with length 136 bits. Add quirk to indicate
> the controller has CRC in MMC_RSP_136. If this quirk is
> set sdhci library shouldn't shift the response present in
> SDHCI_RESPONSE register.
>
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

Thanks, applied for next!

Kind regards
Uffe

> ---
>  drivers/mmc/host/sdhci.c | 3 +++
>  drivers/mmc/host/sdhci.h | 2 ++
>  2 files changed, 5 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index ba639b7851cb..9c8d7428df3c 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1182,6 +1182,9 @@ static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
>                 cmd->resp[i] = sdhci_readl(host, reg);
>         }
>
> +       if (host->quirks2 & SDHCI_QUIRK2_RSP_136_HAS_CRC)
> +               return;
> +
>         /* CRC is stripped so we need to do some shifting */
>         for (i = 0; i < 4; i++) {
>                 cmd->resp[i] <<= 8;
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 399edc681623..54bc444c317f 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -435,6 +435,8 @@ struct sdhci_host {
>  #define SDHCI_QUIRK2_ACMD23_BROKEN                     (1<<14)
>  /* Broken Clock divider zero in controller */
>  #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN             (1<<15)
> +/* Controller has CRC in 136 bit Command Response */
> +#define SDHCI_QUIRK2_RSP_136_HAS_CRC                   (1<<16)
>
>         int irq;                /* Device IRQ */
>         void __iomem *ioaddr;   /* Mapped address */
> --
> 2.11.0
>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH 2/5] mmc: sdhci: Add quirk to indicate MMC_RSP_136 has CRC
@ 2017-08-30 13:13     ` Ulf Hansson
  0 siblings, 0 replies; 86+ messages in thread
From: Ulf Hansson @ 2017-08-30 13:13 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Adrian Hunter, Rob Herring, Tony Lindgren, Sekhar Nori,
	Russell King, Ravikumar Kattekola, linux-mmc, devicetree,
	linux-kernel, linux-omap, linux-arm-kernel

On 21 August 2017 at 09:41, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> TI's implementation of sdhci controller used in DRA7 SoC's has
> CRC in responses with length 136 bits. Add quirk to indicate
> the controller has CRC in MMC_RSP_136. If this quirk is
> set sdhci library shouldn't shift the response present in
> SDHCI_RESPONSE register.
>
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

Thanks, applied for next!

Kind regards
Uffe

> ---
>  drivers/mmc/host/sdhci.c | 3 +++
>  drivers/mmc/host/sdhci.h | 2 ++
>  2 files changed, 5 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index ba639b7851cb..9c8d7428df3c 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1182,6 +1182,9 @@ static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
>                 cmd->resp[i] = sdhci_readl(host, reg);
>         }
>
> +       if (host->quirks2 & SDHCI_QUIRK2_RSP_136_HAS_CRC)
> +               return;
> +
>         /* CRC is stripped so we need to do some shifting */
>         for (i = 0; i < 4; i++) {
>                 cmd->resp[i] <<= 8;
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 399edc681623..54bc444c317f 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -435,6 +435,8 @@ struct sdhci_host {
>  #define SDHCI_QUIRK2_ACMD23_BROKEN                     (1<<14)
>  /* Broken Clock divider zero in controller */
>  #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN             (1<<15)
> +/* Controller has CRC in 136 bit Command Response */
> +#define SDHCI_QUIRK2_RSP_136_HAS_CRC                   (1<<16)
>
>         int irq;                /* Device IRQ */
>         void __iomem *ioaddr;   /* Mapped address */
> --
> 2.11.0
>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH 2/5] mmc: sdhci: Add quirk to indicate MMC_RSP_136 has CRC
@ 2017-08-30 13:13     ` Ulf Hansson
  0 siblings, 0 replies; 86+ messages in thread
From: Ulf Hansson @ 2017-08-30 13:13 UTC (permalink / raw)
  To: linux-arm-kernel

On 21 August 2017 at 09:41, Kishon Vijay Abraham I <kishon@ti.com> wrote:
> TI's implementation of sdhci controller used in DRA7 SoC's has
> CRC in responses with length 136 bits. Add quirk to indicate
> the controller has CRC in MMC_RSP_136. If this quirk is
> set sdhci library shouldn't shift the response present in
> SDHCI_RESPONSE register.
>
> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>

Thanks, applied for next!

Kind regards
Uffe

> ---
>  drivers/mmc/host/sdhci.c | 3 +++
>  drivers/mmc/host/sdhci.h | 2 ++
>  2 files changed, 5 insertions(+)
>
> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
> index ba639b7851cb..9c8d7428df3c 100644
> --- a/drivers/mmc/host/sdhci.c
> +++ b/drivers/mmc/host/sdhci.c
> @@ -1182,6 +1182,9 @@ static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
>                 cmd->resp[i] = sdhci_readl(host, reg);
>         }
>
> +       if (host->quirks2 & SDHCI_QUIRK2_RSP_136_HAS_CRC)
> +               return;
> +
>         /* CRC is stripped so we need to do some shifting */
>         for (i = 0; i < 4; i++) {
>                 cmd->resp[i] <<= 8;
> diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
> index 399edc681623..54bc444c317f 100644
> --- a/drivers/mmc/host/sdhci.h
> +++ b/drivers/mmc/host/sdhci.h
> @@ -435,6 +435,8 @@ struct sdhci_host {
>  #define SDHCI_QUIRK2_ACMD23_BROKEN                     (1<<14)
>  /* Broken Clock divider zero in controller */
>  #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN             (1<<15)
> +/* Controller has CRC in 136 bit Command Response */
> +#define SDHCI_QUIRK2_RSP_136_HAS_CRC                   (1<<16)
>
>         int irq;                /* Device IRQ */
>         void __iomem *ioaddr;   /* Mapped address */
> --
> 2.11.0
>

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH 4/5] mmc: sdhci-omap: Add OMAP SDHCI driver
  2017-08-28  9:06     ` Adrian Hunter
  (?)
@ 2017-08-30 13:53       ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-30 13:53 UTC (permalink / raw)
  To: Adrian Hunter, Ulf Hansson
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel

Hi,

On Monday 28 August 2017 02:36 PM, Adrian Hunter wrote:
> On 21/08/17 10:41, Kishon Vijay Abraham I wrote:
>> Create a new sdhci-omap driver to configure the eMMC/SD/SDIO controller
>> in TI's OMAP SoCs making use of the SDHCI core library. For OMAP specific
>> configurations, populate sdhci_ops with OMAP specific callbacks and use
>> SDHCI quirks.
>> Enable only high speed mode for both SD and eMMC here and add other
>> UHS mode support later.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> 
> There are a few minor comments below.
> 
>> ---
>>  drivers/mmc/host/Kconfig      |  12 +
>>  drivers/mmc/host/Makefile     |   1 +
>>  drivers/mmc/host/sdhci-omap.c | 629 ++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 642 insertions(+)
>>  create mode 100644 drivers/mmc/host/sdhci-omap.c
>>
>> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
>> index 60f90d49e7a9..60d50843e165 100644
>> --- a/drivers/mmc/host/Kconfig
>> +++ b/drivers/mmc/host/Kconfig
>> @@ -899,3 +899,15 @@ config MMC_SDHCI_XENON
>>  	  This selects Marvell Xenon eMMC/SD/SDIO SDHCI.
>>  	  If you have a controller with this interface, say Y or M here.
>>  	  If unsure, say N.
>> +
>> +config MMC_SDHCI_OMAP
>> +	tristate "TI SDHCI Controller Support"
>> +	depends on MMC_SDHCI_PLTFM
>> +	help
>> +	  This selects the Secure Digital Host Controller Interface (SDHCI)
>> +	  support present in TI's DRA7 SOCs. The controller supports
>> +	  SD/MMC/SDIO devices.
>> +
>> +	  If you have a controller with this interface, say Y or M here.
>> +
>> +	  If unsure, say N.
>> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
>> index 8c46766c000c..33181df88a10 100644
>> --- a/drivers/mmc/host/Makefile
>> +++ b/drivers/mmc/host/Makefile
>> @@ -88,6 +88,7 @@ obj-$(CONFIG_MMC_SDHCI_MSM)		+= sdhci-msm.o
>>  obj-$(CONFIG_MMC_SDHCI_ST)		+= sdhci-st.o
>>  obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32)	+= sdhci-pic32.o
>>  obj-$(CONFIG_MMC_SDHCI_BRCMSTB)		+= sdhci-brcmstb.o
>> +obj-$(CONFIG_MMC_SDHCI_OMAP)		+= sdhci-omap.o
>>  
>>  ifeq ($(CONFIG_CB710_DEBUG),y)
>>  	CFLAGS-cb710-mmc	+= -DDEBUG
>> diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c
>> new file mode 100644
>> index 000000000000..73ee3b4a400c
>> --- /dev/null
>> +++ b/drivers/mmc/host/sdhci-omap.c
>> @@ -0,0 +1,629 @@
>> +/**
>> + * SDHCI Controller driver for TI's OMAP SoCs
>> + *
>> + * Copyright (C) 2017 Texas Instruments
>> + * Author: Kishon Vijay Abraham I <kishon@ti.com>
>> + *
>> + * This program is free software: you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 of
>> + * the License as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include <linux/delay.h>
>> +#include <linux/mmc/slot-gpio.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/of_device.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/regulator/consumer.h>
>> +
>> +#include "sdhci-pltfm.h"
>> +
>> +#define SDHCI_OMAP_CON		0x12c
>> +#define CON_DW8			BIT(5)
>> +#define CON_DMA_MASTER		BIT(20)
>> +#define CON_INIT		BIT(1)
>> +#define CON_OD			BIT(0)
>> +
>> +#define SDHCI_OMAP_CMD		0x20c
>> +
>> +#define SDHCI_OMAP_HCTL		0x228
>> +#define HCTL_SDBP		BIT(8)
>> +#define HCTL_SDVS_SHIFT		9
>> +#define HCTL_SDVS_MASK		(0x7 << HCTL_SDVS_SHIFT)
>> +#define HCTL_SDVS_33		(0x7 << HCTL_SDVS_SHIFT)
>> +#define HCTL_SDVS_30		(0x6 << HCTL_SDVS_SHIFT)
>> +#define HCTL_SDVS_18		(0x5 << HCTL_SDVS_SHIFT)
>> +
>> +#define SDHCI_OMAP_SYSCTL	0x22c
>> +#define SYSCTL_CEN		BIT(2)
>> +#define SYSCTL_CLKD_SHIFT	6
>> +#define SYSCTL_CLKD_MASK	0x3ff
>> +
>> +#define SDHCI_OMAP_STAT		0x230
>> +
>> +#define SDHCI_OMAP_IE		0x234
>> +#define INT_CC_EN		BIT(0)
>> +
>> +#define SDHCI_OMAP_AC12		0x23c
>> +#define AC12_V1V8_SIGEN		BIT(19)
>> +
>> +#define SDHCI_OMAP_CAPA		0x240
>> +#define CAPA_VS33		BIT(24)
>> +#define CAPA_VS30		BIT(25)
>> +#define CAPA_VS18		BIT(26)
>> +
>> +#define MMC_TIMEOUT		1		/* 1 msec */
> 
> As before, SDHCI_OMAP_TIMEOUT is a better name

fixed it now.
> 
>> +
>> +#define SYSCTL_CLKD_MAX		0x3FF
>> +
>> +#define IOV_1V8			1800000		/* 180000 uV */
>> +#define IOV_3V0			3000000		/* 300000 uV */
>> +#define IOV_3V3			3300000		/* 330000 uV */
>> +
>> +struct sdhci_omap_data {
>> +	u32 offset;
>> +};
>> +
>> +struct sdhci_omap_host {
>> +	void __iomem		*base;
>> +	struct device		*dev;
>> +	struct	regulator	*pbias;
>> +	bool			pbias_enabled;
>> +	struct sdhci_host	*host;
>> +	unsigned int		flags;
>> +
>> +#define SDHCI_OMAP_SUPPORTS_DUAL_VOLT	BIT(0)
>> +#define SDHCI_OMAP_NO_1_8_V		BIT(1)
>> +
>> +	u8			bus_mode;
>> +	u8			power_mode;
>> +	bool			io_3_3v_support;
>> +};
>> +
>> +static inline u32 sdhci_omap_readl(struct sdhci_omap_host *host,
>> +				   unsigned int offset)
>> +{
>> +	return readl(host->base + offset);
>> +}
>> +
>> +static inline void sdhci_omap_writel(struct sdhci_omap_host *host,
>> +				     unsigned int offset, u32 data)
>> +{
>> +	writel(data, host->base + offset);
>> +}
>> +
>> +static int sdhci_omap_set_pbias(struct sdhci_omap_host *omap_host,
>> +				bool power_on, unsigned int iov)
>> +{
>> +	int ret;
>> +	struct device *dev = omap_host->dev;
>> +
>> +	if (IS_ERR(omap_host->pbias))
>> +		return 0;
>> +
>> +	if (power_on) {
>> +		ret = regulator_set_voltage(omap_host->pbias, iov, iov);
>> +		if (ret) {
>> +			dev_err(dev, "pbias set voltage failed\n");
>> +			return ret;
>> +		}
>> +
>> +		if (omap_host->pbias_enabled)
>> +			return 0;
>> +
>> +		ret = regulator_enable(omap_host->pbias);
>> +		if (ret) {
>> +			dev_err(dev, "pbias reg enable fail\n");
>> +			return ret;
>> +		}
>> +
>> +		omap_host->pbias_enabled = true;
>> +	} else {
>> +		if (!omap_host->pbias_enabled)
>> +			return 0;
>> +
>> +		ret = regulator_disable(omap_host->pbias);
>> +		if (ret) {
>> +			dev_err(dev, "pbias reg disable fail\n");
>> +			return ret;
>> +		}
>> +		omap_host->pbias_enabled = false;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int sdhci_omap_enable_iov(struct sdhci_omap_host *omap_host,
>> +				 unsigned int iov)
>> +{
>> +	int ret;
>> +	struct sdhci_host *host = omap_host->host;
>> +	struct mmc_host *mmc = host->mmc;
>> +
>> +	ret = sdhci_omap_set_pbias(omap_host, false, 0);
>> +	if (ret)
>> +		return ret;
>> +
>> +	if (!IS_ERR(mmc->supply.vqmmc)) {
>> +		ret = regulator_set_voltage(mmc->supply.vqmmc, iov, iov);
>> +		if (ret) {
>> +			dev_err(mmc_dev(mmc), "vqmmc set voltage failed\n");
>> +			return ret;
>> +		}
>> +	}
>> +
>> +	ret = sdhci_omap_set_pbias(omap_host, true, iov);
>> +	if (ret)
>> +		return ret;
>> +
>> +	return 0;
>> +}
>> +
>> +static void sdhci_omap_conf_bus_power(struct sdhci_omap_host *omap_host,
>> +				      unsigned char signal_voltage)
>> +{
>> +	u32 reg;
>> +	ktime_t timeout;
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL);
>> +	reg &= ~HCTL_SDVS_MASK;
>> +
>> +	if (signal_voltage == MMC_SIGNAL_VOLTAGE_180)
>> +		reg |= HCTL_SDVS_18;
>> +	else if (omap_host->io_3_3v_support)
>> +		reg |= HCTL_SDVS_33;
>> +	else
>> +		reg |= HCTL_SDVS_30;
>> +
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
>> +
>> +	reg |= HCTL_SDBP;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
>> +
>> +	/* wait 1ms */
>> +	timeout = ktime_add_ms(ktime_get(), MMC_TIMEOUT);
>> +	while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL) & HCTL_SDBP)) {
>> +		if (WARN_ON(ktime_after(ktime_get(), timeout)))
>> +			return;
>> +		usleep_range(5, 10);
>> +	}
>> +}
>> +
>> +static int sdhci_omap_start_signal_voltage_switch(struct mmc_host *mmc,
>> +						  struct mmc_ios *ios)
>> +{
>> +	u32 reg;
>> +	int ret;
>> +	unsigned int iov;
>> +	struct sdhci_host *host = mmc_priv(mmc);
>> +	struct sdhci_pltfm_host *pltfm_host;
>> +	struct sdhci_omap_host *omap_host;
>> +	struct device *dev;
>> +
>> +	pltfm_host = sdhci_priv(host);
>> +	omap_host = sdhci_pltfm_priv(pltfm_host);
>> +	dev = omap_host->dev;
>> +
>> +	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
>> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
>> +		if (!(reg & (CAPA_VS33 | CAPA_VS30)))
>> +			return -EOPNOTSUPP;
>> +
>> +		sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
>> +
>> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
>> +		reg &= ~AC12_V1V8_SIGEN;
>> +		sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
>> +
>> +		if (omap_host->io_3_3v_support)
>> +			iov = IOV_3V3;
>> +		else
>> +			iov = IOV_3V0;
>> +	} else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
>> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
>> +		if (!(reg & CAPA_VS18))
>> +			return -EOPNOTSUPP;
>> +
>> +		sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
>> +
>> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
>> +		reg |= AC12_V1V8_SIGEN;
>> +		sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
>> +
>> +		iov = IOV_1V8;
>> +	} else {
>> +		return -EOPNOTSUPP;
>> +	}
>> +
>> +	ret = sdhci_omap_enable_iov(omap_host, iov);
>> +	if (ret) {
>> +		dev_err(dev, "failed to switch IO voltage to %dmV\n", iov);
>> +		return ret;
>> +	}
>> +
>> +	dev_dbg(dev, "IO voltage switched to %dmV\n", iov);
>> +	return 0;
>> +}
>> +
>> +static void sdhci_omap_set_bus_mode(struct sdhci_omap_host *omap_host,
>> +				    unsigned int mode)
>> +{
>> +	u32 reg;
>> +
>> +	if (omap_host->bus_mode == mode)
>> +		return;
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
>> +	if (mode == MMC_BUSMODE_OPENDRAIN)
>> +		reg |= CON_OD;
>> +	else
>> +		reg &= ~CON_OD;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
>> +
>> +	omap_host->bus_mode = mode;
>> +}
>> +
>> +void sdhci_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>> +{
>> +	struct sdhci_host *host = mmc_priv(mmc);
>> +	struct sdhci_pltfm_host *pltfm_host;
>> +	struct sdhci_omap_host *omap_host;
>> +
>> +	pltfm_host = sdhci_priv(host);
>> +	omap_host = sdhci_pltfm_priv(pltfm_host);
>> +
>> +	sdhci_omap_set_bus_mode(omap_host, ios->bus_mode);
>> +	sdhci_set_ios(mmc, ios);
>> +}
>> +
>> +static void sdhci_omap_set_capabilities(struct sdhci_omap_host *omap_host)
>> +{
>> +	u32 reg;
>> +
>> +	/* voltage capabilities might be set by boot loader, clear it */
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
>> +	reg &= ~(CAPA_VS18 | CAPA_VS30 | CAPA_VS33);
>> +
>> +	if (omap_host->flags & SDHCI_OMAP_SUPPORTS_DUAL_VOLT) {
>> +		if (omap_host->io_3_3v_support)
>> +			reg |= (CAPA_VS33 | CAPA_VS18);
>> +		else
>> +			reg |= (CAPA_VS30 | CAPA_VS18);
>> +	} else if (omap_host->flags & SDHCI_OMAP_NO_1_8_V) {
>> +		if (omap_host->io_3_3v_support)
>> +			reg |= CAPA_VS33;
>> +		else
>> +			reg |= CAPA_VS30;
>> +	} else {
>> +		reg |= CAPA_VS18;
>> +	}
>> +
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CAPA, reg);
>> +}
>> +
>> +static u16 sdhci_omap_calc_divisor(struct sdhci_pltfm_host *host,
>> +				   unsigned int clock)
>> +{
>> +	u16 dsor;
>> +
>> +	dsor = DIV_ROUND_UP(clk_get_rate(host->clk), clock);
>> +	if (dsor > SYSCTL_CLKD_MAX)
>> +		dsor = SYSCTL_CLKD_MAX;
>> +
>> +	return dsor;
>> +}
>> +
>> +static void sdhci_omap_start_clock(struct sdhci_omap_host *omap_host)
>> +{
>> +	u32 reg;
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
>> +	reg |= SYSCTL_CEN;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
>> +}
>> +
>> +static void sdhci_omap_stop_clock(struct sdhci_omap_host *omap_host)
>> +{
>> +	u32 reg;
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
>> +	reg &= ~SYSCTL_CEN;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
>> +}
>> +
>> +static void sdhci_omap_set_clock(struct sdhci_host *host, unsigned int clock)
>> +{
>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>> +	unsigned long clkdiv;
>> +
>> +	if (!clock)
>> +		return;
> 
> Are you sure you don't want to stop the clock.

There is never a case where the MMC core sends a request to stop the clock.
Maybe this check is not required at all.
> 
>> +
>> +	sdhci_omap_stop_clock(omap_host);
>> +
>> +	clkdiv = sdhci_omap_calc_divisor(pltfm_host, clock);
>> +	clkdiv = (clkdiv & SYSCTL_CLKD_MASK) << SYSCTL_CLKD_SHIFT;
>> +	sdhci_enable_clk(host, clkdiv);
>> +
>> +	sdhci_omap_start_clock(omap_host);
>> +}
>> +
>> +void sdhci_omap_set_power(struct sdhci_host *host, unsigned char mode,
>> +			  unsigned short vdd)
>> +{
>> +	struct mmc_host *mmc = host->mmc;
>> +
>> +	mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
>> +}
>> +
>> +static int sdhci_omap_enable_dma(struct sdhci_host *host)
>> +{
>> +	u32 reg;
>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
>> +	reg |= CON_DMA_MASTER;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
>> +
>> +	return 0;
>> +}
>> +
>> +unsigned int sdhci_omap_get_min_clock(struct sdhci_host *host)
>> +{
>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +
>> +	return clk_get_rate(pltfm_host->clk) / SYSCTL_CLKD_MAX;
>> +}
>> +
>> +static void sdhci_omap_set_bus_width(struct sdhci_host *host, int width)
>> +{
>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>> +	u32 reg;
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
>> +	if (width == MMC_BUS_WIDTH_8)
>> +		reg |= CON_DW8;
>> +	else
>> +		reg &= ~CON_DW8;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
>> +
>> +	sdhci_set_bus_width(host, width);
>> +}
>> +
>> +static void sdhci_omap_init_74_clocks(struct sdhci_host *host, u8 power_mode)
>> +{
>> +	u32 reg;
>> +	ktime_t timeout;
>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>> +
>> +	if (omap_host->power_mode == power_mode)
>> +		return;
>> +
>> +	if (power_mode != MMC_POWER_ON)
>> +		return;
>> +
>> +	disable_irq(host->irq);
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
>> +	reg |= CON_INIT;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CMD, 0x0);
>> +
>> +	/* wait 1ms */
>> +	timeout = ktime_add_ms(ktime_get(), MMC_TIMEOUT);
>> +	while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_STAT) & INT_CC_EN)) {
>> +		if (WARN_ON(ktime_after(ktime_get(), timeout)))
>> +			return;
>> +		usleep_range(5, 10);
>> +	}
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
>> +	reg &= ~CON_INIT;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_STAT, INT_CC_EN);
>> +
>> +	enable_irq(host->irq);
>> +
>> +	omap_host->power_mode = power_mode;
>> +}
>> +
>> +static struct sdhci_ops sdhci_omap_ops = {
>> +	.set_clock = sdhci_omap_set_clock,
>> +	.set_power = sdhci_omap_set_power,
>> +	.enable_dma = sdhci_omap_enable_dma,
>> +	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
>> +	.get_min_clock = sdhci_omap_get_min_clock,
>> +	.set_bus_width = sdhci_omap_set_bus_width,
>> +	.platform_send_init_74_clocks = sdhci_omap_init_74_clocks,
>> +	.reset = sdhci_reset,
>> +	.set_uhs_signaling = sdhci_set_uhs_signaling,
>> +};
>> +
>> +void sdhci_omap_get_of_property(struct sdhci_omap_host *omap_host)
>> +{
>> +	struct device *dev = omap_host->dev;
>> +	struct sdhci_host *host = omap_host->host;
>> +	struct mmc_host *mmc = host->mmc;
>> +
>> +	if (device_property_read_bool(dev, "ti,dual-volt"))
>> +		omap_host->flags |= SDHCI_OMAP_SUPPORTS_DUAL_VOLT;
>> +
>> +	if (device_property_read_bool(dev, "no-1-8-v"))
>> +		omap_host->flags |= SDHCI_OMAP_NO_1_8_V;
>> +
>> +	if (device_property_read_bool(dev, "ti,non-removable"))
>> +		mmc->caps |= MMC_CAP_NONREMOVABLE;
>> +}
>> +
>> +static const struct sdhci_pltfm_data sdhci_omap_pdata = {
>> +	.quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
>> +		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
>> +		  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
>> +		  SDHCI_QUIRK_NO_HISPD_BIT |
>> +		  SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC,
>> +	.quirks2 = SDHCI_QUIRK2_NO_1_8_V |
>> +		   SDHCI_QUIRK2_ACMD23_BROKEN |
>> +		   SDHCI_QUIRK2_RSP_136_HAS_CRC,
>> +	.ops = &sdhci_omap_ops,
>> +};
>> +
>> +static const struct sdhci_omap_data dra7_data = {
>> +	.offset = 0x200,
>> +};
>> +
>> +static const struct of_device_id omap_sdhci_match[] = {
>> +	{ .compatible = "ti,dra7-sdhci", .data = &dra7_data },
>> +	{},
>> +};
>> +MODULE_DEVICE_TABLE(of, omap_sdhci_match);
>> +
>> +static int sdhci_omap_probe(struct platform_device *pdev)
>> +{
>> +	int ret;
>> +	u32 offset;
>> +	struct device *dev = &pdev->dev;
>> +	struct sdhci_host *host;
>> +	struct sdhci_pltfm_host *pltfm_host;
>> +	struct sdhci_omap_host *omap_host;
>> +	struct mmc_host *mmc;
>> +	const struct of_device_id *match;
>> +	struct sdhci_omap_data *data;
>> +
>> +	match = of_match_device(omap_sdhci_match, dev);
>> +	if (!match)
>> +		return -EINVAL;
>> +
>> +	data = (struct sdhci_omap_data *)match->data;
>> +	if (!data) {
>> +		dev_err(dev, "no sdhci omap data\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	offset = data->offset;
>> +
>> +	host = sdhci_pltfm_init(pdev, &sdhci_omap_pdata,
>> +				sizeof(*omap_host));
>> +	if (IS_ERR(host)) {
>> +		dev_err(dev, "Failed sdhci_pltfm_init\n");
>> +		return PTR_ERR(host);
>> +	}
>> +
>> +	pltfm_host = sdhci_priv(host);
>> +	omap_host = sdhci_pltfm_priv(pltfm_host);
>> +	omap_host->host = host;
>> +	omap_host->base = host->ioaddr;
>> +	omap_host->dev = dev;
>> +	sdhci_omap_get_of_property(omap_host);
>> +
>> +	host->ioaddr += offset;
>> +
>> +	mmc = host->mmc;
>> +	ret = mmc_of_parse(mmc);
>> +	if (ret)
>> +		goto err_of_parse;
>> +
>> +	pltfm_host->clk = devm_clk_get(dev, "fck");
>> +	if (IS_ERR(pltfm_host->clk)) {
>> +		ret = PTR_ERR(pltfm_host->clk);
>> +		goto err_of_parse;
>> +	}
>> +
>> +	ret = clk_set_rate(pltfm_host->clk, mmc->f_max);
>> +	if (ret) {
>> +		dev_err(dev, "failed to set clock to %d\n", mmc->f_max);
>> +		goto err_of_parse;
>> +	}
>> +
>> +	omap_host->pbias = devm_regulator_get_optional(dev, "pbias");
>> +	if (IS_ERR(omap_host->pbias)) {
>> +		ret = PTR_ERR(omap_host->pbias);
>> +		if (ret != -ENODEV) {
>> +			dev_err(dev, "CONFIG_REGULATOR_PBIAS not enabled??\n");
>> +			return ret;
>> +		}
>> +		dev_dbg(dev, "unable to get pbias regulator %ld\n",
>> +			PTR_ERR(omap_host->pbias));
>> +	} else {
>> +		if (regulator_is_supported_voltage(omap_host->pbias, IOV_3V3,
>> +						   IOV_3V3))
>> +			omap_host->io_3_3v_support = true;
>> +		dev_vdbg(dev, "Max PBIAS support Voltage: %dmv\n",
>> +			 omap_host->io_3_3v_support ? IOV_3V3 : IOV_3V0);
>> +	}
>> +	omap_host->pbias_enabled = false;
>> +
>> +	/* Enable main Func clock, interface clock and program SYSCONFIG */
> 
> Maybe also mention that the PM domain does those things.  Out of curiousity,
> what happens if CONFIG_PM is not set?

I think then most of the peripherals will depend on bootloader to enable the
clocks if CONFIG_PM is not set.
> 
>> +	pm_runtime_enable(dev);
>> +	ret = pm_runtime_get_sync(dev);
>> +	if (ret < 0) {
>> +		dev_err(dev, "pm_runtime_get_sync failed\n");
>> +		goto err_get_sync;
> 
> The correct "undo" function for pm_runtime_get_sync() failing is
> pm_runtime_put_noidle() not pm_runtime_put_sync().  So:

yeah right! Missed that.
> 
> 		pm_runtime_put_noidle(dev);
> 		goto err_rpm_disable;
> 
>> +	}
>> +
>> +	sdhci_omap_set_capabilities(omap_host);
>> +
>> +	host->mmc_host_ops.get_ro = mmc_gpio_get_ro;
>> +	host->mmc_host_ops.start_signal_voltage_switch =
>> +					sdhci_omap_start_signal_voltage_switch;
>> +	host->mmc_host_ops.set_ios = sdhci_omap_set_ios;
>> +
>> +	sdhci_read_caps(host);
>> +	host->caps |= SDHCI_CAN_DO_ADMA2;
>> +
>> +	ret = sdhci_add_host(host);
>> +	if (ret)
>> +		goto err_get_sync;
>> +
>> +	return 0;
>> +
>> +err_get_sync:
> 
> It is more usual for error labels to describe what they will do rather than
> what failed. i.e. this would be err_put_sync:
> 
>> +	pm_runtime_put_sync(dev);
> 
> err_rpm_disable:
> 
>> +	pm_runtime_disable(dev);
>> +
>> +err_of_parse:
> 
> err_pltfm_free:
> 
>> +	sdhci_pltfm_free(pdev);
>> +	return ret;
>> +}
>> +
>> +static int sdhci_omap_remove(struct platform_device *pdev)
>> +{
>> +	struct device *dev = &pdev->dev;
>> +	struct sdhci_host *host = platform_get_drvdata(pdev);
>> +
>> +	sdhci_remove_host(host, true);
>> +	pm_runtime_put_sync(dev);
>> +	pm_runtime_disable(dev);
>> +	sdhci_pltfm_free(pdev);
>> +
>> +	return 0;
>> +}
>> +
>> +static struct platform_driver sdhci_omap_driver = {
>> +	.probe = sdhci_omap_probe,
>> +	.remove = sdhci_omap_remove,
>> +	.driver = {
>> +		   .name = "sdhci-omap",
>> +		   .of_match_table = of_match_ptr(omap_sdhci_match),
> 
> Don't you need #ifdef CONFIG_OF around the table if you use of_match_ptr()?

yeah. I think I'll remove of_match_ptr here and make the driver depend on OF.
> 
>> +		  },
>> +};
>> +
>> +module_platform_driver(sdhci_omap_driver);
>> +
>> +MODULE_DESCRIPTION("SDHCI driver for OMAP SoCs");
>> +MODULE_AUTHOR("Texas Instruments Inc.");
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_ALIAS("OMAP SDHCI Driver");
> 
> A module alias with spaces in it looks strange.  Is that the intention?

No. Will fix it.

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH 4/5] mmc: sdhci-omap: Add OMAP SDHCI driver
@ 2017-08-30 13:53       ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-30 13:53 UTC (permalink / raw)
  To: Adrian Hunter, Ulf Hansson
  Cc: devicetree, Tony Lindgren, Sekhar Nori, linux-mmc, Russell King,
	linux-kernel, Rob Herring, Ravikumar Kattekola, linux-omap,
	linux-arm-kernel

Hi,

On Monday 28 August 2017 02:36 PM, Adrian Hunter wrote:
> On 21/08/17 10:41, Kishon Vijay Abraham I wrote:
>> Create a new sdhci-omap driver to configure the eMMC/SD/SDIO controller
>> in TI's OMAP SoCs making use of the SDHCI core library. For OMAP specific
>> configurations, populate sdhci_ops with OMAP specific callbacks and use
>> SDHCI quirks.
>> Enable only high speed mode for both SD and eMMC here and add other
>> UHS mode support later.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> 
> There are a few minor comments below.
> 
>> ---
>>  drivers/mmc/host/Kconfig      |  12 +
>>  drivers/mmc/host/Makefile     |   1 +
>>  drivers/mmc/host/sdhci-omap.c | 629 ++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 642 insertions(+)
>>  create mode 100644 drivers/mmc/host/sdhci-omap.c
>>
>> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
>> index 60f90d49e7a9..60d50843e165 100644
>> --- a/drivers/mmc/host/Kconfig
>> +++ b/drivers/mmc/host/Kconfig
>> @@ -899,3 +899,15 @@ config MMC_SDHCI_XENON
>>  	  This selects Marvell Xenon eMMC/SD/SDIO SDHCI.
>>  	  If you have a controller with this interface, say Y or M here.
>>  	  If unsure, say N.
>> +
>> +config MMC_SDHCI_OMAP
>> +	tristate "TI SDHCI Controller Support"
>> +	depends on MMC_SDHCI_PLTFM
>> +	help
>> +	  This selects the Secure Digital Host Controller Interface (SDHCI)
>> +	  support present in TI's DRA7 SOCs. The controller supports
>> +	  SD/MMC/SDIO devices.
>> +
>> +	  If you have a controller with this interface, say Y or M here.
>> +
>> +	  If unsure, say N.
>> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
>> index 8c46766c000c..33181df88a10 100644
>> --- a/drivers/mmc/host/Makefile
>> +++ b/drivers/mmc/host/Makefile
>> @@ -88,6 +88,7 @@ obj-$(CONFIG_MMC_SDHCI_MSM)		+= sdhci-msm.o
>>  obj-$(CONFIG_MMC_SDHCI_ST)		+= sdhci-st.o
>>  obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32)	+= sdhci-pic32.o
>>  obj-$(CONFIG_MMC_SDHCI_BRCMSTB)		+= sdhci-brcmstb.o
>> +obj-$(CONFIG_MMC_SDHCI_OMAP)		+= sdhci-omap.o
>>  
>>  ifeq ($(CONFIG_CB710_DEBUG),y)
>>  	CFLAGS-cb710-mmc	+= -DDEBUG
>> diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c
>> new file mode 100644
>> index 000000000000..73ee3b4a400c
>> --- /dev/null
>> +++ b/drivers/mmc/host/sdhci-omap.c
>> @@ -0,0 +1,629 @@
>> +/**
>> + * SDHCI Controller driver for TI's OMAP SoCs
>> + *
>> + * Copyright (C) 2017 Texas Instruments
>> + * Author: Kishon Vijay Abraham I <kishon@ti.com>
>> + *
>> + * This program is free software: you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 of
>> + * the License as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include <linux/delay.h>
>> +#include <linux/mmc/slot-gpio.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/of_device.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/regulator/consumer.h>
>> +
>> +#include "sdhci-pltfm.h"
>> +
>> +#define SDHCI_OMAP_CON		0x12c
>> +#define CON_DW8			BIT(5)
>> +#define CON_DMA_MASTER		BIT(20)
>> +#define CON_INIT		BIT(1)
>> +#define CON_OD			BIT(0)
>> +
>> +#define SDHCI_OMAP_CMD		0x20c
>> +
>> +#define SDHCI_OMAP_HCTL		0x228
>> +#define HCTL_SDBP		BIT(8)
>> +#define HCTL_SDVS_SHIFT		9
>> +#define HCTL_SDVS_MASK		(0x7 << HCTL_SDVS_SHIFT)
>> +#define HCTL_SDVS_33		(0x7 << HCTL_SDVS_SHIFT)
>> +#define HCTL_SDVS_30		(0x6 << HCTL_SDVS_SHIFT)
>> +#define HCTL_SDVS_18		(0x5 << HCTL_SDVS_SHIFT)
>> +
>> +#define SDHCI_OMAP_SYSCTL	0x22c
>> +#define SYSCTL_CEN		BIT(2)
>> +#define SYSCTL_CLKD_SHIFT	6
>> +#define SYSCTL_CLKD_MASK	0x3ff
>> +
>> +#define SDHCI_OMAP_STAT		0x230
>> +
>> +#define SDHCI_OMAP_IE		0x234
>> +#define INT_CC_EN		BIT(0)
>> +
>> +#define SDHCI_OMAP_AC12		0x23c
>> +#define AC12_V1V8_SIGEN		BIT(19)
>> +
>> +#define SDHCI_OMAP_CAPA		0x240
>> +#define CAPA_VS33		BIT(24)
>> +#define CAPA_VS30		BIT(25)
>> +#define CAPA_VS18		BIT(26)
>> +
>> +#define MMC_TIMEOUT		1		/* 1 msec */
> 
> As before, SDHCI_OMAP_TIMEOUT is a better name

fixed it now.
> 
>> +
>> +#define SYSCTL_CLKD_MAX		0x3FF
>> +
>> +#define IOV_1V8			1800000		/* 180000 uV */
>> +#define IOV_3V0			3000000		/* 300000 uV */
>> +#define IOV_3V3			3300000		/* 330000 uV */
>> +
>> +struct sdhci_omap_data {
>> +	u32 offset;
>> +};
>> +
>> +struct sdhci_omap_host {
>> +	void __iomem		*base;
>> +	struct device		*dev;
>> +	struct	regulator	*pbias;
>> +	bool			pbias_enabled;
>> +	struct sdhci_host	*host;
>> +	unsigned int		flags;
>> +
>> +#define SDHCI_OMAP_SUPPORTS_DUAL_VOLT	BIT(0)
>> +#define SDHCI_OMAP_NO_1_8_V		BIT(1)
>> +
>> +	u8			bus_mode;
>> +	u8			power_mode;
>> +	bool			io_3_3v_support;
>> +};
>> +
>> +static inline u32 sdhci_omap_readl(struct sdhci_omap_host *host,
>> +				   unsigned int offset)
>> +{
>> +	return readl(host->base + offset);
>> +}
>> +
>> +static inline void sdhci_omap_writel(struct sdhci_omap_host *host,
>> +				     unsigned int offset, u32 data)
>> +{
>> +	writel(data, host->base + offset);
>> +}
>> +
>> +static int sdhci_omap_set_pbias(struct sdhci_omap_host *omap_host,
>> +				bool power_on, unsigned int iov)
>> +{
>> +	int ret;
>> +	struct device *dev = omap_host->dev;
>> +
>> +	if (IS_ERR(omap_host->pbias))
>> +		return 0;
>> +
>> +	if (power_on) {
>> +		ret = regulator_set_voltage(omap_host->pbias, iov, iov);
>> +		if (ret) {
>> +			dev_err(dev, "pbias set voltage failed\n");
>> +			return ret;
>> +		}
>> +
>> +		if (omap_host->pbias_enabled)
>> +			return 0;
>> +
>> +		ret = regulator_enable(omap_host->pbias);
>> +		if (ret) {
>> +			dev_err(dev, "pbias reg enable fail\n");
>> +			return ret;
>> +		}
>> +
>> +		omap_host->pbias_enabled = true;
>> +	} else {
>> +		if (!omap_host->pbias_enabled)
>> +			return 0;
>> +
>> +		ret = regulator_disable(omap_host->pbias);
>> +		if (ret) {
>> +			dev_err(dev, "pbias reg disable fail\n");
>> +			return ret;
>> +		}
>> +		omap_host->pbias_enabled = false;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int sdhci_omap_enable_iov(struct sdhci_omap_host *omap_host,
>> +				 unsigned int iov)
>> +{
>> +	int ret;
>> +	struct sdhci_host *host = omap_host->host;
>> +	struct mmc_host *mmc = host->mmc;
>> +
>> +	ret = sdhci_omap_set_pbias(omap_host, false, 0);
>> +	if (ret)
>> +		return ret;
>> +
>> +	if (!IS_ERR(mmc->supply.vqmmc)) {
>> +		ret = regulator_set_voltage(mmc->supply.vqmmc, iov, iov);
>> +		if (ret) {
>> +			dev_err(mmc_dev(mmc), "vqmmc set voltage failed\n");
>> +			return ret;
>> +		}
>> +	}
>> +
>> +	ret = sdhci_omap_set_pbias(omap_host, true, iov);
>> +	if (ret)
>> +		return ret;
>> +
>> +	return 0;
>> +}
>> +
>> +static void sdhci_omap_conf_bus_power(struct sdhci_omap_host *omap_host,
>> +				      unsigned char signal_voltage)
>> +{
>> +	u32 reg;
>> +	ktime_t timeout;
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL);
>> +	reg &= ~HCTL_SDVS_MASK;
>> +
>> +	if (signal_voltage == MMC_SIGNAL_VOLTAGE_180)
>> +		reg |= HCTL_SDVS_18;
>> +	else if (omap_host->io_3_3v_support)
>> +		reg |= HCTL_SDVS_33;
>> +	else
>> +		reg |= HCTL_SDVS_30;
>> +
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
>> +
>> +	reg |= HCTL_SDBP;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
>> +
>> +	/* wait 1ms */
>> +	timeout = ktime_add_ms(ktime_get(), MMC_TIMEOUT);
>> +	while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL) & HCTL_SDBP)) {
>> +		if (WARN_ON(ktime_after(ktime_get(), timeout)))
>> +			return;
>> +		usleep_range(5, 10);
>> +	}
>> +}
>> +
>> +static int sdhci_omap_start_signal_voltage_switch(struct mmc_host *mmc,
>> +						  struct mmc_ios *ios)
>> +{
>> +	u32 reg;
>> +	int ret;
>> +	unsigned int iov;
>> +	struct sdhci_host *host = mmc_priv(mmc);
>> +	struct sdhci_pltfm_host *pltfm_host;
>> +	struct sdhci_omap_host *omap_host;
>> +	struct device *dev;
>> +
>> +	pltfm_host = sdhci_priv(host);
>> +	omap_host = sdhci_pltfm_priv(pltfm_host);
>> +	dev = omap_host->dev;
>> +
>> +	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
>> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
>> +		if (!(reg & (CAPA_VS33 | CAPA_VS30)))
>> +			return -EOPNOTSUPP;
>> +
>> +		sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
>> +
>> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
>> +		reg &= ~AC12_V1V8_SIGEN;
>> +		sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
>> +
>> +		if (omap_host->io_3_3v_support)
>> +			iov = IOV_3V3;
>> +		else
>> +			iov = IOV_3V0;
>> +	} else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
>> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
>> +		if (!(reg & CAPA_VS18))
>> +			return -EOPNOTSUPP;
>> +
>> +		sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
>> +
>> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
>> +		reg |= AC12_V1V8_SIGEN;
>> +		sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
>> +
>> +		iov = IOV_1V8;
>> +	} else {
>> +		return -EOPNOTSUPP;
>> +	}
>> +
>> +	ret = sdhci_omap_enable_iov(omap_host, iov);
>> +	if (ret) {
>> +		dev_err(dev, "failed to switch IO voltage to %dmV\n", iov);
>> +		return ret;
>> +	}
>> +
>> +	dev_dbg(dev, "IO voltage switched to %dmV\n", iov);
>> +	return 0;
>> +}
>> +
>> +static void sdhci_omap_set_bus_mode(struct sdhci_omap_host *omap_host,
>> +				    unsigned int mode)
>> +{
>> +	u32 reg;
>> +
>> +	if (omap_host->bus_mode == mode)
>> +		return;
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
>> +	if (mode == MMC_BUSMODE_OPENDRAIN)
>> +		reg |= CON_OD;
>> +	else
>> +		reg &= ~CON_OD;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
>> +
>> +	omap_host->bus_mode = mode;
>> +}
>> +
>> +void sdhci_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>> +{
>> +	struct sdhci_host *host = mmc_priv(mmc);
>> +	struct sdhci_pltfm_host *pltfm_host;
>> +	struct sdhci_omap_host *omap_host;
>> +
>> +	pltfm_host = sdhci_priv(host);
>> +	omap_host = sdhci_pltfm_priv(pltfm_host);
>> +
>> +	sdhci_omap_set_bus_mode(omap_host, ios->bus_mode);
>> +	sdhci_set_ios(mmc, ios);
>> +}
>> +
>> +static void sdhci_omap_set_capabilities(struct sdhci_omap_host *omap_host)
>> +{
>> +	u32 reg;
>> +
>> +	/* voltage capabilities might be set by boot loader, clear it */
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
>> +	reg &= ~(CAPA_VS18 | CAPA_VS30 | CAPA_VS33);
>> +
>> +	if (omap_host->flags & SDHCI_OMAP_SUPPORTS_DUAL_VOLT) {
>> +		if (omap_host->io_3_3v_support)
>> +			reg |= (CAPA_VS33 | CAPA_VS18);
>> +		else
>> +			reg |= (CAPA_VS30 | CAPA_VS18);
>> +	} else if (omap_host->flags & SDHCI_OMAP_NO_1_8_V) {
>> +		if (omap_host->io_3_3v_support)
>> +			reg |= CAPA_VS33;
>> +		else
>> +			reg |= CAPA_VS30;
>> +	} else {
>> +		reg |= CAPA_VS18;
>> +	}
>> +
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CAPA, reg);
>> +}
>> +
>> +static u16 sdhci_omap_calc_divisor(struct sdhci_pltfm_host *host,
>> +				   unsigned int clock)
>> +{
>> +	u16 dsor;
>> +
>> +	dsor = DIV_ROUND_UP(clk_get_rate(host->clk), clock);
>> +	if (dsor > SYSCTL_CLKD_MAX)
>> +		dsor = SYSCTL_CLKD_MAX;
>> +
>> +	return dsor;
>> +}
>> +
>> +static void sdhci_omap_start_clock(struct sdhci_omap_host *omap_host)
>> +{
>> +	u32 reg;
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
>> +	reg |= SYSCTL_CEN;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
>> +}
>> +
>> +static void sdhci_omap_stop_clock(struct sdhci_omap_host *omap_host)
>> +{
>> +	u32 reg;
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
>> +	reg &= ~SYSCTL_CEN;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
>> +}
>> +
>> +static void sdhci_omap_set_clock(struct sdhci_host *host, unsigned int clock)
>> +{
>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>> +	unsigned long clkdiv;
>> +
>> +	if (!clock)
>> +		return;
> 
> Are you sure you don't want to stop the clock.

There is never a case where the MMC core sends a request to stop the clock.
Maybe this check is not required at all.
> 
>> +
>> +	sdhci_omap_stop_clock(omap_host);
>> +
>> +	clkdiv = sdhci_omap_calc_divisor(pltfm_host, clock);
>> +	clkdiv = (clkdiv & SYSCTL_CLKD_MASK) << SYSCTL_CLKD_SHIFT;
>> +	sdhci_enable_clk(host, clkdiv);
>> +
>> +	sdhci_omap_start_clock(omap_host);
>> +}
>> +
>> +void sdhci_omap_set_power(struct sdhci_host *host, unsigned char mode,
>> +			  unsigned short vdd)
>> +{
>> +	struct mmc_host *mmc = host->mmc;
>> +
>> +	mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
>> +}
>> +
>> +static int sdhci_omap_enable_dma(struct sdhci_host *host)
>> +{
>> +	u32 reg;
>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
>> +	reg |= CON_DMA_MASTER;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
>> +
>> +	return 0;
>> +}
>> +
>> +unsigned int sdhci_omap_get_min_clock(struct sdhci_host *host)
>> +{
>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +
>> +	return clk_get_rate(pltfm_host->clk) / SYSCTL_CLKD_MAX;
>> +}
>> +
>> +static void sdhci_omap_set_bus_width(struct sdhci_host *host, int width)
>> +{
>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>> +	u32 reg;
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
>> +	if (width == MMC_BUS_WIDTH_8)
>> +		reg |= CON_DW8;
>> +	else
>> +		reg &= ~CON_DW8;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
>> +
>> +	sdhci_set_bus_width(host, width);
>> +}
>> +
>> +static void sdhci_omap_init_74_clocks(struct sdhci_host *host, u8 power_mode)
>> +{
>> +	u32 reg;
>> +	ktime_t timeout;
>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>> +
>> +	if (omap_host->power_mode == power_mode)
>> +		return;
>> +
>> +	if (power_mode != MMC_POWER_ON)
>> +		return;
>> +
>> +	disable_irq(host->irq);
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
>> +	reg |= CON_INIT;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CMD, 0x0);
>> +
>> +	/* wait 1ms */
>> +	timeout = ktime_add_ms(ktime_get(), MMC_TIMEOUT);
>> +	while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_STAT) & INT_CC_EN)) {
>> +		if (WARN_ON(ktime_after(ktime_get(), timeout)))
>> +			return;
>> +		usleep_range(5, 10);
>> +	}
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
>> +	reg &= ~CON_INIT;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_STAT, INT_CC_EN);
>> +
>> +	enable_irq(host->irq);
>> +
>> +	omap_host->power_mode = power_mode;
>> +}
>> +
>> +static struct sdhci_ops sdhci_omap_ops = {
>> +	.set_clock = sdhci_omap_set_clock,
>> +	.set_power = sdhci_omap_set_power,
>> +	.enable_dma = sdhci_omap_enable_dma,
>> +	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
>> +	.get_min_clock = sdhci_omap_get_min_clock,
>> +	.set_bus_width = sdhci_omap_set_bus_width,
>> +	.platform_send_init_74_clocks = sdhci_omap_init_74_clocks,
>> +	.reset = sdhci_reset,
>> +	.set_uhs_signaling = sdhci_set_uhs_signaling,
>> +};
>> +
>> +void sdhci_omap_get_of_property(struct sdhci_omap_host *omap_host)
>> +{
>> +	struct device *dev = omap_host->dev;
>> +	struct sdhci_host *host = omap_host->host;
>> +	struct mmc_host *mmc = host->mmc;
>> +
>> +	if (device_property_read_bool(dev, "ti,dual-volt"))
>> +		omap_host->flags |= SDHCI_OMAP_SUPPORTS_DUAL_VOLT;
>> +
>> +	if (device_property_read_bool(dev, "no-1-8-v"))
>> +		omap_host->flags |= SDHCI_OMAP_NO_1_8_V;
>> +
>> +	if (device_property_read_bool(dev, "ti,non-removable"))
>> +		mmc->caps |= MMC_CAP_NONREMOVABLE;
>> +}
>> +
>> +static const struct sdhci_pltfm_data sdhci_omap_pdata = {
>> +	.quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
>> +		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
>> +		  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
>> +		  SDHCI_QUIRK_NO_HISPD_BIT |
>> +		  SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC,
>> +	.quirks2 = SDHCI_QUIRK2_NO_1_8_V |
>> +		   SDHCI_QUIRK2_ACMD23_BROKEN |
>> +		   SDHCI_QUIRK2_RSP_136_HAS_CRC,
>> +	.ops = &sdhci_omap_ops,
>> +};
>> +
>> +static const struct sdhci_omap_data dra7_data = {
>> +	.offset = 0x200,
>> +};
>> +
>> +static const struct of_device_id omap_sdhci_match[] = {
>> +	{ .compatible = "ti,dra7-sdhci", .data = &dra7_data },
>> +	{},
>> +};
>> +MODULE_DEVICE_TABLE(of, omap_sdhci_match);
>> +
>> +static int sdhci_omap_probe(struct platform_device *pdev)
>> +{
>> +	int ret;
>> +	u32 offset;
>> +	struct device *dev = &pdev->dev;
>> +	struct sdhci_host *host;
>> +	struct sdhci_pltfm_host *pltfm_host;
>> +	struct sdhci_omap_host *omap_host;
>> +	struct mmc_host *mmc;
>> +	const struct of_device_id *match;
>> +	struct sdhci_omap_data *data;
>> +
>> +	match = of_match_device(omap_sdhci_match, dev);
>> +	if (!match)
>> +		return -EINVAL;
>> +
>> +	data = (struct sdhci_omap_data *)match->data;
>> +	if (!data) {
>> +		dev_err(dev, "no sdhci omap data\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	offset = data->offset;
>> +
>> +	host = sdhci_pltfm_init(pdev, &sdhci_omap_pdata,
>> +				sizeof(*omap_host));
>> +	if (IS_ERR(host)) {
>> +		dev_err(dev, "Failed sdhci_pltfm_init\n");
>> +		return PTR_ERR(host);
>> +	}
>> +
>> +	pltfm_host = sdhci_priv(host);
>> +	omap_host = sdhci_pltfm_priv(pltfm_host);
>> +	omap_host->host = host;
>> +	omap_host->base = host->ioaddr;
>> +	omap_host->dev = dev;
>> +	sdhci_omap_get_of_property(omap_host);
>> +
>> +	host->ioaddr += offset;
>> +
>> +	mmc = host->mmc;
>> +	ret = mmc_of_parse(mmc);
>> +	if (ret)
>> +		goto err_of_parse;
>> +
>> +	pltfm_host->clk = devm_clk_get(dev, "fck");
>> +	if (IS_ERR(pltfm_host->clk)) {
>> +		ret = PTR_ERR(pltfm_host->clk);
>> +		goto err_of_parse;
>> +	}
>> +
>> +	ret = clk_set_rate(pltfm_host->clk, mmc->f_max);
>> +	if (ret) {
>> +		dev_err(dev, "failed to set clock to %d\n", mmc->f_max);
>> +		goto err_of_parse;
>> +	}
>> +
>> +	omap_host->pbias = devm_regulator_get_optional(dev, "pbias");
>> +	if (IS_ERR(omap_host->pbias)) {
>> +		ret = PTR_ERR(omap_host->pbias);
>> +		if (ret != -ENODEV) {
>> +			dev_err(dev, "CONFIG_REGULATOR_PBIAS not enabled??\n");
>> +			return ret;
>> +		}
>> +		dev_dbg(dev, "unable to get pbias regulator %ld\n",
>> +			PTR_ERR(omap_host->pbias));
>> +	} else {
>> +		if (regulator_is_supported_voltage(omap_host->pbias, IOV_3V3,
>> +						   IOV_3V3))
>> +			omap_host->io_3_3v_support = true;
>> +		dev_vdbg(dev, "Max PBIAS support Voltage: %dmv\n",
>> +			 omap_host->io_3_3v_support ? IOV_3V3 : IOV_3V0);
>> +	}
>> +	omap_host->pbias_enabled = false;
>> +
>> +	/* Enable main Func clock, interface clock and program SYSCONFIG */
> 
> Maybe also mention that the PM domain does those things.  Out of curiousity,
> what happens if CONFIG_PM is not set?

I think then most of the peripherals will depend on bootloader to enable the
clocks if CONFIG_PM is not set.
> 
>> +	pm_runtime_enable(dev);
>> +	ret = pm_runtime_get_sync(dev);
>> +	if (ret < 0) {
>> +		dev_err(dev, "pm_runtime_get_sync failed\n");
>> +		goto err_get_sync;
> 
> The correct "undo" function for pm_runtime_get_sync() failing is
> pm_runtime_put_noidle() not pm_runtime_put_sync().  So:

yeah right! Missed that.
> 
> 		pm_runtime_put_noidle(dev);
> 		goto err_rpm_disable;
> 
>> +	}
>> +
>> +	sdhci_omap_set_capabilities(omap_host);
>> +
>> +	host->mmc_host_ops.get_ro = mmc_gpio_get_ro;
>> +	host->mmc_host_ops.start_signal_voltage_switch =
>> +					sdhci_omap_start_signal_voltage_switch;
>> +	host->mmc_host_ops.set_ios = sdhci_omap_set_ios;
>> +
>> +	sdhci_read_caps(host);
>> +	host->caps |= SDHCI_CAN_DO_ADMA2;
>> +
>> +	ret = sdhci_add_host(host);
>> +	if (ret)
>> +		goto err_get_sync;
>> +
>> +	return 0;
>> +
>> +err_get_sync:
> 
> It is more usual for error labels to describe what they will do rather than
> what failed. i.e. this would be err_put_sync:
> 
>> +	pm_runtime_put_sync(dev);
> 
> err_rpm_disable:
> 
>> +	pm_runtime_disable(dev);
>> +
>> +err_of_parse:
> 
> err_pltfm_free:
> 
>> +	sdhci_pltfm_free(pdev);
>> +	return ret;
>> +}
>> +
>> +static int sdhci_omap_remove(struct platform_device *pdev)
>> +{
>> +	struct device *dev = &pdev->dev;
>> +	struct sdhci_host *host = platform_get_drvdata(pdev);
>> +
>> +	sdhci_remove_host(host, true);
>> +	pm_runtime_put_sync(dev);
>> +	pm_runtime_disable(dev);
>> +	sdhci_pltfm_free(pdev);
>> +
>> +	return 0;
>> +}
>> +
>> +static struct platform_driver sdhci_omap_driver = {
>> +	.probe = sdhci_omap_probe,
>> +	.remove = sdhci_omap_remove,
>> +	.driver = {
>> +		   .name = "sdhci-omap",
>> +		   .of_match_table = of_match_ptr(omap_sdhci_match),
> 
> Don't you need #ifdef CONFIG_OF around the table if you use of_match_ptr()?

yeah. I think I'll remove of_match_ptr here and make the driver depend on OF.
> 
>> +		  },
>> +};
>> +
>> +module_platform_driver(sdhci_omap_driver);
>> +
>> +MODULE_DESCRIPTION("SDHCI driver for OMAP SoCs");
>> +MODULE_AUTHOR("Texas Instruments Inc.");
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_ALIAS("OMAP SDHCI Driver");
> 
> A module alias with spaces in it looks strange.  Is that the intention?

No. Will fix it.

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH 4/5] mmc: sdhci-omap: Add OMAP SDHCI driver
@ 2017-08-30 13:53       ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-08-30 13:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Monday 28 August 2017 02:36 PM, Adrian Hunter wrote:
> On 21/08/17 10:41, Kishon Vijay Abraham I wrote:
>> Create a new sdhci-omap driver to configure the eMMC/SD/SDIO controller
>> in TI's OMAP SoCs making use of the SDHCI core library. For OMAP specific
>> configurations, populate sdhci_ops with OMAP specific callbacks and use
>> SDHCI quirks.
>> Enable only high speed mode for both SD and eMMC here and add other
>> UHS mode support later.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
> 
> There are a few minor comments below.
> 
>> ---
>>  drivers/mmc/host/Kconfig      |  12 +
>>  drivers/mmc/host/Makefile     |   1 +
>>  drivers/mmc/host/sdhci-omap.c | 629 ++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 642 insertions(+)
>>  create mode 100644 drivers/mmc/host/sdhci-omap.c
>>
>> diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
>> index 60f90d49e7a9..60d50843e165 100644
>> --- a/drivers/mmc/host/Kconfig
>> +++ b/drivers/mmc/host/Kconfig
>> @@ -899,3 +899,15 @@ config MMC_SDHCI_XENON
>>  	  This selects Marvell Xenon eMMC/SD/SDIO SDHCI.
>>  	  If you have a controller with this interface, say Y or M here.
>>  	  If unsure, say N.
>> +
>> +config MMC_SDHCI_OMAP
>> +	tristate "TI SDHCI Controller Support"
>> +	depends on MMC_SDHCI_PLTFM
>> +	help
>> +	  This selects the Secure Digital Host Controller Interface (SDHCI)
>> +	  support present in TI's DRA7 SOCs. The controller supports
>> +	  SD/MMC/SDIO devices.
>> +
>> +	  If you have a controller with this interface, say Y or M here.
>> +
>> +	  If unsure, say N.
>> diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
>> index 8c46766c000c..33181df88a10 100644
>> --- a/drivers/mmc/host/Makefile
>> +++ b/drivers/mmc/host/Makefile
>> @@ -88,6 +88,7 @@ obj-$(CONFIG_MMC_SDHCI_MSM)		+= sdhci-msm.o
>>  obj-$(CONFIG_MMC_SDHCI_ST)		+= sdhci-st.o
>>  obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32)	+= sdhci-pic32.o
>>  obj-$(CONFIG_MMC_SDHCI_BRCMSTB)		+= sdhci-brcmstb.o
>> +obj-$(CONFIG_MMC_SDHCI_OMAP)		+= sdhci-omap.o
>>  
>>  ifeq ($(CONFIG_CB710_DEBUG),y)
>>  	CFLAGS-cb710-mmc	+= -DDEBUG
>> diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c
>> new file mode 100644
>> index 000000000000..73ee3b4a400c
>> --- /dev/null
>> +++ b/drivers/mmc/host/sdhci-omap.c
>> @@ -0,0 +1,629 @@
>> +/**
>> + * SDHCI Controller driver for TI's OMAP SoCs
>> + *
>> + * Copyright (C) 2017 Texas Instruments
>> + * Author: Kishon Vijay Abraham I <kishon@ti.com>
>> + *
>> + * This program is free software: you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 of
>> + * the License as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
>> + */
>> +
>> +#include <linux/delay.h>
>> +#include <linux/mmc/slot-gpio.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/of_device.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/pm_runtime.h>
>> +#include <linux/regulator/consumer.h>
>> +
>> +#include "sdhci-pltfm.h"
>> +
>> +#define SDHCI_OMAP_CON		0x12c
>> +#define CON_DW8			BIT(5)
>> +#define CON_DMA_MASTER		BIT(20)
>> +#define CON_INIT		BIT(1)
>> +#define CON_OD			BIT(0)
>> +
>> +#define SDHCI_OMAP_CMD		0x20c
>> +
>> +#define SDHCI_OMAP_HCTL		0x228
>> +#define HCTL_SDBP		BIT(8)
>> +#define HCTL_SDVS_SHIFT		9
>> +#define HCTL_SDVS_MASK		(0x7 << HCTL_SDVS_SHIFT)
>> +#define HCTL_SDVS_33		(0x7 << HCTL_SDVS_SHIFT)
>> +#define HCTL_SDVS_30		(0x6 << HCTL_SDVS_SHIFT)
>> +#define HCTL_SDVS_18		(0x5 << HCTL_SDVS_SHIFT)
>> +
>> +#define SDHCI_OMAP_SYSCTL	0x22c
>> +#define SYSCTL_CEN		BIT(2)
>> +#define SYSCTL_CLKD_SHIFT	6
>> +#define SYSCTL_CLKD_MASK	0x3ff
>> +
>> +#define SDHCI_OMAP_STAT		0x230
>> +
>> +#define SDHCI_OMAP_IE		0x234
>> +#define INT_CC_EN		BIT(0)
>> +
>> +#define SDHCI_OMAP_AC12		0x23c
>> +#define AC12_V1V8_SIGEN		BIT(19)
>> +
>> +#define SDHCI_OMAP_CAPA		0x240
>> +#define CAPA_VS33		BIT(24)
>> +#define CAPA_VS30		BIT(25)
>> +#define CAPA_VS18		BIT(26)
>> +
>> +#define MMC_TIMEOUT		1		/* 1 msec */
> 
> As before, SDHCI_OMAP_TIMEOUT is a better name

fixed it now.
> 
>> +
>> +#define SYSCTL_CLKD_MAX		0x3FF
>> +
>> +#define IOV_1V8			1800000		/* 180000 uV */
>> +#define IOV_3V0			3000000		/* 300000 uV */
>> +#define IOV_3V3			3300000		/* 330000 uV */
>> +
>> +struct sdhci_omap_data {
>> +	u32 offset;
>> +};
>> +
>> +struct sdhci_omap_host {
>> +	void __iomem		*base;
>> +	struct device		*dev;
>> +	struct	regulator	*pbias;
>> +	bool			pbias_enabled;
>> +	struct sdhci_host	*host;
>> +	unsigned int		flags;
>> +
>> +#define SDHCI_OMAP_SUPPORTS_DUAL_VOLT	BIT(0)
>> +#define SDHCI_OMAP_NO_1_8_V		BIT(1)
>> +
>> +	u8			bus_mode;
>> +	u8			power_mode;
>> +	bool			io_3_3v_support;
>> +};
>> +
>> +static inline u32 sdhci_omap_readl(struct sdhci_omap_host *host,
>> +				   unsigned int offset)
>> +{
>> +	return readl(host->base + offset);
>> +}
>> +
>> +static inline void sdhci_omap_writel(struct sdhci_omap_host *host,
>> +				     unsigned int offset, u32 data)
>> +{
>> +	writel(data, host->base + offset);
>> +}
>> +
>> +static int sdhci_omap_set_pbias(struct sdhci_omap_host *omap_host,
>> +				bool power_on, unsigned int iov)
>> +{
>> +	int ret;
>> +	struct device *dev = omap_host->dev;
>> +
>> +	if (IS_ERR(omap_host->pbias))
>> +		return 0;
>> +
>> +	if (power_on) {
>> +		ret = regulator_set_voltage(omap_host->pbias, iov, iov);
>> +		if (ret) {
>> +			dev_err(dev, "pbias set voltage failed\n");
>> +			return ret;
>> +		}
>> +
>> +		if (omap_host->pbias_enabled)
>> +			return 0;
>> +
>> +		ret = regulator_enable(omap_host->pbias);
>> +		if (ret) {
>> +			dev_err(dev, "pbias reg enable fail\n");
>> +			return ret;
>> +		}
>> +
>> +		omap_host->pbias_enabled = true;
>> +	} else {
>> +		if (!omap_host->pbias_enabled)
>> +			return 0;
>> +
>> +		ret = regulator_disable(omap_host->pbias);
>> +		if (ret) {
>> +			dev_err(dev, "pbias reg disable fail\n");
>> +			return ret;
>> +		}
>> +		omap_host->pbias_enabled = false;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>> +static int sdhci_omap_enable_iov(struct sdhci_omap_host *omap_host,
>> +				 unsigned int iov)
>> +{
>> +	int ret;
>> +	struct sdhci_host *host = omap_host->host;
>> +	struct mmc_host *mmc = host->mmc;
>> +
>> +	ret = sdhci_omap_set_pbias(omap_host, false, 0);
>> +	if (ret)
>> +		return ret;
>> +
>> +	if (!IS_ERR(mmc->supply.vqmmc)) {
>> +		ret = regulator_set_voltage(mmc->supply.vqmmc, iov, iov);
>> +		if (ret) {
>> +			dev_err(mmc_dev(mmc), "vqmmc set voltage failed\n");
>> +			return ret;
>> +		}
>> +	}
>> +
>> +	ret = sdhci_omap_set_pbias(omap_host, true, iov);
>> +	if (ret)
>> +		return ret;
>> +
>> +	return 0;
>> +}
>> +
>> +static void sdhci_omap_conf_bus_power(struct sdhci_omap_host *omap_host,
>> +				      unsigned char signal_voltage)
>> +{
>> +	u32 reg;
>> +	ktime_t timeout;
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL);
>> +	reg &= ~HCTL_SDVS_MASK;
>> +
>> +	if (signal_voltage == MMC_SIGNAL_VOLTAGE_180)
>> +		reg |= HCTL_SDVS_18;
>> +	else if (omap_host->io_3_3v_support)
>> +		reg |= HCTL_SDVS_33;
>> +	else
>> +		reg |= HCTL_SDVS_30;
>> +
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
>> +
>> +	reg |= HCTL_SDBP;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_HCTL, reg);
>> +
>> +	/* wait 1ms */
>> +	timeout = ktime_add_ms(ktime_get(), MMC_TIMEOUT);
>> +	while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_HCTL) & HCTL_SDBP)) {
>> +		if (WARN_ON(ktime_after(ktime_get(), timeout)))
>> +			return;
>> +		usleep_range(5, 10);
>> +	}
>> +}
>> +
>> +static int sdhci_omap_start_signal_voltage_switch(struct mmc_host *mmc,
>> +						  struct mmc_ios *ios)
>> +{
>> +	u32 reg;
>> +	int ret;
>> +	unsigned int iov;
>> +	struct sdhci_host *host = mmc_priv(mmc);
>> +	struct sdhci_pltfm_host *pltfm_host;
>> +	struct sdhci_omap_host *omap_host;
>> +	struct device *dev;
>> +
>> +	pltfm_host = sdhci_priv(host);
>> +	omap_host = sdhci_pltfm_priv(pltfm_host);
>> +	dev = omap_host->dev;
>> +
>> +	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
>> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
>> +		if (!(reg & (CAPA_VS33 | CAPA_VS30)))
>> +			return -EOPNOTSUPP;
>> +
>> +		sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
>> +
>> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
>> +		reg &= ~AC12_V1V8_SIGEN;
>> +		sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
>> +
>> +		if (omap_host->io_3_3v_support)
>> +			iov = IOV_3V3;
>> +		else
>> +			iov = IOV_3V0;
>> +	} else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) {
>> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
>> +		if (!(reg & CAPA_VS18))
>> +			return -EOPNOTSUPP;
>> +
>> +		sdhci_omap_conf_bus_power(omap_host, ios->signal_voltage);
>> +
>> +		reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_AC12);
>> +		reg |= AC12_V1V8_SIGEN;
>> +		sdhci_omap_writel(omap_host, SDHCI_OMAP_AC12, reg);
>> +
>> +		iov = IOV_1V8;
>> +	} else {
>> +		return -EOPNOTSUPP;
>> +	}
>> +
>> +	ret = sdhci_omap_enable_iov(omap_host, iov);
>> +	if (ret) {
>> +		dev_err(dev, "failed to switch IO voltage to %dmV\n", iov);
>> +		return ret;
>> +	}
>> +
>> +	dev_dbg(dev, "IO voltage switched to %dmV\n", iov);
>> +	return 0;
>> +}
>> +
>> +static void sdhci_omap_set_bus_mode(struct sdhci_omap_host *omap_host,
>> +				    unsigned int mode)
>> +{
>> +	u32 reg;
>> +
>> +	if (omap_host->bus_mode == mode)
>> +		return;
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
>> +	if (mode == MMC_BUSMODE_OPENDRAIN)
>> +		reg |= CON_OD;
>> +	else
>> +		reg &= ~CON_OD;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
>> +
>> +	omap_host->bus_mode = mode;
>> +}
>> +
>> +void sdhci_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
>> +{
>> +	struct sdhci_host *host = mmc_priv(mmc);
>> +	struct sdhci_pltfm_host *pltfm_host;
>> +	struct sdhci_omap_host *omap_host;
>> +
>> +	pltfm_host = sdhci_priv(host);
>> +	omap_host = sdhci_pltfm_priv(pltfm_host);
>> +
>> +	sdhci_omap_set_bus_mode(omap_host, ios->bus_mode);
>> +	sdhci_set_ios(mmc, ios);
>> +}
>> +
>> +static void sdhci_omap_set_capabilities(struct sdhci_omap_host *omap_host)
>> +{
>> +	u32 reg;
>> +
>> +	/* voltage capabilities might be set by boot loader, clear it */
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CAPA);
>> +	reg &= ~(CAPA_VS18 | CAPA_VS30 | CAPA_VS33);
>> +
>> +	if (omap_host->flags & SDHCI_OMAP_SUPPORTS_DUAL_VOLT) {
>> +		if (omap_host->io_3_3v_support)
>> +			reg |= (CAPA_VS33 | CAPA_VS18);
>> +		else
>> +			reg |= (CAPA_VS30 | CAPA_VS18);
>> +	} else if (omap_host->flags & SDHCI_OMAP_NO_1_8_V) {
>> +		if (omap_host->io_3_3v_support)
>> +			reg |= CAPA_VS33;
>> +		else
>> +			reg |= CAPA_VS30;
>> +	} else {
>> +		reg |= CAPA_VS18;
>> +	}
>> +
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CAPA, reg);
>> +}
>> +
>> +static u16 sdhci_omap_calc_divisor(struct sdhci_pltfm_host *host,
>> +				   unsigned int clock)
>> +{
>> +	u16 dsor;
>> +
>> +	dsor = DIV_ROUND_UP(clk_get_rate(host->clk), clock);
>> +	if (dsor > SYSCTL_CLKD_MAX)
>> +		dsor = SYSCTL_CLKD_MAX;
>> +
>> +	return dsor;
>> +}
>> +
>> +static void sdhci_omap_start_clock(struct sdhci_omap_host *omap_host)
>> +{
>> +	u32 reg;
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
>> +	reg |= SYSCTL_CEN;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
>> +}
>> +
>> +static void sdhci_omap_stop_clock(struct sdhci_omap_host *omap_host)
>> +{
>> +	u32 reg;
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_SYSCTL);
>> +	reg &= ~SYSCTL_CEN;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_SYSCTL, reg);
>> +}
>> +
>> +static void sdhci_omap_set_clock(struct sdhci_host *host, unsigned int clock)
>> +{
>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>> +	unsigned long clkdiv;
>> +
>> +	if (!clock)
>> +		return;
> 
> Are you sure you don't want to stop the clock.

There is never a case where the MMC core sends a request to stop the clock.
Maybe this check is not required at all.
> 
>> +
>> +	sdhci_omap_stop_clock(omap_host);
>> +
>> +	clkdiv = sdhci_omap_calc_divisor(pltfm_host, clock);
>> +	clkdiv = (clkdiv & SYSCTL_CLKD_MASK) << SYSCTL_CLKD_SHIFT;
>> +	sdhci_enable_clk(host, clkdiv);
>> +
>> +	sdhci_omap_start_clock(omap_host);
>> +}
>> +
>> +void sdhci_omap_set_power(struct sdhci_host *host, unsigned char mode,
>> +			  unsigned short vdd)
>> +{
>> +	struct mmc_host *mmc = host->mmc;
>> +
>> +	mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, vdd);
>> +}
>> +
>> +static int sdhci_omap_enable_dma(struct sdhci_host *host)
>> +{
>> +	u32 reg;
>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
>> +	reg |= CON_DMA_MASTER;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
>> +
>> +	return 0;
>> +}
>> +
>> +unsigned int sdhci_omap_get_min_clock(struct sdhci_host *host)
>> +{
>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +
>> +	return clk_get_rate(pltfm_host->clk) / SYSCTL_CLKD_MAX;
>> +}
>> +
>> +static void sdhci_omap_set_bus_width(struct sdhci_host *host, int width)
>> +{
>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>> +	u32 reg;
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
>> +	if (width == MMC_BUS_WIDTH_8)
>> +		reg |= CON_DW8;
>> +	else
>> +		reg &= ~CON_DW8;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
>> +
>> +	sdhci_set_bus_width(host, width);
>> +}
>> +
>> +static void sdhci_omap_init_74_clocks(struct sdhci_host *host, u8 power_mode)
>> +{
>> +	u32 reg;
>> +	ktime_t timeout;
>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>> +
>> +	if (omap_host->power_mode == power_mode)
>> +		return;
>> +
>> +	if (power_mode != MMC_POWER_ON)
>> +		return;
>> +
>> +	disable_irq(host->irq);
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
>> +	reg |= CON_INIT;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CMD, 0x0);
>> +
>> +	/* wait 1ms */
>> +	timeout = ktime_add_ms(ktime_get(), MMC_TIMEOUT);
>> +	while (!(sdhci_omap_readl(omap_host, SDHCI_OMAP_STAT) & INT_CC_EN)) {
>> +		if (WARN_ON(ktime_after(ktime_get(), timeout)))
>> +			return;
>> +		usleep_range(5, 10);
>> +	}
>> +
>> +	reg = sdhci_omap_readl(omap_host, SDHCI_OMAP_CON);
>> +	reg &= ~CON_INIT;
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_CON, reg);
>> +	sdhci_omap_writel(omap_host, SDHCI_OMAP_STAT, INT_CC_EN);
>> +
>> +	enable_irq(host->irq);
>> +
>> +	omap_host->power_mode = power_mode;
>> +}
>> +
>> +static struct sdhci_ops sdhci_omap_ops = {
>> +	.set_clock = sdhci_omap_set_clock,
>> +	.set_power = sdhci_omap_set_power,
>> +	.enable_dma = sdhci_omap_enable_dma,
>> +	.get_max_clock = sdhci_pltfm_clk_get_max_clock,
>> +	.get_min_clock = sdhci_omap_get_min_clock,
>> +	.set_bus_width = sdhci_omap_set_bus_width,
>> +	.platform_send_init_74_clocks = sdhci_omap_init_74_clocks,
>> +	.reset = sdhci_reset,
>> +	.set_uhs_signaling = sdhci_set_uhs_signaling,
>> +};
>> +
>> +void sdhci_omap_get_of_property(struct sdhci_omap_host *omap_host)
>> +{
>> +	struct device *dev = omap_host->dev;
>> +	struct sdhci_host *host = omap_host->host;
>> +	struct mmc_host *mmc = host->mmc;
>> +
>> +	if (device_property_read_bool(dev, "ti,dual-volt"))
>> +		omap_host->flags |= SDHCI_OMAP_SUPPORTS_DUAL_VOLT;
>> +
>> +	if (device_property_read_bool(dev, "no-1-8-v"))
>> +		omap_host->flags |= SDHCI_OMAP_NO_1_8_V;
>> +
>> +	if (device_property_read_bool(dev, "ti,non-removable"))
>> +		mmc->caps |= MMC_CAP_NONREMOVABLE;
>> +}
>> +
>> +static const struct sdhci_pltfm_data sdhci_omap_pdata = {
>> +	.quirks = SDHCI_QUIRK_BROKEN_CARD_DETECTION |
>> +		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
>> +		  SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN |
>> +		  SDHCI_QUIRK_NO_HISPD_BIT |
>> +		  SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC,
>> +	.quirks2 = SDHCI_QUIRK2_NO_1_8_V |
>> +		   SDHCI_QUIRK2_ACMD23_BROKEN |
>> +		   SDHCI_QUIRK2_RSP_136_HAS_CRC,
>> +	.ops = &sdhci_omap_ops,
>> +};
>> +
>> +static const struct sdhci_omap_data dra7_data = {
>> +	.offset = 0x200,
>> +};
>> +
>> +static const struct of_device_id omap_sdhci_match[] = {
>> +	{ .compatible = "ti,dra7-sdhci", .data = &dra7_data },
>> +	{},
>> +};
>> +MODULE_DEVICE_TABLE(of, omap_sdhci_match);
>> +
>> +static int sdhci_omap_probe(struct platform_device *pdev)
>> +{
>> +	int ret;
>> +	u32 offset;
>> +	struct device *dev = &pdev->dev;
>> +	struct sdhci_host *host;
>> +	struct sdhci_pltfm_host *pltfm_host;
>> +	struct sdhci_omap_host *omap_host;
>> +	struct mmc_host *mmc;
>> +	const struct of_device_id *match;
>> +	struct sdhci_omap_data *data;
>> +
>> +	match = of_match_device(omap_sdhci_match, dev);
>> +	if (!match)
>> +		return -EINVAL;
>> +
>> +	data = (struct sdhci_omap_data *)match->data;
>> +	if (!data) {
>> +		dev_err(dev, "no sdhci omap data\n");
>> +		return -EINVAL;
>> +	}
>> +
>> +	offset = data->offset;
>> +
>> +	host = sdhci_pltfm_init(pdev, &sdhci_omap_pdata,
>> +				sizeof(*omap_host));
>> +	if (IS_ERR(host)) {
>> +		dev_err(dev, "Failed sdhci_pltfm_init\n");
>> +		return PTR_ERR(host);
>> +	}
>> +
>> +	pltfm_host = sdhci_priv(host);
>> +	omap_host = sdhci_pltfm_priv(pltfm_host);
>> +	omap_host->host = host;
>> +	omap_host->base = host->ioaddr;
>> +	omap_host->dev = dev;
>> +	sdhci_omap_get_of_property(omap_host);
>> +
>> +	host->ioaddr += offset;
>> +
>> +	mmc = host->mmc;
>> +	ret = mmc_of_parse(mmc);
>> +	if (ret)
>> +		goto err_of_parse;
>> +
>> +	pltfm_host->clk = devm_clk_get(dev, "fck");
>> +	if (IS_ERR(pltfm_host->clk)) {
>> +		ret = PTR_ERR(pltfm_host->clk);
>> +		goto err_of_parse;
>> +	}
>> +
>> +	ret = clk_set_rate(pltfm_host->clk, mmc->f_max);
>> +	if (ret) {
>> +		dev_err(dev, "failed to set clock to %d\n", mmc->f_max);
>> +		goto err_of_parse;
>> +	}
>> +
>> +	omap_host->pbias = devm_regulator_get_optional(dev, "pbias");
>> +	if (IS_ERR(omap_host->pbias)) {
>> +		ret = PTR_ERR(omap_host->pbias);
>> +		if (ret != -ENODEV) {
>> +			dev_err(dev, "CONFIG_REGULATOR_PBIAS not enabled??\n");
>> +			return ret;
>> +		}
>> +		dev_dbg(dev, "unable to get pbias regulator %ld\n",
>> +			PTR_ERR(omap_host->pbias));
>> +	} else {
>> +		if (regulator_is_supported_voltage(omap_host->pbias, IOV_3V3,
>> +						   IOV_3V3))
>> +			omap_host->io_3_3v_support = true;
>> +		dev_vdbg(dev, "Max PBIAS support Voltage: %dmv\n",
>> +			 omap_host->io_3_3v_support ? IOV_3V3 : IOV_3V0);
>> +	}
>> +	omap_host->pbias_enabled = false;
>> +
>> +	/* Enable main Func clock, interface clock and program SYSCONFIG */
> 
> Maybe also mention that the PM domain does those things.  Out of curiousity,
> what happens if CONFIG_PM is not set?

I think then most of the peripherals will depend on bootloader to enable the
clocks if CONFIG_PM is not set.
> 
>> +	pm_runtime_enable(dev);
>> +	ret = pm_runtime_get_sync(dev);
>> +	if (ret < 0) {
>> +		dev_err(dev, "pm_runtime_get_sync failed\n");
>> +		goto err_get_sync;
> 
> The correct "undo" function for pm_runtime_get_sync() failing is
> pm_runtime_put_noidle() not pm_runtime_put_sync().  So:

yeah right! Missed that.
> 
> 		pm_runtime_put_noidle(dev);
> 		goto err_rpm_disable;
> 
>> +	}
>> +
>> +	sdhci_omap_set_capabilities(omap_host);
>> +
>> +	host->mmc_host_ops.get_ro = mmc_gpio_get_ro;
>> +	host->mmc_host_ops.start_signal_voltage_switch =
>> +					sdhci_omap_start_signal_voltage_switch;
>> +	host->mmc_host_ops.set_ios = sdhci_omap_set_ios;
>> +
>> +	sdhci_read_caps(host);
>> +	host->caps |= SDHCI_CAN_DO_ADMA2;
>> +
>> +	ret = sdhci_add_host(host);
>> +	if (ret)
>> +		goto err_get_sync;
>> +
>> +	return 0;
>> +
>> +err_get_sync:
> 
> It is more usual for error labels to describe what they will do rather than
> what failed. i.e. this would be err_put_sync:
> 
>> +	pm_runtime_put_sync(dev);
> 
> err_rpm_disable:
> 
>> +	pm_runtime_disable(dev);
>> +
>> +err_of_parse:
> 
> err_pltfm_free:
> 
>> +	sdhci_pltfm_free(pdev);
>> +	return ret;
>> +}
>> +
>> +static int sdhci_omap_remove(struct platform_device *pdev)
>> +{
>> +	struct device *dev = &pdev->dev;
>> +	struct sdhci_host *host = platform_get_drvdata(pdev);
>> +
>> +	sdhci_remove_host(host, true);
>> +	pm_runtime_put_sync(dev);
>> +	pm_runtime_disable(dev);
>> +	sdhci_pltfm_free(pdev);
>> +
>> +	return 0;
>> +}
>> +
>> +static struct platform_driver sdhci_omap_driver = {
>> +	.probe = sdhci_omap_probe,
>> +	.remove = sdhci_omap_remove,
>> +	.driver = {
>> +		   .name = "sdhci-omap",
>> +		   .of_match_table = of_match_ptr(omap_sdhci_match),
> 
> Don't you need #ifdef CONFIG_OF around the table if you use of_match_ptr()?

yeah. I think I'll remove of_match_ptr here and make the driver depend on OF.
> 
>> +		  },
>> +};
>> +
>> +module_platform_driver(sdhci_omap_driver);
>> +
>> +MODULE_DESCRIPTION("SDHCI driver for OMAP SoCs");
>> +MODULE_AUTHOR("Texas Instruments Inc.");
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_ALIAS("OMAP SDHCI Driver");
> 
> A module alias with spaces in it looks strange.  Is that the intention?

No. Will fix it.

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH 4/5] mmc: sdhci-omap: Add OMAP SDHCI driver
  2017-08-30 13:53       ` Kishon Vijay Abraham I
@ 2017-08-31 13:02         ` Adrian Hunter
  -1 siblings, 0 replies; 86+ messages in thread
From: Adrian Hunter @ 2017-08-31 13:02 UTC (permalink / raw)
  To: Kishon Vijay Abraham I, Ulf Hansson
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel

On 30/08/17 16:53, Kishon Vijay Abraham I wrote:
> On Monday 28 August 2017 02:36 PM, Adrian Hunter wrote:
>> On 21/08/17 10:41, Kishon Vijay Abraham I wrote:
>>> +
>>> +static void sdhci_omap_set_clock(struct sdhci_host *host, unsigned int clock)
>>> +{
>>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>>> +	unsigned long clkdiv;
>>> +
>>> +	if (!clock)
>>> +		return;
>>
>> Are you sure you don't want to stop the clock.
> 
> There is never a case where the MMC core sends a request to stop the clock.
> Maybe this check is not required at all.

It does when voltage switching e.g. mmc_set_uhs_voltage(), but host drivers
should support the possibility anyway.

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH 4/5] mmc: sdhci-omap: Add OMAP SDHCI driver
@ 2017-08-31 13:02         ` Adrian Hunter
  0 siblings, 0 replies; 86+ messages in thread
From: Adrian Hunter @ 2017-08-31 13:02 UTC (permalink / raw)
  To: linux-arm-kernel

On 30/08/17 16:53, Kishon Vijay Abraham I wrote:
> On Monday 28 August 2017 02:36 PM, Adrian Hunter wrote:
>> On 21/08/17 10:41, Kishon Vijay Abraham I wrote:
>>> +
>>> +static void sdhci_omap_set_clock(struct sdhci_host *host, unsigned int clock)
>>> +{
>>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>>> +	unsigned long clkdiv;
>>> +
>>> +	if (!clock)
>>> +		return;
>>
>> Are you sure you don't want to stop the clock.
> 
> There is never a case where the MMC core sends a request to stop the clock.
> Maybe this check is not required at all.

It does when voltage switching e.g. mmc_set_uhs_voltage(), but host drivers
should support the possibility anyway.

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
  2017-08-29 17:39                       ` Tony Lindgren
  (?)
@ 2017-09-05  8:52                         ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-09-05  8:52 UTC (permalink / raw)
  To: Tony Lindgren, Rob Herring
  Cc: Sebastian Reichel, Ulf Hansson, Adrian Hunter, Sekhar Nori,
	Russell King, Ravikumar Kattekola, linux-mmc, devicetree,
	linux-kernel, linux-omap, linux-arm-kernel

Hi,

On Tuesday 29 August 2017 11:09 PM, Tony Lindgren wrote:
> * Rob Herring <robh@kernel.org> [170829 10:09]:
>> On Tue, Aug 29, 2017 at 06:58:23AM -0700, Tony Lindgren wrote:
>>> * Sebastian Reichel <sebastian.reichel@collabora.co.uk> [170829 04:51]:
>>>> I would expect the conversion to look like the one done for UART,
>>>> see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
>>>> same compatible value and you can choose using kernel configuration.
>>>
>>> That does not work unfortunately :( We are now stuck in a situation
>>> where two drivers are attempting to probe with the same compatible
>>> and we can't enable 8250_OMAP because of the user space breakage
>>> with the device names. And I'm actuallly thinking we should add a
>>> new compatible for 8250-omap to be able to start enabling it one
>>> board at a time.
>>
>> Is that the only problem? Presumably, the SD driver doesn't have a 
>> userspace facing issue.
> 
> No userspace issue with the sdhci-omap. But the sdhci-omap driver
> still has the issue of trying enable it for everything at once and
> expect everything to work. The sdhci-omap driver can already be
> used for boards that don't need power management for example, but
> will break things for devices running on batteries.
> 
>>> It's best to enable devices to use the new compatible as things are
>>> tested rather than hope for some magic "flag day" flip that might
>>> never happen. Having two days attempting to probe with the same
>>> binding just won't work.
>>
>> Aren't you just picking whether the flag day is in DT or the kernel? I 
>> guess you're assuming one kernel build and it would be switching all 
>> boards at one. 
> 
> Right, this would be risky and would take unnecessarily long
> to use the new driver on boards that can already use it. While
> power management won't work yet, I'd expect the sdhci-omap be
> faster on SoCs that can do ADMA.
> 
>>> So yeah, I agree with Kishon that we should stick with generic
>>> and sdhci bindings. And then we can start already using it for
>>> boards that can use it, then eventually when we're ready, start
>>> parsing also the legacy bindings and maybe drop the old driver.
>>
>> I assume there are some other common properties you would switch to in 
>> the transition?  You could make the legacy driver bail from probe based 
>> on presence or absence of other properties. Or you could just blacklist 
>> converted platforms in the legacy driver. The point is that the problems 
>> are solvable in the kernel.
> 
> Yes this could be done too. But let's enable it on per-board
> basis rather than attempt to flip it on at once.
> 
>> But if your really want a new compatible, I don't really care. It's 
>> only one device.
> 
> Both a new compatible or a check for some resource work just fine
> for me as long as the driver can be selected on per-board basis.

New compatible sounds simpler to me since it allows to select a driver per-MMC
instance. (SDIO support is not added/validated in sdhci-omap).

To summarize, we'll create new compatible and new bindings for sdhci-omap and
start enabling sdhci-omap on per-board basis. When all the TI platforms starts
to use sdhci-omap, omap-hsmmc will be removed at which point support for old
compatible and old dt bindings will be added to sdhci-omap.c. Does this sound
reasonable?

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-09-05  8:52                         ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-09-05  8:52 UTC (permalink / raw)
  To: Tony Lindgren, Rob Herring
  Cc: devicetree, Ulf Hansson, linux-mmc, Sekhar Nori, Adrian Hunter,
	Russell King, linux-arm-kernel, Ravikumar Kattekola,
	Sebastian Reichel, linux-omap, linux-kernel

Hi,

On Tuesday 29 August 2017 11:09 PM, Tony Lindgren wrote:
> * Rob Herring <robh@kernel.org> [170829 10:09]:
>> On Tue, Aug 29, 2017 at 06:58:23AM -0700, Tony Lindgren wrote:
>>> * Sebastian Reichel <sebastian.reichel@collabora.co.uk> [170829 04:51]:
>>>> I would expect the conversion to look like the one done for UART,
>>>> see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
>>>> same compatible value and you can choose using kernel configuration.
>>>
>>> That does not work unfortunately :( We are now stuck in a situation
>>> where two drivers are attempting to probe with the same compatible
>>> and we can't enable 8250_OMAP because of the user space breakage
>>> with the device names. And I'm actuallly thinking we should add a
>>> new compatible for 8250-omap to be able to start enabling it one
>>> board at a time.
>>
>> Is that the only problem? Presumably, the SD driver doesn't have a 
>> userspace facing issue.
> 
> No userspace issue with the sdhci-omap. But the sdhci-omap driver
> still has the issue of trying enable it for everything at once and
> expect everything to work. The sdhci-omap driver can already be
> used for boards that don't need power management for example, but
> will break things for devices running on batteries.
> 
>>> It's best to enable devices to use the new compatible as things are
>>> tested rather than hope for some magic "flag day" flip that might
>>> never happen. Having two days attempting to probe with the same
>>> binding just won't work.
>>
>> Aren't you just picking whether the flag day is in DT or the kernel? I 
>> guess you're assuming one kernel build and it would be switching all 
>> boards at one. 
> 
> Right, this would be risky and would take unnecessarily long
> to use the new driver on boards that can already use it. While
> power management won't work yet, I'd expect the sdhci-omap be
> faster on SoCs that can do ADMA.
> 
>>> So yeah, I agree with Kishon that we should stick with generic
>>> and sdhci bindings. And then we can start already using it for
>>> boards that can use it, then eventually when we're ready, start
>>> parsing also the legacy bindings and maybe drop the old driver.
>>
>> I assume there are some other common properties you would switch to in 
>> the transition?  You could make the legacy driver bail from probe based 
>> on presence or absence of other properties. Or you could just blacklist 
>> converted platforms in the legacy driver. The point is that the problems 
>> are solvable in the kernel.
> 
> Yes this could be done too. But let's enable it on per-board
> basis rather than attempt to flip it on at once.
> 
>> But if your really want a new compatible, I don't really care. It's 
>> only one device.
> 
> Both a new compatible or a check for some resource work just fine
> for me as long as the driver can be selected on per-board basis.

New compatible sounds simpler to me since it allows to select a driver per-MMC
instance. (SDIO support is not added/validated in sdhci-omap).

To summarize, we'll create new compatible and new bindings for sdhci-omap and
start enabling sdhci-omap on per-board basis. When all the TI platforms starts
to use sdhci-omap, omap-hsmmc will be removed at which point support for old
compatible and old dt bindings will be added to sdhci-omap.c. Does this sound
reasonable?

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-09-05  8:52                         ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-09-05  8:52 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tuesday 29 August 2017 11:09 PM, Tony Lindgren wrote:
> * Rob Herring <robh@kernel.org> [170829 10:09]:
>> On Tue, Aug 29, 2017 at 06:58:23AM -0700, Tony Lindgren wrote:
>>> * Sebastian Reichel <sebastian.reichel@collabora.co.uk> [170829 04:51]:
>>>> I would expect the conversion to look like the one done for UART,
>>>> see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
>>>> same compatible value and you can choose using kernel configuration.
>>>
>>> That does not work unfortunately :( We are now stuck in a situation
>>> where two drivers are attempting to probe with the same compatible
>>> and we can't enable 8250_OMAP because of the user space breakage
>>> with the device names. And I'm actuallly thinking we should add a
>>> new compatible for 8250-omap to be able to start enabling it one
>>> board at a time.
>>
>> Is that the only problem? Presumably, the SD driver doesn't have a 
>> userspace facing issue.
> 
> No userspace issue with the sdhci-omap. But the sdhci-omap driver
> still has the issue of trying enable it for everything at once and
> expect everything to work. The sdhci-omap driver can already be
> used for boards that don't need power management for example, but
> will break things for devices running on batteries.
> 
>>> It's best to enable devices to use the new compatible as things are
>>> tested rather than hope for some magic "flag day" flip that might
>>> never happen. Having two days attempting to probe with the same
>>> binding just won't work.
>>
>> Aren't you just picking whether the flag day is in DT or the kernel? I 
>> guess you're assuming one kernel build and it would be switching all 
>> boards at one. 
> 
> Right, this would be risky and would take unnecessarily long
> to use the new driver on boards that can already use it. While
> power management won't work yet, I'd expect the sdhci-omap be
> faster on SoCs that can do ADMA.
> 
>>> So yeah, I agree with Kishon that we should stick with generic
>>> and sdhci bindings. And then we can start already using it for
>>> boards that can use it, then eventually when we're ready, start
>>> parsing also the legacy bindings and maybe drop the old driver.
>>
>> I assume there are some other common properties you would switch to in 
>> the transition?  You could make the legacy driver bail from probe based 
>> on presence or absence of other properties. Or you could just blacklist 
>> converted platforms in the legacy driver. The point is that the problems 
>> are solvable in the kernel.
> 
> Yes this could be done too. But let's enable it on per-board
> basis rather than attempt to flip it on at once.
> 
>> But if your really want a new compatible, I don't really care. It's 
>> only one device.
> 
> Both a new compatible or a check for some resource work just fine
> for me as long as the driver can be selected on per-board basis.

New compatible sounds simpler to me since it allows to select a driver per-MMC
instance. (SDIO support is not added/validated in sdhci-omap).

To summarize, we'll create new compatible and new bindings for sdhci-omap and
start enabling sdhci-omap on per-board basis. When all the TI platforms starts
to use sdhci-omap, omap-hsmmc will be removed at which point support for old
compatible and old dt bindings will be added to sdhci-omap.c. Does this sound
reasonable?

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
  2017-08-29 17:11         ` Rob Herring
  (?)
@ 2017-09-05  8:53           ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-09-05  8:53 UTC (permalink / raw)
  To: Rob Herring
  Cc: Ulf Hansson, Adrian Hunter, Tony Lindgren, Sekhar Nori,
	Russell King, Ravikumar Kattekola, linux-mmc, devicetree,
	linux-kernel, linux-omap, linux-arm-kernel

Hi,

On Tuesday 29 August 2017 10:41 PM, Rob Herring wrote:
> On Wed, Aug 23, 2017 at 11:12:46AM +0530, Kishon Vijay Abraham I wrote:
>> Add binding for the TI's sdhci-omap controller. This now includes only
>> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
>> include all the properties.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>> Changes from v2:
>> *) Fixed example to use the updated compatible
>>
>> Changes from v1:
>> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>>    of using the ti-omap-hsmmc.txt as suggested by Tony
>>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>>  1 file changed, 22 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>> new file mode 100644
>> index 000000000000..139695ad2d58
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>> @@ -0,0 +1,22 @@
>> +* TI OMAP SDHCI Controller
>> +
>> +Refer to mmc.txt for standard MMC bindings.
>> +
>> +Required properties:
>> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
>> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
>> +
>> +Optional properties:
>> +- ti,dual-volt: boolean, supports dual voltage cards
>> +- ti,non-removable: non-removable slot (like eMMC)
> 
> Well, if you are doing a new compatible, then why aren't you using 
> common properties?

yeah, now moved to generic bindings.
> 
>> +
>> +Example:
>> +	mmc1: mmc@0x4809c000 {
> 
> Drop the '0x'.

sure, will fix it.

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-09-05  8:53           ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-09-05  8:53 UTC (permalink / raw)
  To: Rob Herring
  Cc: devicetree, Ulf Hansson, Tony Lindgren, linux-mmc, Sekhar Nori,
	Adrian Hunter, Russell King, linux-arm-kernel,
	Ravikumar Kattekola, linux-omap, linux-kernel

Hi,

On Tuesday 29 August 2017 10:41 PM, Rob Herring wrote:
> On Wed, Aug 23, 2017 at 11:12:46AM +0530, Kishon Vijay Abraham I wrote:
>> Add binding for the TI's sdhci-omap controller. This now includes only
>> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
>> include all the properties.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>> Changes from v2:
>> *) Fixed example to use the updated compatible
>>
>> Changes from v1:
>> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>>    of using the ti-omap-hsmmc.txt as suggested by Tony
>>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>>  1 file changed, 22 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>> new file mode 100644
>> index 000000000000..139695ad2d58
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>> @@ -0,0 +1,22 @@
>> +* TI OMAP SDHCI Controller
>> +
>> +Refer to mmc.txt for standard MMC bindings.
>> +
>> +Required properties:
>> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
>> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
>> +
>> +Optional properties:
>> +- ti,dual-volt: boolean, supports dual voltage cards
>> +- ti,non-removable: non-removable slot (like eMMC)
> 
> Well, if you are doing a new compatible, then why aren't you using 
> common properties?

yeah, now moved to generic bindings.
> 
>> +
>> +Example:
>> +	mmc1: mmc@0x4809c000 {
> 
> Drop the '0x'.

sure, will fix it.

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-09-05  8:53           ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-09-05  8:53 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Tuesday 29 August 2017 10:41 PM, Rob Herring wrote:
> On Wed, Aug 23, 2017 at 11:12:46AM +0530, Kishon Vijay Abraham I wrote:
>> Add binding for the TI's sdhci-omap controller. This now includes only
>> a subset of properties documented in ti-omap-hsmmc.txt but will eventually
>> include all the properties.
>>
>> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
>> ---
>> Changes from v2:
>> *) Fixed example to use the updated compatible
>>
>> Changes from v1:
>> *) Create a new sdhci-omap.txt document for TI's sdhci-omap controller instead
>>    of using the ti-omap-hsmmc.txt as suggested by Tony
>>  .../devicetree/bindings/mmc/sdhci-omap.txt         | 22 ++++++++++++++++++++++
>>  1 file changed, 22 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-omap.txt b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>> new file mode 100644
>> index 000000000000..139695ad2d58
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mmc/sdhci-omap.txt
>> @@ -0,0 +1,22 @@
>> +* TI OMAP SDHCI Controller
>> +
>> +Refer to mmc.txt for standard MMC bindings.
>> +
>> +Required properties:
>> +- compatible: Should be "ti,dra7-sdhci" for DRA7 and DRA72 controllers
>> +- ti,hwmods: Must be "mmc<n>", <n> is controller instance starting 1
>> +
>> +Optional properties:
>> +- ti,dual-volt: boolean, supports dual voltage cards
>> +- ti,non-removable: non-removable slot (like eMMC)
> 
> Well, if you are doing a new compatible, then why aren't you using 
> common properties?

yeah, now moved to generic bindings.
> 
>> +
>> +Example:
>> +	mmc1: mmc at 0x4809c000 {
> 
> Drop the '0x'.

sure, will fix it.

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH 4/5] mmc: sdhci-omap: Add OMAP SDHCI driver
  2017-08-31 13:02         ` Adrian Hunter
  (?)
@ 2017-09-05  8:57           ` Kishon Vijay Abraham I
  -1 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-09-05  8:57 UTC (permalink / raw)
  To: Adrian Hunter, Ulf Hansson
  Cc: Rob Herring, Tony Lindgren, Sekhar Nori, Russell King,
	Ravikumar Kattekola, linux-mmc, devicetree, linux-kernel,
	linux-omap, linux-arm-kernel

Hi,

On Thursday 31 August 2017 06:32 PM, Adrian Hunter wrote:
> On 30/08/17 16:53, Kishon Vijay Abraham I wrote:
>> On Monday 28 August 2017 02:36 PM, Adrian Hunter wrote:
>>> On 21/08/17 10:41, Kishon Vijay Abraham I wrote:
>>>> +
>>>> +static void sdhci_omap_set_clock(struct sdhci_host *host, unsigned int clock)
>>>> +{
>>>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>>>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>>>> +	unsigned long clkdiv;
>>>> +
>>>> +	if (!clock)
>>>> +		return;
>>>
>>> Are you sure you don't want to stop the clock.
>>
>> There is never a case where the MMC core sends a request to stop the clock.
>> Maybe this check is not required at all.
> 
> It does when voltage switching e.g. mmc_set_uhs_voltage(), but host drivers
> should support the possibility anyway.

Indeed! Will fix it and send a new revision once everyone agrees on the dt binding.

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH 4/5] mmc: sdhci-omap: Add OMAP SDHCI driver
@ 2017-09-05  8:57           ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-09-05  8:57 UTC (permalink / raw)
  To: Adrian Hunter, Ulf Hansson
  Cc: devicetree, Tony Lindgren, Sekhar Nori, linux-mmc, Russell King,
	linux-kernel, Rob Herring, Ravikumar Kattekola, linux-omap,
	linux-arm-kernel

Hi,

On Thursday 31 August 2017 06:32 PM, Adrian Hunter wrote:
> On 30/08/17 16:53, Kishon Vijay Abraham I wrote:
>> On Monday 28 August 2017 02:36 PM, Adrian Hunter wrote:
>>> On 21/08/17 10:41, Kishon Vijay Abraham I wrote:
>>>> +
>>>> +static void sdhci_omap_set_clock(struct sdhci_host *host, unsigned int clock)
>>>> +{
>>>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>>>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>>>> +	unsigned long clkdiv;
>>>> +
>>>> +	if (!clock)
>>>> +		return;
>>>
>>> Are you sure you don't want to stop the clock.
>>
>> There is never a case where the MMC core sends a request to stop the clock.
>> Maybe this check is not required at all.
> 
> It does when voltage switching e.g. mmc_set_uhs_voltage(), but host drivers
> should support the possibility anyway.

Indeed! Will fix it and send a new revision once everyone agrees on the dt binding.

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH 4/5] mmc: sdhci-omap: Add OMAP SDHCI driver
@ 2017-09-05  8:57           ` Kishon Vijay Abraham I
  0 siblings, 0 replies; 86+ messages in thread
From: Kishon Vijay Abraham I @ 2017-09-05  8:57 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

On Thursday 31 August 2017 06:32 PM, Adrian Hunter wrote:
> On 30/08/17 16:53, Kishon Vijay Abraham I wrote:
>> On Monday 28 August 2017 02:36 PM, Adrian Hunter wrote:
>>> On 21/08/17 10:41, Kishon Vijay Abraham I wrote:
>>>> +
>>>> +static void sdhci_omap_set_clock(struct sdhci_host *host, unsigned int clock)
>>>> +{
>>>> +	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
>>>> +	struct sdhci_omap_host *omap_host = sdhci_pltfm_priv(pltfm_host);
>>>> +	unsigned long clkdiv;
>>>> +
>>>> +	if (!clock)
>>>> +		return;
>>>
>>> Are you sure you don't want to stop the clock.
>>
>> There is never a case where the MMC core sends a request to stop the clock.
>> Maybe this check is not required at all.
> 
> It does when voltage switching e.g. mmc_set_uhs_voltage(), but host drivers
> should support the possibility anyway.

Indeed! Will fix it and send a new revision once everyone agrees on the dt binding.

Thanks
Kishon

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
  2017-09-05  8:52                         ` Kishon Vijay Abraham I
  (?)
@ 2017-09-05 16:51                           ` Tony Lindgren
  -1 siblings, 0 replies; 86+ messages in thread
From: Tony Lindgren @ 2017-09-05 16:51 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Rob Herring, Sebastian Reichel, Ulf Hansson, Adrian Hunter,
	Sekhar Nori, Russell King, Ravikumar Kattekola, linux-mmc,
	devicetree, linux-kernel, linux-omap, linux-arm-kernel

* Kishon Vijay Abraham I <kishon@ti.com> [170905 01:53]:
> Hi,
> 
> On Tuesday 29 August 2017 11:09 PM, Tony Lindgren wrote:
> > * Rob Herring <robh@kernel.org> [170829 10:09]:
> >> On Tue, Aug 29, 2017 at 06:58:23AM -0700, Tony Lindgren wrote:
> >>> * Sebastian Reichel <sebastian.reichel@collabora.co.uk> [170829 04:51]:
> >>>> I would expect the conversion to look like the one done for UART,
> >>>> see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
> >>>> same compatible value and you can choose using kernel configuration.
> >>>
> >>> That does not work unfortunately :( We are now stuck in a situation
> >>> where two drivers are attempting to probe with the same compatible
> >>> and we can't enable 8250_OMAP because of the user space breakage
> >>> with the device names. And I'm actuallly thinking we should add a
> >>> new compatible for 8250-omap to be able to start enabling it one
> >>> board at a time.
> >>
> >> Is that the only problem? Presumably, the SD driver doesn't have a 
> >> userspace facing issue.
> > 
> > No userspace issue with the sdhci-omap. But the sdhci-omap driver
> > still has the issue of trying enable it for everything at once and
> > expect everything to work. The sdhci-omap driver can already be
> > used for boards that don't need power management for example, but
> > will break things for devices running on batteries.
> > 
> >>> It's best to enable devices to use the new compatible as things are
> >>> tested rather than hope for some magic "flag day" flip that might
> >>> never happen. Having two days attempting to probe with the same
> >>> binding just won't work.
> >>
> >> Aren't you just picking whether the flag day is in DT or the kernel? I 
> >> guess you're assuming one kernel build and it would be switching all 
> >> boards at one. 
> > 
> > Right, this would be risky and would take unnecessarily long
> > to use the new driver on boards that can already use it. While
> > power management won't work yet, I'd expect the sdhci-omap be
> > faster on SoCs that can do ADMA.
> > 
> >>> So yeah, I agree with Kishon that we should stick with generic
> >>> and sdhci bindings. And then we can start already using it for
> >>> boards that can use it, then eventually when we're ready, start
> >>> parsing also the legacy bindings and maybe drop the old driver.
> >>
> >> I assume there are some other common properties you would switch to in 
> >> the transition?  You could make the legacy driver bail from probe based 
> >> on presence or absence of other properties. Or you could just blacklist 
> >> converted platforms in the legacy driver. The point is that the problems 
> >> are solvable in the kernel.
> > 
> > Yes this could be done too. But let's enable it on per-board
> > basis rather than attempt to flip it on at once.
> > 
> >> But if your really want a new compatible, I don't really care. It's 
> >> only one device.
> > 
> > Both a new compatible or a check for some resource work just fine
> > for me as long as the driver can be selected on per-board basis.
> 
> New compatible sounds simpler to me since it allows to select a driver per-MMC
> instance. (SDIO support is not added/validated in sdhci-omap).
> 
> To summarize, we'll create new compatible and new bindings for sdhci-omap and
> start enabling sdhci-omap on per-board basis. When all the TI platforms starts
> to use sdhci-omap, omap-hsmmc will be removed at which point support for old
> compatible and old dt bindings will be added to sdhci-omap.c. Does this sound
> reasonable?

Sounds like a plan to me.

Regards,

Tony

^ permalink raw reply	[flat|nested] 86+ messages in thread

* Re: [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-09-05 16:51                           ` Tony Lindgren
  0 siblings, 0 replies; 86+ messages in thread
From: Tony Lindgren @ 2017-09-05 16:51 UTC (permalink / raw)
  To: Kishon Vijay Abraham I
  Cc: Rob Herring, Sebastian Reichel, Ulf Hansson, Adrian Hunter,
	Sekhar Nori, Russell King, Ravikumar Kattekola, linux-mmc,
	devicetree, linux-kernel, linux-omap, linux-arm-kernel

* Kishon Vijay Abraham I <kishon@ti.com> [170905 01:53]:
> Hi,
> 
> On Tuesday 29 August 2017 11:09 PM, Tony Lindgren wrote:
> > * Rob Herring <robh@kernel.org> [170829 10:09]:
> >> On Tue, Aug 29, 2017 at 06:58:23AM -0700, Tony Lindgren wrote:
> >>> * Sebastian Reichel <sebastian.reichel@collabora.co.uk> [170829 04:51]:
> >>>> I would expect the conversion to look like the one done for UART,
> >>>> see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
> >>>> same compatible value and you can choose using kernel configuration.
> >>>
> >>> That does not work unfortunately :( We are now stuck in a situation
> >>> where two drivers are attempting to probe with the same compatible
> >>> and we can't enable 8250_OMAP because of the user space breakage
> >>> with the device names. And I'm actuallly thinking we should add a
> >>> new compatible for 8250-omap to be able to start enabling it one
> >>> board at a time.
> >>
> >> Is that the only problem? Presumably, the SD driver doesn't have a 
> >> userspace facing issue.
> > 
> > No userspace issue with the sdhci-omap. But the sdhci-omap driver
> > still has the issue of trying enable it for everything at once and
> > expect everything to work. The sdhci-omap driver can already be
> > used for boards that don't need power management for example, but
> > will break things for devices running on batteries.
> > 
> >>> It's best to enable devices to use the new compatible as things are
> >>> tested rather than hope for some magic "flag day" flip that might
> >>> never happen. Having two days attempting to probe with the same
> >>> binding just won't work.
> >>
> >> Aren't you just picking whether the flag day is in DT or the kernel? I 
> >> guess you're assuming one kernel build and it would be switching all 
> >> boards at one. 
> > 
> > Right, this would be risky and would take unnecessarily long
> > to use the new driver on boards that can already use it. While
> > power management won't work yet, I'd expect the sdhci-omap be
> > faster on SoCs that can do ADMA.
> > 
> >>> So yeah, I agree with Kishon that we should stick with generic
> >>> and sdhci bindings. And then we can start already using it for
> >>> boards that can use it, then eventually when we're ready, start
> >>> parsing also the legacy bindings and maybe drop the old driver.
> >>
> >> I assume there are some other common properties you would switch to in 
> >> the transition?  You could make the legacy driver bail from probe based 
> >> on presence or absence of other properties. Or you could just blacklist 
> >> converted platforms in the legacy driver. The point is that the problems 
> >> are solvable in the kernel.
> > 
> > Yes this could be done too. But let's enable it on per-board
> > basis rather than attempt to flip it on at once.
> > 
> >> But if your really want a new compatible, I don't really care. It's 
> >> only one device.
> > 
> > Both a new compatible or a check for some resource work just fine
> > for me as long as the driver can be selected on per-board basis.
> 
> New compatible sounds simpler to me since it allows to select a driver per-MMC
> instance. (SDIO support is not added/validated in sdhci-omap).
> 
> To summarize, we'll create new compatible and new bindings for sdhci-omap and
> start enabling sdhci-omap on per-board basis. When all the TI platforms starts
> to use sdhci-omap, omap-hsmmc will be removed at which point support for old
> compatible and old dt bindings will be added to sdhci-omap.c. Does this sound
> reasonable?

Sounds like a plan to me.

Regards,

Tony

^ permalink raw reply	[flat|nested] 86+ messages in thread

* [PATCH v3 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller
@ 2017-09-05 16:51                           ` Tony Lindgren
  0 siblings, 0 replies; 86+ messages in thread
From: Tony Lindgren @ 2017-09-05 16:51 UTC (permalink / raw)
  To: linux-arm-kernel

* Kishon Vijay Abraham I <kishon@ti.com> [170905 01:53]:
> Hi,
> 
> On Tuesday 29 August 2017 11:09 PM, Tony Lindgren wrote:
> > * Rob Herring <robh@kernel.org> [170829 10:09]:
> >> On Tue, Aug 29, 2017 at 06:58:23AM -0700, Tony Lindgren wrote:
> >>> * Sebastian Reichel <sebastian.reichel@collabora.co.uk> [170829 04:51]:
> >>>> I would expect the conversion to look like the one done for UART,
> >>>> see CONFIG_SERIAL_OMAP vs CONFIG_SERIAL_8250_OMAP. Both use the
> >>>> same compatible value and you can choose using kernel configuration.
> >>>
> >>> That does not work unfortunately :( We are now stuck in a situation
> >>> where two drivers are attempting to probe with the same compatible
> >>> and we can't enable 8250_OMAP because of the user space breakage
> >>> with the device names. And I'm actuallly thinking we should add a
> >>> new compatible for 8250-omap to be able to start enabling it one
> >>> board at a time.
> >>
> >> Is that the only problem? Presumably, the SD driver doesn't have a 
> >> userspace facing issue.
> > 
> > No userspace issue with the sdhci-omap. But the sdhci-omap driver
> > still has the issue of trying enable it for everything at once and
> > expect everything to work. The sdhci-omap driver can already be
> > used for boards that don't need power management for example, but
> > will break things for devices running on batteries.
> > 
> >>> It's best to enable devices to use the new compatible as things are
> >>> tested rather than hope for some magic "flag day" flip that might
> >>> never happen. Having two days attempting to probe with the same
> >>> binding just won't work.
> >>
> >> Aren't you just picking whether the flag day is in DT or the kernel? I 
> >> guess you're assuming one kernel build and it would be switching all 
> >> boards at one. 
> > 
> > Right, this would be risky and would take unnecessarily long
> > to use the new driver on boards that can already use it. While
> > power management won't work yet, I'd expect the sdhci-omap be
> > faster on SoCs that can do ADMA.
> > 
> >>> So yeah, I agree with Kishon that we should stick with generic
> >>> and sdhci bindings. And then we can start already using it for
> >>> boards that can use it, then eventually when we're ready, start
> >>> parsing also the legacy bindings and maybe drop the old driver.
> >>
> >> I assume there are some other common properties you would switch to in 
> >> the transition?  You could make the legacy driver bail from probe based 
> >> on presence or absence of other properties. Or you could just blacklist 
> >> converted platforms in the legacy driver. The point is that the problems 
> >> are solvable in the kernel.
> > 
> > Yes this could be done too. But let's enable it on per-board
> > basis rather than attempt to flip it on at once.
> > 
> >> But if your really want a new compatible, I don't really care. It's 
> >> only one device.
> > 
> > Both a new compatible or a check for some resource work just fine
> > for me as long as the driver can be selected on per-board basis.
> 
> New compatible sounds simpler to me since it allows to select a driver per-MMC
> instance. (SDIO support is not added/validated in sdhci-omap).
> 
> To summarize, we'll create new compatible and new bindings for sdhci-omap and
> start enabling sdhci-omap on per-board basis. When all the TI platforms starts
> to use sdhci-omap, omap-hsmmc will be removed at which point support for old
> compatible and old dt bindings will be added to sdhci-omap.c. Does this sound
> reasonable?

Sounds like a plan to me.

Regards,

Tony

^ permalink raw reply	[flat|nested] 86+ messages in thread

end of thread, other threads:[~2017-09-05 16:51 UTC | newest]

Thread overview: 86+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-21  7:41 [PATCH 0/5] mmc: Add OMAP SDHCI driver Kishon Vijay Abraham I
2017-08-21  7:41 ` Kishon Vijay Abraham I
2017-08-21  7:41 ` Kishon Vijay Abraham I
2017-08-21  7:41 ` [PATCH 1/5] mmc: sdhci: Tidy reading 136-bit responses Kishon Vijay Abraham I
2017-08-21  7:41   ` Kishon Vijay Abraham I
2017-08-21  7:41   ` Kishon Vijay Abraham I
2017-08-30 13:13   ` Ulf Hansson
2017-08-30 13:13     ` Ulf Hansson
2017-08-30 13:13     ` Ulf Hansson
2017-08-21  7:41 ` [PATCH 2/5] mmc: sdhci: Add quirk to indicate MMC_RSP_136 has CRC Kishon Vijay Abraham I
2017-08-21  7:41   ` Kishon Vijay Abraham I
2017-08-21  7:41   ` Kishon Vijay Abraham I
2017-08-28  7:57   ` Adrian Hunter
2017-08-28  7:57     ` Adrian Hunter
2017-08-30 13:13   ` Ulf Hansson
2017-08-30 13:13     ` Ulf Hansson
2017-08-30 13:13     ` Ulf Hansson
2017-08-21  7:41 ` [PATCH 3/5] dt-bindings: ti-omap-hsmmc: Document new compatible for sdhci omap Kishon Vijay Abraham I
2017-08-21  7:41   ` Kishon Vijay Abraham I
2017-08-21  7:41   ` Kishon Vijay Abraham I
2017-08-21 14:21   ` Tony Lindgren
2017-08-21 14:21     ` Tony Lindgren
2017-08-22 13:39     ` [PATCH v2 3/5] dt-bindings: sdhci-omap: Add bindings for the sdhci-omap controller Kishon Vijay Abraham I
2017-08-22 13:39       ` Kishon Vijay Abraham I
2017-08-22 13:39       ` Kishon Vijay Abraham I
2017-08-22 17:39       ` Tony Lindgren
2017-08-22 17:39         ` Tony Lindgren
2017-08-23  5:42     ` [PATCH v3 " Kishon Vijay Abraham I
2017-08-23  5:42       ` Kishon Vijay Abraham I
2017-08-23  5:42       ` Kishon Vijay Abraham I
2017-08-23 13:07       ` Ulf Hansson
2017-08-23 13:07         ` Ulf Hansson
2017-08-23 13:07         ` Ulf Hansson
2017-08-23 13:56         ` Kishon Vijay Abraham I
2017-08-23 13:56           ` Kishon Vijay Abraham I
2017-08-23 13:56           ` Kishon Vijay Abraham I
2017-08-24 11:29           ` Ulf Hansson
2017-08-24 11:29             ` Ulf Hansson
2017-08-24 11:29             ` Ulf Hansson
2017-08-29 11:20             ` Kishon Vijay Abraham I
2017-08-29 11:20               ` Kishon Vijay Abraham I
2017-08-29 11:20               ` Kishon Vijay Abraham I
2017-08-29 11:50               ` Sebastian Reichel
2017-08-29 11:50                 ` Sebastian Reichel
2017-08-29 11:50                 ` Sebastian Reichel
2017-08-29 13:58                 ` Tony Lindgren
2017-08-29 13:58                   ` Tony Lindgren
2017-08-29 13:58                   ` Tony Lindgren
2017-08-29 14:43                   ` Tony Lindgren
2017-08-29 14:43                     ` Tony Lindgren
2017-08-29 14:43                     ` Tony Lindgren
2017-08-29 17:09                   ` Rob Herring
2017-08-29 17:09                     ` Rob Herring
2017-08-29 17:09                     ` Rob Herring
2017-08-29 17:39                     ` Tony Lindgren
2017-08-29 17:39                       ` Tony Lindgren
2017-08-29 17:39                       ` Tony Lindgren
2017-09-05  8:52                       ` Kishon Vijay Abraham I
2017-09-05  8:52                         ` Kishon Vijay Abraham I
2017-09-05  8:52                         ` Kishon Vijay Abraham I
2017-09-05 16:51                         ` Tony Lindgren
2017-09-05 16:51                           ` Tony Lindgren
2017-09-05 16:51                           ` Tony Lindgren
2017-08-29 17:11       ` Rob Herring
2017-08-29 17:11         ` Rob Herring
2017-09-05  8:53         ` Kishon Vijay Abraham I
2017-09-05  8:53           ` Kishon Vijay Abraham I
2017-09-05  8:53           ` Kishon Vijay Abraham I
2017-08-21  7:41 ` [PATCH 4/5] mmc: sdhci-omap: Add OMAP SDHCI driver Kishon Vijay Abraham I
2017-08-21  7:41   ` Kishon Vijay Abraham I
2017-08-21  7:41   ` Kishon Vijay Abraham I
2017-08-28  9:06   ` Adrian Hunter
2017-08-28  9:06     ` Adrian Hunter
2017-08-30 13:53     ` Kishon Vijay Abraham I
2017-08-30 13:53       ` Kishon Vijay Abraham I
2017-08-30 13:53       ` Kishon Vijay Abraham I
2017-08-31 13:02       ` Adrian Hunter
2017-08-31 13:02         ` Adrian Hunter
2017-09-05  8:57         ` Kishon Vijay Abraham I
2017-09-05  8:57           ` Kishon Vijay Abraham I
2017-09-05  8:57           ` Kishon Vijay Abraham I
2017-08-21  7:41 ` [PATCH 5/5] MAINTAINERS: Add TI OMAP SDHCI Maintainer Kishon Vijay Abraham I
2017-08-21  7:41   ` Kishon Vijay Abraham I
2017-08-21  7:41   ` Kishon Vijay Abraham I
2017-08-28  9:07   ` Adrian Hunter
2017-08-28  9:07     ` Adrian Hunter

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.