* [PATCHv2 0/4] socfpga: Enable SD/MMC support
@ 2013-11-04 20:36 dinguyen
2013-11-04 20:36 ` [PATCHv2 1/4] clk: socfpga: Add a clock driver for SOCFPGA's system manager dinguyen
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: dinguyen @ 2013-11-04 20:36 UTC (permalink / raw)
To: dinh.linux
Cc: Dinh Nguyen, Arnd Bergmann, Mike Turquette, Olof Johansson,
Rob Herring, Pawel Moll, Mark Rutland, Stephen Warren,
Ian Campbell, Chris Ball, Jaehoon Chung, Seungwon Jeon,
devicetree, linux-mmc, linux-arm-kernel
From: Dinh Nguyen <dinguyen@altera.com>
Hi,
This is v2 of the patch series to enable SD/MMC on the SOCFPGA platform.
V2 adds a syscon driver to control the system manager registers.
V1 of the cover-letter of this patch series appears below:
This patch series enables support for the Synopsys SD/MMC driver that is
on the Altera SOCFPGA platform. The reason why this series has 4 patches
is to implement Arnd's suggestion:
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-October/204982.html
To summarize Arnd's suggestion:
1. Create a backend syscon driver to control the system manager.
2. Create a clock driver independent of the SOCFPGA clock driver that
uses syscon as the low-level interface.
3. Make the sdmmc driver use the normal clock API and link its clock to
the driver step 2 in the device tree.
The end approach is a bit different because I did not find the need for a
syscon driver for the system manager. Since the system manager had already
been iomap already in the SOCFPGA platform code, I just reused it in the
new clock driver.
Patch 1/4: clk: socfpga: Add a clock driver for SOCFPGA's system manager
This patch adds a clk-sysmgr driver that can be use by a common clock API
to set system manager register bits needed by the SD/MMC driver. The SD/MMC
driver can simply call a common clock API to set the required clock phase
settings for the SD/MMC CIU.
Patch 2/4: arm: dts: Add a system manager compatible property
This patch adds a DTS compatible entry for the new clk-sysmgr driver.
Patch 3/4: mmc: dw_mmc-socfpga: Clean up SOCFPGA platform specific functionality
This patch cleans up dw_mmc-socpfga.c file from defines that are outside of
the SD/MMC IP. It makes the common clock API call to set the SD/MMC clock
phase settings in the system manager.
Patch 4/4: arm: dts: Add support for SD/MMC on SOCFPGA
This patch adds the necessary DTS bindings for the SOCFPGA specific extensions
to the base Synopsys DW SD/MMC driver.
Thanks,
Dinh
Dinh Nguyen (4):
clk: socfpga: Add a clock driver for SOCFPGA's system manager
arm: dts: Add a system manager compatible property
mmc: dw_mmc-socfpga: Clean up SOCFPGA platform specific functionality
arm: dts: Add support for SD/MMC on SOCFPGA
.../bindings/arm/altera/socfpga-system.txt | 10 ++
.../devicetree/bindings/mmc/socfpga-dw-mshc.txt | 38 ++++++++
arch/arm/boot/dts/socfpga.dtsi | 23 ++++-
arch/arm/boot/dts/socfpga_cyclone5.dts | 12 +++
arch/arm/boot/dts/socfpga_vt.dts | 12 +++
drivers/clk/socfpga/Makefile | 2 +-
drivers/clk/socfpga/clk-sysmgr.c | 98 ++++++++++++++++++++
drivers/mmc/host/dw_mmc-socfpga.c | 80 ++--------------
8 files changed, 202 insertions(+), 73 deletions(-)
create mode 100644 Documentation/devicetree/bindings/mmc/socfpga-dw-mshc.txt
create mode 100644 drivers/clk/socfpga/clk-sysmgr.c
---
CC: Arnd Bergmann <arnd@arndb.de>
Cc: Mike Turquette <mturquette@linaro.org>
CC: Olof Johansson <olof@lixom.net>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Chris Ball <cjb@laptop.org>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Seungwon Jeon <tgih.jun@samsung.com>
Cc: devicetree@vger.kernel.org
Cc: linux-mmc@vger.kernel.org
CC: linux-arm-kernel@lists.infradead.org
--
1.7.9.5
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCHv2 1/4] clk: socfpga: Add a clock driver for SOCFPGA's system manager
2013-11-04 20:36 [PATCHv2 0/4] socfpga: Enable SD/MMC support dinguyen
@ 2013-11-04 20:36 ` dinguyen
2013-11-04 20:36 ` [PATCHv2 2/4] arm: dts: Add a system manager compatible property dinguyen
2013-11-04 20:36 ` [PATCHv2 3/4] mmc: dw_mmc-socfpga: Clean up SOCFPGA platform specific functionality dinguyen
2 siblings, 0 replies; 4+ messages in thread
From: dinguyen @ 2013-11-04 20:36 UTC (permalink / raw)
To: dinh.linux
Cc: Dinh Nguyen, Arnd Bergmann, Mike Turquette, Olof Johansson,
Rob Herring, Pawel Moll, Mark Rutland, Stephen Warren,
Ian Campbell, Chris Ball, Jaehoon Chung, Seungwon Jeon,
devicetree, linux-mmc, linux-arm-kernel
From: Dinh Nguyen <dinguyen@altera.com>
The system manager is an IP block on the SOCFPGA platform. The system manager
contains registers that control other IPs on the platform. One of the IPs that
the system manager has control over is the SD/MMC, by way of controlling the
clock phase on the SD/MMC Card Interface Unit.
This patch adds a clock driver that the SD/MMC driver can use by calling
the common clock API in order to set the appropriate register in the
system manager by way of a syscon driver.
This clock driver can also be re-used for other IPs that need to poke the system
manager.
Signed-off-by: Dinh Nguyen <dinguyen@altera.com>
CC: Arnd Bergmann <arnd@arndb.de>
Cc: Mike Turquette <mturquette@linaro.org>
CC: Olof Johansson <olof@lixom.net>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Chris Ball <cjb@laptop.org>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Seungwon Jeon <tgih.jun@samsung.com>
Cc: devicetree@vger.kernel.org
Cc: linux-mmc@vger.kernel.org
CC: linux-arm-kernel@lists.infradead.org
---
v2: Use the syscon driver
---
drivers/clk/socfpga/Makefile | 2 +-
drivers/clk/socfpga/clk-sysmgr.c | 98 ++++++++++++++++++++++++++++++++++++++
2 files changed, 99 insertions(+), 1 deletion(-)
create mode 100644 drivers/clk/socfpga/clk-sysmgr.c
diff --git a/drivers/clk/socfpga/Makefile b/drivers/clk/socfpga/Makefile
index 0303c0b..cfceabc 100644
--- a/drivers/clk/socfpga/Makefile
+++ b/drivers/clk/socfpga/Makefile
@@ -1 +1 @@
-obj-y += clk.o
+obj-y += clk.o clk-sysmgr.o
diff --git a/drivers/clk/socfpga/clk-sysmgr.c b/drivers/clk/socfpga/clk-sysmgr.c
new file mode 100644
index 0000000..96f9b26
--- /dev/null
+++ b/drivers/clk/socfpga/clk-sysmgr.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2013 Altera Corporation <www.altera.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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/slab.h>
+#include <linux/clk-provider.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+
+/* SDMMC Group for System Manager defines */
+#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \
+ ((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0))
+
+struct socfpga_sysmgr {
+ struct clk_hw hw;
+ struct regmap *sysreg;
+ u32 reg;
+};
+#define to_sysmgr_clk(p) container_of(p, struct socfpga_sysmgr, hw)
+
+static int sysmgr_set_dwmmc_drvsel_smpsel(struct clk_hw *hwclk)
+{
+ struct device_node *np;
+ struct socfpga_sysmgr *socfpga_sysmgr = to_sysmgr_clk(hwclk);
+ u32 timing[2];
+ u32 hs_timing;
+
+ np = of_find_compatible_node(NULL, NULL, "altr,socfpga-dw-mshc");
+ of_property_read_u32_array(np, "samsung,dw-mshc-sdr-timing", timing, 2);
+ hs_timing = SYSMGR_SDMMC_CTRL_SET(timing[1], timing[0]);
+ regmap_write(socfpga_sysmgr->sysreg, socfpga_sysmgr->reg, hs_timing);
+ return 0;
+}
+
+static const struct clk_ops clk_sysmgr_sdmmc_ops = {
+ .enable = sysmgr_set_dwmmc_drvsel_smpsel,
+};
+
+static void __init socfpga_sysmgr_init(struct device_node *node, const struct clk_ops *ops)
+{
+ u32 reg;
+ struct clk *clk;
+ struct socfpga_sysmgr *socfpga_sysmgr;
+ const char *clk_name = node->name;
+ struct clk_init_data init;
+ int rc;
+
+ socfpga_sysmgr = kzalloc(sizeof(*socfpga_sysmgr), GFP_KERNEL);
+ if (WARN_ON(!socfpga_sysmgr))
+ return;
+
+ rc = of_property_read_u32(node, "reg", ®);
+ if (WARN_ON(rc))
+ return;
+
+ socfpga_sysmgr->reg = reg;
+
+ socfpga_sysmgr->sysreg = syscon_regmap_lookup_by_compatible("altr,sys-mgr");
+ if (WARN_ON(IS_ERR(socfpga_sysmgr->sysreg))) {
+ pr_err("%s: No sysmgr phandle specified\n", __func__);
+ return;
+ }
+
+ init.name = clk_name;
+ init.ops = ops;
+ init.flags = 0;
+ init.num_parents = 0;
+
+ socfpga_sysmgr->hw.init = &init;
+ clk = clk_register(NULL, &socfpga_sysmgr->hw);
+ if (WARN_ON(IS_ERR(clk))) {
+ kfree(socfpga_sysmgr);
+ return;
+ }
+ rc = of_clk_add_provider(node, of_clk_src_simple_get, clk);
+ if (WARN_ON(rc))
+ return;
+}
+
+static void __init sysmgr_init(struct device_node *node)
+{
+ socfpga_sysmgr_init(node, &clk_sysmgr_sdmmc_ops);
+}
+CLK_OF_DECLARE(sysmgr, "altr,sysmgr-sdmmc-sdr", sysmgr_init);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCHv2 2/4] arm: dts: Add a system manager compatible property
2013-11-04 20:36 [PATCHv2 0/4] socfpga: Enable SD/MMC support dinguyen
2013-11-04 20:36 ` [PATCHv2 1/4] clk: socfpga: Add a clock driver for SOCFPGA's system manager dinguyen
@ 2013-11-04 20:36 ` dinguyen
2013-11-04 20:36 ` [PATCHv2 3/4] mmc: dw_mmc-socfpga: Clean up SOCFPGA platform specific functionality dinguyen
2 siblings, 0 replies; 4+ messages in thread
From: dinguyen @ 2013-11-04 20:36 UTC (permalink / raw)
To: dinh.linux
Cc: Dinh Nguyen, Arnd Bergmann, Mike Turquette, Olof Johansson,
Rob Herring, Pawel Moll, Mark Rutland, Stephen Warren,
Ian Campbell, Chris Ball, Jaehoon Chung, Seungwon Jeon,
devicetree, linux-mmc, linux-arm-kernel
From: Dinh Nguyen <dinguyen@altera.com>
The "altr,sysmgr-sdmmc-sdr" compatible property is used for the SOCFPGA
clk-sysmgr driver. This property represents the register inside the
system manager that controls the clock phase of the SD/MMC driver.
Also add "syscon" to the system manager node.
Signed-off-by: Dinh Nguyen <dinguyen@altera.com>
CC: Arnd Bergmann <arnd@arndb.de>
Cc: Mike Turquette <mturquette@linaro.org>
CC: Olof Johansson <olof@lixom.net>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Chris Ball <cjb@laptop.org>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Seungwon Jeon <tgih.jun@samsung.com>
Cc: devicetree@vger.kernel.org
Cc: linux-mmc@vger.kernel.org
CC: linux-arm-kernel@lists.infradead.org
---
.../bindings/arm/altera/socfpga-system.txt | 10 ++++++++++
arch/arm/boot/dts/socfpga.dtsi | 12 ++++++++++--
2 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt b/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt
index f4d04a0..7a6c7ed 100644
--- a/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt
+++ b/Documentation/devicetree/bindings/arm/altera/socfpga-system.txt
@@ -5,9 +5,19 @@ Required properties:
- reg : Should contain 1 register ranges(address and length)
- cpu1-start-addr : CPU1 start address in hex.
+Optional properties:
+- compatible = "altr,sysmgr-sdmmc-sdr". This compatible property is used
+to represent the clock phase settings for the SD/MMC IP.
+
Example:
sysmgr@ffd08000 {
compatible = "altr,sys-mgr";
reg = <0xffd08000 0x1000>;
cpu1-start-addr = <0xffd080c4>;
+
+ sysmgr_sdr_mmc: sysmgr_sdr_mmc {
+ #clock-cells = <0>;
+ compatible = "altr,sysmgr-sdmmc-sdr";
+ reg = <0x108 1>;
+ };
};
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
index e273fa9..eb990d2 100644
--- a/arch/arm/boot/dts/socfpga.dtsi
+++ b/arch/arm/boot/dts/socfpga.dtsi
@@ -521,8 +521,16 @@
};
sysmgr@ffd08000 {
- compatible = "altr,sys-mgr";
- reg = <0xffd08000 0x4000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "altr,sys-mgr", "syscon";
+ reg = <0xffd08000 0x4000>;
+
+ sysmgr_sdr_mmc: sysmgr_sdr_mmc {
+ #clock-cells = <0>;
+ compatible = "altr,sysmgr-sdmmc-sdr";
+ reg = <0x108 1>;
};
+ };
};
};
--
1.7.9.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCHv2 3/4] mmc: dw_mmc-socfpga: Clean up SOCFPGA platform specific functionality
2013-11-04 20:36 [PATCHv2 0/4] socfpga: Enable SD/MMC support dinguyen
2013-11-04 20:36 ` [PATCHv2 1/4] clk: socfpga: Add a clock driver for SOCFPGA's system manager dinguyen
2013-11-04 20:36 ` [PATCHv2 2/4] arm: dts: Add a system manager compatible property dinguyen
@ 2013-11-04 20:36 ` dinguyen
2 siblings, 0 replies; 4+ messages in thread
From: dinguyen @ 2013-11-04 20:36 UTC (permalink / raw)
To: dinh.linux
Cc: Dinh Nguyen, Arnd Bergmann, Mike Turquette, Olof Johansson,
Rob Herring, Pawel Moll, Mark Rutland, Stephen Warren,
Ian Campbell, Chris Ball, Jaehoon Chung, Seungwon Jeon,
devicetree, linux-mmc, linux-arm-kernel
From: Dinh Nguyen <dinguyen@altera.com>
The SDR timing registers for the SD/MMC IP block for SOCFPGA is located
in the system manager. This system manager IP block is located outside of
the SD IP block itself. We can use the normal clock API to set the SDR
settings.
Also, there is no need for "altr,dw-mshc-ciu-div" as the driver can get
the value of the CIU clock from the common clock API.
Signed-off-by: Dinh Nguyen <dinguyen@altera.com>
CC: Arnd Bergmann <arnd@arndb.de>
Cc: Mike Turquette <mturquette@linaro.org>
CC: Olof Johansson <olof@lixom.net>
Cc: Rob Herring <rob.herring@calxeda.com>
Cc: Pawel Moll <pawel.moll@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>
Cc: Ian Campbell <ian.campbell@citrix.com>
Cc: Chris Ball <cjb@laptop.org>
Cc: Jaehoon Chung <jh80.chung@samsung.com>
Cc: Seungwon Jeon <tgih.jun@samsung.com>
Cc: devicetree@vger.kernel.org
Cc: linux-mmc@vger.kernel.org
CC: linux-arm-kernel@lists.infradead.org
---
drivers/mmc/host/dw_mmc-socfpga.c | 80 +++++--------------------------------
1 file changed, 10 insertions(+), 70 deletions(-)
diff --git a/drivers/mmc/host/dw_mmc-socfpga.c b/drivers/mmc/host/dw_mmc-socfpga.c
index 14b5961..4999454 100644
--- a/drivers/mmc/host/dw_mmc-socfpga.c
+++ b/drivers/mmc/host/dw_mmc-socfpga.c
@@ -13,97 +13,37 @@
* Taken from dw_mmc-exynos.c
*/
#include <linux/clk.h>
-#include <linux/mfd/syscon.h>
#include <linux/mmc/host.h>
#include <linux/mmc/dw_mmc.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
-#include <linux/regmap.h>
#include "dw_mmc.h"
#include "dw_mmc-pltfm.h"
-#define SYSMGR_SDMMCGRP_CTRL_OFFSET 0x108
-#define DRV_CLK_PHASE_SHIFT_SEL_MASK 0x7
-#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \
- ((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0))
-
-/* SOCFPGA implementation specific driver private data */
-struct dw_mci_socfpga_priv_data {
- u8 ciu_div; /* card interface unit divisor */
- u32 hs_timing; /* bitmask for CIU clock phase shift */
- struct regmap *sysreg; /* regmap for system manager register */
-};
-
-static int dw_mci_socfpga_priv_init(struct dw_mci *host)
-{
- struct dw_mci_socfpga_priv_data *priv;
-
- priv = devm_kzalloc(host->dev, sizeof(*priv), GFP_KERNEL);
- if (!priv) {
- dev_err(host->dev, "mem alloc failed for private data\n");
- return -ENOMEM;
- }
-
- priv->sysreg = syscon_regmap_lookup_by_compatible("altr,sys-mgr");
- if (IS_ERR(priv->sysreg)) {
- dev_err(host->dev, "regmap for altr,sys-mgr lookup failed.\n");
- return PTR_ERR(priv->sysreg);
- }
- host->priv = priv;
-
- return 0;
-}
-
static int dw_mci_socfpga_setup_clock(struct dw_mci *host)
{
- struct dw_mci_socfpga_priv_data *priv = host->priv;
-
- clk_disable_unprepare(host->ciu_clk);
- regmap_write(priv->sysreg, SYSMGR_SDMMCGRP_CTRL_OFFSET,
- priv->hs_timing);
- clk_prepare_enable(host->ciu_clk);
-
- host->bus_hz /= (priv->ciu_div + 1);
+ struct clk *sysmgr_clk = devm_clk_get(host->dev, "sysmgr-sdr-mmc");
+
+ if (IS_ERR(sysmgr_clk))
+ dev_err(host->dev, "sysmgr-sdr-mmc not available\n");
+ else {
+ clk_disable_unprepare(host->ciu_clk);
+ clk_prepare_enable(sysmgr_clk);
+ clk_prepare_enable(host->ciu_clk);
+ }
return 0;
}
static void dw_mci_socfpga_prepare_command(struct dw_mci *host, u32 *cmdr)
{
- struct dw_mci_socfpga_priv_data *priv = host->priv;
-
- if (priv->hs_timing & DRV_CLK_PHASE_SHIFT_SEL_MASK)
- *cmdr |= SDMMC_CMD_USE_HOLD_REG;
-}
-
-static int dw_mci_socfpga_parse_dt(struct dw_mci *host)
-{
- struct dw_mci_socfpga_priv_data *priv = host->priv;
- struct device_node *np = host->dev->of_node;
- u32 timing[2];
- u32 div = 0;
- int ret;
-
- ret = of_property_read_u32(np, "altr,dw-mshc-ciu-div", &div);
- if (ret)
- dev_info(host->dev, "No dw-mshc-ciu-div specified, assuming 1");
- priv->ciu_div = div;
-
- ret = of_property_read_u32_array(np,
- "altr,dw-mshc-sdr-timing", timing, 2);
- if (ret)
- return ret;
-
- priv->hs_timing = SYSMGR_SDMMC_CTRL_SET(timing[0], timing[1]);
- return 0;
+ *cmdr |= SDMMC_CMD_USE_HOLD_REG;
}
static const struct dw_mci_drv_data socfpga_drv_data = {
- .init = dw_mci_socfpga_priv_init,
.setup_clock = dw_mci_socfpga_setup_clock,
.prepare_command = dw_mci_socfpga_prepare_command,
- .parse_dt = dw_mci_socfpga_parse_dt,
};
static const struct of_device_id dw_mci_socfpga_match[] = {
--
1.7.9.5
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2013-11-04 20:36 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-11-04 20:36 [PATCHv2 0/4] socfpga: Enable SD/MMC support dinguyen
2013-11-04 20:36 ` [PATCHv2 1/4] clk: socfpga: Add a clock driver for SOCFPGA's system manager dinguyen
2013-11-04 20:36 ` [PATCHv2 2/4] arm: dts: Add a system manager compatible property dinguyen
2013-11-04 20:36 ` [PATCHv2 3/4] mmc: dw_mmc-socfpga: Clean up SOCFPGA platform specific functionality dinguyen
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).