From 0691bb1b5a1865b3bbc9b7ce6e26eff546abb1cf Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Mon, 12 May 2014 12:27:22 -0500 Subject: clk: socfpga: add divider registers to the main pll outputs The C0(mpu_clk), C1(main_clk), and C2(dbg_base_clk) outputs from the main PLL go through a pre-divider before coming into the system. These registers were hidden for the CycloneV platform, but are now used for the ArriaV platform. This patch updates the clock driver to read the div-reg property for the socfpga-periph-clk clocks. Also moves the div_mask define to clk.h for re-use. Signed-off-by: Dinh Nguyen --- drivers/clk/socfpga/clk-periph.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'drivers/clk/socfpga/clk-periph.c') diff --git a/drivers/clk/socfpga/clk-periph.c b/drivers/clk/socfpga/clk-periph.c index 81623a3736f9..46531c34ec9b 100644 --- a/drivers/clk/socfpga/clk-periph.c +++ b/drivers/clk/socfpga/clk-periph.c @@ -29,12 +29,18 @@ static unsigned long clk_periclk_recalc_rate(struct clk_hw *hwclk, unsigned long parent_rate) { struct socfpga_periph_clk *socfpgaclk = to_socfpga_periph_clk(hwclk); - u32 div; + u32 div, val; - if (socfpgaclk->fixed_div) + if (socfpgaclk->fixed_div) { div = socfpgaclk->fixed_div; - else + } else { + if (socfpgaclk->div_reg) { + val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift; + val &= div_mask(socfpgaclk->width); + parent_rate /= (val + 1); + } div = ((readl(socfpgaclk->hw.reg) & 0x1ff) + 1); + } return parent_rate / div; } @@ -54,6 +60,7 @@ static __init void __socfpga_periph_init(struct device_node *node, struct clk_init_data init; int rc; u32 fixed_div; + u32 div_reg[3]; of_property_read_u32(node, "reg", ®); @@ -63,6 +70,15 @@ static __init void __socfpga_periph_init(struct device_node *node, periph_clk->hw.reg = clk_mgr_base_addr + reg; + rc = of_property_read_u32_array(node, "div-reg", div_reg, 3); + if (!rc) { + periph_clk->div_reg = clk_mgr_base_addr + div_reg[0]; + periph_clk->shift = div_reg[1]; + periph_clk->width = div_reg[2]; + } else { + periph_clk->div_reg = 0; + } + rc = of_property_read_u32(node, "fixed-divider", &fixed_div); if (rc) periph_clk->fixed_div = 0; -- cgit v1.2.3