linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] introduce driver for the Atmel SDMMC
@ 2015-07-03 14:17 Ludovic Desroches
  2015-07-03 14:17 ` [PATCH 1/3] mmc: sdhci: switch from programmable clock mode to divided one if needed Ludovic Desroches
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Ludovic Desroches @ 2015-07-03 14:17 UTC (permalink / raw)
  To: linux-mmc, linux-kernel, devicetree
  Cc: ulf.hansson, nicolas.ferre, alexandre.belloni, Ludovic Desroches

Hi,

This set of patches introduce a driver for the new Atmel SDMMC device avaible
on SAMA5D2 SoC.

There is also a resend of an old patch which has not been taken. Ulf asked
for some reviews since it could impact all sdhci devices but nobody did it...


Regards

Ludovic Desroches (3):
  mmc: sdhci: switch from programmable clock mode to divided one if
    needed
  mmc: sdhci-of-at91: introduce driver for the Atmel SDMMC
  MAINTAINERS: add entry for Atmel sdhci-of-at91 driver

 .../devicetree/bindings/mmc/sdhci-atmel.txt        |  21 +++
 MAINTAINERS                                        |   6 +
 drivers/mmc/host/Kconfig                           |   8 +
 drivers/mmc/host/Makefile                          |   1 +
 drivers/mmc/host/sdhci-of-at91.c                   | 188 +++++++++++++++++++++
 drivers/mmc/host/sdhci.c                           |  29 +++-
 6 files changed, 244 insertions(+), 9 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-atmel.txt
 create mode 100644 drivers/mmc/host/sdhci-of-at91.c

-- 
2.2.0


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

* [PATCH 1/3] mmc: sdhci: switch from programmable clock mode to divided one if needed
  2015-07-03 14:17 [PATCH 0/3] introduce driver for the Atmel SDMMC Ludovic Desroches
@ 2015-07-03 14:17 ` Ludovic Desroches
  2015-07-03 14:17 ` [PATCH 2/3] mmc: sdhci-of-at91: introduce driver for the Atmel SDMMC Ludovic Desroches
  2015-07-03 14:17 ` [PATCH 3/3] MAINTAINERS: add entry for Atmel sdhci-of-at91 driver Ludovic Desroches
  2 siblings, 0 replies; 8+ messages in thread
From: Ludovic Desroches @ 2015-07-03 14:17 UTC (permalink / raw)
  To: linux-mmc, linux-kernel, devicetree
  Cc: ulf.hansson, nicolas.ferre, alexandre.belloni, Ludovic Desroches

In programmable mode, if the clock frequency is too high, the divider
can be too small to meet the clock frequency requirement especially to
init the SD card. In this case, switch to the divided clock mode.

Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
---
 drivers/mmc/host/sdhci.c | 29 ++++++++++++++++++++---------
 1 file changed, 20 insertions(+), 9 deletions(-)

diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index bc14452..32cf274 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1152,6 +1152,7 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 	int real_div = div, clk_mul = 1;
 	u16 clk = 0;
 	unsigned long timeout;
+	bool switch_base_clk = false;
 
 	host->mmc->actual_clock = 0;
 
@@ -1189,15 +1190,25 @@ void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 					<= clock)
 					break;
 			}
