Message ID | 1386597462-29471-3-git-send-email-dinguyen@altera.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
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
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 --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; }