diff mbox

[PATCHv5,2/4] clk: socfpga: Add a hook for SD/MMC driver to control CIU clock settings

Message ID 1386597462-29471-3-git-send-email-dinguyen@altera.com (mailing list archive)
State New, archived
Headers show

Commit Message

Dinh Nguyen Dec. 9, 2013, 1:57 p.m. UTC
From: Dinh Nguyen <dinguyen@altera.com>

Populate the .prepare function in the clk-ops for the "sdmmc_clk" that represents
the "ciu" clock for the SD/MMC driver. The prepare function will handle setting
the correct clock-phase for the CIU clock of the SD/MMC IP.

Signed-off-by: Dinh Nguyen <dinguyen@altera.com>
---
v5: Use the "snps,dw-mshc" binding
v4: none
v3: none
v2: none
---
 drivers/clk/socfpga/clk.c |   25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

Comments

Arnd Bergmann Dec. 9, 2013, 4:28 p.m. UTC | #1
On Monday 09 December 2013, dinguyen@altera.com wrote:
> From: Dinh Nguyen <dinguyen@altera.com>
> 
> Populate the .prepare function in the clk-ops for the "sdmmc_clk" that represents
> the "ciu" clock for the SD/MMC driver. The prepare function will handle setting
> the correct clock-phase for the CIU clock of the SD/MMC IP.
> 
> Signed-off-by: Dinh Nguyen <dinguyen@altera.com>

Please see my comments for this patch for v4, it still looks wrong to me.
The other three patches are good though.

	Arnd
Dinh Nguyen Dec. 9, 2013, 7:41 p.m. UTC | #2
On Mon, 2013-12-09 at 17:28 +0100, Arnd Bergmann wrote:
> On Monday 09 December 2013, dinguyen@altera.com wrote:
> > From: Dinh Nguyen <dinguyen@altera.com>
> > 
> > Populate the .prepare function in the clk-ops for the "sdmmc_clk" that represents
> > the "ciu" clock for the SD/MMC driver. The prepare function will handle setting
> > the correct clock-phase for the CIU clock of the SD/MMC IP.
> > 
> > Signed-off-by: Dinh Nguyen <dinguyen@altera.com>
> 
> Please see my comments for this patch for v4, it still looks wrong to me.
> The other three patches are good though.

I apologize for missing your V4 comments. It somehow never ended in my
Altera mbox but is there at gmail. I will address them.

Dinh
> 
> 	Arnd
>
diff mbox

Patch

diff --git a/drivers/clk/socfpga/clk.c b/drivers/clk/socfpga/clk.c
index 60cb2f5..fe2670e 100644
--- a/drivers/clk/socfpga/clk.c
+++ b/drivers/clk/socfpga/clk.c
@@ -55,7 +55,13 @@ 
 #define div_mask(width)	((1 << (width)) - 1)
 #define streq(a, b) (strcmp((a), (b)) == 0)
 
+#define SYSMGR_SDMMCGRP_CTRL_OFFSET	0x108
+/* SDMMC Group for System Manager defines */
+#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel)          \
+	((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0))
+
 extern void __iomem *clk_mgr_base_addr;
+extern void __iomem *sys_manager_base_addr;
 
 struct socfpga_clk {
 	struct clk_gate hw;
@@ -68,6 +74,22 @@  struct socfpga_clk {
 };
 #define to_socfpga_clk(p) container_of(p, struct socfpga_clk, hw.hw)
 
+static int sdmmc_ciuclk_prepare(struct clk_hw *hwclk)
+{
+	struct device_node *np;
+	u32 timing[2];
+	u32 hs_timing;
+
+	np = of_find_compatible_node(NULL, NULL, "snps,dw-mshc");
+	if (of_property_read_u32_array(np, "samsung,dw-mshc-sdr-timing", timing, 2)) {
+		pr_err("SDMMC: cannot find samsung,dw-mshc-sdr-timing!\n");
+		return -ENODATA;
+	}
+	hs_timing = SYSMGR_SDMMC_CTRL_SET(timing[0], timing[1]);
+	writel(hs_timing, sys_manager_base_addr + SYSMGR_SDMMCGRP_CTRL_OFFSET);
+	return 0;
+}
+
 static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk,
 					 unsigned long parent_rate)
 {
@@ -274,6 +296,9 @@  static void __init socfpga_gate_clk_init(struct device_node *node,
 		socfpga_clk->hw.reg = clk_mgr_base_addr + clk_gate[0];
 		socfpga_clk->hw.bit_idx = clk_gate[1];
 
+		if (streq(clk_name, "sdmmc_clk"))
+			gateclk_ops.prepare = sdmmc_ciuclk_prepare;
+
 		gateclk_ops.enable = clk_gate_ops.enable;
 		gateclk_ops.disable = clk_gate_ops.disable;
 	}