-			/*
-			 * Set Programmable Clock Mode in the Clock
-			 * Control register.
-			 */
-			clk = SDHCI_PROG_CLOCK_MODE;
-			real_div = div;
-			clk_mul = host->clk_mul;
-			div--;
-		} else {
+			if ((host->max_clk * host->clk_mul / div) <= clock) {
+				/*
+				 * Set Programmable Clock Mode in the Clock
+				 * Control register.
+				 */
+				clk = SDHCI_PROG_CLOCK_MODE;
+				real_div = div;
+				clk_mul = host->clk_mul;
+				div--;
+			} else {
+				/*
+				 * Divisor can be too small to reach clock
+				 * speed requirement. Then use the base clock.
+				 */
+				switch_base_clk = true;
+			}
+		}
+
+		if (!host->clk_mul || switch_base_clk) {
 			/* Version 3.00 divisors must be a multiple of 2. */
 			if (host->max_clk <= clock)
 				div = 1;
-- 
2.2.0


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

* [PATCH 2/3] mmc: sdhci-of-at91: introduce driver for the Atmel SDMMC
  2015-07-03 14:17 [PATCH 0/3] introduce driver for the Atmel SDMMC Ludovic Desroches
  2015-07-03 14:17 ` [PATCH 1/3] mmc: sdhci: switch from programmable clock mode to divided one if needed Ludovic Desroches
@ 2015-07-03 14:17 ` Ludovic Desroches
  2015-07-04  8:30   ` Paul Bolle
  2015-07-04 20:06   ` Arnd Bergmann
  2015-07-03 14:17 ` [PATCH 3/3] MAINTAINERS: add entry for Atmel sdhci-of-at91 driver Ludovic Desroches
  2 siblings, 2 replies; 8+ messages in thread
From: Ludovic Desroches @ 2015-07-03 14:17 UTC (permalink / raw)
  To: linux-mmc, linux-kernel, devicetree
  Cc: ulf.hansson, nicolas.ferre, alexandre.belloni, Ludovic Desroches

Introduce driver for he Atmel SDMMC available on sama5d2. It is a sdhci
compliant controller.

Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
---
 .../devicetree/bindings/mmc/sdhci-atmel.txt        |  21 +++
 drivers/mmc/host/Kconfig                           |   8 +
 drivers/mmc/host/Makefile                          |   1 +
 drivers/mmc/host/sdhci-of-at91.c                   | 188 +++++++++++++++++++++
 4 files changed, 218 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-atmel.txt
 create mode 100644 drivers/mmc/host/sdhci-of-at91.c

diff --git a/Documentation/devicetree/bindings/mmc/sdhci-atmel.txt b/Documentation/devicetree/bindings/mmc/sdhci-atmel.txt
new file mode 100644
index 0000000..1b662d7
--- /dev/null
+++ b/Documentation/devicetree/bindings/mmc/sdhci-atmel.txt
@@ -0,0 +1,21 @@
+* Atmel SDHCI controller
+
+This file documents the differences between the core properties in
+Documentation/devicetree/bindings/mmc/mmc.txt and the properties used by the
+sdhci-of-at91 driver.
+
+Required properties:
+- compatible:		Must be "atmel,sama5d2-sdhci".
+- clocks:		Phandlers to the clocks.
+- clock-names:		Must be "hclock", "multclk", "baseclk";
+
+
+Example:
+
+sdmmc0: sdio-host@a0000000 {
+	compatible = "atmel,sama5d2-sdhci";
+	reg = <0xa0000000 0x300>;
+	interrupts = <31 IRQ_TYPE_LEVEL_HIGH 0>;
+	clocks = <&sdmmc0_hclk>, <&sdmmc0_gclk>, <&main>;
+	clock-names = "hclock", "multclk", "baseclk";
+};
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index fd9a58e..c1c75e8 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -129,6 +129,14 @@ config MMC_SDHCI_OF_ARASAN
 
 	  If unsure, say N.
 
+config MMC_SDHCI_OF_AT91
+	tristate "SDHCI OF support for the Atmel SDMMC controller"
+	depends on MMC_SDHCI_PLTFM
+	depends on OF
+	select MMC_SDHCI_IO_ACCESSORS
+	help
+	  This selects the Atmel SDMMC driver
+
 config MMC_SDHCI_OF_ESDHC
 	tristate "SDHCI OF support for the Freescale eSDHC controller"
 	depends on MMC_SDHCI_PLTFM
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index e928d61..4f3452a 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX)	+= sdhci-esdhc-imx.o
 obj-$(CONFIG_MMC_SDHCI_DOVE)		+= sdhci-dove.o
 obj-$(CONFIG_MMC_SDHCI_TEGRA)		+= sdhci-tegra.o
 obj-$(CONFIG_MMC_SDHCI_OF_ARASAN)	+= sdhci-of-arasan.o
+obj-$(CONFIG_MMC_SDHCI_OF_AT91)		+= sdhci-of-at91.o
 obj-$(CONFIG_MMC_SDHCI_OF_ESDHC)	+= sdhci-of-esdhc.o
 obj-$(CONFIG_MMC_SDHCI_OF_HLWD)		+= sdhci-of-hlwd.o
 obj-$(CONFIG_MMC_SDHCI_BCM_KONA)	+= sdhci-bcm-kona.o
diff --git a/drivers/mmc/host/sdhci-of-at91.c b/drivers/mmc/host/sdhci-of-at91.c
new file mode 100644
index 0000000..2e3716a
--- /dev/null
+++ b/drivers/mmc/host/sdhci-of-at91.c
@@ -0,0 +1,188 @@
+/*
+ * Atmel SDMMC controller driver.
+ *
+ * Copyright (C) 2015 Atmel,
+ *		 2015 Ludovic Desroches <ludovic.desroches@atmel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/mmc/host.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+
+#include "sdhci-pltfm.h"
+
+#define SDMMC_CACR	0x230
+#define		SDMMC_CACR_CAPWREN	BIT(0)
+#define		SDMMC_CACR_KEY		(0x46 << 8)
+
+struct sdhci_at91_priv {
+	struct clk *hclock;
+	struct clk *gck;
+	struct clk *mainck;
+};
+
+static const struct sdhci_ops sdhci_at91_sama5d2_ops = {
+	.set_clock		= sdhci_set_clock,
+	.set_bus_width		= sdhci_set_bus_width,
+	.reset			= sdhci_reset,
+	.set_uhs_signaling	= sdhci_set_uhs_signaling,
+};
+
+static const struct sdhci_pltfm_data soc_data_sama5d2 = {
+	.ops = &sdhci_at91_sama5d2_ops,
+};
+
+static const struct of_device_id sdhci_at91_dt_match[] = {
+	{ .compatible = "atmel,sama5d2-sdhci", .data = &soc_data_sama5d2 },
+	{}
+};
+
+static int sdhci_at91_probe(struct platform_device *pdev)
+{
+	const struct of_device_id	*match;
+	const struct sdhci_pltfm_data	*soc_data;
+	struct sdhci_host		*host;
+	struct sdhci_pltfm_host		*pltfm_host;
+	struct sdhci_at91_priv		*priv;
+	unsigned int			caps0, caps1;
+	unsigned int			clk_base, clk_mul;
+	unsigned int			gck_rate, real_gck_rate;
+	int				ret;
+
+	match = of_match_device(sdhci_at91_dt_match, &pdev->dev);
+	if (!match)
+		return -EINVAL;
+	soc_data = match->data;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv) {
+		dev_err(&pdev->dev, "unable to allocate private data\n");
+		return -ENOMEM;
+	}
+
+	priv->mainck = devm_clk_get(&pdev->dev, "baseclk");
+	if (IS_ERR(priv->mainck)) {
+		dev_err(&pdev->dev, "failed to get baseclk\n");
+		return PTR_ERR(priv->mainck);
+	}
+
+	priv->hclock = devm_clk_get(&pdev->dev, "hclock");
+	if (IS_ERR(priv->hclock)) {
+		dev_err(&pdev->dev, "failed to get hclock\n");
+		return PTR_ERR(priv->hclock);
+	}
+
+	priv->gck = devm_clk_get(&pdev->dev, "multclk");
+	if (IS_ERR(priv->gck)) {
+		dev_err(&pdev->dev, "failed to get multclk\n");
+		return PTR_ERR(priv->gck);
+	}
+
+	host = sdhci_pltfm_init(pdev, soc_data, 0);
+	if (IS_ERR(host))
+		return PTR_ERR(host);
+
+	/*
+	 * The mult clock is provided by as a generated clock by the PMC
+	 * controller. In order to set the rate of gck, we have to get the
+	 * base clock rate and the clock mult from capabilities.
+	 */
+	clk_prepare_enable(priv->hclock);
+	caps0 = readl(host->ioaddr + SDHCI_CAPABILITIES);
+	caps1 = readl(host->ioaddr + SDHCI_CAPABILITIES_1);
+	clk_base = (caps0 & SDHCI_CLOCK_V3_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
+	clk_mul = (caps1 & SDHCI_CLOCK_MUL_MASK) >> SDHCI_CLOCK_MUL_SHIFT;
+	gck_rate = clk_base * 1000000 * (clk_mul + 1);
+	ret = clk_set_rate(priv->gck, gck_rate);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "failed to set gck");
+		goto hclock_disable_unprepare;
+		return -EINVAL;
+	}
+	/*
+	 * We need to check if we have the requested rate for gck because in
+	 * some cases this rate could be not supported. If it happens, the rate
+	 * is the closest one gck can provide. We have to update the value
+	 * of clk mul.
+	 */
+	real_gck_rate = clk_get_rate(priv->gck);
+	if (real_gck_rate != gck_rate) {
+		clk_mul = real_gck_rate / (clk_base * 1000000) - 1;
+		caps1 &= (~SDHCI_CLOCK_MUL_MASK);
+		caps1 |= ((clk_mul << SDHCI_CLOCK_MUL_SHIFT) & SDHCI_CLOCK_MUL_MASK);
+		/* Set capabilities in r/w mode. */
+		writel(SDMMC_CACR_KEY | SDMMC_CACR_CAPWREN, host->ioaddr + SDMMC_CACR);
+		writel(caps1, host->ioaddr + SDHCI_CAPABILITIES_1);
+		/* Set capabilities in ro mode. */
+		writel(0, host->ioaddr + SDMMC_CACR);
+		dev_info(&pdev->dev, "update clk mul to %u as gck rate is %u Hz\n",
+			 clk_mul, real_gck_rate);
+	}
+
+	clk_prepare_enable(priv->mainck);
+	clk_prepare_enable(priv->gck);
+
+	pltfm_host = sdhci_priv(host);
+	pltfm_host->priv = priv;
+
+	ret = mmc_of_parse(host->mmc);
+	if (ret)
+		goto clocks_disable_unprepare;
+
+	sdhci_get_of_property(pdev);
+
+	ret = sdhci_add_host(host);
+	if (ret)
+		goto clocks_disable_unprepare;
+
+	return 0;
+
+clocks_disable_unprepare:
+	clk_disable_unprepare(priv->gck);
+	clk_disable_unprepare(priv->mainck);
+hclock_disable_unprepare:
+	clk_disable_unprepare(priv->hclock);
+	sdhci_pltfm_free(pdev);
+	return ret;
+}
+
+static int sdhci_at91_remove(struct platform_device *pdev)
+{
+	struct sdhci_host	*host = platform_get_drvdata(pdev);
+	struct sdhci_pltfm_host	*pltfm_host = sdhci_priv(host);
+	struct sdhci_at91_priv	*priv = pltfm_host->priv;
+
+	sdhci_pltfm_unregister(pdev);
+
+	clk_disable_unprepare(priv->gck);
+	clk_disable_unprepare(priv->hclock);
+	clk_disable_unprepare(priv->mainck);
+
+	return 0;
+}
+
+static struct platform_driver sdhci_at91_driver = {
+	.driver		= {
+		.name	= "sdhci-at91",
+		.owner	= THIS_MODULE,
+		.of_match_table = sdhci_at91_dt_match,
+		.pm	= SDHCI_PLTFM_PMOPS,
+	},
+	.probe		= sdhci_at91_probe,
+	.remove		= sdhci_at91_remove,
+};
+
+module_platform_driver(sdhci_at91_driver);
+
+MODULE_DESCRIPTION("SDHCI driver for at91");
+MODULE_AUTHOR("Ludovic Desroches <ludovic.desroches@atmel.com>");
+MODULE_LICENSE("GPL v2");
-- 
2.2.0


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

* [PATCH 3/3] MAINTAINERS: add entry for Atmel sdhci-of-at91 driver
  2015-07-03 14:17 [PATCH 0/3] introduce driver for the Atmel SDMMC Ludovic Desroches
  2015-07-03 14:17 ` [PATCH 1/3] mmc: sdhci: switch from programmable clock mode to divided one if needed Ludovic Desroches
  2015-07-03 14:17 ` [PATCH 2/3] mmc: sdhci-of-at91: introduce driver for the Atmel SDMMC Ludovic Desroches
@ 2015-07-03 14:17 ` Ludovic Desroches
  2 siblings, 0 replies; 8+ messages in thread
From: Ludovic Desroches @ 2015-07-03 14:17 UTC (permalink / raw)
  To: linux-mmc, linux-kernel, devicetree
  Cc: ulf.hansson, nicolas.ferre, alexandre.belloni, Ludovic Desroches

Add an entry for Atmel SDMMC device.

Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
---
 MAINTAINERS | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e7bdbac..6480ce9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1880,6 +1880,12 @@ L:	linux-mtd@lists.infradead.org
 S:	Supported
 F:	drivers/mtd/nand/atmel_nand*
 
+ATMEL SDMMC DRIVER
+M:	Ludovic Desroches <ludovic.desroches@atmel.com>
+L:	linux-mmc@vger.kernel.org
+S:	Supported
+F:	drivers/mmc/host/sdhci-of-at91.c
+
 ATMEL SPI DRIVER
 M:	Nicolas Ferre <nicolas.ferre@atmel.com>
 S:	Supported
-- 
2.2.0


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

* Re: [PATCH 2/3] mmc: sdhci-of-at91: introduce driver for the Atmel SDMMC
  2015-07-03 14:17 ` [PATCH 2/3] mmc: sdhci-of-at91: introduce driver for the Atmel SDMMC Ludovic Desroches
@ 2015-07-04  8:30   ` Paul Bolle
  2015-07-06  7:33     ` Ludovic Desroches
  2015-07-04 20:06   ` Arnd Bergmann
  1 sibling, 1 reply; 8+ messages in thread
From: Paul Bolle @ 2015-07-04  8:30 UTC (permalink / raw)
  To: Ludovic Desroches, linux-mmc, linux-kernel, devicetree
  Cc: ulf.hansson, nicolas.ferre, alexandre.belloni

A nit only: a license mismatch.

On vr, 2015-07-03 at 16:17 +0200, Ludovic Desroches wrote:
> --- /dev/null
> +++ b/drivers/mmc/host/sdhci-of-at91.c
> 
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or (at
> + * your option) any later version.

This states the license is GPL v2 or later.

> +MODULE_LICENSE("GPL v2");

And, according to include/linux/module.h, this states the license is
(only) GPL v2. So I think that either the comment at the top of this
file or the ident used in MODULE_LICENSE() needs to change.

Thanks,


Paul Bolle

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

* Re: [PATCH 2/3] mmc: sdhci-of-at91: introduce driver for the Atmel SDMMC
  2015-07-03 14:17 ` [PATCH 2/3] mmc: sdhci-of-at91: introduce driver for the Atmel SDMMC Ludovic Desroches
  2015-07-04  8:30   ` Paul Bolle
@ 2015-07-04 20:06   ` Arnd Bergmann
  2015-07-06  7:33     ` Ludovic Desroches
  1 sibling, 1 reply; 8+ messages in thread
From: Arnd Bergmann @ 2015-07-04 20:06 UTC (permalink / raw)
  To: Ludovic Desroches
  Cc: linux-mmc, linux-kernel, devicetree, ulf.hansson, nicolas.ferre,
	alexandre.belloni

On Friday 03 July 2015 16:17:16 Ludovic Desroches wrote:
> Introduce driver for he Atmel SDMMC available on sama5d2. It is a sdhci
> compliant controller.
> 
> Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
> ---
>  .../devicetree/bindings/mmc/sdhci-atmel.txt        |  21 +++
>  drivers/mmc/host/Kconfig                           |   8 +
>  drivers/mmc/host/Makefile                          |   1 +
>  drivers/mmc/host/sdhci-of-at91.c                   | 188 +++++++++++++++++++++
>  4 files changed, 218 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-atmel.txt
>  create mode 100644 drivers/mmc/host/sdhci-of-at91.c
> 
> diff --git a/Documentation/devicetree/bindings/mmc/sdhci-atmel.txt b/Documentation/devicetree/bindings/mmc/sdhci-atmel.txt
> new file mode 100644
> index 0000000..1b662d7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mmc/sdhci-atmel.txt
> @@ -0,0 +1,21 @@
> +* Atmel SDHCI controller
> +
> +This file documents the differences between the core properties in
> +Documentation/devicetree/bindings/mmc/mmc.txt and the properties used by the
> +sdhci-of-at91 driver.
> +
> +Required properties:
> +- compatible:		Must be "atmel,sama5d2-sdhci".
> +- clocks:		Phandlers to the clocks.
> +- clock-names:		Must be "hclock", "multclk", "baseclk";
> +

Are you sure that these are all new clocks that are unrelated to the "core",
"mmc", and "iface" clocks that are used in other drivers?

> +
> +	priv->mainck = devm_clk_get(&pdev->dev, "baseclk");
> +	if (IS_ERR(priv->mainck)) {
> +		dev_err(&pdev->dev, "failed to get baseclk\n");
> +		return PTR_ERR(priv->mainck);
> +	}
> +
> +	priv->hclock = devm_clk_get(&pdev->dev, "hclock");
> +	if (IS_ERR(priv->hclock)) {
> +		dev_err(&pdev->dev, "failed to get hclock\n");
> +		return PTR_ERR(priv->hclock);
> +	}
> +
> +	priv->gck = devm_clk_get(&pdev->dev, "multclk");
> +	if (IS_ERR(priv->gck)) {
> +		dev_err(&pdev->dev, "failed to get multclk\n");
> +		return PTR_ERR(priv->gck);
> +	}
> +
> +	host = sdhci_pltfm_init(pdev, soc_data, 0);
> +	if (IS_ERR(host))
> +		return PTR_ERR(host);
> +
> +	/*
> +	 * The mult clock is provided by as a generated clock by the PMC
> +	 * controller. In order to set the rate of gck, we have to get the
> +	 * base clock rate and the clock mult from capabilities.
> +	 */
> +	clk_prepare_enable(priv->hclock);
> +	caps0 = readl(host->ioaddr + SDHCI_CAPABILITIES);
> +	caps1 = readl(host->ioaddr + SDHCI_CAPABILITIES_1);
> +	clk_base = (caps0 & SDHCI_CLOCK_V3_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
> +	clk_mul = (caps1 & SDHCI_CLOCK_MUL_MASK) >> SDHCI_CLOCK_MUL_SHIFT;
> +	gck_rate = clk_base * 1000000 * (clk_mul + 1);
> +	ret = clk_set_rate(priv->gck, gck_rate);
> +	if (ret < 0) {
> +		dev_err(&pdev->dev, "failed to set gck");
> +		goto hclock_disable_unprepare;
> +		return -EINVAL;
> +	}

Could this be shared with other drivers?

	Arnd

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

* Re: [PATCH 2/3] mmc: sdhci-of-at91: introduce driver for the Atmel SDMMC
  2015-07-04 20:06   ` Arnd Bergmann
@ 2015-07-06  7:33     ` Ludovic Desroches
  0 siblings, 0 replies; 8+ messages in thread
From: Ludovic Desroches @ 2015-07-06  7:33 UTC (permalink / raw)
  To: Arnd Bergmann
  Cc: Ludovic Desroches, linux-mmc, linux-kernel, devicetree,
	ulf.hansson, nicolas.ferre, alexandre.belloni

On Sat, Jul 04, 2015 at 10:06:49PM +0200, Arnd Bergmann wrote:
> On Friday 03 July 2015 16:17:16 Ludovic Desroches wrote:
> > Introduce driver for he Atmel SDMMC available on sama5d2. It is a sdhci
> > compliant controller.
> > 
> > Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
> > ---
> >  .../devicetree/bindings/mmc/sdhci-atmel.txt        |  21 +++
> >  drivers/mmc/host/Kconfig                           |   8 +
> >  drivers/mmc/host/Makefile                          |   1 +
> >  drivers/mmc/host/sdhci-of-at91.c                   | 188 +++++++++++++++++++++
> >  4 files changed, 218 insertions(+)
> >  create mode 100644 Documentation/devicetree/bindings/mmc/sdhci-atmel.txt
> >  create mode 100644 drivers/mmc/host/sdhci-of-at91.c
> > 
> > diff --git a/Documentation/devicetree/bindings/mmc/sdhci-atmel.txt b/Documentation/devicetree/bindings/mmc/sdhci-atmel.txt
> > new file mode 100644
> > index 0000000..1b662d7
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/mmc/sdhci-atmel.txt
> > @@ -0,0 +1,21 @@
> > +* Atmel SDHCI controller
> > +
> > +This file documents the differences between the core properties in
> > +Documentation/devicetree/bindings/mmc/mmc.txt and the properties used by the
> > +sdhci-of-at91 driver.
> > +
> > +Required properties:
> > +- compatible:		Must be "atmel,sama5d2-sdhci".
> > +- clocks:		Phandlers to the clocks.
> > +- clock-names:		Must be "hclock", "multclk", "baseclk";
> > +
> 
> Are you sure that these are all new clocks that are unrelated to the "core",
> "mmc", and "iface" clocks that are used in other drivers?
> 

Maybe hclock could be considered as the core and interface clock. The
mmc clock will be baseclk or multclk. I think other devices manage the
multclk internally. Here we have to provide both clocks. Internally, we
only choose which clock to use and add a divider if necessary.

> > +
> > +	priv->mainck = devm_clk_get(&pdev->dev, "baseclk");
> > +	if (IS_ERR(priv->mainck)) {
> > +		dev_err(&pdev->dev, "failed to get baseclk\n");
> > +		return PTR_ERR(priv->mainck);
> > +	}
> > +
> > +	priv->hclock = devm_clk_get(&pdev->dev, "hclock");
> > +	if (IS_ERR(priv->hclock)) {
> > +		dev_err(&pdev->dev, "failed to get hclock\n");
> > +		return PTR_ERR(priv->hclock);
> > +	}
> > +
> > +	priv->gck = devm_clk_get(&pdev->dev, "multclk");
> > +	if (IS_ERR(priv->gck)) {
> > +		dev_err(&pdev->dev, "failed to get multclk\n");
> > +		return PTR_ERR(priv->gck);
> > +	}
> > +
> > +	host = sdhci_pltfm_init(pdev, soc_data, 0);
> > +	if (IS_ERR(host))
> > +		return PTR_ERR(host);
> > +
> > +	/*
> > +	 * The mult clock is provided by as a generated clock by the PMC
> > +	 * controller. In order to set the rate of gck, we have to get the
> > +	 * base clock rate and the clock mult from capabilities.
> > +	 */
> > +	clk_prepare_enable(priv->hclock);
> > +	caps0 = readl(host->ioaddr + SDHCI_CAPABILITIES);
> > +	caps1 = readl(host->ioaddr + SDHCI_CAPABILITIES_1);
> > +	clk_base = (caps0 & SDHCI_CLOCK_V3_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
> > +	clk_mul = (caps1 & SDHCI_CLOCK_MUL_MASK) >> SDHCI_CLOCK_MUL_SHIFT;
> > +	gck_rate = clk_base * 1000000 * (clk_mul + 1);
> > +	ret = clk_set_rate(priv->gck, gck_rate);
> > +	if (ret < 0) {
> > +		dev_err(&pdev->dev, "failed to set gck");
> > +		goto hclock_disable_unprepare;
> > +		return -EINVAL;
> > +	}
> 
> Could this be shared with other drivers?

No, it's risk-free to do this.

> 
> 	Arnd

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

* Re: [PATCH 2/3] mmc: sdhci-of-at91: introduce driver for the Atmel SDMMC
  2015-07-04  8:30   ` Paul Bolle
@ 2015-07-06  7:33     ` Ludovic Desroches
  0 siblings, 0 replies; 8+ messages in thread
From: Ludovic Desroches @ 2015-07-06  7:33 UTC (permalink / raw)
  To: Paul Bolle
  Cc: Ludovic Desroches, linux-mmc, linux-kernel, devicetree,
	ulf.hansson, nicolas.ferre, alexandre.belloni

On Sat, Jul 04, 2015 at 10:30:28AM +0200, Paul Bolle wrote:
> A nit only: a license mismatch.

Thanks Paul, I'll correct it.

> 
> On vr, 2015-07-03 at 16:17 +0200, Ludovic Desroches wrote:
> > --- /dev/null
> > +++ b/drivers/mmc/host/sdhci-of-at91.c
> > 
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or (at
> > + * your option) any later version.
> 
> This states the license is GPL v2 or later.
> 
> > +MODULE_LICENSE("GPL v2");
> 
> And, according to include/linux/module.h, this states the license is
> (only) GPL v2. So I think that either the comment at the top of this
> file or the ident used in MODULE_LICENSE() needs to change.
> 
> Thanks,
> 
> 
> Paul Bolle

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

end of thread, other threads:[~2015-07-06  7:33 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-07-03 14:17 [PATCH 0/3] introduce driver for the Atmel SDMMC Ludovic Desroches
2015-07-03 14:17 ` [PATCH 1/3] mmc: sdhci: switch from programmable clock mode to divided one if needed Ludovic Desroches
2015-07-03 14:17 ` [PATCH 2/3] mmc: sdhci-of-at91: introduce driver for the Atmel SDMMC Ludovic Desroches
2015-07-04  8:30   ` Paul Bolle
2015-07-06  7:33     ` Ludovic Desroches
2015-07-04 20:06   ` Arnd Bergmann
2015-07-06  7:33     ` Ludovic Desroches
2015-07-03 14:17 ` [PATCH 3/3] MAINTAINERS: add entry for Atmel sdhci-of-at91 driver Ludovic Desroches

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).