Re: [PATCH v1 01/12] clk: davinci - add Main PLL clock driver

2012-09-26 Thread Linus Walleij
On Tue, Sep 25, 2012 at 12:20 AM, Murali Karicheri m-kariche...@ti.com wrote:

 +struct clk_davinci_pll_data {
 +   /* physical addresses set by platform code */
 +   u32 phy_pllm;
 +   /* if PLL has a prediv register this should be non zero */
 +   u32 phy_prediv;
 +   /* if PLL has a postdiv register this should be non zero */
 +   u32 phy_postdiv;
 +   /* mapped addresses. should be initialized by  */
 +   void __iomem *pllm;
 +   void __iomem *prediv;
 +   void __iomem *postdiv;
 +   u32 pllm_mask;
 +   u32 prediv_mask;
 +   u32 postdiv_mask;
 +   u32 num;
 +   /* framework flags */
 +   u32 flags;
 +   /* pll flags */
 +   u32 pll_flags;
 +   u32 fixed_prediv;   /* use this value for prediv */
 +   u32 pllm_multiplier;/* multiply PLLM by this factor. By default
 +* most SOC set this to zero that translates
 +* to a multiplier of 1 and incrementer of 1.
 +* To override default, set this factor */
 +};

OMG this commenting style hurt my eyes ;-)

Please use good old kerneldoc above the struct instead.

Yours,
Linus Walleij
___
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source


RE: [linux-keystone] Re: [PATCH v1 01/12] clk: davinci - add Main PLL clock driver

2012-09-26 Thread Karicheri, Muralidharan
 -Original Message-
 From: Linus Walleij [mailto:linus.wall...@linaro.org]
 Sent: Wednesday, September 26, 2012 7:11 AM
 To: Karicheri, Muralidharan
 Cc: mturque...@linaro.org; a...@arndb.de; a...@linux-foundation.org;
 shawn@linaro.org; rob.herr...@calxeda.com; viresh.li...@gmail.com; linux-
 ker...@vger.kernel.org; Nori, Sekhar; Hilman, Kevin; li...@arm.linux.org.uk; 
 davinci-
 linux-open-sou...@linux.davincidsp.com; 
 linux-arm-ker...@lists.infradead.org; linux-
 keyst...@list.ti.com - Linux developers for Keystone family of devices (May 
 contain non-
 TIers); linux-c6x-...@linux-c6x.org; Chemparathy, Cyril
 Subject: [linux-keystone] Re: [PATCH v1 01/12] clk: davinci - add Main PLL 
 clock driver
 
 On Tue, Sep 25, 2012 at 12:20 AM, Murali Karicheri m-kariche...@ti.com 
 wrote:
 
  +struct clk_davinci_pll_data {
  +   /* physical addresses set by platform code */
  +   u32 phy_pllm;
  +   /* if PLL has a prediv register this should be non zero */
  +   u32 phy_prediv;
  +   /* if PLL has a postdiv register this should be non zero */
  +   u32 phy_postdiv;
  +   /* mapped addresses. should be initialized by  */
  +   void __iomem *pllm;
  +   void __iomem *prediv;
  +   void __iomem *postdiv;
  +   u32 pllm_mask;
  +   u32 prediv_mask;
  +   u32 postdiv_mask;
  +   u32 num;
  +   /* framework flags */
  +   u32 flags;
  +   /* pll flags */
  +   u32 pll_flags;
  +   u32 fixed_prediv;   /* use this value for prediv */
  +   u32 pllm_multiplier;/* multiply PLLM by this factor. By default
  +* most SOC set this to zero that 
  translates
  +* to a multiplier of 1 and incrementer of 
  1.
  +* To override default, set this factor */
  +};
 
 OMG this commenting style hurt my eyes ;-)
 
 Please use good old kerneldoc above the struct instead.
 
 Yours,
 Linus Walleij

Sure! I will fix these in my next revision.

Murali
___
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source


[PATCH v1 01/12] clk: davinci - add Main PLL clock driver

2012-09-24 Thread Murali Karicheri
This is the driver for the main PLL clock hardware found on DM SoCs.
This driver borrowed code from arch/arm/mach-davinci/clock.c and
implemented the driver as per common clock provider API. The main PLL
hardware typically has a multiplier, a pre-divider and a post-divider.
Some of the SoCs has the divider fixed meaning they can not be
configured through a register. HAS_PREDIV and HAS_POSTDIV flags are used
to tell the driver if a hardware has these dividers present or not.
Driver is configured through the structure clk_davinci_pll_data
that has the platform data for the driver.

Signed-off-by: Murali Karicheri m-kariche...@ti.com

diff --git a/drivers/clk/davinci/clk-davinci-pll.c 
b/drivers/clk/davinci/clk-davinci-pll.c
new file mode 100644
index 000..13e1690
--- /dev/null
+++ b/drivers/clk/davinci/clk-davinci-pll.c
@@ -0,0 +1,128 @@
+/*
+ * PLL clk driver DaVinci devices
+ *
+ * Copyright (C) 2006-2012 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * 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.
+ * TODO - Add set_parent_rate()
+ */
+#include linux/clk.h
+#include linux/clk-provider.h
+#include linux/delay.h
+#include linux/err.h
+#include linux/io.h
+#include linux/slab.h
+#include linux/platform_data/clk-davinci-pll.h
+
+#include mach/cputype.h
+
+#define PLLM   0x110
+#define PLLM_PLLM_MASK  0xff
+#define PREDIV  0x114
+#define POSTDIV 0x128
+#define PLLDIV_EN   BIT(15)
+
+/**
+ * struct clk_davinci_pll - DaVinci Main pll clock
+ * @hw: clk_hw for the pll
+ * @pll_data: PLL driver specific data
+ */
+struct clk_davinci_pll {
+   struct clk_hw hw;
+   struct clk_davinci_pll_data *pll_data;
+};
+
+#define to_clk_pll(_hw) container_of(_hw, struct clk_davinci_pll, hw)
+
+static unsigned long clk_pllclk_recalc(struct clk_hw *hw,
+   unsigned long parent_rate)
+{
+   struct clk_davinci_pll *pll = to_clk_pll(hw);
+   struct clk_davinci_pll_data *pll_data = pll-pll_data;
+   u32 mult = 1, prediv = 1, postdiv = 1;
+   unsigned long rate = parent_rate;
+
+   /* If there is a device specific recalc defined invoke it. Otherwise
+* fallback to default one
+*/
+   mult = __raw_readl(pll_data-pllm);
+   if (pll_data-pllm_multiplier)
+   mult =  pll_data-pllm_multiplier *
+   (mult  pll_data-pllm_mask);
+   else
+   mult = (mult  pll_data-pllm_mask) + 1;
+
+   if (pll_data-flags  CLK_DAVINCI_PLL_HAS_PREDIV) {
+   /* pre-divider is fixed, take prediv value from pll_data  */
+   if (pll_data-fixed_prediv)
+   prediv = pll_data-fixed_prediv;
+   else {
+   prediv = __raw_readl(pll_data-prediv);
+   if (prediv  PLLDIV_EN)
+   prediv = (prediv  pll_data-prediv_mask) + 1;
+   else
+   prediv = 1;
+   }
+   }
+
+   if (pll_data-flags  CLK_DAVINCI_PLL_HAS_POSTDIV) {
+   postdiv = __raw_readl(pll_data-postdiv);
+   if (postdiv  PLLDIV_EN)
+   postdiv = (postdiv  pll_data-postdiv_mask) + 1;
+   else
+   postdiv = 1;
+   }
+
+   rate /= prediv;
+   rate *= mult;
+   rate /= postdiv;
+
+   pr_debug(PLL%d: input = %lu MHz [ ,
+pll_data-num, parent_rate / 100);
+   if (prediv  1)
+   pr_debug(/ %d , prediv);
+   if (mult  1)
+   pr_debug(* %d , mult);
+   if (postdiv  1)
+   pr_debug(/ %d , postdiv);
+   pr_debug(] -- %lu MHz output.\n, rate / 100);
+   return rate;
+}
+
+static const struct clk_ops clk_pll_ops = {
+   .recalc_rate = clk_pllclk_recalc,
+};
+
+struct clk *clk_register_davinci_pll(struct device *dev, const char *name,
+   const char *parent_name,
+   struct clk_davinci_pll_data *pll_data)
+{
+   struct clk_init_data init;
+   struct clk_davinci_pll *pll;
+   struct clk *clk;
+
+   if (!pll_data)
+   return ERR_PTR(-ENODEV);
+
+   pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+   if (!pll)
+   return ERR_PTR(-ENOMEM);
+   init.name = name;
+   init.ops = clk_pll_ops;
+   init.flags = pll_data-flags;
+   init.parent_names = (parent_name ? parent_name : NULL);
+   init.num_parents = (parent_name ? 1 : 0);
+
+   pll-pll_data   = pll_data;
+   pll-hw.init = init;
+
+   clk = clk_register(NULL, pll-hw);
+   if (IS_ERR(clk))
+   kfree(pll);
+
+   return clk;
+}
diff --git