All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/7] Add generic set_rate clk_ops for PLL35xx and PLL36xx for samsung SoCs
@ 2013-06-10 13:24 ` Yadwinder Singh Brar
  0 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-10 13:24 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, kgene.kim, mturquette, thomas.abraham,
	dianders, t.figa, vikas.sajjan, abrestic, Yadwinder Singh Brar

This patch series does the following:

 1) Unifies the clk strutures  and registration function used for PLL35xx &
    PLL36xx, to factor out possible common code.

 2) Defines a common rate_table which will contain recommended p, m, s and k
    values for supported rates that needs to be changed for changing
    corresponding PLL's rate

 3) Adds set_rate() and round_rate() clk_ops for PLL35xx and PLL36xx

changes since v5:
	- Corrected to use rate table as specified in UM for exynos5250 epll.
	- Took care of exynos5420 as well, as new exynos5420 clk driver came in
	while rebasing on latest Kgene's for-next.

	Since we spilted 1st patch into 2 different patches,
	can we expect "reviewed-by" again for the same? 

changes since v4:
	- Defined common samsung samsung_clk_register_pll() to register a list
	of PLL and used a struct samsung_pll_clock for passing intialisation
	data instead of passing as arguments. Now passing LOCK as well as CON0
	offset as intialisation data.
	- Calculated length of rate table while registering PLL instead of
	getting it as intialisation data.

changes since v3:
	- Used __clk_lookup() instead of adding alias for mout_vpllsrc
	- Added check for changing only M value in samsung_pll36xx_set_rate()
	- Modified samsung_pll35xx_mp_change() & samsung_pll35xx_set_rate()
	to improve readabilty.
	- Made the input rate_table as __init_data which is to be provided while
	registering PLL and made a copy of that table while registering, so
	that if multiple tables are their, they can be freed after getting the
	P, M, S, K setting values from required one.

changes since v2:
	- Added new patch to reorder the MUX registration for mout_vpllsrc MUX
	before the PLL registrations. And to add the alias for the mout_vpllsrc MUX.
        - Added a check to confirm parent rate while registrating the PLL
	rate tables.

changes since v1:
	- removed sorting and bsearch
	- modified the definition of struct "samsung_pll_rate_table"
	- added generic round_rate()
	- rectified the ops assignment for "rate table passed as NULL"
	  during PLL registration

Is rebased on branch kgene's "for-next"
https://git.kernel.org/cgit/linux/kernel/git/kgene/linux-samsung.git/log/?h=for-next

Vikas Sajjan (2):
  clk: samsung: Add set_rate() clk_ops for PLL36xx
  clk: samsung: Reorder MUX registration for mout_vpllsrc

Yadwinder Singh Brar (5):
  clk: samsung: Introduce a common samsung_clk_pll struct
  clk: samsung: Define a common samsung_clk_register_pll()
  clk: samsung: Add support to register rate_table for samsung plls
  clk: samsung: Add set_rate() clk_ops for PLL35xx
  clk: samsung: Add EPLL and VPLL freq table for exynos5250 SoC

 drivers/clk/samsung/clk-exynos4.c    |   40 +++--
 drivers/clk/samsung/clk-exynos5250.c |  101 +++++++++--
 drivers/clk/samsung/clk-exynos5420.c |   86 ++++++---
 drivers/clk/samsung/clk-pll.c        |  332 ++++++++++++++++++++++++++--------
 drivers/clk/samsung/clk-pll.h        |   38 ++++-
 drivers/clk/samsung/clk.h            |   54 ++++++
 6 files changed, 513 insertions(+), 138 deletions(-)

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 0/7] Add generic set_rate clk_ops for PLL35xx and PLL36xx for samsung SoCs
@ 2013-06-10 13:24 ` Yadwinder Singh Brar
  0 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-10 13:24 UTC (permalink / raw)
  To: linux-arm-kernel

This patch series does the following:

 1) Unifies the clk strutures  and registration function used for PLL35xx &
    PLL36xx, to factor out possible common code.

 2) Defines a common rate_table which will contain recommended p, m, s and k
    values for supported rates that needs to be changed for changing
    corresponding PLL's rate

 3) Adds set_rate() and round_rate() clk_ops for PLL35xx and PLL36xx

changes since v5:
	- Corrected to use rate table as specified in UM for exynos5250 epll.
	- Took care of exynos5420 as well, as new exynos5420 clk driver came in
	while rebasing on latest Kgene's for-next.

	Since we spilted 1st patch into 2 different patches,
	can we expect "reviewed-by" again for the same? 

changes since v4:
	- Defined common samsung samsung_clk_register_pll() to register a list
	of PLL and used a struct samsung_pll_clock for passing intialisation
	data instead of passing as arguments. Now passing LOCK as well as CON0
	offset as intialisation data.
	- Calculated length of rate table while registering PLL instead of
	getting it as intialisation data.

changes since v3:
	- Used __clk_lookup() instead of adding alias for mout_vpllsrc
	- Added check for changing only M value in samsung_pll36xx_set_rate()
	- Modified samsung_pll35xx_mp_change() & samsung_pll35xx_set_rate()
	to improve readabilty.
	- Made the input rate_table as __init_data which is to be provided while
	registering PLL and made a copy of that table while registering, so
	that if multiple tables are their, they can be freed after getting the
	P, M, S, K setting values from required one.

changes since v2:
	- Added new patch to reorder the MUX registration for mout_vpllsrc MUX
	before the PLL registrations. And to add the alias for the mout_vpllsrc MUX.
        - Added a check to confirm parent rate while registrating the PLL
	rate tables.

changes since v1:
	- removed sorting and bsearch
	- modified the definition of struct "samsung_pll_rate_table"
	- added generic round_rate()
	- rectified the ops assignment for "rate table passed as NULL"
	  during PLL registration

Is rebased on branch kgene's "for-next"
https://git.kernel.org/cgit/linux/kernel/git/kgene/linux-samsung.git/log/?h=for-next

Vikas Sajjan (2):
  clk: samsung: Add set_rate() clk_ops for PLL36xx
  clk: samsung: Reorder MUX registration for mout_vpllsrc

Yadwinder Singh Brar (5):
  clk: samsung: Introduce a common samsung_clk_pll struct
  clk: samsung: Define a common samsung_clk_register_pll()
  clk: samsung: Add support to register rate_table for samsung plls
  clk: samsung: Add set_rate() clk_ops for PLL35xx
  clk: samsung: Add EPLL and VPLL freq table for exynos5250 SoC

 drivers/clk/samsung/clk-exynos4.c    |   40 +++--
 drivers/clk/samsung/clk-exynos5250.c |  101 +++++++++--
 drivers/clk/samsung/clk-exynos5420.c |   86 ++++++---
 drivers/clk/samsung/clk-pll.c        |  332 ++++++++++++++++++++++++++--------
 drivers/clk/samsung/clk-pll.h        |   38 ++++-
 drivers/clk/samsung/clk.h            |   54 ++++++
 6 files changed, 513 insertions(+), 138 deletions(-)

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 1/7] clk: samsung: Introduce a common samsung_clk_pll struct
  2013-06-10 13:24 ` Yadwinder Singh Brar
@ 2013-06-10 13:24   ` Yadwinder Singh Brar
  -1 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-10 13:24 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, kgene.kim, mturquette, thomas.abraham,
	dianders, t.figa, vikas.sajjan, abrestic, Yadwinder Singh Brar

This patch unifies clk strutures used for PLL35xx & PLL36xx and
adding an extra member lock_reg, so that common code can be factored out.

Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
---
 drivers/clk/samsung/clk-pll.c |   30 ++++++++++++------------------
 1 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 89135f6..8224bde 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -13,6 +13,14 @@
 #include "clk.h"
 #include "clk-pll.h"
 
+struct samsung_clk_pll {
+	struct clk_hw		hw;
+	void __iomem		*lock_reg;
+	void __iomem		*con_reg;
+};
+
+#define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
+
 /*
  * PLL35xx Clock Type
  */
@@ -24,17 +32,10 @@
 #define PLL35XX_PDIV_SHIFT      (8)
 #define PLL35XX_SDIV_SHIFT      (0)
 
-struct samsung_clk_pll35xx {
-	struct clk_hw		hw;
-	const void __iomem	*con_reg;
-};
-
-#define to_clk_pll35xx(_hw) container_of(_hw, struct samsung_clk_pll35xx, hw)
-
 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
 				unsigned long parent_rate)
 {
-	struct samsung_clk_pll35xx *pll = to_clk_pll35xx(hw);
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
 	u32 mdiv, pdiv, sdiv, pll_con;
 	u64 fvco = parent_rate;
 
@@ -56,7 +57,7 @@ static const struct clk_ops samsung_pll35xx_clk_ops = {
 struct clk * __init samsung_clk_register_pll35xx(const char *name,
 			const char *pname, const void __iomem *con_reg)
 {
-	struct samsung_clk_pll35xx *pll;
+	struct samsung_clk_pll *pll;
 	struct clk *clk;
 	struct clk_init_data init;
 
@@ -100,17 +101,10 @@ struct clk * __init samsung_clk_register_pll35xx(const char *name,
 #define PLL36XX_PDIV_SHIFT	(8)
 #define PLL36XX_SDIV_SHIFT	(0)
 
-struct samsung_clk_pll36xx {
-	struct clk_hw		hw;
-	const void __iomem	*con_reg;
-};
-
-#define to_clk_pll36xx(_hw) container_of(_hw, struct samsung_clk_pll36xx, hw)
-
 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
 				unsigned long parent_rate)
 {
-	struct samsung_clk_pll36xx *pll = to_clk_pll36xx(hw);
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
 	u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
 	u64 fvco = parent_rate;
 
@@ -135,7 +129,7 @@ static const struct clk_ops samsung_pll36xx_clk_ops = {
 struct clk * __init samsung_clk_register_pll36xx(const char *name,
 			const char *pname, const void __iomem *con_reg)
 {
-	struct samsung_clk_pll36xx *pll;
+	struct samsung_clk_pll *pll;
 	struct clk *clk;
 	struct clk_init_data init;
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 1/7] clk: samsung: Introduce a common samsung_clk_pll struct
@ 2013-06-10 13:24   ` Yadwinder Singh Brar
  0 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-10 13:24 UTC (permalink / raw)
  To: linux-arm-kernel

This patch unifies clk strutures used for PLL35xx & PLL36xx and
adding an extra member lock_reg, so that common code can be factored out.

Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
---
 drivers/clk/samsung/clk-pll.c |   30 ++++++++++++------------------
 1 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 89135f6..8224bde 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -13,6 +13,14 @@
 #include "clk.h"
 #include "clk-pll.h"
 
+struct samsung_clk_pll {
+	struct clk_hw		hw;
+	void __iomem		*lock_reg;
+	void __iomem		*con_reg;
+};
+
+#define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
+
 /*
  * PLL35xx Clock Type
  */
@@ -24,17 +32,10 @@
 #define PLL35XX_PDIV_SHIFT      (8)
 #define PLL35XX_SDIV_SHIFT      (0)
 
-struct samsung_clk_pll35xx {
-	struct clk_hw		hw;
-	const void __iomem	*con_reg;
-};
-
-#define to_clk_pll35xx(_hw) container_of(_hw, struct samsung_clk_pll35xx, hw)
-
 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
 				unsigned long parent_rate)
 {
-	struct samsung_clk_pll35xx *pll = to_clk_pll35xx(hw);
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
 	u32 mdiv, pdiv, sdiv, pll_con;
 	u64 fvco = parent_rate;
 
@@ -56,7 +57,7 @@ static const struct clk_ops samsung_pll35xx_clk_ops = {
 struct clk * __init samsung_clk_register_pll35xx(const char *name,
 			const char *pname, const void __iomem *con_reg)
 {
-	struct samsung_clk_pll35xx *pll;
+	struct samsung_clk_pll *pll;
 	struct clk *clk;
 	struct clk_init_data init;
 
@@ -100,17 +101,10 @@ struct clk * __init samsung_clk_register_pll35xx(const char *name,
 #define PLL36XX_PDIV_SHIFT	(8)
 #define PLL36XX_SDIV_SHIFT	(0)
 
-struct samsung_clk_pll36xx {
-	struct clk_hw		hw;
-	const void __iomem	*con_reg;
-};
-
-#define to_clk_pll36xx(_hw) container_of(_hw, struct samsung_clk_pll36xx, hw)
-
 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
 				unsigned long parent_rate)
 {
-	struct samsung_clk_pll36xx *pll = to_clk_pll36xx(hw);
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
 	u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
 	u64 fvco = parent_rate;
 
@@ -135,7 +129,7 @@ static const struct clk_ops samsung_pll36xx_clk_ops = {
 struct clk * __init samsung_clk_register_pll36xx(const char *name,
 			const char *pname, const void __iomem *con_reg)
 {
-	struct samsung_clk_pll36xx *pll;
+	struct samsung_clk_pll *pll;
 	struct clk *clk;
 	struct clk_init_data init;
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 2/7] clk: samsung: Define a common samsung_clk_register_pll()
  2013-06-10 13:24 ` Yadwinder Singh Brar
@ 2013-06-10 13:24   ` Yadwinder Singh Brar
  -1 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-10 13:24 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, kgene.kim, mturquette, thomas.abraham,
	dianders, t.figa, vikas.sajjan, abrestic, Yadwinder Singh Brar

This patch defines a common samsung_clk_register_pll() and its migrating the
PLL35xx & PLL36xx to use it. Other samsung PLL can also be migrated to it.
It also adds exynos5250 & exynos5420 PLLs to unique id list of clocks.
Since pll2550 & pll35xx and pll2650 & pll36xx have exactly same clk ops
implementation, added pll2550 and pll2650 also.

Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
---
 drivers/clk/samsung/clk-exynos4.c    |   40 +++++++----
 drivers/clk/samsung/clk-exynos5250.c |   60 +++++++++++-----
 drivers/clk/samsung/clk-exynos5420.c |   86 +++++++++++++++-------
 drivers/clk/samsung/clk-pll.c        |  132 ++++++++++++++++------------------
 drivers/clk/samsung/clk-pll.h        |   11 ++-
 drivers/clk/samsung/clk.h            |   48 ++++++++++++
 6 files changed, 242 insertions(+), 135 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index addc738..ba25a1b 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -17,7 +17,6 @@
 #include <linux/of_address.h>
 
 #include "clk.h"
-#include "clk-pll.h"
 
 /* Exynos4 clock controller register offsets */
 #define SRC_LEFTBUS		0x4200
@@ -97,12 +96,14 @@
 #define GATE_IP_PERIL		0xc950
 #define E4210_GATE_IP_PERIR	0xc960
 #define GATE_BLOCK		0xc970
+#define E4X12_MPLL_LOCK		0x10008
 #define E4X12_MPLL_CON0		0x10108
 #define SRC_DMC			0x10200
 #define SRC_MASK_DMC		0x10300
 #define DIV_DMC0		0x10500
 #define DIV_DMC1		0x10504
 #define GATE_IP_DMC		0x10900
+#define APLL_LOCK		0x14000
 #define APLL_CON0		0x14100
 #define E4210_MPLL_CON0		0x14108
 #define SRC_CPU			0x14200
@@ -121,6 +122,12 @@ enum exynos4_soc {
 	EXYNOS4X12,
 };
 
+/* list of PLLs to be registered */
+enum exynos4_plls {
+	apll, mpll, epll, vpll,
+	nr_plls			/* number of PLLs */
+};
+
 /*
  * Let each supported clock get a unique id. This id is used to lookup the clock
  * for device tree based platforms. The clocks are categorized into three
@@ -988,6 +995,17 @@ static __initdata struct of_device_id ext_clk_match[] = {
 	{},
 };
 
+struct __initdata samsung_pll_clock exynos4_plls[nr_plls] = {
+	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
+		APLL_CON0, "fout_apll"),
+	[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll",
+		E4X12_MPLL_LOCK, E4X12_MPLL_CON0, "fout_mpll"),
+	[epll] = PLL_A(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
+		EPLL_CON0, "fout_epll"),
+	[vpll] = PLL_A(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
+		VPLL_CON0, "fout_vpll"),
+};
+
 /* register exynos4 clocks */
 void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_soc, void __iomem *reg_base, unsigned long xom)
 {
@@ -1024,22 +1042,16 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
 					reg_base + EPLL_CON0, pll_4600);
 		vpll = samsung_clk_register_pll46xx("fout_vpll", "mout_vpllsrc",
 					reg_base + VPLL_CON0, pll_4650c);
+
+		samsung_clk_add_lookup(apll, fout_apll);
+		samsung_clk_add_lookup(mpll, fout_mpll);
+		samsung_clk_add_lookup(epll, fout_epll);
+		samsung_clk_add_lookup(vpll, fout_vpll);
 	} else {
-		apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
-					reg_base + APLL_CON0);
-		mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
-					reg_base + E4X12_MPLL_CON0);
-		epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
-					reg_base + EPLL_CON0);
-		vpll = samsung_clk_register_pll36xx("fout_vpll", "fin_pll",
-					reg_base + VPLL_CON0);
+		samsung_clk_register_pll(exynos4_plls,
+					ARRAY_SIZE(exynos4_plls), reg_base);
 	}
 
-	samsung_clk_add_lookup(apll, fout_apll);
-	samsung_clk_add_lookup(mpll, fout_mpll);
-	samsung_clk_add_lookup(epll, fout_epll);
-	samsung_clk_add_lookup(vpll, fout_vpll);
-
 	samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks,
 			ARRAY_SIZE(exynos4_fixed_rate_clks));
 	samsung_clk_register_mux(exynos4_mux_clks,
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 7c68850..dc6a700 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -17,11 +17,22 @@
 #include <linux/of_address.h>
 
 #include "clk.h"
-#include "clk-pll.h"
 
+#define APLL_LOCK		0x0
+#define APLL_CON0		0x100
 #define SRC_CPU			0x200
 #define DIV_CPU0		0x500
+#define MPLL_LOCK		0x4000
+#define MPLL_CON0		0x4100
 #define SRC_CORE1		0x4204
+#define CPLL_LOCK		0x10020
+#define EPLL_LOCK		0x10030
+#define VPLL_LOCK		0x10040
+#define GPLL_LOCK		0x10050
+#define CPLL_CON0		0x10120
+#define EPLL_CON0		0x10130
+#define VPLL_CON0		0x10140
+#define GPLL_CON0		0x10150
 #define SRC_TOP0		0x10210
 #define SRC_TOP2		0x10218
 #define SRC_GSCL		0x10220
@@ -59,10 +70,18 @@
 #define GATE_IP_FSYS		0x10944
 #define GATE_IP_PERIC		0x10950
 #define GATE_IP_PERIS		0x10960
+#define BPLL_LOCK		0x20010
+#define BPLL_CON0		0x20110
 #define SRC_CDREX		0x20200
 #define PLL_DIV2_SEL		0x20a24
 #define GATE_IP_DISP1		0x10928
 
+/* list of PLLs to be registered */
+enum exynos5250_plls {
+	apll, mpll, bpll, gpll, cpll, epll, vpll,
+	nr_plls			/* number of PLLs */
+};
+
 /*
  * Let each supported clock get a unique id. This id is used to lookup the clock
  * for device tree based platforms. The clocks are categorized into three
@@ -79,7 +98,8 @@ enum exynos5250_clks {
 	none,
 
 	/* core clocks */
-	fin_pll,
+	fin_pll, fout_apll, fout_mpll, fout_bpll, fout_gpll, fout_cpll,
+	fout_epll, fout_vpll,
 
 	/* gate for special clocks (sclk) */
 	sclk_cam_bayer = 128, sclk_cam0, sclk_cam1, sclk_gscl_wa, sclk_gscl_wb,
@@ -470,11 +490,27 @@ static __initdata struct of_device_id ext_clk_match[] = {
 	{ },
 };
 
+struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = {
+	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
+		APLL_CON0, "fout_apll"),
+	[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
+		MPLL_CON0, "fout_mpll"),
+	[bpll] = PLL(pll_35xx, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
+		BPLL_CON0),
+	[gpll] = PLL(pll_35xx, fout_gpll, "fout_gpll", "fin_pll", GPLL_LOCK,
+		GPLL_CON0),
+	[cpll] = PLL(pll_35xx, fout_cpll, "fout_cpll", "fin_pll", CPLL_LOCK,
+		CPLL_CON0),
+	[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
+		EPLL_CON0),
+	[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
+		VPLL_CON0),
+};
+
 /* register exynox5250 clocks */
 void __init exynos5250_clk_init(struct device_node *np)
 {
 	void __iomem *reg_base;
-	struct clk *apll, *mpll, *epll, *vpll, *bpll, *gpll, *cpll;
 
 	if (np) {
 		reg_base = of_iomap(np, 0);
@@ -490,22 +526,8 @@ void __init exynos5250_clk_init(struct device_node *np)
 	samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks,
 			ARRAY_SIZE(exynos5250_fixed_rate_ext_clks),
 			ext_clk_match);
-
-	apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
-			reg_base + 0x100);
-	mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
-			reg_base + 0x4100);
-	bpll = samsung_clk_register_pll35xx("fout_bpll", "fin_pll",
-			reg_base + 0x20110);
-	gpll = samsung_clk_register_pll35xx("fout_gpll", "fin_pll",
-			reg_base + 0x10150);
-	cpll = samsung_clk_register_pll35xx("fout_cpll", "fin_pll",
-			reg_base + 0x10120);
-	epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
-			reg_base + 0x10130);
-	vpll = samsung_clk_register_pll36xx("fout_vpll", "mout_vpllsrc",
-			reg_base + 0x10140);
-
+	samsung_clk_register_pll(exynos5250_plls, ARRAY_SIZE(exynos5250_plls),
+					reg_base);
 	samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,
 			ARRAY_SIZE(exynos5250_fixed_rate_clks));
 	samsung_clk_register_fixed_factor(exynos5250_fixed_factor_clks,
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 68a96cb..3ea6b4f 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -17,13 +17,30 @@
 #include <linux/of_address.h>
 
 #include "clk.h"
-#include "clk-pll.h"
 
+#define APLL_LOCK		0x0
+#define APLL_CON0		0x100
 #define SRC_CPU			0x200
 #define DIV_CPU0		0x500
 #define DIV_CPU1		0x504
 #define GATE_BUS_CPU		0x700
 #define GATE_SCLK_CPU		0x800
+#define CPLL_LOCK		0x10020
+#define DPLL_LOCK		0x10030
+#define EPLL_LOCK		0x10040
+#define RPLL_LOCK		0x10050
+#define IPLL_LOCK		0x10060
+#define SPLL_LOCK		0x10070
+#define VPLL_LOCK		0x10070
+#define MPLL_LOCK		0x10090
+#define CPLL_CON0		0x10120
+#define DPLL_CON0		0x10128
+#define EPLL_CON0		0x10130
+#define RPLL_CON0		0x10140
+#define IPLL_CON0		0x10150
+#define SPLL_CON0		0x10160
+#define VPLL_CON0		0x10170
+#define MPLL_CON0		0x10180
 #define SRC_TOP0		0x10200
 #define SRC_TOP1		0x10204
 #define SRC_TOP2		0x10208
@@ -75,15 +92,27 @@
 #define GATE_TOP_SCLK_MAU	0x1083c
 #define GATE_TOP_SCLK_FSYS	0x10840
 #define GATE_TOP_SCLK_PERIC	0x10850
+#define BPLL_LOCK		0x20010
+#define BPLL_CON0		0x20110
 #define SRC_CDREX		0x20200
+#define KPLL_LOCK		0x28000
+#define KPLL_CON0		0x28100
 #define SRC_KFC			0x28200
 #define DIV_KFC0		0x28500
 
+/* list of PLLs */
+enum exynos5420_plls {
+	apll, cpll, dpll, epll, rpll, ipll, spll, vpll, mpll,
+	bpll, kpll,
+	nr_plls			/* number of PLLs */
+};
+
 enum exynos5420_clks {
 	none,
 
 	/* core clocks */
-	fin_pll,
+	fin_pll,  fout_apll, fout_cpll, fout_dpll, fout_epll, fout_rpll,
+	fout_ipll, fout_spll, fout_vpll, fout_mpll, fout_bpll, fout_kpll,
 
 	/* gate for special clocks (sclk) */
 	sclk_uart0 = 128, sclk_uart1, sclk_uart2, sclk_uart3, sclk_mmc0,
@@ -698,6 +727,31 @@ struct samsung_gate_clock exynos5420_gate_clks[] __initdata = {
 	GATE(smmu_mscl2, "smmu_mscl2", "aclk400_mscl", GATE_IP_MSCL, 10, 0, 0),
 };
 
+struct __initdata samsung_pll_clock exynos5420_plls[nr_plls] = {
+	[apll] = PLL(pll_2550, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
+		APLL_CON0),
+	[cpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
+		MPLL_CON0),
+	[dpll] = PLL(pll_2550, fout_dpll, "fout_dpll", "fin_pll", DPLL_LOCK,
+		DPLL_CON0),
+	[epll] = PLL(pll_2650, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
+		EPLL_CON0),
+	[rpll] = PLL(pll_2650, fout_rpll, "fout_rpll", "fin_pll", RPLL_LOCK,
+		RPLL_CON0),
+	[ipll] = PLL(pll_2550, fout_ipll, "fout_ipll", "fin_pll", IPLL_LOCK,
+		IPLL_CON0),
+	[spll] = PLL(pll_2550, fout_spll, "fout_spll", "fin_pll", SPLL_LOCK,
+		SPLL_CON0),
+	[vpll] = PLL(pll_2550, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
+		VPLL_CON0),
+	[mpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
+		MPLL_CON0),
+	[bpll] = PLL(pll_2550, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
+		BPLL_CON0),
+	[kpll] = PLL(pll_2550, fout_kpll, "fout_kpll", "fin_pll", KPLL_LOCK,
+		KPLL_CON0),
+};
+
 static __initdata struct of_device_id ext_clk_match[] = {
 	{ .compatible = "samsung,exynos5420-oscclk", .data = (void *)0, },
 	{ },
@@ -707,8 +761,6 @@ static __initdata struct of_device_id ext_clk_match[] = {
 void __init exynos5420_clk_init(struct device_node *np)
 {
 	void __iomem *reg_base;
-	struct clk *apll, *bpll, *cpll, *dpll, *epll, *ipll, *kpll, *mpll;
-	struct clk *rpll, *spll, *vpll;
 
 	if (np) {
 		reg_base = of_iomap(np, 0);
@@ -724,30 +776,8 @@ void __init exynos5420_clk_init(struct device_node *np)
 	samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
 			ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
 			ext_clk_match);
-
-	apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
-			reg_base + 0x100);
-	bpll = samsung_clk_register_pll35xx("fout_bpll", "fin_pll",
-			reg_base + 0x20110);
-	cpll = samsung_clk_register_pll35xx("fout_cpll", "fin_pll",
-			reg_base + 0x10120);
-	dpll = samsung_clk_register_pll35xx("fout_dpll", "fin_pll",
-			reg_base + 0x10128);
-	epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
-			reg_base + 0x10130);
-	ipll = samsung_clk_register_pll35xx("fout_ipll", "fin_pll",
-			reg_base + 0x10150);
-	kpll = samsung_clk_register_pll35xx("fout_kpll", "fin_pll",
-			reg_base + 0x28100);
-	mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
-			reg_base + 0x10180);
-	rpll = samsung_clk_register_pll36xx("fout_rpll", "fin_pll",
-			reg_base + 0x10140);
-	spll = samsung_clk_register_pll35xx("fout_spll", "fin_pll",
-			reg_base + 0x10160);
-	vpll = samsung_clk_register_pll35xx("fout_vpll", "fin_pll",
-			reg_base + 0x10170);
-
+	samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
+					reg_base);
 	samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
 			ARRAY_SIZE(exynos5420_fixed_rate_clks));
 	samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 8224bde..f132353 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -17,6 +17,7 @@ struct samsung_clk_pll {
 	struct clk_hw		hw;
 	void __iomem		*lock_reg;
 	void __iomem		*con_reg;
+	enum samsung_pll_type	type;
 };
 
 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
@@ -54,41 +55,6 @@ static const struct clk_ops samsung_pll35xx_clk_ops = {
 	.recalc_rate = samsung_pll35xx_recalc_rate,
 };
 
-struct clk * __init samsung_clk_register_pll35xx(const char *name,
-			const char *pname, const void __iomem *con_reg)
-{
-	struct samsung_clk_pll *pll;
-	struct clk *clk;
-	struct clk_init_data init;
-
-	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
-	if (!pll) {
-		pr_err("%s: could not allocate pll clk %s\n", __func__, name);
-		return NULL;
-	}
-
-	init.name = name;
-	init.ops = &samsung_pll35xx_clk_ops;
-	init.flags = CLK_GET_RATE_NOCACHE;
-	init.parent_names = &pname;
-	init.num_parents = 1;
-
-	pll->hw.init = &init;
-	pll->con_reg = con_reg;
-
-	clk = clk_register(NULL, &pll->hw);
-	if (IS_ERR(clk)) {
-		pr_err("%s: failed to register pll clock %s\n", __func__,
-				name);
-		kfree(pll);
-	}
-
-	if (clk_register_clkdev(clk, name, NULL))
-		pr_err("%s: failed to register lookup for %s", __func__, name);
-
-	return clk;
-}
-
 /*
  * PLL36xx Clock Type
  */
@@ -126,41 +92,6 @@ static const struct clk_ops samsung_pll36xx_clk_ops = {
 	.recalc_rate = samsung_pll36xx_recalc_rate,
 };
 
-struct clk * __init samsung_clk_register_pll36xx(const char *name,
-			const char *pname, const void __iomem *con_reg)
-{
-	struct samsung_clk_pll *pll;
-	struct clk *clk;
-	struct clk_init_data init;
-
-	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
-	if (!pll) {
-		pr_err("%s: could not allocate pll clk %s\n", __func__, name);
-		return NULL;
-	}
-
-	init.name = name;
-	init.ops = &samsung_pll36xx_clk_ops;
-	init.flags = CLK_GET_RATE_NOCACHE;
-	init.parent_names = &pname;
-	init.num_parents = 1;
-
-	pll->hw.init = &init;
-	pll->con_reg = con_reg;
-
-	clk = clk_register(NULL, &pll->hw);
-	if (IS_ERR(clk)) {
-		pr_err("%s: failed to register pll clock %s\n", __func__,
-				name);
-		kfree(pll);
-	}
-
-	if (clk_register_clkdev(clk, name, NULL))
-		pr_err("%s: failed to register lookup for %s", __func__, name);
-
-	return clk;
-}
-
 /*
  * PLL45xx Clock Type
  */
@@ -411,3 +342,64 @@ struct clk * __init samsung_clk_register_pll2550x(const char *name,
 
 	return clk;
 }
+
+void __init samsung_clk_register_pll(struct samsung_pll_clock *clk_list,
+				unsigned int nr_pll, void __iomem *base)
+{
+	struct samsung_clk_pll *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+	struct samsung_pll_clock *list = clk_list;
+	int cnt;
+
+	for (cnt = 0; cnt < nr_pll; cnt++, list++) {
+		pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+		if (!pll) {
+			pr_err("%s: could not allocate pll clk %s\n",
+				__func__, list->name);
+			continue;
+		}
+
+		init.name = list->name;
+		init.flags = list->flags;
+		init.parent_names = &list->parent_name;
+		init.num_parents = 1;
+
+		switch (list->type) {
+		/* clk_ops for 35xx and 2550 are similar */
+		case pll_35xx:
+		case pll_2550:
+			init.ops = &samsung_pll35xx_clk_ops;
+			break;
+		/* clk_ops for 36xx and 2650 are similar */
+		case pll_36xx:
+		case pll_2650:
+			init.ops = &samsung_pll36xx_clk_ops;
+			break;
+		default:
+			pr_warn("%s: Unknown pll type for pll clk %s\n",
+				__func__, list->name);
+		}
+
+		pll->hw.init = &init;
+		pll->type = list->type;
+		pll->lock_reg = base + list->lock_offset;
+		pll->con_reg = base + list->con_offset;
+
+		clk = clk_register(NULL, &pll->hw);
+		if (IS_ERR(clk)) {
+			pr_err("%s: failed to register pll clock %s\n",
+				__func__, list->name);
+			kfree(pll);
+			continue;
+		}
+
+		samsung_clk_add_lookup(clk, list->id);
+
+		if (list->alias)
+			if (clk_register_clkdev(clk, list->alias,
+				list->dev_name))
+				pr_err("%s: failed to register lookup for %s",
+					__func__, list->name);
+	}
+}
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index f33786e..1536f27 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -12,6 +12,13 @@
 #ifndef __SAMSUNG_CLK_PLL_H
 #define __SAMSUNG_CLK_PLL_H
 
+enum samsung_pll_type {
+	pll_35xx,
+	pll_36xx,
+	pll_2550,
+	pll_2650,
+};
+
 enum pll45xx_type {
 	pll_4500,
 	pll_4502,
@@ -24,10 +31,6 @@ enum pll46xx_type {
 	pll_4650c,
 };
 
-extern struct clk * __init samsung_clk_register_pll35xx(const char *name,
-			const char *pname, const void __iomem *con_reg);
-extern struct clk * __init samsung_clk_register_pll36xx(const char *name,
-			const char *pname, const void __iomem *con_reg);
 extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
 			const char *pname, const void __iomem *con_reg,
 			enum pll45xx_type type);
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index e4ad6ea..51f60ca 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -19,6 +19,7 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include "clk-pll.h"
 
 /**
  * struct samsung_clock_alias: information about mux clock
@@ -258,6 +259,51 @@ struct samsung_clk_reg_dump {
 	u32	value;
 };
 
+/**
+ * struct samsung_pll_clock: information about pll clock
+ * @id: platform specific id of the clock.
+ * @dev_name: name of the device to which this clock belongs.
+ * @name: name of this pll clock.
+ * @parent_name: name of the parent clock.
+ * @flags: optional flags for basic clock.
+ * @con_offset: offset of the register for configuring the PLL.
+ * @lock_offset: offset of the register for locking the PLL.
+ * @type: Type of PLL to be registered.
+ * @alias: optional clock alias name to be assigned to this clock.
+ */
+struct samsung_pll_clock {
+	unsigned int		id;
+	const char		*dev_name;
+	const char		*name;
+	const char		*parent_name;
+	unsigned long		flags;
+	const int		con_offset;
+	const int		lock_offset;
+	enum			samsung_pll_type type;
+	const char              *alias;
+};
+
+#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con, _alias) \
+	{								\
+		.id		= _id,					\
+		.type		= _typ,					\
+		.dev_name	= _dname,				\
+		.name		= _name,				\
+		.parent_name	= _pname,				\
+		.flags		= CLK_GET_RATE_NOCACHE,			\
+		.con_offset	= _con,					\
+		.lock_offset	= _lock,				\
+		.alias		= _alias,				\
+	}
+
+#define PLL(_typ, _id, _name, _pname, _lock, _con)			\
+	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
+		_lock, _con, NULL)
+
+#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias)		\
+	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
+		_lock, _con, _alias)
+
 extern void __init samsung_clk_init(struct device_node *np, void __iomem *base,
 		unsigned long nr_clks, unsigned long *rdump,
 		unsigned long nr_rdump, unsigned long *soc_rdump,
@@ -281,6 +327,8 @@ extern void __init samsung_clk_register_div(struct samsung_div_clock *clk_list,
 		unsigned int nr_clk);
 extern void __init samsung_clk_register_gate(
 		struct samsung_gate_clock *clk_list, unsigned int nr_clk);
+extern void __init samsung_clk_register_pll(struct samsung_pll_clock *list,
+		unsigned int nr_clk, void __iomem *base);
 
 extern unsigned long _get_rate(const char *clk_name);
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 2/7] clk: samsung: Define a common samsung_clk_register_pll()
@ 2013-06-10 13:24   ` Yadwinder Singh Brar
  0 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-10 13:24 UTC (permalink / raw)
  To: linux-arm-kernel

This patch defines a common samsung_clk_register_pll() and its migrating the
PLL35xx & PLL36xx to use it. Other samsung PLL can also be migrated to it.
It also adds exynos5250 & exynos5420 PLLs to unique id list of clocks.
Since pll2550 & pll35xx and pll2650 & pll36xx have exactly same clk ops
implementation, added pll2550 and pll2650 also.

Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
---
 drivers/clk/samsung/clk-exynos4.c    |   40 +++++++----
 drivers/clk/samsung/clk-exynos5250.c |   60 +++++++++++-----
 drivers/clk/samsung/clk-exynos5420.c |   86 +++++++++++++++-------
 drivers/clk/samsung/clk-pll.c        |  132 ++++++++++++++++------------------
 drivers/clk/samsung/clk-pll.h        |   11 ++-
 drivers/clk/samsung/clk.h            |   48 ++++++++++++
 6 files changed, 242 insertions(+), 135 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index addc738..ba25a1b 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -17,7 +17,6 @@
 #include <linux/of_address.h>
 
 #include "clk.h"
-#include "clk-pll.h"
 
 /* Exynos4 clock controller register offsets */
 #define SRC_LEFTBUS		0x4200
@@ -97,12 +96,14 @@
 #define GATE_IP_PERIL		0xc950
 #define E4210_GATE_IP_PERIR	0xc960
 #define GATE_BLOCK		0xc970
+#define E4X12_MPLL_LOCK		0x10008
 #define E4X12_MPLL_CON0		0x10108
 #define SRC_DMC			0x10200
 #define SRC_MASK_DMC		0x10300
 #define DIV_DMC0		0x10500
 #define DIV_DMC1		0x10504
 #define GATE_IP_DMC		0x10900
+#define APLL_LOCK		0x14000
 #define APLL_CON0		0x14100
 #define E4210_MPLL_CON0		0x14108
 #define SRC_CPU			0x14200
@@ -121,6 +122,12 @@ enum exynos4_soc {
 	EXYNOS4X12,
 };
 
+/* list of PLLs to be registered */
+enum exynos4_plls {
+	apll, mpll, epll, vpll,
+	nr_plls			/* number of PLLs */
+};
+
 /*
  * Let each supported clock get a unique id. This id is used to lookup the clock
  * for device tree based platforms. The clocks are categorized into three
@@ -988,6 +995,17 @@ static __initdata struct of_device_id ext_clk_match[] = {
 	{},
 };
 
+struct __initdata samsung_pll_clock exynos4_plls[nr_plls] = {
+	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
+		APLL_CON0, "fout_apll"),
+	[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll",
+		E4X12_MPLL_LOCK, E4X12_MPLL_CON0, "fout_mpll"),
+	[epll] = PLL_A(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
+		EPLL_CON0, "fout_epll"),
+	[vpll] = PLL_A(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
+		VPLL_CON0, "fout_vpll"),
+};
+
 /* register exynos4 clocks */
 void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_soc, void __iomem *reg_base, unsigned long xom)
 {
@@ -1024,22 +1042,16 @@ void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc exynos4_so
 					reg_base + EPLL_CON0, pll_4600);
 		vpll = samsung_clk_register_pll46xx("fout_vpll", "mout_vpllsrc",
 					reg_base + VPLL_CON0, pll_4650c);
+
+		samsung_clk_add_lookup(apll, fout_apll);
+		samsung_clk_add_lookup(mpll, fout_mpll);
+		samsung_clk_add_lookup(epll, fout_epll);
+		samsung_clk_add_lookup(vpll, fout_vpll);
 	} else {
-		apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
-					reg_base + APLL_CON0);
-		mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
-					reg_base + E4X12_MPLL_CON0);
-		epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
-					reg_base + EPLL_CON0);
-		vpll = samsung_clk_register_pll36xx("fout_vpll", "fin_pll",
-					reg_base + VPLL_CON0);
+		samsung_clk_register_pll(exynos4_plls,
+					ARRAY_SIZE(exynos4_plls), reg_base);
 	}
 
-	samsung_clk_add_lookup(apll, fout_apll);
-	samsung_clk_add_lookup(mpll, fout_mpll);
-	samsung_clk_add_lookup(epll, fout_epll);
-	samsung_clk_add_lookup(vpll, fout_vpll);
-
 	samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks,
 			ARRAY_SIZE(exynos4_fixed_rate_clks));
 	samsung_clk_register_mux(exynos4_mux_clks,
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 7c68850..dc6a700 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -17,11 +17,22 @@
 #include <linux/of_address.h>
 
 #include "clk.h"
-#include "clk-pll.h"
 
+#define APLL_LOCK		0x0
+#define APLL_CON0		0x100
 #define SRC_CPU			0x200
 #define DIV_CPU0		0x500
+#define MPLL_LOCK		0x4000
+#define MPLL_CON0		0x4100
 #define SRC_CORE1		0x4204
+#define CPLL_LOCK		0x10020
+#define EPLL_LOCK		0x10030
+#define VPLL_LOCK		0x10040
+#define GPLL_LOCK		0x10050
+#define CPLL_CON0		0x10120
+#define EPLL_CON0		0x10130
+#define VPLL_CON0		0x10140
+#define GPLL_CON0		0x10150
 #define SRC_TOP0		0x10210
 #define SRC_TOP2		0x10218
 #define SRC_GSCL		0x10220
@@ -59,10 +70,18 @@
 #define GATE_IP_FSYS		0x10944
 #define GATE_IP_PERIC		0x10950
 #define GATE_IP_PERIS		0x10960
+#define BPLL_LOCK		0x20010
+#define BPLL_CON0		0x20110
 #define SRC_CDREX		0x20200
 #define PLL_DIV2_SEL		0x20a24
 #define GATE_IP_DISP1		0x10928
 
+/* list of PLLs to be registered */
+enum exynos5250_plls {
+	apll, mpll, bpll, gpll, cpll, epll, vpll,
+	nr_plls			/* number of PLLs */
+};
+
 /*
  * Let each supported clock get a unique id. This id is used to lookup the clock
  * for device tree based platforms. The clocks are categorized into three
@@ -79,7 +98,8 @@ enum exynos5250_clks {
 	none,
 
 	/* core clocks */
-	fin_pll,
+	fin_pll, fout_apll, fout_mpll, fout_bpll, fout_gpll, fout_cpll,
+	fout_epll, fout_vpll,
 
 	/* gate for special clocks (sclk) */
 	sclk_cam_bayer = 128, sclk_cam0, sclk_cam1, sclk_gscl_wa, sclk_gscl_wb,
@@ -470,11 +490,27 @@ static __initdata struct of_device_id ext_clk_match[] = {
 	{ },
 };
 
+struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = {
+	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
+		APLL_CON0, "fout_apll"),
+	[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
+		MPLL_CON0, "fout_mpll"),
+	[bpll] = PLL(pll_35xx, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
+		BPLL_CON0),
+	[gpll] = PLL(pll_35xx, fout_gpll, "fout_gpll", "fin_pll", GPLL_LOCK,
+		GPLL_CON0),
+	[cpll] = PLL(pll_35xx, fout_cpll, "fout_cpll", "fin_pll", CPLL_LOCK,
+		CPLL_CON0),
+	[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
+		EPLL_CON0),
+	[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
+		VPLL_CON0),
+};
+
 /* register exynox5250 clocks */
 void __init exynos5250_clk_init(struct device_node *np)
 {
 	void __iomem *reg_base;
-	struct clk *apll, *mpll, *epll, *vpll, *bpll, *gpll, *cpll;
 
 	if (np) {
 		reg_base = of_iomap(np, 0);
@@ -490,22 +526,8 @@ void __init exynos5250_clk_init(struct device_node *np)
 	samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks,
 			ARRAY_SIZE(exynos5250_fixed_rate_ext_clks),
 			ext_clk_match);
-
-	apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
-			reg_base + 0x100);
-	mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
-			reg_base + 0x4100);
-	bpll = samsung_clk_register_pll35xx("fout_bpll", "fin_pll",
-			reg_base + 0x20110);
-	gpll = samsung_clk_register_pll35xx("fout_gpll", "fin_pll",
-			reg_base + 0x10150);
-	cpll = samsung_clk_register_pll35xx("fout_cpll", "fin_pll",
-			reg_base + 0x10120);
-	epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
-			reg_base + 0x10130);
-	vpll = samsung_clk_register_pll36xx("fout_vpll", "mout_vpllsrc",
-			reg_base + 0x10140);
-
+	samsung_clk_register_pll(exynos5250_plls, ARRAY_SIZE(exynos5250_plls),
+					reg_base);
 	samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,
 			ARRAY_SIZE(exynos5250_fixed_rate_clks));
 	samsung_clk_register_fixed_factor(exynos5250_fixed_factor_clks,
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 68a96cb..3ea6b4f 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -17,13 +17,30 @@
 #include <linux/of_address.h>
 
 #include "clk.h"
-#include "clk-pll.h"
 
+#define APLL_LOCK		0x0
+#define APLL_CON0		0x100
 #define SRC_CPU			0x200
 #define DIV_CPU0		0x500
 #define DIV_CPU1		0x504
 #define GATE_BUS_CPU		0x700
 #define GATE_SCLK_CPU		0x800
+#define CPLL_LOCK		0x10020
+#define DPLL_LOCK		0x10030
+#define EPLL_LOCK		0x10040
+#define RPLL_LOCK		0x10050
+#define IPLL_LOCK		0x10060
+#define SPLL_LOCK		0x10070
+#define VPLL_LOCK		0x10070
+#define MPLL_LOCK		0x10090
+#define CPLL_CON0		0x10120
+#define DPLL_CON0		0x10128
+#define EPLL_CON0		0x10130
+#define RPLL_CON0		0x10140
+#define IPLL_CON0		0x10150
+#define SPLL_CON0		0x10160
+#define VPLL_CON0		0x10170
+#define MPLL_CON0		0x10180
 #define SRC_TOP0		0x10200
 #define SRC_TOP1		0x10204
 #define SRC_TOP2		0x10208
@@ -75,15 +92,27 @@
 #define GATE_TOP_SCLK_MAU	0x1083c
 #define GATE_TOP_SCLK_FSYS	0x10840
 #define GATE_TOP_SCLK_PERIC	0x10850
+#define BPLL_LOCK		0x20010
+#define BPLL_CON0		0x20110
 #define SRC_CDREX		0x20200
+#define KPLL_LOCK		0x28000
+#define KPLL_CON0		0x28100
 #define SRC_KFC			0x28200
 #define DIV_KFC0		0x28500
 
+/* list of PLLs */
+enum exynos5420_plls {
+	apll, cpll, dpll, epll, rpll, ipll, spll, vpll, mpll,
+	bpll, kpll,
+	nr_plls			/* number of PLLs */
+};
+
 enum exynos5420_clks {
 	none,
 
 	/* core clocks */
-	fin_pll,
+	fin_pll,  fout_apll, fout_cpll, fout_dpll, fout_epll, fout_rpll,
+	fout_ipll, fout_spll, fout_vpll, fout_mpll, fout_bpll, fout_kpll,
 
 	/* gate for special clocks (sclk) */
 	sclk_uart0 = 128, sclk_uart1, sclk_uart2, sclk_uart3, sclk_mmc0,
@@ -698,6 +727,31 @@ struct samsung_gate_clock exynos5420_gate_clks[] __initdata = {
 	GATE(smmu_mscl2, "smmu_mscl2", "aclk400_mscl", GATE_IP_MSCL, 10, 0, 0),
 };
 
+struct __initdata samsung_pll_clock exynos5420_plls[nr_plls] = {
+	[apll] = PLL(pll_2550, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
+		APLL_CON0),
+	[cpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
+		MPLL_CON0),
+	[dpll] = PLL(pll_2550, fout_dpll, "fout_dpll", "fin_pll", DPLL_LOCK,
+		DPLL_CON0),
+	[epll] = PLL(pll_2650, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
+		EPLL_CON0),
+	[rpll] = PLL(pll_2650, fout_rpll, "fout_rpll", "fin_pll", RPLL_LOCK,
+		RPLL_CON0),
+	[ipll] = PLL(pll_2550, fout_ipll, "fout_ipll", "fin_pll", IPLL_LOCK,
+		IPLL_CON0),
+	[spll] = PLL(pll_2550, fout_spll, "fout_spll", "fin_pll", SPLL_LOCK,
+		SPLL_CON0),
+	[vpll] = PLL(pll_2550, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
+		VPLL_CON0),
+	[mpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
+		MPLL_CON0),
+	[bpll] = PLL(pll_2550, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
+		BPLL_CON0),
+	[kpll] = PLL(pll_2550, fout_kpll, "fout_kpll", "fin_pll", KPLL_LOCK,
+		KPLL_CON0),
+};
+
 static __initdata struct of_device_id ext_clk_match[] = {
 	{ .compatible = "samsung,exynos5420-oscclk", .data = (void *)0, },
 	{ },
@@ -707,8 +761,6 @@ static __initdata struct of_device_id ext_clk_match[] = {
 void __init exynos5420_clk_init(struct device_node *np)
 {
 	void __iomem *reg_base;
-	struct clk *apll, *bpll, *cpll, *dpll, *epll, *ipll, *kpll, *mpll;
-	struct clk *rpll, *spll, *vpll;
 
 	if (np) {
 		reg_base = of_iomap(np, 0);
@@ -724,30 +776,8 @@ void __init exynos5420_clk_init(struct device_node *np)
 	samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
 			ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
 			ext_clk_match);
-
-	apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
-			reg_base + 0x100);
-	bpll = samsung_clk_register_pll35xx("fout_bpll", "fin_pll",
-			reg_base + 0x20110);
-	cpll = samsung_clk_register_pll35xx("fout_cpll", "fin_pll",
-			reg_base + 0x10120);
-	dpll = samsung_clk_register_pll35xx("fout_dpll", "fin_pll",
-			reg_base + 0x10128);
-	epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
-			reg_base + 0x10130);
-	ipll = samsung_clk_register_pll35xx("fout_ipll", "fin_pll",
-			reg_base + 0x10150);
-	kpll = samsung_clk_register_pll35xx("fout_kpll", "fin_pll",
-			reg_base + 0x28100);
-	mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
-			reg_base + 0x10180);
-	rpll = samsung_clk_register_pll36xx("fout_rpll", "fin_pll",
-			reg_base + 0x10140);
-	spll = samsung_clk_register_pll35xx("fout_spll", "fin_pll",
-			reg_base + 0x10160);
-	vpll = samsung_clk_register_pll35xx("fout_vpll", "fin_pll",
-			reg_base + 0x10170);
-
+	samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls),
+					reg_base);
 	samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
 			ARRAY_SIZE(exynos5420_fixed_rate_clks));
 	samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 8224bde..f132353 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -17,6 +17,7 @@ struct samsung_clk_pll {
 	struct clk_hw		hw;
 	void __iomem		*lock_reg;
 	void __iomem		*con_reg;
+	enum samsung_pll_type	type;
 };
 
 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
@@ -54,41 +55,6 @@ static const struct clk_ops samsung_pll35xx_clk_ops = {
 	.recalc_rate = samsung_pll35xx_recalc_rate,
 };
 
-struct clk * __init samsung_clk_register_pll35xx(const char *name,
-			const char *pname, const void __iomem *con_reg)
-{
-	struct samsung_clk_pll *pll;
-	struct clk *clk;
-	struct clk_init_data init;
-
-	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
-	if (!pll) {
-		pr_err("%s: could not allocate pll clk %s\n", __func__, name);
-		return NULL;
-	}
-
-	init.name = name;
-	init.ops = &samsung_pll35xx_clk_ops;
-	init.flags = CLK_GET_RATE_NOCACHE;
-	init.parent_names = &pname;
-	init.num_parents = 1;
-
-	pll->hw.init = &init;
-	pll->con_reg = con_reg;
-
-	clk = clk_register(NULL, &pll->hw);
-	if (IS_ERR(clk)) {
-		pr_err("%s: failed to register pll clock %s\n", __func__,
-				name);
-		kfree(pll);
-	}
-
-	if (clk_register_clkdev(clk, name, NULL))
-		pr_err("%s: failed to register lookup for %s", __func__, name);
-
-	return clk;
-}
-
 /*
  * PLL36xx Clock Type
  */
@@ -126,41 +92,6 @@ static const struct clk_ops samsung_pll36xx_clk_ops = {
 	.recalc_rate = samsung_pll36xx_recalc_rate,
 };
 
-struct clk * __init samsung_clk_register_pll36xx(const char *name,
-			const char *pname, const void __iomem *con_reg)
-{
-	struct samsung_clk_pll *pll;
-	struct clk *clk;
-	struct clk_init_data init;
-
-	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
-	if (!pll) {
-		pr_err("%s: could not allocate pll clk %s\n", __func__, name);
-		return NULL;
-	}
-
-	init.name = name;
-	init.ops = &samsung_pll36xx_clk_ops;
-	init.flags = CLK_GET_RATE_NOCACHE;
-	init.parent_names = &pname;
-	init.num_parents = 1;
-
-	pll->hw.init = &init;
-	pll->con_reg = con_reg;
-
-	clk = clk_register(NULL, &pll->hw);
-	if (IS_ERR(clk)) {
-		pr_err("%s: failed to register pll clock %s\n", __func__,
-				name);
-		kfree(pll);
-	}
-
-	if (clk_register_clkdev(clk, name, NULL))
-		pr_err("%s: failed to register lookup for %s", __func__, name);
-
-	return clk;
-}
-
 /*
  * PLL45xx Clock Type
  */
@@ -411,3 +342,64 @@ struct clk * __init samsung_clk_register_pll2550x(const char *name,
 
 	return clk;
 }
+
+void __init samsung_clk_register_pll(struct samsung_pll_clock *clk_list,
+				unsigned int nr_pll, void __iomem *base)
+{
+	struct samsung_clk_pll *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+	struct samsung_pll_clock *list = clk_list;
+	int cnt;
+
+	for (cnt = 0; cnt < nr_pll; cnt++, list++) {
+		pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+		if (!pll) {
+			pr_err("%s: could not allocate pll clk %s\n",
+				__func__, list->name);
+			continue;
+		}
+
+		init.name = list->name;
+		init.flags = list->flags;
+		init.parent_names = &list->parent_name;
+		init.num_parents = 1;
+
+		switch (list->type) {
+		/* clk_ops for 35xx and 2550 are similar */
+		case pll_35xx:
+		case pll_2550:
+			init.ops = &samsung_pll35xx_clk_ops;
+			break;
+		/* clk_ops for 36xx and 2650 are similar */
+		case pll_36xx:
+		case pll_2650:
+			init.ops = &samsung_pll36xx_clk_ops;
+			break;
+		default:
+			pr_warn("%s: Unknown pll type for pll clk %s\n",
+				__func__, list->name);
+		}
+
+		pll->hw.init = &init;
+		pll->type = list->type;
+		pll->lock_reg = base + list->lock_offset;
+		pll->con_reg = base + list->con_offset;
+
+		clk = clk_register(NULL, &pll->hw);
+		if (IS_ERR(clk)) {
+			pr_err("%s: failed to register pll clock %s\n",
+				__func__, list->name);
+			kfree(pll);
+			continue;
+		}
+
+		samsung_clk_add_lookup(clk, list->id);
+
+		if (list->alias)
+			if (clk_register_clkdev(clk, list->alias,
+				list->dev_name))
+				pr_err("%s: failed to register lookup for %s",
+					__func__, list->name);
+	}
+}
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index f33786e..1536f27 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -12,6 +12,13 @@
 #ifndef __SAMSUNG_CLK_PLL_H
 #define __SAMSUNG_CLK_PLL_H
 
+enum samsung_pll_type {
+	pll_35xx,
+	pll_36xx,
+	pll_2550,
+	pll_2650,
+};
+
 enum pll45xx_type {
 	pll_4500,
 	pll_4502,
@@ -24,10 +31,6 @@ enum pll46xx_type {
 	pll_4650c,
 };
 
-extern struct clk * __init samsung_clk_register_pll35xx(const char *name,
-			const char *pname, const void __iomem *con_reg);
-extern struct clk * __init samsung_clk_register_pll36xx(const char *name,
-			const char *pname, const void __iomem *con_reg);
 extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
 			const char *pname, const void __iomem *con_reg,
 			enum pll45xx_type type);
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index e4ad6ea..51f60ca 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -19,6 +19,7 @@
 #include <linux/clk-provider.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
+#include "clk-pll.h"
 
 /**
  * struct samsung_clock_alias: information about mux clock
@@ -258,6 +259,51 @@ struct samsung_clk_reg_dump {
 	u32	value;
 };
 
+/**
+ * struct samsung_pll_clock: information about pll clock
+ * @id: platform specific id of the clock.
+ * @dev_name: name of the device to which this clock belongs.
+ * @name: name of this pll clock.
+ * @parent_name: name of the parent clock.
+ * @flags: optional flags for basic clock.
+ * @con_offset: offset of the register for configuring the PLL.
+ * @lock_offset: offset of the register for locking the PLL.
+ * @type: Type of PLL to be registered.
+ * @alias: optional clock alias name to be assigned to this clock.
+ */
+struct samsung_pll_clock {
+	unsigned int		id;
+	const char		*dev_name;
+	const char		*name;
+	const char		*parent_name;
+	unsigned long		flags;
+	const int		con_offset;
+	const int		lock_offset;
+	enum			samsung_pll_type type;
+	const char              *alias;
+};
+
+#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con, _alias) \
+	{								\
+		.id		= _id,					\
+		.type		= _typ,					\
+		.dev_name	= _dname,				\
+		.name		= _name,				\
+		.parent_name	= _pname,				\
+		.flags		= CLK_GET_RATE_NOCACHE,			\
+		.con_offset	= _con,					\
+		.lock_offset	= _lock,				\
+		.alias		= _alias,				\
+	}
+
+#define PLL(_typ, _id, _name, _pname, _lock, _con)			\
+	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
+		_lock, _con, NULL)
+
+#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias)		\
+	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
+		_lock, _con, _alias)
+
 extern void __init samsung_clk_init(struct device_node *np, void __iomem *base,
 		unsigned long nr_clks, unsigned long *rdump,
 		unsigned long nr_rdump, unsigned long *soc_rdump,
@@ -281,6 +327,8 @@ extern void __init samsung_clk_register_div(struct samsung_div_clock *clk_list,
 		unsigned int nr_clk);
 extern void __init samsung_clk_register_gate(
 		struct samsung_gate_clock *clk_list, unsigned int nr_clk);
+extern void __init samsung_clk_register_pll(struct samsung_pll_clock *list,
+		unsigned int nr_clk, void __iomem *base);
 
 extern unsigned long _get_rate(const char *clk_name);
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 3/7] clk: samsung: Add support to register rate_table for samsung plls
  2013-06-10 13:24 ` Yadwinder Singh Brar
@ 2013-06-10 13:24   ` Yadwinder Singh Brar
  -1 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-10 13:24 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, kgene.kim, mturquette, thomas.abraham,
	dianders, t.figa, vikas.sajjan, abrestic, Yadwinder Singh Brar

This patch defines a common rate_table which will contain recommended p, m, s,
k values for supported rates that needs to be changed for changing
corresponding PLL's rate.

Reviewed-by: Doug Anderson <dianders@chromium.org>
Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
---
 drivers/clk/samsung/clk-exynos4.c    |    8 ++++----
 drivers/clk/samsung/clk-exynos5250.c |   14 +++++++-------
 drivers/clk/samsung/clk-exynos5420.c |   22 +++++++++++-----------
 drivers/clk/samsung/clk-pll.c        |   22 ++++++++++++++++++++--
 drivers/clk/samsung/clk-pll.h        |   27 +++++++++++++++++++++++++++
 drivers/clk/samsung/clk.h            |   14 +++++++++-----
 6 files changed, 78 insertions(+), 29 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index ba25a1b..ceee66c 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -997,13 +997,13 @@ static __initdata struct of_device_id ext_clk_match[] = {
 
 struct __initdata samsung_pll_clock exynos4_plls[nr_plls] = {
 	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
-		APLL_CON0, "fout_apll"),
+		APLL_CON0, "fout_apll", NULL),
 	[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll",
-		E4X12_MPLL_LOCK, E4X12_MPLL_CON0, "fout_mpll"),
+		E4X12_MPLL_LOCK, E4X12_MPLL_CON0, "fout_mpll", NULL),
 	[epll] = PLL_A(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
-		EPLL_CON0, "fout_epll"),
+		EPLL_CON0, "fout_epll", NULL),
 	[vpll] = PLL_A(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
-		VPLL_CON0, "fout_vpll"),
+		VPLL_CON0, "fout_vpll", NULL),
 };
 
 /* register exynos4 clocks */
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index dc6a700..21f5491 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -492,19 +492,19 @@ static __initdata struct of_device_id ext_clk_match[] = {
 
 struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = {
 	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
-		APLL_CON0, "fout_apll"),
+		APLL_CON0, "fout_apll", NULL),
 	[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
-		MPLL_CON0, "fout_mpll"),
+		MPLL_CON0, "fout_mpll", NULL),
 	[bpll] = PLL(pll_35xx, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
-		BPLL_CON0),
+		BPLL_CON0, NULL),
 	[gpll] = PLL(pll_35xx, fout_gpll, "fout_gpll", "fin_pll", GPLL_LOCK,
-		GPLL_CON0),
+		GPLL_CON0, NULL),
 	[cpll] = PLL(pll_35xx, fout_cpll, "fout_cpll", "fin_pll", CPLL_LOCK,
-		CPLL_CON0),
+		CPLL_CON0, NULL),
 	[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
-		EPLL_CON0),
+		EPLL_CON0, NULL),
 	[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
-		VPLL_CON0),
+		VPLL_CON0, NULL),
 };
 
 /* register exynox5250 clocks */
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 3ea6b4f..86dfc64 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -729,27 +729,27 @@ struct samsung_gate_clock exynos5420_gate_clks[] __initdata = {
 
 struct __initdata samsung_pll_clock exynos5420_plls[nr_plls] = {
 	[apll] = PLL(pll_2550, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
-		APLL_CON0),
+		APLL_CON0, NULL),
 	[cpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
-		MPLL_CON0),
+		MPLL_CON0, NULL),
 	[dpll] = PLL(pll_2550, fout_dpll, "fout_dpll", "fin_pll", DPLL_LOCK,
-		DPLL_CON0),
+		DPLL_CON0, NULL),
 	[epll] = PLL(pll_2650, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
-		EPLL_CON0),
+		EPLL_CON0, NULL),
 	[rpll] = PLL(pll_2650, fout_rpll, "fout_rpll", "fin_pll", RPLL_LOCK,
-		RPLL_CON0),
+		RPLL_CON0, NULL),
 	[ipll] = PLL(pll_2550, fout_ipll, "fout_ipll", "fin_pll", IPLL_LOCK,
-		IPLL_CON0),
+		IPLL_CON0, NULL),
 	[spll] = PLL(pll_2550, fout_spll, "fout_spll", "fin_pll", SPLL_LOCK,
-		SPLL_CON0),
+		SPLL_CON0, NULL),
 	[vpll] = PLL(pll_2550, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
-		VPLL_CON0),
+		VPLL_CON0, NULL),
 	[mpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
-		MPLL_CON0),
+		MPLL_CON0, NULL),
 	[bpll] = PLL(pll_2550, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
-		BPLL_CON0),
+		BPLL_CON0, NULL),
 	[kpll] = PLL(pll_2550, fout_kpll, "fout_kpll", "fin_pll", KPLL_LOCK,
-		KPLL_CON0),
+		KPLL_CON0, NULL),
 };
 
 static __initdata struct of_device_id ext_clk_match[] = {
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index f132353..b2088dd 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -18,6 +18,8 @@ struct samsung_clk_pll {
 	void __iomem		*lock_reg;
 	void __iomem		*con_reg;
 	enum samsung_pll_type	type;
+	unsigned int		rate_count;
+	const struct samsung_pll_rate_table *rate_table;
 };
 
 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
@@ -350,7 +352,7 @@ void __init samsung_clk_register_pll(struct samsung_pll_clock *clk_list,
 	struct clk *clk;
 	struct clk_init_data init;
 	struct samsung_pll_clock *list = clk_list;
-	int cnt;
+	int cnt, len;
 
 	for (cnt = 0; cnt < nr_pll; cnt++, list++) {
 		pll = kzalloc(sizeof(*pll), GFP_KERNEL);
@@ -365,6 +367,21 @@ void __init samsung_clk_register_pll(struct samsung_pll_clock *clk_list,
 		init.parent_names = &list->parent_name;
 		init.num_parents = 1;
 
+		if (list->rate_table) {
+			/* find count of rates in rate_table */
+			for (len = 0; list->rate_table[len].rate != 0; )
+				len++;
+
+			pll->rate_count = len;
+			pll->rate_table = kmemdup(list->rate_table,
+					list->rate_count *
+					sizeof(struct samsung_pll_rate_table),
+					GFP_KERNEL);
+			WARN(!pll->rate_table,
+				"%s: could not allocate rate table for %s\n",
+				__func__, list->name);
+		}
+
 		switch (list->type) {
 		/* clk_ops for 35xx and 2550 are similar */
 		case pll_35xx:
@@ -396,10 +413,11 @@ void __init samsung_clk_register_pll(struct samsung_pll_clock *clk_list,
 
 		samsung_clk_add_lookup(clk, list->id);
 
-		if (list->alias)
+		if (list->alias) {
 			if (clk_register_clkdev(clk, list->alias,
 				list->dev_name))
 				pr_err("%s: failed to register lookup for %s",
 					__func__, list->name);
+		}
 	}
 }
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index 1536f27..95ae23d 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -19,6 +19,33 @@ enum samsung_pll_type {
 	pll_2650,
 };
 
+#define PLL_35XX_RATE(_rate, _m, _p, _s)			\
+	{							\
+		.rate	=	(_rate),				\
+		.mdiv	=	(_m),				\
+		.pdiv	=	(_p),				\
+		.sdiv	=	(_s),				\
+	}
+
+#define PLL_36XX_RATE(_rate, _m, _p, _s, _k)			\
+	{							\
+		.rate	=	(_rate),				\
+		.mdiv	=	(_m),				\
+		.pdiv	=	(_p),				\
+		.sdiv	=	(_s),				\
+		.kdiv	=	(_k),				\
+	}
+
+/* NOTE: Rate table should be kept sorted in descending order. */
+
+struct samsung_pll_rate_table {
+	unsigned int rate;
+	unsigned int pdiv;
+	unsigned int mdiv;
+	unsigned int sdiv;
+	unsigned int kdiv;
+};
+
 enum pll45xx_type {
 	pll_4500,
 	pll_4502,
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 51f60ca..3e6501c 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -280,10 +280,13 @@ struct samsung_pll_clock {
 	const int		con_offset;
 	const int		lock_offset;
 	enum			samsung_pll_type type;
+	const struct samsung_pll_rate_table *rate_table;
+	unsigned int		rate_count;
 	const char              *alias;
 };
 
-#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con, _alias) \
+#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con,	\
+		_rtable, _alias)					\
 	{								\
 		.id		= _id,					\
 		.type		= _typ,					\
@@ -293,16 +296,17 @@ struct samsung_pll_clock {
 		.flags		= CLK_GET_RATE_NOCACHE,			\
 		.con_offset	= _con,					\
 		.lock_offset	= _lock,				\
+		.rate_table	= _rtable,				\
 		.alias		= _alias,				\
 	}
 
-#define PLL(_typ, _id, _name, _pname, _lock, _con)			\
+#define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable)	\
 	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
-		_lock, _con, NULL)
+		_lock, _con, _rtable, _name)
 
-#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias)		\
+#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias, _rtable) \
 	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
-		_lock, _con, _alias)
+		_lock, _con, _rtable, _alias)
 
 extern void __init samsung_clk_init(struct device_node *np, void __iomem *base,
 		unsigned long nr_clks, unsigned long *rdump,
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 3/7] clk: samsung: Add support to register rate_table for samsung plls
@ 2013-06-10 13:24   ` Yadwinder Singh Brar
  0 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-10 13:24 UTC (permalink / raw)
  To: linux-arm-kernel

This patch defines a common rate_table which will contain recommended p, m, s,
k values for supported rates that needs to be changed for changing
corresponding PLL's rate.

Reviewed-by: Doug Anderson <dianders@chromium.org>
Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
---
 drivers/clk/samsung/clk-exynos4.c    |    8 ++++----
 drivers/clk/samsung/clk-exynos5250.c |   14 +++++++-------
 drivers/clk/samsung/clk-exynos5420.c |   22 +++++++++++-----------
 drivers/clk/samsung/clk-pll.c        |   22 ++++++++++++++++++++--
 drivers/clk/samsung/clk-pll.h        |   27 +++++++++++++++++++++++++++
 drivers/clk/samsung/clk.h            |   14 +++++++++-----
 6 files changed, 78 insertions(+), 29 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c
index ba25a1b..ceee66c 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -997,13 +997,13 @@ static __initdata struct of_device_id ext_clk_match[] = {
 
 struct __initdata samsung_pll_clock exynos4_plls[nr_plls] = {
 	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
-		APLL_CON0, "fout_apll"),
+		APLL_CON0, "fout_apll", NULL),
 	[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll",
-		E4X12_MPLL_LOCK, E4X12_MPLL_CON0, "fout_mpll"),
+		E4X12_MPLL_LOCK, E4X12_MPLL_CON0, "fout_mpll", NULL),
 	[epll] = PLL_A(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
-		EPLL_CON0, "fout_epll"),
+		EPLL_CON0, "fout_epll", NULL),
 	[vpll] = PLL_A(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
-		VPLL_CON0, "fout_vpll"),
+		VPLL_CON0, "fout_vpll", NULL),
 };
 
 /* register exynos4 clocks */
diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index dc6a700..21f5491 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -492,19 +492,19 @@ static __initdata struct of_device_id ext_clk_match[] = {
 
 struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = {
 	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
-		APLL_CON0, "fout_apll"),
+		APLL_CON0, "fout_apll", NULL),
 	[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
-		MPLL_CON0, "fout_mpll"),
+		MPLL_CON0, "fout_mpll", NULL),
 	[bpll] = PLL(pll_35xx, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
-		BPLL_CON0),
+		BPLL_CON0, NULL),
 	[gpll] = PLL(pll_35xx, fout_gpll, "fout_gpll", "fin_pll", GPLL_LOCK,
-		GPLL_CON0),
+		GPLL_CON0, NULL),
 	[cpll] = PLL(pll_35xx, fout_cpll, "fout_cpll", "fin_pll", CPLL_LOCK,
-		CPLL_CON0),
+		CPLL_CON0, NULL),
 	[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
-		EPLL_CON0),
+		EPLL_CON0, NULL),
 	[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
-		VPLL_CON0),
+		VPLL_CON0, NULL),
 };
 
 /* register exynox5250 clocks */
diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c
index 3ea6b4f..86dfc64 100644
--- a/drivers/clk/samsung/clk-exynos5420.c
+++ b/drivers/clk/samsung/clk-exynos5420.c
@@ -729,27 +729,27 @@ struct samsung_gate_clock exynos5420_gate_clks[] __initdata = {
 
 struct __initdata samsung_pll_clock exynos5420_plls[nr_plls] = {
 	[apll] = PLL(pll_2550, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
-		APLL_CON0),
+		APLL_CON0, NULL),
 	[cpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
-		MPLL_CON0),
+		MPLL_CON0, NULL),
 	[dpll] = PLL(pll_2550, fout_dpll, "fout_dpll", "fin_pll", DPLL_LOCK,
-		DPLL_CON0),
+		DPLL_CON0, NULL),
 	[epll] = PLL(pll_2650, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
-		EPLL_CON0),
+		EPLL_CON0, NULL),
 	[rpll] = PLL(pll_2650, fout_rpll, "fout_rpll", "fin_pll", RPLL_LOCK,
-		RPLL_CON0),
+		RPLL_CON0, NULL),
 	[ipll] = PLL(pll_2550, fout_ipll, "fout_ipll", "fin_pll", IPLL_LOCK,
-		IPLL_CON0),
+		IPLL_CON0, NULL),
 	[spll] = PLL(pll_2550, fout_spll, "fout_spll", "fin_pll", SPLL_LOCK,
-		SPLL_CON0),
+		SPLL_CON0, NULL),
 	[vpll] = PLL(pll_2550, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
-		VPLL_CON0),
+		VPLL_CON0, NULL),
 	[mpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", MPLL_LOCK,
-		MPLL_CON0),
+		MPLL_CON0, NULL),
 	[bpll] = PLL(pll_2550, fout_bpll, "fout_bpll", "fin_pll", BPLL_LOCK,
-		BPLL_CON0),
+		BPLL_CON0, NULL),
 	[kpll] = PLL(pll_2550, fout_kpll, "fout_kpll", "fin_pll", KPLL_LOCK,
-		KPLL_CON0),
+		KPLL_CON0, NULL),
 };
 
 static __initdata struct of_device_id ext_clk_match[] = {
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index f132353..b2088dd 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -18,6 +18,8 @@ struct samsung_clk_pll {
 	void __iomem		*lock_reg;
 	void __iomem		*con_reg;
 	enum samsung_pll_type	type;
+	unsigned int		rate_count;
+	const struct samsung_pll_rate_table *rate_table;
 };
 
 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
@@ -350,7 +352,7 @@ void __init samsung_clk_register_pll(struct samsung_pll_clock *clk_list,
 	struct clk *clk;
 	struct clk_init_data init;
 	struct samsung_pll_clock *list = clk_list;
-	int cnt;
+	int cnt, len;
 
 	for (cnt = 0; cnt < nr_pll; cnt++, list++) {
 		pll = kzalloc(sizeof(*pll), GFP_KERNEL);
@@ -365,6 +367,21 @@ void __init samsung_clk_register_pll(struct samsung_pll_clock *clk_list,
 		init.parent_names = &list->parent_name;
 		init.num_parents = 1;
 
+		if (list->rate_table) {
+			/* find count of rates in rate_table */
+			for (len = 0; list->rate_table[len].rate != 0; )
+				len++;
+
+			pll->rate_count = len;
+			pll->rate_table = kmemdup(list->rate_table,
+					list->rate_count *
+					sizeof(struct samsung_pll_rate_table),
+					GFP_KERNEL);
+			WARN(!pll->rate_table,
+				"%s: could not allocate rate table for %s\n",
+				__func__, list->name);
+		}
+
 		switch (list->type) {
 		/* clk_ops for 35xx and 2550 are similar */
 		case pll_35xx:
@@ -396,10 +413,11 @@ void __init samsung_clk_register_pll(struct samsung_pll_clock *clk_list,
 
 		samsung_clk_add_lookup(clk, list->id);
 
-		if (list->alias)
+		if (list->alias) {
 			if (clk_register_clkdev(clk, list->alias,
 				list->dev_name))
 				pr_err("%s: failed to register lookup for %s",
 					__func__, list->name);
+		}
 	}
 }
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index 1536f27..95ae23d 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -19,6 +19,33 @@ enum samsung_pll_type {
 	pll_2650,
 };
 
+#define PLL_35XX_RATE(_rate, _m, _p, _s)			\
+	{							\
+		.rate	=	(_rate),				\
+		.mdiv	=	(_m),				\
+		.pdiv	=	(_p),				\
+		.sdiv	=	(_s),				\
+	}
+
+#define PLL_36XX_RATE(_rate, _m, _p, _s, _k)			\
+	{							\
+		.rate	=	(_rate),				\
+		.mdiv	=	(_m),				\
+		.pdiv	=	(_p),				\
+		.sdiv	=	(_s),				\
+		.kdiv	=	(_k),				\
+	}
+
+/* NOTE: Rate table should be kept sorted in descending order. */
+
+struct samsung_pll_rate_table {
+	unsigned int rate;
+	unsigned int pdiv;
+	unsigned int mdiv;
+	unsigned int sdiv;
+	unsigned int kdiv;
+};
+
 enum pll45xx_type {
 	pll_4500,
 	pll_4502,
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 51f60ca..3e6501c 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -280,10 +280,13 @@ struct samsung_pll_clock {
 	const int		con_offset;
 	const int		lock_offset;
 	enum			samsung_pll_type type;
+	const struct samsung_pll_rate_table *rate_table;
+	unsigned int		rate_count;
 	const char              *alias;
 };
 
-#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con, _alias) \
+#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con,	\
+		_rtable, _alias)					\
 	{								\
 		.id		= _id,					\
 		.type		= _typ,					\
@@ -293,16 +296,17 @@ struct samsung_pll_clock {
 		.flags		= CLK_GET_RATE_NOCACHE,			\
 		.con_offset	= _con,					\
 		.lock_offset	= _lock,				\
+		.rate_table	= _rtable,				\
 		.alias		= _alias,				\
 	}
 
-#define PLL(_typ, _id, _name, _pname, _lock, _con)			\
+#define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable)	\
 	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
-		_lock, _con, NULL)
+		_lock, _con, _rtable, _name)
 
-#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias)		\
+#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias, _rtable) \
 	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
-		_lock, _con, _alias)
+		_lock, _con, _rtable, _alias)
 
 extern void __init samsung_clk_init(struct device_node *np, void __iomem *base,
 		unsigned long nr_clks, unsigned long *rdump,
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 4/7] clk: samsung: Add set_rate() clk_ops for PLL35xx
  2013-06-10 13:24 ` Yadwinder Singh Brar
@ 2013-06-10 13:24   ` Yadwinder Singh Brar
  -1 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-10 13:24 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, kgene.kim, mturquette, thomas.abraham,
	dianders, t.figa, vikas.sajjan, abrestic, Yadwinder Singh Brar

This patch add set_rate() and round_rate() for PLL35xx

Reviewed-by: Doug Anderson <dianders@chromium.org>
Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
---
 drivers/clk/samsung/clk-pll.c |  105 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 104 insertions(+), 1 deletions(-)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index b2088dd..e3e7f0c 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -24,16 +24,51 @@ struct samsung_clk_pll {
 
 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
 
+static const struct samsung_pll_rate_table *samsung_get_pll_settings(
+				struct samsung_clk_pll *pll, unsigned long rate)
+{
+	const struct samsung_pll_rate_table  *rate_table = pll->rate_table;
+	int i;
+
+	for (i = 0; i < pll->rate_count; i++) {
+		if (rate == rate_table[i].rate)
+			return &rate_table[i];
+	}
+
+	return NULL;
+}
+
+static long samsung_pll_round_rate(struct clk_hw *hw,
+			unsigned long drate, unsigned long *prate)
+{
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
+	const struct samsung_pll_rate_table *rate_table = pll->rate_table;
+	int i;
+
+	/* Assumming rate_table is in descending order */
+	for (i = 0; i < pll->rate_count; i++) {
+		if (drate >= rate_table[i].rate)
+			return rate_table[i].rate;
+	}
+
+	/* return minimum supported value */
+	return rate_table[i - 1].rate;
+}
+
 /*
  * PLL35xx Clock Type
  */
+/* Maximum lock time can be 270 * PDIV cycles */
+#define PLL35XX_LOCK_FACTOR	(270)
 
 #define PLL35XX_MDIV_MASK       (0x3FF)
 #define PLL35XX_PDIV_MASK       (0x3F)
 #define PLL35XX_SDIV_MASK       (0x7)
+#define PLL35XX_LOCK_STAT_MASK	(0x1)
 #define PLL35XX_MDIV_SHIFT      (16)
 #define PLL35XX_PDIV_SHIFT      (8)
 #define PLL35XX_SDIV_SHIFT      (0)
+#define PLL35XX_LOCK_STAT_SHIFT	(29)
 
 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
 				unsigned long parent_rate)
@@ -53,8 +88,73 @@ static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
 	return (unsigned long)fvco;
 }
 
+static inline bool samsung_pll35xx_mp_change(
+		const struct samsung_pll_rate_table *rate, u32 pll_con)
+{
+	u32 old_mdiv, old_pdiv;
+
+	old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
+	old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
+
+	return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
+}
+
+static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
+					unsigned long prate)
+{
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
+	const struct samsung_pll_rate_table *rate;
+	u32 tmp;
+
+	/* Get required rate settings from table */
+	rate = samsung_get_pll_settings(pll, drate);
+	if (!rate) {
+		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+			drate, __clk_get_name(hw->clk));
+		return -EINVAL;
+	}
+
+	tmp = __raw_readl(pll->con_reg);
+
+	if (!(samsung_pll35xx_mp_change(rate, tmp))) {
+		/* If only s change, change just s value only*/
+		tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
+		tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
+		__raw_writel(tmp, pll->con_reg);
+
+		return 0;
+	}
+
+	/* Set PLL lock time. */
+	__raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
+			pll->lock_reg);
+
+	/* Change PLL PMS values */
+	tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
+			(PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
+			(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
+	tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) |
+			(rate->pdiv << PLL35XX_PDIV_SHIFT) |
+			(rate->sdiv << PLL35XX_SDIV_SHIFT);
+	__raw_writel(tmp, pll->con_reg);
+
+	/* wait_lock_time */
+	do {
+		cpu_relax();
+		tmp = __raw_readl(pll->con_reg);
+	} while (!(tmp & (PLL35XX_LOCK_STAT_MASK
+				<< PLL35XX_LOCK_STAT_SHIFT)));
+	return 0;
+}
+
 static const struct clk_ops samsung_pll35xx_clk_ops = {
 	.recalc_rate = samsung_pll35xx_recalc_rate,
+	.round_rate = samsung_pll_round_rate,
+	.set_rate = samsung_pll35xx_set_rate,
+};
+
+static const struct clk_ops samsung_pll35xx_clk_min_ops = {
+	.recalc_rate = samsung_pll35xx_recalc_rate,
 };
 
 /*
@@ -386,7 +486,10 @@ void __init samsung_clk_register_pll(struct samsung_pll_clock *clk_list,
 		/* clk_ops for 35xx and 2550 are similar */
 		case pll_35xx:
 		case pll_2550:
-			init.ops = &samsung_pll35xx_clk_ops;
+			if (!pll->rate_table)
+				init.ops = &samsung_pll35xx_clk_min_ops;
+			else
+				init.ops = &samsung_pll35xx_clk_ops;
 			break;
 		/* clk_ops for 36xx and 2650 are similar */
 		case pll_36xx:
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 4/7] clk: samsung: Add set_rate() clk_ops for PLL35xx
@ 2013-06-10 13:24   ` Yadwinder Singh Brar
  0 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-10 13:24 UTC (permalink / raw)
  To: linux-arm-kernel

This patch add set_rate() and round_rate() for PLL35xx

Reviewed-by: Doug Anderson <dianders@chromium.org>
Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
---
 drivers/clk/samsung/clk-pll.c |  105 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 104 insertions(+), 1 deletions(-)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index b2088dd..e3e7f0c 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -24,16 +24,51 @@ struct samsung_clk_pll {
 
 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
 
+static const struct samsung_pll_rate_table *samsung_get_pll_settings(
+				struct samsung_clk_pll *pll, unsigned long rate)
+{
+	const struct samsung_pll_rate_table  *rate_table = pll->rate_table;
+	int i;
+
+	for (i = 0; i < pll->rate_count; i++) {
+		if (rate == rate_table[i].rate)
+			return &rate_table[i];
+	}
+
+	return NULL;
+}
+
+static long samsung_pll_round_rate(struct clk_hw *hw,
+			unsigned long drate, unsigned long *prate)
+{
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
+	const struct samsung_pll_rate_table *rate_table = pll->rate_table;
+	int i;
+
+	/* Assumming rate_table is in descending order */
+	for (i = 0; i < pll->rate_count; i++) {
+		if (drate >= rate_table[i].rate)
+			return rate_table[i].rate;
+	}
+
+	/* return minimum supported value */
+	return rate_table[i - 1].rate;
+}
+
 /*
  * PLL35xx Clock Type
  */
+/* Maximum lock time can be 270 * PDIV cycles */
+#define PLL35XX_LOCK_FACTOR	(270)
 
 #define PLL35XX_MDIV_MASK       (0x3FF)
 #define PLL35XX_PDIV_MASK       (0x3F)
 #define PLL35XX_SDIV_MASK       (0x7)
+#define PLL35XX_LOCK_STAT_MASK	(0x1)
 #define PLL35XX_MDIV_SHIFT      (16)
 #define PLL35XX_PDIV_SHIFT      (8)
 #define PLL35XX_SDIV_SHIFT      (0)
+#define PLL35XX_LOCK_STAT_SHIFT	(29)
 
 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
 				unsigned long parent_rate)
@@ -53,8 +88,73 @@ static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
 	return (unsigned long)fvco;
 }
 
+static inline bool samsung_pll35xx_mp_change(
+		const struct samsung_pll_rate_table *rate, u32 pll_con)
+{
+	u32 old_mdiv, old_pdiv;
+
+	old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
+	old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
+
+	return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
+}
+
+static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
+					unsigned long prate)
+{
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
+	const struct samsung_pll_rate_table *rate;
+	u32 tmp;
+
+	/* Get required rate settings from table */
+	rate = samsung_get_pll_settings(pll, drate);
+	if (!rate) {
+		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+			drate, __clk_get_name(hw->clk));
+		return -EINVAL;
+	}
+
+	tmp = __raw_readl(pll->con_reg);
+
+	if (!(samsung_pll35xx_mp_change(rate, tmp))) {
+		/* If only s change, change just s value only*/
+		tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
+		tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
+		__raw_writel(tmp, pll->con_reg);
+
+		return 0;
+	}
+
+	/* Set PLL lock time. */
+	__raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
+			pll->lock_reg);
+
+	/* Change PLL PMS values */
+	tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
+			(PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
+			(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
+	tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) |
+			(rate->pdiv << PLL35XX_PDIV_SHIFT) |
+			(rate->sdiv << PLL35XX_SDIV_SHIFT);
+	__raw_writel(tmp, pll->con_reg);
+
+	/* wait_lock_time */
+	do {
+		cpu_relax();
+		tmp = __raw_readl(pll->con_reg);
+	} while (!(tmp & (PLL35XX_LOCK_STAT_MASK
+				<< PLL35XX_LOCK_STAT_SHIFT)));
+	return 0;
+}
+
 static const struct clk_ops samsung_pll35xx_clk_ops = {
 	.recalc_rate = samsung_pll35xx_recalc_rate,
+	.round_rate = samsung_pll_round_rate,
+	.set_rate = samsung_pll35xx_set_rate,
+};
+
+static const struct clk_ops samsung_pll35xx_clk_min_ops = {
+	.recalc_rate = samsung_pll35xx_recalc_rate,
 };
 
 /*
@@ -386,7 +486,10 @@ void __init samsung_clk_register_pll(struct samsung_pll_clock *clk_list,
 		/* clk_ops for 35xx and 2550 are similar */
 		case pll_35xx:
 		case pll_2550:
-			init.ops = &samsung_pll35xx_clk_ops;
+			if (!pll->rate_table)
+				init.ops = &samsung_pll35xx_clk_min_ops;
+			else
+				init.ops = &samsung_pll35xx_clk_ops;
 			break;
 		/* clk_ops for 36xx and 2650 are similar */
 		case pll_36xx:
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 5/7] clk: samsung: Add set_rate() clk_ops for PLL36xx
  2013-06-10 13:24 ` Yadwinder Singh Brar
@ 2013-06-10 13:24   ` Yadwinder Singh Brar
  -1 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-10 13:24 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, kgene.kim, mturquette, thomas.abraham,
	dianders, t.figa, vikas.sajjan, abrestic

From: Vikas Sajjan <vikas.sajjan@linaro.org>

This patch adds set_rate and round_rate clk_ops for PLL36xx

Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Reviewed-by: Doug Anderson <dianders@chromium.org>
Signed-off-by: Vikas Sajjan <vikas.sajjan@linaro.org>
---
 drivers/clk/samsung/clk-pll.c |   79 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 78 insertions(+), 1 deletions(-)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index e3e7f0c..2197004 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -160,6 +160,8 @@ static const struct clk_ops samsung_pll35xx_clk_min_ops = {
 /*
  * PLL36xx Clock Type
  */
+/* Maximum lock time can be 3000 * PDIV cycles */
+#define PLL36XX_LOCK_FACTOR    (3000)
 
 #define PLL36XX_KDIV_MASK	(0xFFFF)
 #define PLL36XX_MDIV_MASK	(0x1FF)
@@ -168,6 +170,8 @@ static const struct clk_ops samsung_pll35xx_clk_min_ops = {
 #define PLL36XX_MDIV_SHIFT	(16)
 #define PLL36XX_PDIV_SHIFT	(8)
 #define PLL36XX_SDIV_SHIFT	(0)
+#define PLL36XX_KDIV_SHIFT	(0)
+#define PLL36XX_LOCK_STAT_SHIFT	(29)
 
 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
 				unsigned long parent_rate)
@@ -190,8 +194,78 @@ static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
 	return (unsigned long)fvco;
 }
 
+static inline bool samsung_pll36xx_mpk_change(
+	const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
+{
+	u32 old_mdiv, old_pdiv, old_kdiv;
+
+	old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
+	old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
+	old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
+
+	return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
+		rate->kdiv != old_kdiv);
+}
+
+static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
+					unsigned long parent_rate)
+{
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
+	u32 tmp, pll_con0, pll_con1;
+	const struct samsung_pll_rate_table *rate;
+
+	rate = samsung_get_pll_settings(pll, drate);
+	if (!rate) {
+		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+			drate, __clk_get_name(hw->clk));
+		return -EINVAL;
+	}
+
+	pll_con0 = __raw_readl(pll->con_reg);
+	pll_con1 = __raw_readl(pll->con_reg + 4);
+
+	if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
+		/* If only s change, change just s value only*/
+		pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
+		pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
+		__raw_writel(pll_con0, pll->con_reg);
+
+		return 0;
+	}
+
+	/* Set PLL lock time. */
+	__raw_writel(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
+
+	 /* Change PLL PMS values */
+	pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
+			(PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
+			(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
+	pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
+			(rate->pdiv << PLL36XX_PDIV_SHIFT) |
+			(rate->sdiv << PLL36XX_SDIV_SHIFT);
+	__raw_writel(pll_con0, pll->con_reg);
+
+	pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
+	pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
+	__raw_writel(pll_con1, pll->con_reg + 4);
+
+	/* wait_lock_time */
+	do {
+		cpu_relax();
+		tmp = __raw_readl(pll->con_reg);
+	} while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT)));
+
+	return 0;
+}
+
 static const struct clk_ops samsung_pll36xx_clk_ops = {
 	.recalc_rate = samsung_pll36xx_recalc_rate,
+	.set_rate = samsung_pll36xx_set_rate,
+	.round_rate = samsung_pll_round_rate,
+};
+
+static const struct clk_ops samsung_pll36xx_clk_min_ops = {
+	.recalc_rate = samsung_pll36xx_recalc_rate,
 };
 
 /*
@@ -494,7 +568,10 @@ void __init samsung_clk_register_pll(struct samsung_pll_clock *clk_list,
 		/* clk_ops for 36xx and 2650 are similar */
 		case pll_36xx:
 		case pll_2650:
-			init.ops = &samsung_pll36xx_clk_ops;
+			if (!pll->rate_table)
+				init.ops = &samsung_pll36xx_clk_min_ops;
+			else
+				init.ops = &samsung_pll36xx_clk_ops;
 			break;
 		default:
 			pr_warn("%s: Unknown pll type for pll clk %s\n",
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 5/7] clk: samsung: Add set_rate() clk_ops for PLL36xx
@ 2013-06-10 13:24   ` Yadwinder Singh Brar
  0 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-10 13:24 UTC (permalink / raw)
  To: linux-arm-kernel

From: Vikas Sajjan <vikas.sajjan@linaro.org>

This patch adds set_rate and round_rate clk_ops for PLL36xx

Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Reviewed-by: Doug Anderson <dianders@chromium.org>
Signed-off-by: Vikas Sajjan <vikas.sajjan@linaro.org>
---
 drivers/clk/samsung/clk-pll.c |   79 ++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 78 insertions(+), 1 deletions(-)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index e3e7f0c..2197004 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -160,6 +160,8 @@ static const struct clk_ops samsung_pll35xx_clk_min_ops = {
 /*
  * PLL36xx Clock Type
  */
+/* Maximum lock time can be 3000 * PDIV cycles */
+#define PLL36XX_LOCK_FACTOR    (3000)
 
 #define PLL36XX_KDIV_MASK	(0xFFFF)
 #define PLL36XX_MDIV_MASK	(0x1FF)
@@ -168,6 +170,8 @@ static const struct clk_ops samsung_pll35xx_clk_min_ops = {
 #define PLL36XX_MDIV_SHIFT	(16)
 #define PLL36XX_PDIV_SHIFT	(8)
 #define PLL36XX_SDIV_SHIFT	(0)
+#define PLL36XX_KDIV_SHIFT	(0)
+#define PLL36XX_LOCK_STAT_SHIFT	(29)
 
 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
 				unsigned long parent_rate)
@@ -190,8 +194,78 @@ static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
 	return (unsigned long)fvco;
 }
 
+static inline bool samsung_pll36xx_mpk_change(
+	const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 pll_con1)
+{
+	u32 old_mdiv, old_pdiv, old_kdiv;
+
+	old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
+	old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
+	old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
+
+	return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
+		rate->kdiv != old_kdiv);
+}
+
+static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
+					unsigned long parent_rate)
+{
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
+	u32 tmp, pll_con0, pll_con1;
+	const struct samsung_pll_rate_table *rate;
+
+	rate = samsung_get_pll_settings(pll, drate);
+	if (!rate) {
+		pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__,
+			drate, __clk_get_name(hw->clk));
+		return -EINVAL;
+	}
+
+	pll_con0 = __raw_readl(pll->con_reg);
+	pll_con1 = __raw_readl(pll->con_reg + 4);
+
+	if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
+		/* If only s change, change just s value only*/
+		pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
+		pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
+		__raw_writel(pll_con0, pll->con_reg);
+
+		return 0;
+	}
+
+	/* Set PLL lock time. */
+	__raw_writel(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
+
+	 /* Change PLL PMS values */
+	pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
+			(PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
+			(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
+	pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
+			(rate->pdiv << PLL36XX_PDIV_SHIFT) |
+			(rate->sdiv << PLL36XX_SDIV_SHIFT);
+	__raw_writel(pll_con0, pll->con_reg);
+
+	pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
+	pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
+	__raw_writel(pll_con1, pll->con_reg + 4);
+
+	/* wait_lock_time */
+	do {
+		cpu_relax();
+		tmp = __raw_readl(pll->con_reg);
+	} while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT)));
+
+	return 0;
+}
+
 static const struct clk_ops samsung_pll36xx_clk_ops = {
 	.recalc_rate = samsung_pll36xx_recalc_rate,
+	.set_rate = samsung_pll36xx_set_rate,
+	.round_rate = samsung_pll_round_rate,
+};
+
+static const struct clk_ops samsung_pll36xx_clk_min_ops = {
+	.recalc_rate = samsung_pll36xx_recalc_rate,
 };
 
 /*
@@ -494,7 +568,10 @@ void __init samsung_clk_register_pll(struct samsung_pll_clock *clk_list,
 		/* clk_ops for 36xx and 2650 are similar */
 		case pll_36xx:
 		case pll_2650:
-			init.ops = &samsung_pll36xx_clk_ops;
+			if (!pll->rate_table)
+				init.ops = &samsung_pll36xx_clk_min_ops;
+			else
+				init.ops = &samsung_pll36xx_clk_ops;
 			break;
 		default:
 			pr_warn("%s: Unknown pll type for pll clk %s\n",
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 6/7] clk: samsung: Reorder MUX registration for mout_vpllsrc
  2013-06-10 13:24 ` Yadwinder Singh Brar
@ 2013-06-10 13:24   ` Yadwinder Singh Brar
  -1 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-10 13:24 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, kgene.kim, mturquette, thomas.abraham,
	dianders, t.figa, vikas.sajjan, abrestic, Yadwinder Singh Brar

From: Vikas Sajjan <vikas.sajjan@linaro.org>

While trying to get rate of "mout_vpllsrc" MUX (parent) for registering the
"fout_vpll" (child), we found get rate was failing.

So this patch moves the mout_vpllsrc MUX out of the existing common list
and registers the mout_vpllsrc MUX before the PLL registrations.

Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Vikas Sajjan <vikas.sajjan@linaro.org>
Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
---
 drivers/clk/samsung/clk-exynos5250.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 21f5491..6881810 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -228,6 +228,10 @@ struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __initdata = {
 	FFACTOR(none, "fout_bplldiv2", "fout_bpll", 1, 2, 0),
 };
 
+struct samsung_mux_clock exynos5250_pll_pmux_clks[] __initdata = {
+	MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1),
+};
+
 struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
 	MUX(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1),
 	MUX(none, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1),
@@ -235,7 +239,6 @@ struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
 	MUX(none, "sclk_mpll", mout_mpll_p, SRC_CORE1, 8, 1),
 	MUX(none, "mout_bpll_fout", mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1),
 	MUX(none, "sclk_bpll", mout_bpll_p, SRC_CDREX, 0, 1),
-	MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1),
 	MUX(none, "sclk_vpll", mout_vpll_p, SRC_TOP2, 16, 1),
 	MUX(none, "sclk_epll", mout_epll_p, SRC_TOP2, 12, 1),
 	MUX(none, "sclk_cpll", mout_cpll_p, SRC_TOP2, 8, 1),
@@ -526,6 +529,8 @@ void __init exynos5250_clk_init(struct device_node *np)
 	samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks,
 			ARRAY_SIZE(exynos5250_fixed_rate_ext_clks),
 			ext_clk_match);
+	samsung_clk_register_mux(exynos5250_pll_pmux_clks,
+				ARRAY_SIZE(exynos5250_pll_pmux_clks));
 	samsung_clk_register_pll(exynos5250_plls, ARRAY_SIZE(exynos5250_plls),
 					reg_base);
 	samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 6/7] clk: samsung: Reorder MUX registration for mout_vpllsrc
@ 2013-06-10 13:24   ` Yadwinder Singh Brar
  0 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-10 13:24 UTC (permalink / raw)
  To: linux-arm-kernel

From: Vikas Sajjan <vikas.sajjan@linaro.org>

While trying to get rate of "mout_vpllsrc" MUX (parent) for registering the
"fout_vpll" (child), we found get rate was failing.

So this patch moves the mout_vpllsrc MUX out of the existing common list
and registers the mout_vpllsrc MUX before the PLL registrations.

Reviewed-by: Tomasz Figa <t.figa@samsung.com>
Signed-off-by: Vikas Sajjan <vikas.sajjan@linaro.org>
Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
---
 drivers/clk/samsung/clk-exynos5250.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 21f5491..6881810 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -228,6 +228,10 @@ struct samsung_fixed_factor_clock exynos5250_fixed_factor_clks[] __initdata = {
 	FFACTOR(none, "fout_bplldiv2", "fout_bpll", 1, 2, 0),
 };
 
+struct samsung_mux_clock exynos5250_pll_pmux_clks[] __initdata = {
+	MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1),
+};
+
 struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
 	MUX(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1),
 	MUX(none, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1),
@@ -235,7 +239,6 @@ struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
 	MUX(none, "sclk_mpll", mout_mpll_p, SRC_CORE1, 8, 1),
 	MUX(none, "mout_bpll_fout", mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1),
 	MUX(none, "sclk_bpll", mout_bpll_p, SRC_CDREX, 0, 1),
-	MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1),
 	MUX(none, "sclk_vpll", mout_vpll_p, SRC_TOP2, 16, 1),
 	MUX(none, "sclk_epll", mout_epll_p, SRC_TOP2, 12, 1),
 	MUX(none, "sclk_cpll", mout_cpll_p, SRC_TOP2, 8, 1),
@@ -526,6 +529,8 @@ void __init exynos5250_clk_init(struct device_node *np)
 	samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks,
 			ARRAY_SIZE(exynos5250_fixed_rate_ext_clks),
 			ext_clk_match);
+	samsung_clk_register_mux(exynos5250_pll_pmux_clks,
+				ARRAY_SIZE(exynos5250_pll_pmux_clks));
 	samsung_clk_register_pll(exynos5250_plls, ARRAY_SIZE(exynos5250_plls),
 					reg_base);
 	samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 7/7] clk: samsung: Add EPLL and VPLL freq table for exynos5250 SoC
  2013-06-10 13:24 ` Yadwinder Singh Brar
@ 2013-06-10 13:24   ` Yadwinder Singh Brar
  -1 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-10 13:24 UTC (permalink / raw)
  To: linux-samsung-soc
  Cc: linux-arm-kernel, kgene.kim, mturquette, thomas.abraham,
	dianders, t.figa, vikas.sajjan, abrestic, Yadwinder Singh Brar

Adds the EPLL and VPLL freq table for exynos5250 SoC.

Signed-off-by: Vikas Sajjan <vikas.sajjan@linaro.org>
Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
---
 drivers/clk/samsung/clk-exynos5250.c |   42 ++++++++++++++++++++++++++++++++-
 drivers/clk/samsung/clk.h            |    2 +
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 6881810..13e293e 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -493,6 +493,29 @@ static __initdata struct of_device_id ext_clk_match[] = {
 	{ },
 };
 
+static __initdata struct samsung_pll_rate_table vpll_24mhz_tbl[] = {
+	/* sorted in descending order */
+	/* PLL_36XX_RATE(rate, m, p, s, k) */
+	PLL_36XX_RATE(266000000, 266, 3, 3, 0),
+	/* Not in UM, but need for eDP on snow */
+	PLL_36XX_RATE(70500000, 94, 2, 4, 0),
+	{ },
+};
+
+static __initdata struct samsung_pll_rate_table epll_24mhz_tbl[] = {
+	/* sorted in descending order */
+	/* PLL_36XX_RATE(rate, m, p, s, k) */
+	PLL_36XX_RATE(192000000, 64, 2, 2, 0),
+	PLL_36XX_RATE(180633600, 90, 3, 2, 20762),
+	PLL_36XX_RATE(180000000, 90, 3, 2, 0),
+	PLL_36XX_RATE(73728000, 98, 2, 4, 19923),
+	PLL_36XX_RATE(67737600, 90, 2, 4, 20762),
+	PLL_36XX_RATE(49152000, 98, 3, 4, 19923),
+	PLL_36XX_RATE(45158400, 90, 3, 4, 20762),
+	PLL_36XX_RATE(32768000, 131, 3, 5, 4719)
+	{ },
+};
+
 struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = {
 	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
 		APLL_CON0, "fout_apll", NULL),
@@ -506,14 +529,16 @@ struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = {
 		CPLL_CON0, NULL),
 	[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
 		EPLL_CON0, NULL),
-	[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
-		VPLL_CON0, NULL),
+	[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "mout_vpllsrc",
+		VPLL_LOCK, VPLL_CON0, NULL),
 };
 
 /* register exynox5250 clocks */
 void __init exynos5250_clk_init(struct device_node *np)
 {
 	void __iomem *reg_base;
+	struct clk *vpllsrc;
+	unsigned long fin_pll_rate, mout_vpllsrc_rate = 0;
 
 	if (np) {
 		reg_base = of_iomap(np, 0);
@@ -531,6 +556,19 @@ void __init exynos5250_clk_init(struct device_node *np)
 			ext_clk_match);
 	samsung_clk_register_mux(exynos5250_pll_pmux_clks,
 				ARRAY_SIZE(exynos5250_pll_pmux_clks));
+
+	fin_pll_rate = _get_rate("fin_pll");
+
+	if (fin_pll_rate == (24 * MHZ))
+		exynos5250_plls[epll].rate_table = epll_24mhz_tbl;
+
+	vpllsrc = __clk_lookup("mout_vpllsrc");
+	if (vpllsrc)
+		mout_vpllsrc_rate = clk_get_rate(vpllsrc);
+
+	if (mout_vpllsrc_rate == (24 * MHZ))
+		exynos5250_plls[vpll].rate_table =  vpll_24mhz_tbl;
+
 	samsung_clk_register_pll(exynos5250_plls, ARRAY_SIZE(exynos5250_plls),
 					reg_base);
 	samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 3e6501c..378bf98 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -40,6 +40,8 @@ struct samsung_clock_alias {
 		.alias		= a,				\
 	}
 
+#define MHZ (1000*1000)
+
 /**
  * struct samsung_fixed_rate_clock: information about fixed-rate clock
  * @id: platform specific id of the clock.
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* [PATCH v6 7/7] clk: samsung: Add EPLL and VPLL freq table for exynos5250 SoC
@ 2013-06-10 13:24   ` Yadwinder Singh Brar
  0 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-10 13:24 UTC (permalink / raw)
  To: linux-arm-kernel

Adds the EPLL and VPLL freq table for exynos5250 SoC.

Signed-off-by: Vikas Sajjan <vikas.sajjan@linaro.org>
Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
---
 drivers/clk/samsung/clk-exynos5250.c |   42 ++++++++++++++++++++++++++++++++-
 drivers/clk/samsung/clk.h            |    2 +
 2 files changed, 42 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index 6881810..13e293e 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -493,6 +493,29 @@ static __initdata struct of_device_id ext_clk_match[] = {
 	{ },
 };
 
+static __initdata struct samsung_pll_rate_table vpll_24mhz_tbl[] = {
+	/* sorted in descending order */
+	/* PLL_36XX_RATE(rate, m, p, s, k) */
+	PLL_36XX_RATE(266000000, 266, 3, 3, 0),
+	/* Not in UM, but need for eDP on snow */
+	PLL_36XX_RATE(70500000, 94, 2, 4, 0),
+	{ },
+};
+
+static __initdata struct samsung_pll_rate_table epll_24mhz_tbl[] = {
+	/* sorted in descending order */
+	/* PLL_36XX_RATE(rate, m, p, s, k) */
+	PLL_36XX_RATE(192000000, 64, 2, 2, 0),
+	PLL_36XX_RATE(180633600, 90, 3, 2, 20762),
+	PLL_36XX_RATE(180000000, 90, 3, 2, 0),
+	PLL_36XX_RATE(73728000, 98, 2, 4, 19923),
+	PLL_36XX_RATE(67737600, 90, 2, 4, 20762),
+	PLL_36XX_RATE(49152000, 98, 3, 4, 19923),
+	PLL_36XX_RATE(45158400, 90, 3, 4, 20762),
+	PLL_36XX_RATE(32768000, 131, 3, 5, 4719)
+	{ },
+};
+
 struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = {
 	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", APLL_LOCK,
 		APLL_CON0, "fout_apll", NULL),
@@ -506,14 +529,16 @@ struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = {
 		CPLL_CON0, NULL),
 	[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", EPLL_LOCK,
 		EPLL_CON0, NULL),
-	[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", VPLL_LOCK,
-		VPLL_CON0, NULL),
+	[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "mout_vpllsrc",
+		VPLL_LOCK, VPLL_CON0, NULL),
 };
 
 /* register exynox5250 clocks */
 void __init exynos5250_clk_init(struct device_node *np)
 {
 	void __iomem *reg_base;
+	struct clk *vpllsrc;
+	unsigned long fin_pll_rate, mout_vpllsrc_rate = 0;
 
 	if (np) {
 		reg_base = of_iomap(np, 0);
@@ -531,6 +556,19 @@ void __init exynos5250_clk_init(struct device_node *np)
 			ext_clk_match);
 	samsung_clk_register_mux(exynos5250_pll_pmux_clks,
 				ARRAY_SIZE(exynos5250_pll_pmux_clks));
+
+	fin_pll_rate = _get_rate("fin_pll");
+
+	if (fin_pll_rate == (24 * MHZ))
+		exynos5250_plls[epll].rate_table = epll_24mhz_tbl;
+
+	vpllsrc = __clk_lookup("mout_vpllsrc");
+	if (vpllsrc)
+		mout_vpllsrc_rate = clk_get_rate(vpllsrc);
+
+	if (mout_vpllsrc_rate == (24 * MHZ))
+		exynos5250_plls[vpll].rate_table =  vpll_24mhz_tbl;
+
 	samsung_clk_register_pll(exynos5250_plls, ARRAY_SIZE(exynos5250_plls),
 					reg_base);
 	samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,
diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
index 3e6501c..378bf98 100644
--- a/drivers/clk/samsung/clk.h
+++ b/drivers/clk/samsung/clk.h
@@ -40,6 +40,8 @@ struct samsung_clock_alias {
 		.alias		= a,				\
 	}
 
+#define MHZ (1000*1000)
+
 /**
  * struct samsung_fixed_rate_clock: information about fixed-rate clock
  * @id: platform specific id of the clock.
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 34+ messages in thread

* Re: [PATCH v6 2/7] clk: samsung: Define a common samsung_clk_register_pll()
  2013-06-10 13:24   ` Yadwinder Singh Brar
@ 2013-06-19 16:54     ` Tomasz Figa
  -1 siblings, 0 replies; 34+ messages in thread
From: Tomasz Figa @ 2013-06-19 16:54 UTC (permalink / raw)
  To: Yadwinder Singh Brar
  Cc: linux-samsung-soc, linux-arm-kernel, kgene.kim, mturquette,
	thomas.abraham, dianders, t.figa, vikas.sajjan, abrestic

Hi Yadwinder,

Generally looks really good, but some comments inline.

On Monday 10 of June 2013 18:54:14 Yadwinder Singh Brar wrote:
> This patch defines a common samsung_clk_register_pll() and its migrating
> the PLL35xx & PLL36xx to use it. Other samsung PLL can also be migrated
> to it. It also adds exynos5250 & exynos5420 PLLs to unique id list of
> clocks. Since pll2550 & pll35xx and pll2650 & pll36xx have exactly same
> clk ops implementation, added pll2550 and pll2650 also.
> 
> Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
> ---
>  drivers/clk/samsung/clk-exynos4.c    |   40 +++++++----
>  drivers/clk/samsung/clk-exynos5250.c |   60 +++++++++++-----
>  drivers/clk/samsung/clk-exynos5420.c |   86 +++++++++++++++-------
>  drivers/clk/samsung/clk-pll.c        |  132
> ++++++++++++++++------------------ drivers/clk/samsung/clk-pll.h       
> |   11 ++-
>  drivers/clk/samsung/clk.h            |   48 ++++++++++++
>  6 files changed, 242 insertions(+), 135 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-exynos4.c
> b/drivers/clk/samsung/clk-exynos4.c index addc738..ba25a1b 100644
> --- a/drivers/clk/samsung/clk-exynos4.c
> +++ b/drivers/clk/samsung/clk-exynos4.c
> @@ -17,7 +17,6 @@
>  #include <linux/of_address.h>
> 
>  #include "clk.h"
> -#include "clk-pll.h"
> 
>  /* Exynos4 clock controller register offsets */
>  #define SRC_LEFTBUS		0x4200
> @@ -97,12 +96,14 @@
>  #define GATE_IP_PERIL		0xc950
>  #define E4210_GATE_IP_PERIR	0xc960
>  #define GATE_BLOCK		0xc970
> +#define E4X12_MPLL_LOCK		0x10008
>  #define E4X12_MPLL_CON0		0x10108
>  #define SRC_DMC			0x10200
>  #define SRC_MASK_DMC		0x10300
>  #define DIV_DMC0		0x10500
>  #define DIV_DMC1		0x10504
>  #define GATE_IP_DMC		0x10900
> +#define APLL_LOCK		0x14000
>  #define APLL_CON0		0x14100
>  #define E4210_MPLL_CON0		0x14108
>  #define SRC_CPU			0x14200
> @@ -121,6 +122,12 @@ enum exynos4_soc {
>  	EXYNOS4X12,
>  };
> 
> +/* list of PLLs to be registered */
> +enum exynos4_plls {
> +	apll, mpll, epll, vpll,
> +	nr_plls			/* number of PLLs */
> +};
> +
>  /*
>   * Let each supported clock get a unique id. This id is used to lookup
> the clock * for device tree based platforms. The clocks are categorized
> into three @@ -988,6 +995,17 @@ static __initdata struct of_device_id
> ext_clk_match[] = { {},
>  };
> 
> +struct __initdata samsung_pll_clock exynos4_plls[nr_plls] = {
> +	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", 
APLL_LOCK,
> +		APLL_CON0, "fout_apll"),
> +	[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll",
> +		E4X12_MPLL_LOCK, E4X12_MPLL_CON0, "fout_mpll"),
> +	[epll] = PLL_A(pll_36xx, fout_epll, "fout_epll", "fin_pll", 
EPLL_LOCK,
> +		EPLL_CON0, "fout_epll"),
> +	[vpll] = PLL_A(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", 
VPLL_LOCK,
> +		VPLL_CON0, "fout_vpll"),
> +};
> +
>  /* register exynos4 clocks */
>  void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc
> exynos4_soc, void __iomem *reg_base, unsigned long xom) {
> @@ -1024,22 +1042,16 @@ void __init exynos4_clk_init(struct device_node
> *np, enum exynos4_soc exynos4_so reg_base + EPLL_CON0, pll_4600);
>  		vpll = samsung_clk_register_pll46xx("fout_vpll", 
"mout_vpllsrc",
>  					reg_base + VPLL_CON0, pll_4650c);
> +
> +		samsung_clk_add_lookup(apll, fout_apll);
> +		samsung_clk_add_lookup(mpll, fout_mpll);
> +		samsung_clk_add_lookup(epll, fout_epll);
> +		samsung_clk_add_lookup(vpll, fout_vpll);
>  	} else {
> -		apll = samsung_clk_register_pll35xx("fout_apll", 
"fin_pll",
> -					reg_base + APLL_CON0);
> -		mpll = samsung_clk_register_pll35xx("fout_mpll", 
"fin_pll",
> -					reg_base + E4X12_MPLL_CON0);
> -		epll = samsung_clk_register_pll36xx("fout_epll", 
"fin_pll",
> -					reg_base + EPLL_CON0);
> -		vpll = samsung_clk_register_pll36xx("fout_vpll", 
"fin_pll",
> -					reg_base + VPLL_CON0);
> +		samsung_clk_register_pll(exynos4_plls,
> +					ARRAY_SIZE(exynos4_plls), 
reg_base);
>  	}
> 
> -	samsung_clk_add_lookup(apll, fout_apll);
> -	samsung_clk_add_lookup(mpll, fout_mpll);
> -	samsung_clk_add_lookup(epll, fout_epll);
> -	samsung_clk_add_lookup(vpll, fout_vpll);
> -
>  	samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks,
>  			ARRAY_SIZE(exynos4_fixed_rate_clks));
>  	samsung_clk_register_mux(exynos4_mux_clks,
> diff --git a/drivers/clk/samsung/clk-exynos5250.c
> b/drivers/clk/samsung/clk-exynos5250.c index 7c68850..dc6a700 100644
> --- a/drivers/clk/samsung/clk-exynos5250.c
> +++ b/drivers/clk/samsung/clk-exynos5250.c
> @@ -17,11 +17,22 @@
>  #include <linux/of_address.h>
> 
>  #include "clk.h"
> -#include "clk-pll.h"
> 
> +#define APLL_LOCK		0x0
> +#define APLL_CON0		0x100
>  #define SRC_CPU			0x200
>  #define DIV_CPU0		0x500
> +#define MPLL_LOCK		0x4000
> +#define MPLL_CON0		0x4100
>  #define SRC_CORE1		0x4204
> +#define CPLL_LOCK		0x10020
> +#define EPLL_LOCK		0x10030
> +#define VPLL_LOCK		0x10040
> +#define GPLL_LOCK		0x10050
> +#define CPLL_CON0		0x10120
> +#define EPLL_CON0		0x10130
> +#define VPLL_CON0		0x10140
> +#define GPLL_CON0		0x10150
>  #define SRC_TOP0		0x10210
>  #define SRC_TOP2		0x10218
>  #define SRC_GSCL		0x10220
> @@ -59,10 +70,18 @@
>  #define GATE_IP_FSYS		0x10944
>  #define GATE_IP_PERIC		0x10950
>  #define GATE_IP_PERIS		0x10960
> +#define BPLL_LOCK		0x20010
> +#define BPLL_CON0		0x20110
>  #define SRC_CDREX		0x20200
>  #define PLL_DIV2_SEL		0x20a24
>  #define GATE_IP_DISP1		0x10928
> 
> +/* list of PLLs to be registered */
> +enum exynos5250_plls {
> +	apll, mpll, bpll, gpll, cpll, epll, vpll,
> +	nr_plls			/* number of PLLs */
> +};
> +
>  /*
>   * Let each supported clock get a unique id. This id is used to lookup
> the clock * for device tree based platforms. The clocks are categorized
> into three @@ -79,7 +98,8 @@ enum exynos5250_clks {
>  	none,
> 
>  	/* core clocks */
> -	fin_pll,
> +	fin_pll, fout_apll, fout_mpll, fout_bpll, fout_gpll, fout_cpll,
> +	fout_epll, fout_vpll,
> 
>  	/* gate for special clocks (sclk) */
>  	sclk_cam_bayer = 128, sclk_cam0, sclk_cam1, sclk_gscl_wa,
> sclk_gscl_wb, @@ -470,11 +490,27 @@ static __initdata struct
> of_device_id ext_clk_match[] = { { },
>  };
> 
> +struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = {
> +	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", 
APLL_LOCK,
> +		APLL_CON0, "fout_apll"),
> +	[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll", 
MPLL_LOCK,
> +		MPLL_CON0, "fout_mpll"),
> +	[bpll] = PLL(pll_35xx, fout_bpll, "fout_bpll", "fin_pll", 
BPLL_LOCK,
> +		BPLL_CON0),
> +	[gpll] = PLL(pll_35xx, fout_gpll, "fout_gpll", "fin_pll", 
GPLL_LOCK,
> +		GPLL_CON0),
> +	[cpll] = PLL(pll_35xx, fout_cpll, "fout_cpll", "fin_pll", 
CPLL_LOCK,
> +		CPLL_CON0),
> +	[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", 
EPLL_LOCK,
> +		EPLL_CON0),
> +	[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", 
VPLL_LOCK,
> +		VPLL_CON0),
> +};
> +
>  /* register exynox5250 clocks */
>  void __init exynos5250_clk_init(struct device_node *np)
>  {
>  	void __iomem *reg_base;
> -	struct clk *apll, *mpll, *epll, *vpll, *bpll, *gpll, *cpll;
> 
>  	if (np) {
>  		reg_base = of_iomap(np, 0);
> @@ -490,22 +526,8 @@ void __init exynos5250_clk_init(struct device_node
> *np) samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks,
> ARRAY_SIZE(exynos5250_fixed_rate_ext_clks),
>  			ext_clk_match);
> -
> -	apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
> -			reg_base + 0x100);
> -	mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
> -			reg_base + 0x4100);
> -	bpll = samsung_clk_register_pll35xx("fout_bpll", "fin_pll",
> -			reg_base + 0x20110);
> -	gpll = samsung_clk_register_pll35xx("fout_gpll", "fin_pll",
> -			reg_base + 0x10150);
> -	cpll = samsung_clk_register_pll35xx("fout_cpll", "fin_pll",
> -			reg_base + 0x10120);
> -	epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
> -			reg_base + 0x10130);
> -	vpll = samsung_clk_register_pll36xx("fout_vpll", "mout_vpllsrc",
> -			reg_base + 0x10140);
> -
> +	samsung_clk_register_pll(exynos5250_plls, 
ARRAY_SIZE(exynos5250_plls),
> +					reg_base);
>  	samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,
>  			ARRAY_SIZE(exynos5250_fixed_rate_clks));
>  	samsung_clk_register_fixed_factor(exynos5250_fixed_factor_clks,
> diff --git a/drivers/clk/samsung/clk-exynos5420.c
> b/drivers/clk/samsung/clk-exynos5420.c index 68a96cb..3ea6b4f 100644
> --- a/drivers/clk/samsung/clk-exynos5420.c
> +++ b/drivers/clk/samsung/clk-exynos5420.c
> @@ -17,13 +17,30 @@
>  #include <linux/of_address.h>
> 
>  #include "clk.h"
> -#include "clk-pll.h"
> 
> +#define APLL_LOCK		0x0
> +#define APLL_CON0		0x100
>  #define SRC_CPU			0x200
>  #define DIV_CPU0		0x500
>  #define DIV_CPU1		0x504
>  #define GATE_BUS_CPU		0x700
>  #define GATE_SCLK_CPU		0x800
> +#define CPLL_LOCK		0x10020
> +#define DPLL_LOCK		0x10030
> +#define EPLL_LOCK		0x10040
> +#define RPLL_LOCK		0x10050
> +#define IPLL_LOCK		0x10060
> +#define SPLL_LOCK		0x10070
> +#define VPLL_LOCK		0x10070
> +#define MPLL_LOCK		0x10090
> +#define CPLL_CON0		0x10120
> +#define DPLL_CON0		0x10128
> +#define EPLL_CON0		0x10130
> +#define RPLL_CON0		0x10140
> +#define IPLL_CON0		0x10150
> +#define SPLL_CON0		0x10160
> +#define VPLL_CON0		0x10170
> +#define MPLL_CON0		0x10180
>  #define SRC_TOP0		0x10200
>  #define SRC_TOP1		0x10204
>  #define SRC_TOP2		0x10208
> @@ -75,15 +92,27 @@
>  #define GATE_TOP_SCLK_MAU	0x1083c
>  #define GATE_TOP_SCLK_FSYS	0x10840
>  #define GATE_TOP_SCLK_PERIC	0x10850
> +#define BPLL_LOCK		0x20010
> +#define BPLL_CON0		0x20110
>  #define SRC_CDREX		0x20200
> +#define KPLL_LOCK		0x28000
> +#define KPLL_CON0		0x28100
>  #define SRC_KFC			0x28200
>  #define DIV_KFC0		0x28500
> 
> +/* list of PLLs */
> +enum exynos5420_plls {
> +	apll, cpll, dpll, epll, rpll, ipll, spll, vpll, mpll,
> +	bpll, kpll,
> +	nr_plls			/* number of PLLs */
> +};
> +
>  enum exynos5420_clks {
>  	none,
> 
>  	/* core clocks */
> -	fin_pll,
> +	fin_pll,  fout_apll, fout_cpll, fout_dpll, fout_epll, fout_rpll,
> +	fout_ipll, fout_spll, fout_vpll, fout_mpll, fout_bpll, fout_kpll,
> 
>  	/* gate for special clocks (sclk) */
>  	sclk_uart0 = 128, sclk_uart1, sclk_uart2, sclk_uart3, sclk_mmc0,
> @@ -698,6 +727,31 @@ struct samsung_gate_clock exynos5420_gate_clks[]
> __initdata = { GATE(smmu_mscl2, "smmu_mscl2", "aclk400_mscl",
> GATE_IP_MSCL, 10, 0, 0), };
> 
> +struct __initdata samsung_pll_clock exynos5420_plls[nr_plls] = {
> +	[apll] = PLL(pll_2550, fout_apll, "fout_apll", "fin_pll", 
APLL_LOCK,
> +		APLL_CON0),
> +	[cpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", 
MPLL_LOCK,
> +		MPLL_CON0),
> +	[dpll] = PLL(pll_2550, fout_dpll, "fout_dpll", "fin_pll", 
DPLL_LOCK,
> +		DPLL_CON0),
> +	[epll] = PLL(pll_2650, fout_epll, "fout_epll", "fin_pll", 
EPLL_LOCK,
> +		EPLL_CON0),
> +	[rpll] = PLL(pll_2650, fout_rpll, "fout_rpll", "fin_pll", 
RPLL_LOCK,
> +		RPLL_CON0),
> +	[ipll] = PLL(pll_2550, fout_ipll, "fout_ipll", "fin_pll", 
IPLL_LOCK,
> +		IPLL_CON0),
> +	[spll] = PLL(pll_2550, fout_spll, "fout_spll", "fin_pll", 
SPLL_LOCK,
> +		SPLL_CON0),
> +	[vpll] = PLL(pll_2550, fout_vpll, "fout_vpll", "fin_pll", 
VPLL_LOCK,
> +		VPLL_CON0),
> +	[mpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", 
MPLL_LOCK,
> +		MPLL_CON0),
> +	[bpll] = PLL(pll_2550, fout_bpll, "fout_bpll", "fin_pll", 
BPLL_LOCK,
> +		BPLL_CON0),
> +	[kpll] = PLL(pll_2550, fout_kpll, "fout_kpll", "fin_pll", 
KPLL_LOCK,
> +		KPLL_CON0),
> +};
> +
>  static __initdata struct of_device_id ext_clk_match[] = {
>  	{ .compatible = "samsung,exynos5420-oscclk", .data = (void *)0, },
>  	{ },
> @@ -707,8 +761,6 @@ static __initdata struct of_device_id
> ext_clk_match[] = { void __init exynos5420_clk_init(struct device_node
> *np)
>  {
>  	void __iomem *reg_base;
> -	struct clk *apll, *bpll, *cpll, *dpll, *epll, *ipll, *kpll, *mpll;
> -	struct clk *rpll, *spll, *vpll;
> 
>  	if (np) {
>  		reg_base = of_iomap(np, 0);
> @@ -724,30 +776,8 @@ void __init exynos5420_clk_init(struct device_node
> *np) samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
> ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
>  			ext_clk_match);
> -
> -	apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
> -			reg_base + 0x100);
> -	bpll = samsung_clk_register_pll35xx("fout_bpll", "fin_pll",
> -			reg_base + 0x20110);
> -	cpll = samsung_clk_register_pll35xx("fout_cpll", "fin_pll",
> -			reg_base + 0x10120);
> -	dpll = samsung_clk_register_pll35xx("fout_dpll", "fin_pll",
> -			reg_base + 0x10128);
> -	epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
> -			reg_base + 0x10130);
> -	ipll = samsung_clk_register_pll35xx("fout_ipll", "fin_pll",
> -			reg_base + 0x10150);
> -	kpll = samsung_clk_register_pll35xx("fout_kpll", "fin_pll",
> -			reg_base + 0x28100);
> -	mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
> -			reg_base + 0x10180);
> -	rpll = samsung_clk_register_pll36xx("fout_rpll", "fin_pll",
> -			reg_base + 0x10140);
> -	spll = samsung_clk_register_pll35xx("fout_spll", "fin_pll",
> -			reg_base + 0x10160);
> -	vpll = samsung_clk_register_pll35xx("fout_vpll", "fin_pll",
> -			reg_base + 0x10170);
> -
> +	samsung_clk_register_pll(exynos5420_plls, 
ARRAY_SIZE(exynos5420_plls),
> +					reg_base);
>  	samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
>  			ARRAY_SIZE(exynos5420_fixed_rate_clks));
>  	samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
> diff --git a/drivers/clk/samsung/clk-pll.c
> b/drivers/clk/samsung/clk-pll.c index 8224bde..f132353 100644
> --- a/drivers/clk/samsung/clk-pll.c
> +++ b/drivers/clk/samsung/clk-pll.c
> @@ -17,6 +17,7 @@ struct samsung_clk_pll {
>  	struct clk_hw		hw;
>  	void __iomem		*lock_reg;
>  	void __iomem		*con_reg;
> +	enum samsung_pll_type	type;
>  };
> 
>  #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
> @@ -54,41 +55,6 @@ static const struct clk_ops samsung_pll35xx_clk_ops =
> { .recalc_rate = samsung_pll35xx_recalc_rate,
>  };
> 
> -struct clk * __init samsung_clk_register_pll35xx(const char *name,
> -			const char *pname, const void __iomem *con_reg)
> -{
> -	struct samsung_clk_pll *pll;
> -	struct clk *clk;
> -	struct clk_init_data init;
> -
> -	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> -	if (!pll) {
> -		pr_err("%s: could not allocate pll clk %s\n", __func__, 
name);
> -		return NULL;
> -	}
> -
> -	init.name = name;
> -	init.ops = &samsung_pll35xx_clk_ops;
> -	init.flags = CLK_GET_RATE_NOCACHE;
> -	init.parent_names = &pname;
> -	init.num_parents = 1;
> -
> -	pll->hw.init = &init;
> -	pll->con_reg = con_reg;
> -
> -	clk = clk_register(NULL, &pll->hw);
> -	if (IS_ERR(clk)) {
> -		pr_err("%s: failed to register pll clock %s\n", __func__,
> -				name);
> -		kfree(pll);
> -	}
> -
> -	if (clk_register_clkdev(clk, name, NULL))
> -		pr_err("%s: failed to register lookup for %s", __func__, 
name);
> -
> -	return clk;
> -}
> -
>  /*
>   * PLL36xx Clock Type
>   */
> @@ -126,41 +92,6 @@ static const struct clk_ops samsung_pll36xx_clk_ops
> = { .recalc_rate = samsung_pll36xx_recalc_rate,
>  };
> 
> -struct clk * __init samsung_clk_register_pll36xx(const char *name,
> -			const char *pname, const void __iomem *con_reg)
> -{
> -	struct samsung_clk_pll *pll;
> -	struct clk *clk;
> -	struct clk_init_data init;
> -
> -	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> -	if (!pll) {
> -		pr_err("%s: could not allocate pll clk %s\n", __func__, 
name);
> -		return NULL;
> -	}
> -
> -	init.name = name;
> -	init.ops = &samsung_pll36xx_clk_ops;
> -	init.flags = CLK_GET_RATE_NOCACHE;
> -	init.parent_names = &pname;
> -	init.num_parents = 1;
> -
> -	pll->hw.init = &init;
> -	pll->con_reg = con_reg;
> -
> -	clk = clk_register(NULL, &pll->hw);
> -	if (IS_ERR(clk)) {
> -		pr_err("%s: failed to register pll clock %s\n", __func__,
> -				name);
> -		kfree(pll);
> -	}
> -
> -	if (clk_register_clkdev(clk, name, NULL))
> -		pr_err("%s: failed to register lookup for %s", __func__, 
name);
> -
> -	return clk;
> -}
> -
>  /*
>   * PLL45xx Clock Type
>   */
> @@ -411,3 +342,64 @@ struct clk * __init
> samsung_clk_register_pll2550x(const char *name,
> 
>  	return clk;
>  }
> +
> +void __init samsung_clk_register_pll(struct samsung_pll_clock
> *clk_list, +				unsigned int nr_pll, void __iomem 
*base)
> +{
> +	struct samsung_clk_pll *pll;
> +	struct clk *clk;
> +	struct clk_init_data init;
> +	struct samsung_pll_clock *list = clk_list;
> +	int cnt;
> +
> +	for (cnt = 0; cnt < nr_pll; cnt++, list++) {

I'd suggest moving contents of this loop to a function like following?

static int __init _samsung_clk_register_pll(struct samsung_pll_clock *pll,
					    void __iomem *base)

This will make the code less indented and so more readable.

> +		pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> +		if (!pll) {
> +			pr_err("%s: could not allocate pll clk %s\n",
> +				__func__, list->name);
> +			continue;
> +		}
> +
> +		init.name = list->name;
> +		init.flags = list->flags;
> +		init.parent_names = &list->parent_name;
> +		init.num_parents = 1;
> +
> +		switch (list->type) {
> +		/* clk_ops for 35xx and 2550 are similar */
> +		case pll_35xx:
> +		case pll_2550:
> +			init.ops = &samsung_pll35xx_clk_ops;
> +			break;
> +		/* clk_ops for 36xx and 2650 are similar */
> +		case pll_36xx:
> +		case pll_2650:
> +			init.ops = &samsung_pll36xx_clk_ops;
> +			break;
> +		default:
> +			pr_warn("%s: Unknown pll type for pll clk %s\n",
> +				__func__, list->name);
> +		}
> +
> +		pll->hw.init = &init;
> +		pll->type = list->type;
> +		pll->lock_reg = base + list->lock_offset;
> +		pll->con_reg = base + list->con_offset;
> +
> +		clk = clk_register(NULL, &pll->hw);
> +		if (IS_ERR(clk)) {
> +			pr_err("%s: failed to register pll clock %s\n",
> +				__func__, list->name);
> +			kfree(pll);
> +			continue;
> +		}
> +
> +		samsung_clk_add_lookup(clk, list->id);
> +
> +		if (list->alias)
> +			if (clk_register_clkdev(clk, list->alias,
> +				list->dev_name))

What about

		if (!list->alias)
			return;

		ret = clk_register_clkdev(clk, list->alias, list-
>dev_name);
		if (ret)
			pr_err("%s: failed to register lookup for %s",
						__func__, list->name);

> +				pr_err("%s: failed to register lookup for 
%s",
> +					__func__, list->name);
> +	}
> +}
> diff --git a/drivers/clk/samsung/clk-pll.h
> b/drivers/clk/samsung/clk-pll.h index f33786e..1536f27 100644
> --- a/drivers/clk/samsung/clk-pll.h
> +++ b/drivers/clk/samsung/clk-pll.h
> @@ -12,6 +12,13 @@
>  #ifndef __SAMSUNG_CLK_PLL_H
>  #define __SAMSUNG_CLK_PLL_H
> 
> +enum samsung_pll_type {
> +	pll_35xx,
> +	pll_36xx,
> +	pll_2550,
> +	pll_2650,
> +};
> +
>  enum pll45xx_type {
>  	pll_4500,
>  	pll_4502,
> @@ -24,10 +31,6 @@ enum pll46xx_type {
>  	pll_4650c,
>  };
> 
> -extern struct clk * __init samsung_clk_register_pll35xx(const char
> *name, -			const char *pname, const void __iomem 
*con_reg);
> -extern struct clk * __init samsung_clk_register_pll36xx(const char
> *name, -			const char *pname, const void __iomem 
*con_reg);
>  extern struct clk * __init samsung_clk_register_pll45xx(const char
> *name, const char *pname, const void __iomem *con_reg,
>  			enum pll45xx_type type);
> diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
> index e4ad6ea..51f60ca 100644
> --- a/drivers/clk/samsung/clk.h
> +++ b/drivers/clk/samsung/clk.h
> @@ -19,6 +19,7 @@
>  #include <linux/clk-provider.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
> +#include "clk-pll.h"
> 
>  /**
>   * struct samsung_clock_alias: information about mux clock
> @@ -258,6 +259,51 @@ struct samsung_clk_reg_dump {
>  	u32	value;
>  };
> 
> +/**
> + * struct samsung_pll_clock: information about pll clock
> + * @id: platform specific id of the clock.
> + * @dev_name: name of the device to which this clock belongs.
> + * @name: name of this pll clock.
> + * @parent_name: name of the parent clock.
> + * @flags: optional flags for basic clock.
> + * @con_offset: offset of the register for configuring the PLL.
> + * @lock_offset: offset of the register for locking the PLL.
> + * @type: Type of PLL to be registered.
> + * @alias: optional clock alias name to be assigned to this clock.
> + */
> +struct samsung_pll_clock {
> +	unsigned int		id;
> +	const char		*dev_name;
> +	const char		*name;
> +	const char		*parent_name;
> +	unsigned long		flags;
> +	const int		con_offset;
> +	const int		lock_offset;

I don't see any point of having all those const qualifiers of non-
pointers. This makes the struct useless for creating and initializing at 
runtime.

> +	enum			samsung_pll_type type;

IMHO the enum keyword shouldn't be separated from enum name like this.

Otherwise the patch looks fine. Maybe it's a bit too big - things could be 
done a bit more gradually, like:
1) first add required structs and functions,
2) then move existing clock drivers to use the new API, possibly one patch 
per driver,
3) remove the old API.

This would make the whole change easier to review and, in case of any 
regressions, easier to track down the problem.

Best regards,
Tomasz

> +	const char              *alias;
> +};
> +
> +#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con,
> _alias) \ +	{								
\
> +		.id		= _id,					\
> +		.type		= _typ,					\
> +		.dev_name	= _dname,				\
> +		.name		= _name,				\
> +		.parent_name	= _pname,				\
> +		.flags		= CLK_GET_RATE_NOCACHE,			\
> +		.con_offset	= _con,					\
> +		.lock_offset	= _lock,				\
> +		.alias		= _alias,				\
> +	}
> +
> +#define PLL(_typ, _id, _name, _pname, _lock, _con)			\
> +	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
> +		_lock, _con, NULL)
> +
> +#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias)		\
> +	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
> +		_lock, _con, _alias)
> +
>  extern void __init samsung_clk_init(struct device_node *np, void
> __iomem *base, unsigned long nr_clks, unsigned long *rdump,
>  		unsigned long nr_rdump, unsigned long *soc_rdump,
> @@ -281,6 +327,8 @@ extern void __init samsung_clk_register_div(struct
> samsung_div_clock *clk_list, unsigned int nr_clk);
>  extern void __init samsung_clk_register_gate(
>  		struct samsung_gate_clock *clk_list, unsigned int nr_clk);
> +extern void __init samsung_clk_register_pll(struct samsung_pll_clock
> *list, +		unsigned int nr_clk, void __iomem *base);
> 
>  extern unsigned long _get_rate(const char *clk_name);

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 2/7] clk: samsung: Define a common samsung_clk_register_pll()
@ 2013-06-19 16:54     ` Tomasz Figa
  0 siblings, 0 replies; 34+ messages in thread
From: Tomasz Figa @ 2013-06-19 16:54 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Yadwinder,

Generally looks really good, but some comments inline.

On Monday 10 of June 2013 18:54:14 Yadwinder Singh Brar wrote:
> This patch defines a common samsung_clk_register_pll() and its migrating
> the PLL35xx & PLL36xx to use it. Other samsung PLL can also be migrated
> to it. It also adds exynos5250 & exynos5420 PLLs to unique id list of
> clocks. Since pll2550 & pll35xx and pll2650 & pll36xx have exactly same
> clk ops implementation, added pll2550 and pll2650 also.
> 
> Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
> ---
>  drivers/clk/samsung/clk-exynos4.c    |   40 +++++++----
>  drivers/clk/samsung/clk-exynos5250.c |   60 +++++++++++-----
>  drivers/clk/samsung/clk-exynos5420.c |   86 +++++++++++++++-------
>  drivers/clk/samsung/clk-pll.c        |  132
> ++++++++++++++++------------------ drivers/clk/samsung/clk-pll.h       
> |   11 ++-
>  drivers/clk/samsung/clk.h            |   48 ++++++++++++
>  6 files changed, 242 insertions(+), 135 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-exynos4.c
> b/drivers/clk/samsung/clk-exynos4.c index addc738..ba25a1b 100644
> --- a/drivers/clk/samsung/clk-exynos4.c
> +++ b/drivers/clk/samsung/clk-exynos4.c
> @@ -17,7 +17,6 @@
>  #include <linux/of_address.h>
> 
>  #include "clk.h"
> -#include "clk-pll.h"
> 
>  /* Exynos4 clock controller register offsets */
>  #define SRC_LEFTBUS		0x4200
> @@ -97,12 +96,14 @@
>  #define GATE_IP_PERIL		0xc950
>  #define E4210_GATE_IP_PERIR	0xc960
>  #define GATE_BLOCK		0xc970
> +#define E4X12_MPLL_LOCK		0x10008
>  #define E4X12_MPLL_CON0		0x10108
>  #define SRC_DMC			0x10200
>  #define SRC_MASK_DMC		0x10300
>  #define DIV_DMC0		0x10500
>  #define DIV_DMC1		0x10504
>  #define GATE_IP_DMC		0x10900
> +#define APLL_LOCK		0x14000
>  #define APLL_CON0		0x14100
>  #define E4210_MPLL_CON0		0x14108
>  #define SRC_CPU			0x14200
> @@ -121,6 +122,12 @@ enum exynos4_soc {
>  	EXYNOS4X12,
>  };
> 
> +/* list of PLLs to be registered */
> +enum exynos4_plls {
> +	apll, mpll, epll, vpll,
> +	nr_plls			/* number of PLLs */
> +};
> +
>  /*
>   * Let each supported clock get a unique id. This id is used to lookup
> the clock * for device tree based platforms. The clocks are categorized
> into three @@ -988,6 +995,17 @@ static __initdata struct of_device_id
> ext_clk_match[] = { {},
>  };
> 
> +struct __initdata samsung_pll_clock exynos4_plls[nr_plls] = {
> +	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", 
APLL_LOCK,
> +		APLL_CON0, "fout_apll"),
> +	[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll",
> +		E4X12_MPLL_LOCK, E4X12_MPLL_CON0, "fout_mpll"),
> +	[epll] = PLL_A(pll_36xx, fout_epll, "fout_epll", "fin_pll", 
EPLL_LOCK,
> +		EPLL_CON0, "fout_epll"),
> +	[vpll] = PLL_A(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", 
VPLL_LOCK,
> +		VPLL_CON0, "fout_vpll"),
> +};
> +
>  /* register exynos4 clocks */
>  void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc
> exynos4_soc, void __iomem *reg_base, unsigned long xom) {
> @@ -1024,22 +1042,16 @@ void __init exynos4_clk_init(struct device_node
> *np, enum exynos4_soc exynos4_so reg_base + EPLL_CON0, pll_4600);
>  		vpll = samsung_clk_register_pll46xx("fout_vpll", 
"mout_vpllsrc",
>  					reg_base + VPLL_CON0, pll_4650c);
> +
> +		samsung_clk_add_lookup(apll, fout_apll);
> +		samsung_clk_add_lookup(mpll, fout_mpll);
> +		samsung_clk_add_lookup(epll, fout_epll);
> +		samsung_clk_add_lookup(vpll, fout_vpll);
>  	} else {
> -		apll = samsung_clk_register_pll35xx("fout_apll", 
"fin_pll",
> -					reg_base + APLL_CON0);
> -		mpll = samsung_clk_register_pll35xx("fout_mpll", 
"fin_pll",
> -					reg_base + E4X12_MPLL_CON0);
> -		epll = samsung_clk_register_pll36xx("fout_epll", 
"fin_pll",
> -					reg_base + EPLL_CON0);
> -		vpll = samsung_clk_register_pll36xx("fout_vpll", 
"fin_pll",
> -					reg_base + VPLL_CON0);
> +		samsung_clk_register_pll(exynos4_plls,
> +					ARRAY_SIZE(exynos4_plls), 
reg_base);
>  	}
> 
> -	samsung_clk_add_lookup(apll, fout_apll);
> -	samsung_clk_add_lookup(mpll, fout_mpll);
> -	samsung_clk_add_lookup(epll, fout_epll);
> -	samsung_clk_add_lookup(vpll, fout_vpll);
> -
>  	samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks,
>  			ARRAY_SIZE(exynos4_fixed_rate_clks));
>  	samsung_clk_register_mux(exynos4_mux_clks,
> diff --git a/drivers/clk/samsung/clk-exynos5250.c
> b/drivers/clk/samsung/clk-exynos5250.c index 7c68850..dc6a700 100644
> --- a/drivers/clk/samsung/clk-exynos5250.c
> +++ b/drivers/clk/samsung/clk-exynos5250.c
> @@ -17,11 +17,22 @@
>  #include <linux/of_address.h>
> 
>  #include "clk.h"
> -#include "clk-pll.h"
> 
> +#define APLL_LOCK		0x0
> +#define APLL_CON0		0x100
>  #define SRC_CPU			0x200
>  #define DIV_CPU0		0x500
> +#define MPLL_LOCK		0x4000
> +#define MPLL_CON0		0x4100
>  #define SRC_CORE1		0x4204
> +#define CPLL_LOCK		0x10020
> +#define EPLL_LOCK		0x10030
> +#define VPLL_LOCK		0x10040
> +#define GPLL_LOCK		0x10050
> +#define CPLL_CON0		0x10120
> +#define EPLL_CON0		0x10130
> +#define VPLL_CON0		0x10140
> +#define GPLL_CON0		0x10150
>  #define SRC_TOP0		0x10210
>  #define SRC_TOP2		0x10218
>  #define SRC_GSCL		0x10220
> @@ -59,10 +70,18 @@
>  #define GATE_IP_FSYS		0x10944
>  #define GATE_IP_PERIC		0x10950
>  #define GATE_IP_PERIS		0x10960
> +#define BPLL_LOCK		0x20010
> +#define BPLL_CON0		0x20110
>  #define SRC_CDREX		0x20200
>  #define PLL_DIV2_SEL		0x20a24
>  #define GATE_IP_DISP1		0x10928
> 
> +/* list of PLLs to be registered */
> +enum exynos5250_plls {
> +	apll, mpll, bpll, gpll, cpll, epll, vpll,
> +	nr_plls			/* number of PLLs */
> +};
> +
>  /*
>   * Let each supported clock get a unique id. This id is used to lookup
> the clock * for device tree based platforms. The clocks are categorized
> into three @@ -79,7 +98,8 @@ enum exynos5250_clks {
>  	none,
> 
>  	/* core clocks */
> -	fin_pll,
> +	fin_pll, fout_apll, fout_mpll, fout_bpll, fout_gpll, fout_cpll,
> +	fout_epll, fout_vpll,
> 
>  	/* gate for special clocks (sclk) */
>  	sclk_cam_bayer = 128, sclk_cam0, sclk_cam1, sclk_gscl_wa,
> sclk_gscl_wb, @@ -470,11 +490,27 @@ static __initdata struct
> of_device_id ext_clk_match[] = { { },
>  };
> 
> +struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = {
> +	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", 
APLL_LOCK,
> +		APLL_CON0, "fout_apll"),
> +	[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll", 
MPLL_LOCK,
> +		MPLL_CON0, "fout_mpll"),
> +	[bpll] = PLL(pll_35xx, fout_bpll, "fout_bpll", "fin_pll", 
BPLL_LOCK,
> +		BPLL_CON0),
> +	[gpll] = PLL(pll_35xx, fout_gpll, "fout_gpll", "fin_pll", 
GPLL_LOCK,
> +		GPLL_CON0),
> +	[cpll] = PLL(pll_35xx, fout_cpll, "fout_cpll", "fin_pll", 
CPLL_LOCK,
> +		CPLL_CON0),
> +	[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", 
EPLL_LOCK,
> +		EPLL_CON0),
> +	[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", 
VPLL_LOCK,
> +		VPLL_CON0),
> +};
> +
>  /* register exynox5250 clocks */
>  void __init exynos5250_clk_init(struct device_node *np)
>  {
>  	void __iomem *reg_base;
> -	struct clk *apll, *mpll, *epll, *vpll, *bpll, *gpll, *cpll;
> 
>  	if (np) {
>  		reg_base = of_iomap(np, 0);
> @@ -490,22 +526,8 @@ void __init exynos5250_clk_init(struct device_node
> *np) samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks,
> ARRAY_SIZE(exynos5250_fixed_rate_ext_clks),
>  			ext_clk_match);
> -
> -	apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
> -			reg_base + 0x100);
> -	mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
> -			reg_base + 0x4100);
> -	bpll = samsung_clk_register_pll35xx("fout_bpll", "fin_pll",
> -			reg_base + 0x20110);
> -	gpll = samsung_clk_register_pll35xx("fout_gpll", "fin_pll",
> -			reg_base + 0x10150);
> -	cpll = samsung_clk_register_pll35xx("fout_cpll", "fin_pll",
> -			reg_base + 0x10120);
> -	epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
> -			reg_base + 0x10130);
> -	vpll = samsung_clk_register_pll36xx("fout_vpll", "mout_vpllsrc",
> -			reg_base + 0x10140);
> -
> +	samsung_clk_register_pll(exynos5250_plls, 
ARRAY_SIZE(exynos5250_plls),
> +					reg_base);
>  	samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,
>  			ARRAY_SIZE(exynos5250_fixed_rate_clks));
>  	samsung_clk_register_fixed_factor(exynos5250_fixed_factor_clks,
> diff --git a/drivers/clk/samsung/clk-exynos5420.c
> b/drivers/clk/samsung/clk-exynos5420.c index 68a96cb..3ea6b4f 100644
> --- a/drivers/clk/samsung/clk-exynos5420.c
> +++ b/drivers/clk/samsung/clk-exynos5420.c
> @@ -17,13 +17,30 @@
>  #include <linux/of_address.h>
> 
>  #include "clk.h"
> -#include "clk-pll.h"
> 
> +#define APLL_LOCK		0x0
> +#define APLL_CON0		0x100
>  #define SRC_CPU			0x200
>  #define DIV_CPU0		0x500
>  #define DIV_CPU1		0x504
>  #define GATE_BUS_CPU		0x700
>  #define GATE_SCLK_CPU		0x800
> +#define CPLL_LOCK		0x10020
> +#define DPLL_LOCK		0x10030
> +#define EPLL_LOCK		0x10040
> +#define RPLL_LOCK		0x10050
> +#define IPLL_LOCK		0x10060
> +#define SPLL_LOCK		0x10070
> +#define VPLL_LOCK		0x10070
> +#define MPLL_LOCK		0x10090
> +#define CPLL_CON0		0x10120
> +#define DPLL_CON0		0x10128
> +#define EPLL_CON0		0x10130
> +#define RPLL_CON0		0x10140
> +#define IPLL_CON0		0x10150
> +#define SPLL_CON0		0x10160
> +#define VPLL_CON0		0x10170
> +#define MPLL_CON0		0x10180
>  #define SRC_TOP0		0x10200
>  #define SRC_TOP1		0x10204
>  #define SRC_TOP2		0x10208
> @@ -75,15 +92,27 @@
>  #define GATE_TOP_SCLK_MAU	0x1083c
>  #define GATE_TOP_SCLK_FSYS	0x10840
>  #define GATE_TOP_SCLK_PERIC	0x10850
> +#define BPLL_LOCK		0x20010
> +#define BPLL_CON0		0x20110
>  #define SRC_CDREX		0x20200
> +#define KPLL_LOCK		0x28000
> +#define KPLL_CON0		0x28100
>  #define SRC_KFC			0x28200
>  #define DIV_KFC0		0x28500
> 
> +/* list of PLLs */
> +enum exynos5420_plls {
> +	apll, cpll, dpll, epll, rpll, ipll, spll, vpll, mpll,
> +	bpll, kpll,
> +	nr_plls			/* number of PLLs */
> +};
> +
>  enum exynos5420_clks {
>  	none,
> 
>  	/* core clocks */
> -	fin_pll,
> +	fin_pll,  fout_apll, fout_cpll, fout_dpll, fout_epll, fout_rpll,
> +	fout_ipll, fout_spll, fout_vpll, fout_mpll, fout_bpll, fout_kpll,
> 
>  	/* gate for special clocks (sclk) */
>  	sclk_uart0 = 128, sclk_uart1, sclk_uart2, sclk_uart3, sclk_mmc0,
> @@ -698,6 +727,31 @@ struct samsung_gate_clock exynos5420_gate_clks[]
> __initdata = { GATE(smmu_mscl2, "smmu_mscl2", "aclk400_mscl",
> GATE_IP_MSCL, 10, 0, 0), };
> 
> +struct __initdata samsung_pll_clock exynos5420_plls[nr_plls] = {
> +	[apll] = PLL(pll_2550, fout_apll, "fout_apll", "fin_pll", 
APLL_LOCK,
> +		APLL_CON0),
> +	[cpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", 
MPLL_LOCK,
> +		MPLL_CON0),
> +	[dpll] = PLL(pll_2550, fout_dpll, "fout_dpll", "fin_pll", 
DPLL_LOCK,
> +		DPLL_CON0),
> +	[epll] = PLL(pll_2650, fout_epll, "fout_epll", "fin_pll", 
EPLL_LOCK,
> +		EPLL_CON0),
> +	[rpll] = PLL(pll_2650, fout_rpll, "fout_rpll", "fin_pll", 
RPLL_LOCK,
> +		RPLL_CON0),
> +	[ipll] = PLL(pll_2550, fout_ipll, "fout_ipll", "fin_pll", 
IPLL_LOCK,
> +		IPLL_CON0),
> +	[spll] = PLL(pll_2550, fout_spll, "fout_spll", "fin_pll", 
SPLL_LOCK,
> +		SPLL_CON0),
> +	[vpll] = PLL(pll_2550, fout_vpll, "fout_vpll", "fin_pll", 
VPLL_LOCK,
> +		VPLL_CON0),
> +	[mpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", 
MPLL_LOCK,
> +		MPLL_CON0),
> +	[bpll] = PLL(pll_2550, fout_bpll, "fout_bpll", "fin_pll", 
BPLL_LOCK,
> +		BPLL_CON0),
> +	[kpll] = PLL(pll_2550, fout_kpll, "fout_kpll", "fin_pll", 
KPLL_LOCK,
> +		KPLL_CON0),
> +};
> +
>  static __initdata struct of_device_id ext_clk_match[] = {
>  	{ .compatible = "samsung,exynos5420-oscclk", .data = (void *)0, },
>  	{ },
> @@ -707,8 +761,6 @@ static __initdata struct of_device_id
> ext_clk_match[] = { void __init exynos5420_clk_init(struct device_node
> *np)
>  {
>  	void __iomem *reg_base;
> -	struct clk *apll, *bpll, *cpll, *dpll, *epll, *ipll, *kpll, *mpll;
> -	struct clk *rpll, *spll, *vpll;
> 
>  	if (np) {
>  		reg_base = of_iomap(np, 0);
> @@ -724,30 +776,8 @@ void __init exynos5420_clk_init(struct device_node
> *np) samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks,
> ARRAY_SIZE(exynos5420_fixed_rate_ext_clks),
>  			ext_clk_match);
> -
> -	apll = samsung_clk_register_pll35xx("fout_apll", "fin_pll",
> -			reg_base + 0x100);
> -	bpll = samsung_clk_register_pll35xx("fout_bpll", "fin_pll",
> -			reg_base + 0x20110);
> -	cpll = samsung_clk_register_pll35xx("fout_cpll", "fin_pll",
> -			reg_base + 0x10120);
> -	dpll = samsung_clk_register_pll35xx("fout_dpll", "fin_pll",
> -			reg_base + 0x10128);
> -	epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
> -			reg_base + 0x10130);
> -	ipll = samsung_clk_register_pll35xx("fout_ipll", "fin_pll",
> -			reg_base + 0x10150);
> -	kpll = samsung_clk_register_pll35xx("fout_kpll", "fin_pll",
> -			reg_base + 0x28100);
> -	mpll = samsung_clk_register_pll35xx("fout_mpll", "fin_pll",
> -			reg_base + 0x10180);
> -	rpll = samsung_clk_register_pll36xx("fout_rpll", "fin_pll",
> -			reg_base + 0x10140);
> -	spll = samsung_clk_register_pll35xx("fout_spll", "fin_pll",
> -			reg_base + 0x10160);
> -	vpll = samsung_clk_register_pll35xx("fout_vpll", "fin_pll",
> -			reg_base + 0x10170);
> -
> +	samsung_clk_register_pll(exynos5420_plls, 
ARRAY_SIZE(exynos5420_plls),
> +					reg_base);
>  	samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks,
>  			ARRAY_SIZE(exynos5420_fixed_rate_clks));
>  	samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks,
> diff --git a/drivers/clk/samsung/clk-pll.c
> b/drivers/clk/samsung/clk-pll.c index 8224bde..f132353 100644
> --- a/drivers/clk/samsung/clk-pll.c
> +++ b/drivers/clk/samsung/clk-pll.c
> @@ -17,6 +17,7 @@ struct samsung_clk_pll {
>  	struct clk_hw		hw;
>  	void __iomem		*lock_reg;
>  	void __iomem		*con_reg;
> +	enum samsung_pll_type	type;
>  };
> 
>  #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
> @@ -54,41 +55,6 @@ static const struct clk_ops samsung_pll35xx_clk_ops =
> { .recalc_rate = samsung_pll35xx_recalc_rate,
>  };
> 
> -struct clk * __init samsung_clk_register_pll35xx(const char *name,
> -			const char *pname, const void __iomem *con_reg)
> -{
> -	struct samsung_clk_pll *pll;
> -	struct clk *clk;
> -	struct clk_init_data init;
> -
> -	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> -	if (!pll) {
> -		pr_err("%s: could not allocate pll clk %s\n", __func__, 
name);
> -		return NULL;
> -	}
> -
> -	init.name = name;
> -	init.ops = &samsung_pll35xx_clk_ops;
> -	init.flags = CLK_GET_RATE_NOCACHE;
> -	init.parent_names = &pname;
> -	init.num_parents = 1;
> -
> -	pll->hw.init = &init;
> -	pll->con_reg = con_reg;
> -
> -	clk = clk_register(NULL, &pll->hw);
> -	if (IS_ERR(clk)) {
> -		pr_err("%s: failed to register pll clock %s\n", __func__,
> -				name);
> -		kfree(pll);
> -	}
> -
> -	if (clk_register_clkdev(clk, name, NULL))
> -		pr_err("%s: failed to register lookup for %s", __func__, 
name);
> -
> -	return clk;
> -}
> -
>  /*
>   * PLL36xx Clock Type
>   */
> @@ -126,41 +92,6 @@ static const struct clk_ops samsung_pll36xx_clk_ops
> = { .recalc_rate = samsung_pll36xx_recalc_rate,
>  };
> 
> -struct clk * __init samsung_clk_register_pll36xx(const char *name,
> -			const char *pname, const void __iomem *con_reg)
> -{
> -	struct samsung_clk_pll *pll;
> -	struct clk *clk;
> -	struct clk_init_data init;
> -
> -	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> -	if (!pll) {
> -		pr_err("%s: could not allocate pll clk %s\n", __func__, 
name);
> -		return NULL;
> -	}
> -
> -	init.name = name;
> -	init.ops = &samsung_pll36xx_clk_ops;
> -	init.flags = CLK_GET_RATE_NOCACHE;
> -	init.parent_names = &pname;
> -	init.num_parents = 1;
> -
> -	pll->hw.init = &init;
> -	pll->con_reg = con_reg;
> -
> -	clk = clk_register(NULL, &pll->hw);
> -	if (IS_ERR(clk)) {
> -		pr_err("%s: failed to register pll clock %s\n", __func__,
> -				name);
> -		kfree(pll);
> -	}
> -
> -	if (clk_register_clkdev(clk, name, NULL))
> -		pr_err("%s: failed to register lookup for %s", __func__, 
name);
> -
> -	return clk;
> -}
> -
>  /*
>   * PLL45xx Clock Type
>   */
> @@ -411,3 +342,64 @@ struct clk * __init
> samsung_clk_register_pll2550x(const char *name,
> 
>  	return clk;
>  }
> +
> +void __init samsung_clk_register_pll(struct samsung_pll_clock
> *clk_list, +				unsigned int nr_pll, void __iomem 
*base)
> +{
> +	struct samsung_clk_pll *pll;
> +	struct clk *clk;
> +	struct clk_init_data init;
> +	struct samsung_pll_clock *list = clk_list;
> +	int cnt;
> +
> +	for (cnt = 0; cnt < nr_pll; cnt++, list++) {

I'd suggest moving contents of this loop to a function like following?

static int __init _samsung_clk_register_pll(struct samsung_pll_clock *pll,
					    void __iomem *base)

This will make the code less indented and so more readable.

> +		pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> +		if (!pll) {
> +			pr_err("%s: could not allocate pll clk %s\n",
> +				__func__, list->name);
> +			continue;
> +		}
> +
> +		init.name = list->name;
> +		init.flags = list->flags;
> +		init.parent_names = &list->parent_name;
> +		init.num_parents = 1;
> +
> +		switch (list->type) {
> +		/* clk_ops for 35xx and 2550 are similar */
> +		case pll_35xx:
> +		case pll_2550:
> +			init.ops = &samsung_pll35xx_clk_ops;
> +			break;
> +		/* clk_ops for 36xx and 2650 are similar */
> +		case pll_36xx:
> +		case pll_2650:
> +			init.ops = &samsung_pll36xx_clk_ops;
> +			break;
> +		default:
> +			pr_warn("%s: Unknown pll type for pll clk %s\n",
> +				__func__, list->name);
> +		}
> +
> +		pll->hw.init = &init;
> +		pll->type = list->type;
> +		pll->lock_reg = base + list->lock_offset;
> +		pll->con_reg = base + list->con_offset;
> +
> +		clk = clk_register(NULL, &pll->hw);
> +		if (IS_ERR(clk)) {
> +			pr_err("%s: failed to register pll clock %s\n",
> +				__func__, list->name);
> +			kfree(pll);
> +			continue;
> +		}
> +
> +		samsung_clk_add_lookup(clk, list->id);
> +
> +		if (list->alias)
> +			if (clk_register_clkdev(clk, list->alias,
> +				list->dev_name))

What about

		if (!list->alias)
			return;

		ret = clk_register_clkdev(clk, list->alias, list-
>dev_name);
		if (ret)
			pr_err("%s: failed to register lookup for %s",
						__func__, list->name);

> +				pr_err("%s: failed to register lookup for 
%s",
> +					__func__, list->name);
> +	}
> +}
> diff --git a/drivers/clk/samsung/clk-pll.h
> b/drivers/clk/samsung/clk-pll.h index f33786e..1536f27 100644
> --- a/drivers/clk/samsung/clk-pll.h
> +++ b/drivers/clk/samsung/clk-pll.h
> @@ -12,6 +12,13 @@
>  #ifndef __SAMSUNG_CLK_PLL_H
>  #define __SAMSUNG_CLK_PLL_H
> 
> +enum samsung_pll_type {
> +	pll_35xx,
> +	pll_36xx,
> +	pll_2550,
> +	pll_2650,
> +};
> +
>  enum pll45xx_type {
>  	pll_4500,
>  	pll_4502,
> @@ -24,10 +31,6 @@ enum pll46xx_type {
>  	pll_4650c,
>  };
> 
> -extern struct clk * __init samsung_clk_register_pll35xx(const char
> *name, -			const char *pname, const void __iomem 
*con_reg);
> -extern struct clk * __init samsung_clk_register_pll36xx(const char
> *name, -			const char *pname, const void __iomem 
*con_reg);
>  extern struct clk * __init samsung_clk_register_pll45xx(const char
> *name, const char *pname, const void __iomem *con_reg,
>  			enum pll45xx_type type);
> diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
> index e4ad6ea..51f60ca 100644
> --- a/drivers/clk/samsung/clk.h
> +++ b/drivers/clk/samsung/clk.h
> @@ -19,6 +19,7 @@
>  #include <linux/clk-provider.h>
>  #include <linux/of.h>
>  #include <linux/of_address.h>
> +#include "clk-pll.h"
> 
>  /**
>   * struct samsung_clock_alias: information about mux clock
> @@ -258,6 +259,51 @@ struct samsung_clk_reg_dump {
>  	u32	value;
>  };
> 
> +/**
> + * struct samsung_pll_clock: information about pll clock
> + * @id: platform specific id of the clock.
> + * @dev_name: name of the device to which this clock belongs.
> + * @name: name of this pll clock.
> + * @parent_name: name of the parent clock.
> + * @flags: optional flags for basic clock.
> + * @con_offset: offset of the register for configuring the PLL.
> + * @lock_offset: offset of the register for locking the PLL.
> + * @type: Type of PLL to be registered.
> + * @alias: optional clock alias name to be assigned to this clock.
> + */
> +struct samsung_pll_clock {
> +	unsigned int		id;
> +	const char		*dev_name;
> +	const char		*name;
> +	const char		*parent_name;
> +	unsigned long		flags;
> +	const int		con_offset;
> +	const int		lock_offset;

I don't see any point of having all those const qualifiers of non-
pointers. This makes the struct useless for creating and initializing at 
runtime.

> +	enum			samsung_pll_type type;

IMHO the enum keyword shouldn't be separated from enum name like this.

Otherwise the patch looks fine. Maybe it's a bit too big - things could be 
done a bit more gradually, like:
1) first add required structs and functions,
2) then move existing clock drivers to use the new API, possibly one patch 
per driver,
3) remove the old API.

This would make the whole change easier to review and, in case of any 
regressions, easier to track down the problem.

Best regards,
Tomasz

> +	const char              *alias;
> +};
> +
> +#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con,
> _alias) \ +	{								
\
> +		.id		= _id,					\
> +		.type		= _typ,					\
> +		.dev_name	= _dname,				\
> +		.name		= _name,				\
> +		.parent_name	= _pname,				\
> +		.flags		= CLK_GET_RATE_NOCACHE,			\
> +		.con_offset	= _con,					\
> +		.lock_offset	= _lock,				\
> +		.alias		= _alias,				\
> +	}
> +
> +#define PLL(_typ, _id, _name, _pname, _lock, _con)			\
> +	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
> +		_lock, _con, NULL)
> +
> +#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias)		\
> +	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
> +		_lock, _con, _alias)
> +
>  extern void __init samsung_clk_init(struct device_node *np, void
> __iomem *base, unsigned long nr_clks, unsigned long *rdump,
>  		unsigned long nr_rdump, unsigned long *soc_rdump,
> @@ -281,6 +327,8 @@ extern void __init samsung_clk_register_div(struct
> samsung_div_clock *clk_list, unsigned int nr_clk);
>  extern void __init samsung_clk_register_gate(
>  		struct samsung_gate_clock *clk_list, unsigned int nr_clk);
> +extern void __init samsung_clk_register_pll(struct samsung_pll_clock
> *list, +		unsigned int nr_clk, void __iomem *base);
> 
>  extern unsigned long _get_rate(const char *clk_name);

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v6 3/7] clk: samsung: Add support to register rate_table for samsung plls
  2013-06-10 13:24   ` Yadwinder Singh Brar
@ 2013-06-19 17:00     ` Tomasz Figa
  -1 siblings, 0 replies; 34+ messages in thread
From: Tomasz Figa @ 2013-06-19 17:00 UTC (permalink / raw)
  To: Yadwinder Singh Brar
  Cc: linux-samsung-soc, linux-arm-kernel, kgene.kim, mturquette,
	thomas.abraham, dianders, t.figa, vikas.sajjan, abrestic

On Monday 10 of June 2013 18:54:15 Yadwinder Singh Brar wrote:
> This patch defines a common rate_table which will contain recommended p,
> m, s, k values for supported rates that needs to be changed for
> changing corresponding PLL's rate.
> 
> Reviewed-by: Doug Anderson <dianders@chromium.org>
> Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
> ---
>  drivers/clk/samsung/clk-exynos4.c    |    8 ++++----
>  drivers/clk/samsung/clk-exynos5250.c |   14 +++++++-------
>  drivers/clk/samsung/clk-exynos5420.c |   22 +++++++++++-----------
>  drivers/clk/samsung/clk-pll.c        |   22 ++++++++++++++++++++--
>  drivers/clk/samsung/clk-pll.h        |   27 +++++++++++++++++++++++++++
> drivers/clk/samsung/clk.h            |   14 +++++++++-----
>  6 files changed, 78 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-exynos4.c
> b/drivers/clk/samsung/clk-exynos4.c index ba25a1b..ceee66c 100644
> --- a/drivers/clk/samsung/clk-exynos4.c
> +++ b/drivers/clk/samsung/clk-exynos4.c
> @@ -997,13 +997,13 @@ static __initdata struct of_device_id
> ext_clk_match[] = {
> 
>  struct __initdata samsung_pll_clock exynos4_plls[nr_plls] = {
>  	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", 
APLL_LOCK,
> -		APLL_CON0, "fout_apll"),
> +		APLL_CON0, "fout_apll", NULL),
>  	[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll",
> -		E4X12_MPLL_LOCK, E4X12_MPLL_CON0, "fout_mpll"),
> +		E4X12_MPLL_LOCK, E4X12_MPLL_CON0, "fout_mpll", NULL),
>  	[epll] = PLL_A(pll_36xx, fout_epll, "fout_epll", "fin_pll", 
EPLL_LOCK,
> -		EPLL_CON0, "fout_epll"),
> +		EPLL_CON0, "fout_epll", NULL),
>  	[vpll] = PLL_A(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", 
VPLL_LOCK,
> -		VPLL_CON0, "fout_vpll"),
> +		VPLL_CON0, "fout_vpll", NULL),
>  };
> 
>  /* register exynos4 clocks */
> diff --git a/drivers/clk/samsung/clk-exynos5250.c
> b/drivers/clk/samsung/clk-exynos5250.c index dc6a700..21f5491 100644
> --- a/drivers/clk/samsung/clk-exynos5250.c
> +++ b/drivers/clk/samsung/clk-exynos5250.c
> @@ -492,19 +492,19 @@ static __initdata struct of_device_id
> ext_clk_match[] = {
> 
>  struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = {
>  	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", 
APLL_LOCK,
> -		APLL_CON0, "fout_apll"),
> +		APLL_CON0, "fout_apll", NULL),
>  	[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll", 
MPLL_LOCK,
> -		MPLL_CON0, "fout_mpll"),
> +		MPLL_CON0, "fout_mpll", NULL),
>  	[bpll] = PLL(pll_35xx, fout_bpll, "fout_bpll", "fin_pll", 
BPLL_LOCK,
> -		BPLL_CON0),
> +		BPLL_CON0, NULL),
>  	[gpll] = PLL(pll_35xx, fout_gpll, "fout_gpll", "fin_pll", 
GPLL_LOCK,
> -		GPLL_CON0),
> +		GPLL_CON0, NULL),
>  	[cpll] = PLL(pll_35xx, fout_cpll, "fout_cpll", "fin_pll", 
CPLL_LOCK,
> -		CPLL_CON0),
> +		CPLL_CON0, NULL),
>  	[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", 
EPLL_LOCK,
> -		EPLL_CON0),
> +		EPLL_CON0, NULL),
>  	[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", 
VPLL_LOCK,
> -		VPLL_CON0),
> +		VPLL_CON0, NULL),
>  };
> 
>  /* register exynox5250 clocks */
> diff --git a/drivers/clk/samsung/clk-exynos5420.c
> b/drivers/clk/samsung/clk-exynos5420.c index 3ea6b4f..86dfc64 100644
> --- a/drivers/clk/samsung/clk-exynos5420.c
> +++ b/drivers/clk/samsung/clk-exynos5420.c
> @@ -729,27 +729,27 @@ struct samsung_gate_clock exynos5420_gate_clks[]
> __initdata = {
> 
>  struct __initdata samsung_pll_clock exynos5420_plls[nr_plls] = {
>  	[apll] = PLL(pll_2550, fout_apll, "fout_apll", "fin_pll", 
APLL_LOCK,
> -		APLL_CON0),
> +		APLL_CON0, NULL),
>  	[cpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", 
MPLL_LOCK,
> -		MPLL_CON0),
> +		MPLL_CON0, NULL),
>  	[dpll] = PLL(pll_2550, fout_dpll, "fout_dpll", "fin_pll", 
DPLL_LOCK,
> -		DPLL_CON0),
> +		DPLL_CON0, NULL),
>  	[epll] = PLL(pll_2650, fout_epll, "fout_epll", "fin_pll", 
EPLL_LOCK,
> -		EPLL_CON0),
> +		EPLL_CON0, NULL),
>  	[rpll] = PLL(pll_2650, fout_rpll, "fout_rpll", "fin_pll", 
RPLL_LOCK,
> -		RPLL_CON0),
> +		RPLL_CON0, NULL),
>  	[ipll] = PLL(pll_2550, fout_ipll, "fout_ipll", "fin_pll", 
IPLL_LOCK,
> -		IPLL_CON0),
> +		IPLL_CON0, NULL),
>  	[spll] = PLL(pll_2550, fout_spll, "fout_spll", "fin_pll", 
SPLL_LOCK,
> -		SPLL_CON0),
> +		SPLL_CON0, NULL),
>  	[vpll] = PLL(pll_2550, fout_vpll, "fout_vpll", "fin_pll", 
VPLL_LOCK,
> -		VPLL_CON0),
> +		VPLL_CON0, NULL),
>  	[mpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", 
MPLL_LOCK,
> -		MPLL_CON0),
> +		MPLL_CON0, NULL),
>  	[bpll] = PLL(pll_2550, fout_bpll, "fout_bpll", "fin_pll", 
BPLL_LOCK,
> -		BPLL_CON0),
> +		BPLL_CON0, NULL),
>  	[kpll] = PLL(pll_2550, fout_kpll, "fout_kpll", "fin_pll", 
KPLL_LOCK,
> -		KPLL_CON0),
> +		KPLL_CON0, NULL),
>  };
> 
>  static __initdata struct of_device_id ext_clk_match[] = {
> diff --git a/drivers/clk/samsung/clk-pll.c
> b/drivers/clk/samsung/clk-pll.c index f132353..b2088dd 100644
> --- a/drivers/clk/samsung/clk-pll.c
> +++ b/drivers/clk/samsung/clk-pll.c
> @@ -18,6 +18,8 @@ struct samsung_clk_pll {
>  	void __iomem		*lock_reg;
>  	void __iomem		*con_reg;
>  	enum samsung_pll_type	type;
> +	unsigned int		rate_count;
> +	const struct samsung_pll_rate_table *rate_table;
>  };
> 
>  #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
> @@ -350,7 +352,7 @@ void __init samsung_clk_register_pll(struct
> samsung_pll_clock *clk_list, struct clk *clk;
>  	struct clk_init_data init;
>  	struct samsung_pll_clock *list = clk_list;
> -	int cnt;
> +	int cnt, len;
> 
>  	for (cnt = 0; cnt < nr_pll; cnt++, list++) {
>  		pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> @@ -365,6 +367,21 @@ void __init samsung_clk_register_pll(struct
> samsung_pll_clock *clk_list, init.parent_names = &list->parent_name;
>  		init.num_parents = 1;
> 
> +		if (list->rate_table) {
> +			/* find count of rates in rate_table */
> +			for (len = 0; list->rate_table[len].rate != 0; )
> +				len++;
> +
> +			pll->rate_count = len;
> +			pll->rate_table = kmemdup(list->rate_table,
> +					list->rate_count *
> +					sizeof(struct 
samsung_pll_rate_table),
> +					GFP_KERNEL);
> +			WARN(!pll->rate_table,
> +				"%s: could not allocate rate table for 
%s\n",
> +				__func__, list->name);

This warning is not needed, because kmalloc() already prints a warning 
when allocation fails.

> +		}
> +
>  		switch (list->type) {
>  		/* clk_ops for 35xx and 2550 are similar */
>  		case pll_35xx:
> @@ -396,10 +413,11 @@ void __init samsung_clk_register_pll(struct
> samsung_pll_clock *clk_list,
> 
>  		samsung_clk_add_lookup(clk, list->id);
> 
> -		if (list->alias)
> +		if (list->alias) {

What about

		if (!list->alias)
			return;

		ret = clk_register_clkdev(clk, list->alias, list-
>dev_name);
		if (ret)
			pr_err("%s: failed to register lookup for %s",

This will make the code a bit nicer to read.

Otherwise looks good.

Best regards,
Tomasz

>  			if (clk_register_clkdev(clk, list->alias,
>  				list->dev_name))
>  				pr_err("%s: failed to register lookup for 
%s",
>  					__func__, list->name);
> +		}
>  	}
>  }
> diff --git a/drivers/clk/samsung/clk-pll.h
> b/drivers/clk/samsung/clk-pll.h index 1536f27..95ae23d 100644
> --- a/drivers/clk/samsung/clk-pll.h
> +++ b/drivers/clk/samsung/clk-pll.h
> @@ -19,6 +19,33 @@ enum samsung_pll_type {
>  	pll_2650,
>  };
> 
> +#define PLL_35XX_RATE(_rate, _m, _p, _s)			\
> +	{							\
> +		.rate	=	(_rate),				\
> +		.mdiv	=	(_m),				\
> +		.pdiv	=	(_p),				\
> +		.sdiv	=	(_s),				\
> +	}
> +
> +#define PLL_36XX_RATE(_rate, _m, _p, _s, _k)			\
> +	{							\
> +		.rate	=	(_rate),				\
> +		.mdiv	=	(_m),				\
> +		.pdiv	=	(_p),				\
> +		.sdiv	=	(_s),				\
> +		.kdiv	=	(_k),				\
> +	}
> +
> +/* NOTE: Rate table should be kept sorted in descending order. */
> +
> +struct samsung_pll_rate_table {
> +	unsigned int rate;
> +	unsigned int pdiv;
> +	unsigned int mdiv;
> +	unsigned int sdiv;
> +	unsigned int kdiv;
> +};
> +
>  enum pll45xx_type {
>  	pll_4500,
>  	pll_4502,
> diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
> index 51f60ca..3e6501c 100644
> --- a/drivers/clk/samsung/clk.h
> +++ b/drivers/clk/samsung/clk.h
> @@ -280,10 +280,13 @@ struct samsung_pll_clock {
>  	const int		con_offset;
>  	const int		lock_offset;
>  	enum			samsung_pll_type type;
> +	const struct samsung_pll_rate_table *rate_table;
> +	unsigned int		rate_count;
>  	const char              *alias;
>  };
> 
> -#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con,
> _alias) \ +#define __PLL(_typ, _id, _dname, _name, _pname, _flags,
> _lock, _con,	\ +		_rtable, _alias)				
	\
>  	{								\
>  		.id		= _id,					\
>  		.type		= _typ,					\
> @@ -293,16 +296,17 @@ struct samsung_pll_clock {
>  		.flags		= CLK_GET_RATE_NOCACHE,			\
>  		.con_offset	= _con,					\
>  		.lock_offset	= _lock,				\
> +		.rate_table	= _rtable,				\
>  		.alias		= _alias,				\
>  	}
> 
> -#define PLL(_typ, _id, _name, _pname, _lock, _con)			\
> +#define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable)	\
>  	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
> -		_lock, _con, NULL)
> +		_lock, _con, _rtable, _name)
> 
> -#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias)		\
> +#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias, _rtable) \
> __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\ -		
_lock,
> _con, _alias)
> +		_lock, _con, _rtable, _alias)
> 
>  extern void __init samsung_clk_init(struct device_node *np, void
> __iomem *base, unsigned long nr_clks, unsigned long *rdump,

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 3/7] clk: samsung: Add support to register rate_table for samsung plls
@ 2013-06-19 17:00     ` Tomasz Figa
  0 siblings, 0 replies; 34+ messages in thread
From: Tomasz Figa @ 2013-06-19 17:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 10 of June 2013 18:54:15 Yadwinder Singh Brar wrote:
> This patch defines a common rate_table which will contain recommended p,
> m, s, k values for supported rates that needs to be changed for
> changing corresponding PLL's rate.
> 
> Reviewed-by: Doug Anderson <dianders@chromium.org>
> Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
> ---
>  drivers/clk/samsung/clk-exynos4.c    |    8 ++++----
>  drivers/clk/samsung/clk-exynos5250.c |   14 +++++++-------
>  drivers/clk/samsung/clk-exynos5420.c |   22 +++++++++++-----------
>  drivers/clk/samsung/clk-pll.c        |   22 ++++++++++++++++++++--
>  drivers/clk/samsung/clk-pll.h        |   27 +++++++++++++++++++++++++++
> drivers/clk/samsung/clk.h            |   14 +++++++++-----
>  6 files changed, 78 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-exynos4.c
> b/drivers/clk/samsung/clk-exynos4.c index ba25a1b..ceee66c 100644
> --- a/drivers/clk/samsung/clk-exynos4.c
> +++ b/drivers/clk/samsung/clk-exynos4.c
> @@ -997,13 +997,13 @@ static __initdata struct of_device_id
> ext_clk_match[] = {
> 
>  struct __initdata samsung_pll_clock exynos4_plls[nr_plls] = {
>  	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", 
APLL_LOCK,
> -		APLL_CON0, "fout_apll"),
> +		APLL_CON0, "fout_apll", NULL),
>  	[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll",
> -		E4X12_MPLL_LOCK, E4X12_MPLL_CON0, "fout_mpll"),
> +		E4X12_MPLL_LOCK, E4X12_MPLL_CON0, "fout_mpll", NULL),
>  	[epll] = PLL_A(pll_36xx, fout_epll, "fout_epll", "fin_pll", 
EPLL_LOCK,
> -		EPLL_CON0, "fout_epll"),
> +		EPLL_CON0, "fout_epll", NULL),
>  	[vpll] = PLL_A(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", 
VPLL_LOCK,
> -		VPLL_CON0, "fout_vpll"),
> +		VPLL_CON0, "fout_vpll", NULL),
>  };
> 
>  /* register exynos4 clocks */
> diff --git a/drivers/clk/samsung/clk-exynos5250.c
> b/drivers/clk/samsung/clk-exynos5250.c index dc6a700..21f5491 100644
> --- a/drivers/clk/samsung/clk-exynos5250.c
> +++ b/drivers/clk/samsung/clk-exynos5250.c
> @@ -492,19 +492,19 @@ static __initdata struct of_device_id
> ext_clk_match[] = {
> 
>  struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = {
>  	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", 
APLL_LOCK,
> -		APLL_CON0, "fout_apll"),
> +		APLL_CON0, "fout_apll", NULL),
>  	[mpll] = PLL_A(pll_35xx, fout_mpll, "fout_mpll", "fin_pll", 
MPLL_LOCK,
> -		MPLL_CON0, "fout_mpll"),
> +		MPLL_CON0, "fout_mpll", NULL),
>  	[bpll] = PLL(pll_35xx, fout_bpll, "fout_bpll", "fin_pll", 
BPLL_LOCK,
> -		BPLL_CON0),
> +		BPLL_CON0, NULL),
>  	[gpll] = PLL(pll_35xx, fout_gpll, "fout_gpll", "fin_pll", 
GPLL_LOCK,
> -		GPLL_CON0),
> +		GPLL_CON0, NULL),
>  	[cpll] = PLL(pll_35xx, fout_cpll, "fout_cpll", "fin_pll", 
CPLL_LOCK,
> -		CPLL_CON0),
> +		CPLL_CON0, NULL),
>  	[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", 
EPLL_LOCK,
> -		EPLL_CON0),
> +		EPLL_CON0, NULL),
>  	[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", 
VPLL_LOCK,
> -		VPLL_CON0),
> +		VPLL_CON0, NULL),
>  };
> 
>  /* register exynox5250 clocks */
> diff --git a/drivers/clk/samsung/clk-exynos5420.c
> b/drivers/clk/samsung/clk-exynos5420.c index 3ea6b4f..86dfc64 100644
> --- a/drivers/clk/samsung/clk-exynos5420.c
> +++ b/drivers/clk/samsung/clk-exynos5420.c
> @@ -729,27 +729,27 @@ struct samsung_gate_clock exynos5420_gate_clks[]
> __initdata = {
> 
>  struct __initdata samsung_pll_clock exynos5420_plls[nr_plls] = {
>  	[apll] = PLL(pll_2550, fout_apll, "fout_apll", "fin_pll", 
APLL_LOCK,
> -		APLL_CON0),
> +		APLL_CON0, NULL),
>  	[cpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", 
MPLL_LOCK,
> -		MPLL_CON0),
> +		MPLL_CON0, NULL),
>  	[dpll] = PLL(pll_2550, fout_dpll, "fout_dpll", "fin_pll", 
DPLL_LOCK,
> -		DPLL_CON0),
> +		DPLL_CON0, NULL),
>  	[epll] = PLL(pll_2650, fout_epll, "fout_epll", "fin_pll", 
EPLL_LOCK,
> -		EPLL_CON0),
> +		EPLL_CON0, NULL),
>  	[rpll] = PLL(pll_2650, fout_rpll, "fout_rpll", "fin_pll", 
RPLL_LOCK,
> -		RPLL_CON0),
> +		RPLL_CON0, NULL),
>  	[ipll] = PLL(pll_2550, fout_ipll, "fout_ipll", "fin_pll", 
IPLL_LOCK,
> -		IPLL_CON0),
> +		IPLL_CON0, NULL),
>  	[spll] = PLL(pll_2550, fout_spll, "fout_spll", "fin_pll", 
SPLL_LOCK,
> -		SPLL_CON0),
> +		SPLL_CON0, NULL),
>  	[vpll] = PLL(pll_2550, fout_vpll, "fout_vpll", "fin_pll", 
VPLL_LOCK,
> -		VPLL_CON0),
> +		VPLL_CON0, NULL),
>  	[mpll] = PLL(pll_2550, fout_mpll, "fout_mpll", "fin_pll", 
MPLL_LOCK,
> -		MPLL_CON0),
> +		MPLL_CON0, NULL),
>  	[bpll] = PLL(pll_2550, fout_bpll, "fout_bpll", "fin_pll", 
BPLL_LOCK,
> -		BPLL_CON0),
> +		BPLL_CON0, NULL),
>  	[kpll] = PLL(pll_2550, fout_kpll, "fout_kpll", "fin_pll", 
KPLL_LOCK,
> -		KPLL_CON0),
> +		KPLL_CON0, NULL),
>  };
> 
>  static __initdata struct of_device_id ext_clk_match[] = {
> diff --git a/drivers/clk/samsung/clk-pll.c
> b/drivers/clk/samsung/clk-pll.c index f132353..b2088dd 100644
> --- a/drivers/clk/samsung/clk-pll.c
> +++ b/drivers/clk/samsung/clk-pll.c
> @@ -18,6 +18,8 @@ struct samsung_clk_pll {
>  	void __iomem		*lock_reg;
>  	void __iomem		*con_reg;
>  	enum samsung_pll_type	type;
> +	unsigned int		rate_count;
> +	const struct samsung_pll_rate_table *rate_table;
>  };
> 
>  #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
> @@ -350,7 +352,7 @@ void __init samsung_clk_register_pll(struct
> samsung_pll_clock *clk_list, struct clk *clk;
>  	struct clk_init_data init;
>  	struct samsung_pll_clock *list = clk_list;
> -	int cnt;
> +	int cnt, len;
> 
>  	for (cnt = 0; cnt < nr_pll; cnt++, list++) {
>  		pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> @@ -365,6 +367,21 @@ void __init samsung_clk_register_pll(struct
> samsung_pll_clock *clk_list, init.parent_names = &list->parent_name;
>  		init.num_parents = 1;
> 
> +		if (list->rate_table) {
> +			/* find count of rates in rate_table */
> +			for (len = 0; list->rate_table[len].rate != 0; )
> +				len++;
> +
> +			pll->rate_count = len;
> +			pll->rate_table = kmemdup(list->rate_table,
> +					list->rate_count *
> +					sizeof(struct 
samsung_pll_rate_table),
> +					GFP_KERNEL);
> +			WARN(!pll->rate_table,
> +				"%s: could not allocate rate table for 
%s\n",
> +				__func__, list->name);

This warning is not needed, because kmalloc() already prints a warning 
when allocation fails.

> +		}
> +
>  		switch (list->type) {
>  		/* clk_ops for 35xx and 2550 are similar */
>  		case pll_35xx:
> @@ -396,10 +413,11 @@ void __init samsung_clk_register_pll(struct
> samsung_pll_clock *clk_list,
> 
>  		samsung_clk_add_lookup(clk, list->id);
> 
> -		if (list->alias)
> +		if (list->alias) {

What about

		if (!list->alias)
			return;

		ret = clk_register_clkdev(clk, list->alias, list-
>dev_name);
		if (ret)
			pr_err("%s: failed to register lookup for %s",

This will make the code a bit nicer to read.

Otherwise looks good.

Best regards,
Tomasz

>  			if (clk_register_clkdev(clk, list->alias,
>  				list->dev_name))
>  				pr_err("%s: failed to register lookup for 
%s",
>  					__func__, list->name);
> +		}
>  	}
>  }
> diff --git a/drivers/clk/samsung/clk-pll.h
> b/drivers/clk/samsung/clk-pll.h index 1536f27..95ae23d 100644
> --- a/drivers/clk/samsung/clk-pll.h
> +++ b/drivers/clk/samsung/clk-pll.h
> @@ -19,6 +19,33 @@ enum samsung_pll_type {
>  	pll_2650,
>  };
> 
> +#define PLL_35XX_RATE(_rate, _m, _p, _s)			\
> +	{							\
> +		.rate	=	(_rate),				\
> +		.mdiv	=	(_m),				\
> +		.pdiv	=	(_p),				\
> +		.sdiv	=	(_s),				\
> +	}
> +
> +#define PLL_36XX_RATE(_rate, _m, _p, _s, _k)			\
> +	{							\
> +		.rate	=	(_rate),				\
> +		.mdiv	=	(_m),				\
> +		.pdiv	=	(_p),				\
> +		.sdiv	=	(_s),				\
> +		.kdiv	=	(_k),				\
> +	}
> +
> +/* NOTE: Rate table should be kept sorted in descending order. */
> +
> +struct samsung_pll_rate_table {
> +	unsigned int rate;
> +	unsigned int pdiv;
> +	unsigned int mdiv;
> +	unsigned int sdiv;
> +	unsigned int kdiv;
> +};
> +
>  enum pll45xx_type {
>  	pll_4500,
>  	pll_4502,
> diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
> index 51f60ca..3e6501c 100644
> --- a/drivers/clk/samsung/clk.h
> +++ b/drivers/clk/samsung/clk.h
> @@ -280,10 +280,13 @@ struct samsung_pll_clock {
>  	const int		con_offset;
>  	const int		lock_offset;
>  	enum			samsung_pll_type type;
> +	const struct samsung_pll_rate_table *rate_table;
> +	unsigned int		rate_count;
>  	const char              *alias;
>  };
> 
> -#define __PLL(_typ, _id, _dname, _name, _pname, _flags, _lock, _con,
> _alias) \ +#define __PLL(_typ, _id, _dname, _name, _pname, _flags,
> _lock, _con,	\ +		_rtable, _alias)				
	\
>  	{								\
>  		.id		= _id,					\
>  		.type		= _typ,					\
> @@ -293,16 +296,17 @@ struct samsung_pll_clock {
>  		.flags		= CLK_GET_RATE_NOCACHE,			\
>  		.con_offset	= _con,					\
>  		.lock_offset	= _lock,				\
> +		.rate_table	= _rtable,				\
>  		.alias		= _alias,				\
>  	}
> 
> -#define PLL(_typ, _id, _name, _pname, _lock, _con)			\
> +#define PLL(_typ, _id, _name, _pname, _lock, _con, _rtable)	\
>  	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
> -		_lock, _con, NULL)
> +		_lock, _con, _rtable, _name)
> 
> -#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias)		\
> +#define PLL_A(_typ, _id, _name, _pname, _lock, _con, _alias, _rtable) \
> __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\ -		
_lock,
> _con, _alias)
> +		_lock, _con, _rtable, _alias)
> 
>  extern void __init samsung_clk_init(struct device_node *np, void
> __iomem *base, unsigned long nr_clks, unsigned long *rdump,

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v6 4/7] clk: samsung: Add set_rate() clk_ops for PLL35xx
  2013-06-10 13:24   ` Yadwinder Singh Brar
@ 2013-06-19 17:02     ` Tomasz Figa
  -1 siblings, 0 replies; 34+ messages in thread
From: Tomasz Figa @ 2013-06-19 17:02 UTC (permalink / raw)
  To: Yadwinder Singh Brar
  Cc: linux-samsung-soc, linux-arm-kernel, kgene.kim, mturquette,
	thomas.abraham, dianders, t.figa, vikas.sajjan, abrestic

On Monday 10 of June 2013 18:54:16 Yadwinder Singh Brar wrote:
> This patch add set_rate() and round_rate() for PLL35xx
> 
> Reviewed-by: Doug Anderson <dianders@chromium.org>
> Reviewed-by: Tomasz Figa <t.figa@samsung.com>
> Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
> ---
>  drivers/clk/samsung/clk-pll.c |  105
> ++++++++++++++++++++++++++++++++++++++++- 1 files changed, 104
> insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-pll.c
> b/drivers/clk/samsung/clk-pll.c index b2088dd..e3e7f0c 100644
> --- a/drivers/clk/samsung/clk-pll.c
> +++ b/drivers/clk/samsung/clk-pll.c
> @@ -24,16 +24,51 @@ struct samsung_clk_pll {
> 
>  #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
> 
> +static const struct samsung_pll_rate_table *samsung_get_pll_settings(
> +				struct samsung_clk_pll *pll, unsigned long 
rate)
> +{
> +	const struct samsung_pll_rate_table  *rate_table = pll-
>rate_table;
> +	int i;
> +
> +	for (i = 0; i < pll->rate_count; i++) {
> +		if (rate == rate_table[i].rate)
> +			return &rate_table[i];
> +	}
> +
> +	return NULL;
> +}
> +
> +static long samsung_pll_round_rate(struct clk_hw *hw,
> +			unsigned long drate, unsigned long *prate)
> +{
> +	struct samsung_clk_pll *pll = to_clk_pll(hw);
> +	const struct samsung_pll_rate_table *rate_table = pll->rate_table;
> +	int i;
> +
> +	/* Assumming rate_table is in descending order */
> +	for (i = 0; i < pll->rate_count; i++) {
> +		if (drate >= rate_table[i].rate)
> +			return rate_table[i].rate;
> +	}
> +
> +	/* return minimum supported value */
> +	return rate_table[i - 1].rate;
> +}
> +
>  /*
>   * PLL35xx Clock Type
>   */
> +/* Maximum lock time can be 270 * PDIV cycles */
> +#define PLL35XX_LOCK_FACTOR	(270)
> 
>  #define PLL35XX_MDIV_MASK       (0x3FF)
>  #define PLL35XX_PDIV_MASK       (0x3F)
>  #define PLL35XX_SDIV_MASK       (0x7)
> +#define PLL35XX_LOCK_STAT_MASK	(0x1)
>  #define PLL35XX_MDIV_SHIFT      (16)
>  #define PLL35XX_PDIV_SHIFT      (8)
>  #define PLL35XX_SDIV_SHIFT      (0)
> +#define PLL35XX_LOCK_STAT_SHIFT	(29)
> 
>  static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
>  				unsigned long parent_rate)
> @@ -53,8 +88,73 @@ static unsigned long
> samsung_pll35xx_recalc_rate(struct clk_hw *hw, return (unsigned
> long)fvco;
>  }
> 
> +static inline bool samsung_pll35xx_mp_change(
> +		const struct samsung_pll_rate_table *rate, u32 pll_con)
> +{
> +	u32 old_mdiv, old_pdiv;
> +
> +	old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
> +	old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
> +
> +	return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
> +}
> +
> +static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long
> drate, +					unsigned long prate)
> +{
> +	struct samsung_clk_pll *pll = to_clk_pll(hw);
> +	const struct samsung_pll_rate_table *rate;
> +	u32 tmp;
> +
> +	/* Get required rate settings from table */
> +	rate = samsung_get_pll_settings(pll, drate);
> +	if (!rate) {
> +		pr_err("%s: Invalid rate : %lu for pll clk %s\n", 
__func__,
> +			drate, __clk_get_name(hw->clk));
> +		return -EINVAL;
> +	}
> +
> +	tmp = __raw_readl(pll->con_reg);
> +
> +	if (!(samsung_pll35xx_mp_change(rate, tmp))) {
> +		/* If only s change, change just s value only*/
> +		tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
> +		tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
> +		__raw_writel(tmp, pll->con_reg);
> +
> +		return 0;
> +	}
> +
> +	/* Set PLL lock time. */
> +	__raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
> +			pll->lock_reg);
> +
> +	/* Change PLL PMS values */
> +	tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
> +			(PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
> +			(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
> +	tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) |
> +			(rate->pdiv << PLL35XX_PDIV_SHIFT) |
> +			(rate->sdiv << PLL35XX_SDIV_SHIFT);
> +	__raw_writel(tmp, pll->con_reg);
> +
> +	/* wait_lock_time */
> +	do {
> +		cpu_relax();
> +		tmp = __raw_readl(pll->con_reg);
> +	} while (!(tmp & (PLL35XX_LOCK_STAT_MASK
> +				<< PLL35XX_LOCK_STAT_SHIFT)));
> +	return 0;
> +}
> +
>  static const struct clk_ops samsung_pll35xx_clk_ops = {
>  	.recalc_rate = samsung_pll35xx_recalc_rate,
> +	.round_rate = samsung_pll_round_rate,
> +	.set_rate = samsung_pll35xx_set_rate,
> +};
> +
> +static const struct clk_ops samsung_pll35xx_clk_min_ops = {
> +	.recalc_rate = samsung_pll35xx_recalc_rate,
>  };
> 
>  /*
> @@ -386,7 +486,10 @@ void __init samsung_clk_register_pll(struct
> samsung_pll_clock *clk_list, /* clk_ops for 35xx and 2550 are similar
> */
>  		case pll_35xx:
>  		case pll_2550:
> -			init.ops = &samsung_pll35xx_clk_ops;
> +			if (!pll->rate_table)
> +				init.ops = &samsung_pll35xx_clk_min_ops;
> +			else
> +				init.ops = &samsung_pll35xx_clk_ops;
>  			break;
>  		/* clk_ops for 36xx and 2650 are similar */
>  		case pll_36xx:

Looks good.

Reviewed-by: Tomasz Figa <t.figa@samsung.com>

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 4/7] clk: samsung: Add set_rate() clk_ops for PLL35xx
@ 2013-06-19 17:02     ` Tomasz Figa
  0 siblings, 0 replies; 34+ messages in thread
From: Tomasz Figa @ 2013-06-19 17:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 10 of June 2013 18:54:16 Yadwinder Singh Brar wrote:
> This patch add set_rate() and round_rate() for PLL35xx
> 
> Reviewed-by: Doug Anderson <dianders@chromium.org>
> Reviewed-by: Tomasz Figa <t.figa@samsung.com>
> Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
> ---
>  drivers/clk/samsung/clk-pll.c |  105
> ++++++++++++++++++++++++++++++++++++++++- 1 files changed, 104
> insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-pll.c
> b/drivers/clk/samsung/clk-pll.c index b2088dd..e3e7f0c 100644
> --- a/drivers/clk/samsung/clk-pll.c
> +++ b/drivers/clk/samsung/clk-pll.c
> @@ -24,16 +24,51 @@ struct samsung_clk_pll {
> 
>  #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
> 
> +static const struct samsung_pll_rate_table *samsung_get_pll_settings(
> +				struct samsung_clk_pll *pll, unsigned long 
rate)
> +{
> +	const struct samsung_pll_rate_table  *rate_table = pll-
>rate_table;
> +	int i;
> +
> +	for (i = 0; i < pll->rate_count; i++) {
> +		if (rate == rate_table[i].rate)
> +			return &rate_table[i];
> +	}
> +
> +	return NULL;
> +}
> +
> +static long samsung_pll_round_rate(struct clk_hw *hw,
> +			unsigned long drate, unsigned long *prate)
> +{
> +	struct samsung_clk_pll *pll = to_clk_pll(hw);
> +	const struct samsung_pll_rate_table *rate_table = pll->rate_table;
> +	int i;
> +
> +	/* Assumming rate_table is in descending order */
> +	for (i = 0; i < pll->rate_count; i++) {
> +		if (drate >= rate_table[i].rate)
> +			return rate_table[i].rate;
> +	}
> +
> +	/* return minimum supported value */
> +	return rate_table[i - 1].rate;
> +}
> +
>  /*
>   * PLL35xx Clock Type
>   */
> +/* Maximum lock time can be 270 * PDIV cycles */
> +#define PLL35XX_LOCK_FACTOR	(270)
> 
>  #define PLL35XX_MDIV_MASK       (0x3FF)
>  #define PLL35XX_PDIV_MASK       (0x3F)
>  #define PLL35XX_SDIV_MASK       (0x7)
> +#define PLL35XX_LOCK_STAT_MASK	(0x1)
>  #define PLL35XX_MDIV_SHIFT      (16)
>  #define PLL35XX_PDIV_SHIFT      (8)
>  #define PLL35XX_SDIV_SHIFT      (0)
> +#define PLL35XX_LOCK_STAT_SHIFT	(29)
> 
>  static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
>  				unsigned long parent_rate)
> @@ -53,8 +88,73 @@ static unsigned long
> samsung_pll35xx_recalc_rate(struct clk_hw *hw, return (unsigned
> long)fvco;
>  }
> 
> +static inline bool samsung_pll35xx_mp_change(
> +		const struct samsung_pll_rate_table *rate, u32 pll_con)
> +{
> +	u32 old_mdiv, old_pdiv;
> +
> +	old_mdiv = (pll_con >> PLL35XX_MDIV_SHIFT) & PLL35XX_MDIV_MASK;
> +	old_pdiv = (pll_con >> PLL35XX_PDIV_SHIFT) & PLL35XX_PDIV_MASK;
> +
> +	return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv);
> +}
> +
> +static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long
> drate, +					unsigned long prate)
> +{
> +	struct samsung_clk_pll *pll = to_clk_pll(hw);
> +	const struct samsung_pll_rate_table *rate;
> +	u32 tmp;
> +
> +	/* Get required rate settings from table */
> +	rate = samsung_get_pll_settings(pll, drate);
> +	if (!rate) {
> +		pr_err("%s: Invalid rate : %lu for pll clk %s\n", 
__func__,
> +			drate, __clk_get_name(hw->clk));
> +		return -EINVAL;
> +	}
> +
> +	tmp = __raw_readl(pll->con_reg);
> +
> +	if (!(samsung_pll35xx_mp_change(rate, tmp))) {
> +		/* If only s change, change just s value only*/
> +		tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
> +		tmp |= rate->sdiv << PLL35XX_SDIV_SHIFT;
> +		__raw_writel(tmp, pll->con_reg);
> +
> +		return 0;
> +	}
> +
> +	/* Set PLL lock time. */
> +	__raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
> +			pll->lock_reg);
> +
> +	/* Change PLL PMS values */
> +	tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
> +			(PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
> +			(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
> +	tmp |= (rate->mdiv << PLL35XX_MDIV_SHIFT) |
> +			(rate->pdiv << PLL35XX_PDIV_SHIFT) |
> +			(rate->sdiv << PLL35XX_SDIV_SHIFT);
> +	__raw_writel(tmp, pll->con_reg);
> +
> +	/* wait_lock_time */
> +	do {
> +		cpu_relax();
> +		tmp = __raw_readl(pll->con_reg);
> +	} while (!(tmp & (PLL35XX_LOCK_STAT_MASK
> +				<< PLL35XX_LOCK_STAT_SHIFT)));
> +	return 0;
> +}
> +
>  static const struct clk_ops samsung_pll35xx_clk_ops = {
>  	.recalc_rate = samsung_pll35xx_recalc_rate,
> +	.round_rate = samsung_pll_round_rate,
> +	.set_rate = samsung_pll35xx_set_rate,
> +};
> +
> +static const struct clk_ops samsung_pll35xx_clk_min_ops = {
> +	.recalc_rate = samsung_pll35xx_recalc_rate,
>  };
> 
>  /*
> @@ -386,7 +486,10 @@ void __init samsung_clk_register_pll(struct
> samsung_pll_clock *clk_list, /* clk_ops for 35xx and 2550 are similar
> */
>  		case pll_35xx:
>  		case pll_2550:
> -			init.ops = &samsung_pll35xx_clk_ops;
> +			if (!pll->rate_table)
> +				init.ops = &samsung_pll35xx_clk_min_ops;
> +			else
> +				init.ops = &samsung_pll35xx_clk_ops;
>  			break;
>  		/* clk_ops for 36xx and 2650 are similar */
>  		case pll_36xx:

Looks good.

Reviewed-by: Tomasz Figa <t.figa@samsung.com>

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v6 1/7] clk: samsung: Introduce a common samsung_clk_pll struct
  2013-06-10 13:24   ` Yadwinder Singh Brar
@ 2013-06-19 17:03     ` Tomasz Figa
  -1 siblings, 0 replies; 34+ messages in thread
From: Tomasz Figa @ 2013-06-19 17:03 UTC (permalink / raw)
  To: Yadwinder Singh Brar
  Cc: linux-samsung-soc, linux-arm-kernel, kgene.kim, mturquette,
	thomas.abraham, dianders, t.figa, vikas.sajjan, abrestic

On Monday 10 of June 2013 18:54:13 Yadwinder Singh Brar wrote:
> This patch unifies clk strutures used for PLL35xx & PLL36xx and
> adding an extra member lock_reg, so that common code can be factored
> out.
> 
> Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
> ---
>  drivers/clk/samsung/clk-pll.c |   30 ++++++++++++------------------
>  1 files changed, 12 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-pll.c
> b/drivers/clk/samsung/clk-pll.c index 89135f6..8224bde 100644
> --- a/drivers/clk/samsung/clk-pll.c
> +++ b/drivers/clk/samsung/clk-pll.c
> @@ -13,6 +13,14 @@
>  #include "clk.h"
>  #include "clk-pll.h"
> 
> +struct samsung_clk_pll {
> +	struct clk_hw		hw;
> +	void __iomem		*lock_reg;
> +	void __iomem		*con_reg;
> +};
> +
> +#define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
> +
>  /*
>   * PLL35xx Clock Type
>   */
> @@ -24,17 +32,10 @@
>  #define PLL35XX_PDIV_SHIFT      (8)
>  #define PLL35XX_SDIV_SHIFT      (0)
> 
> -struct samsung_clk_pll35xx {
> -	struct clk_hw		hw;
> -	const void __iomem	*con_reg;
> -};
> -
> -#define to_clk_pll35xx(_hw) container_of(_hw, struct
> samsung_clk_pll35xx, hw) -
>  static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
>  				unsigned long parent_rate)
>  {
> -	struct samsung_clk_pll35xx *pll = to_clk_pll35xx(hw);
> +	struct samsung_clk_pll *pll = to_clk_pll(hw);
>  	u32 mdiv, pdiv, sdiv, pll_con;
>  	u64 fvco = parent_rate;
> 
> @@ -56,7 +57,7 @@ static const struct clk_ops samsung_pll35xx_clk_ops =
> { struct clk * __init samsung_clk_register_pll35xx(const char *name,
> const char *pname, const void __iomem *con_reg)
>  {
> -	struct samsung_clk_pll35xx *pll;
> +	struct samsung_clk_pll *pll;
>  	struct clk *clk;
>  	struct clk_init_data init;
> 
> @@ -100,17 +101,10 @@ struct clk * __init
> samsung_clk_register_pll35xx(const char *name, #define
> PLL36XX_PDIV_SHIFT	(8)
>  #define PLL36XX_SDIV_SHIFT	(0)
> 
> -struct samsung_clk_pll36xx {
> -	struct clk_hw		hw;
> -	const void __iomem	*con_reg;
> -};
> -
> -#define to_clk_pll36xx(_hw) container_of(_hw, struct
> samsung_clk_pll36xx, hw) -
>  static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
>  				unsigned long parent_rate)
>  {
> -	struct samsung_clk_pll36xx *pll = to_clk_pll36xx(hw);
> +	struct samsung_clk_pll *pll = to_clk_pll(hw);
>  	u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
>  	u64 fvco = parent_rate;
> 
> @@ -135,7 +129,7 @@ static const struct clk_ops samsung_pll36xx_clk_ops
> = { struct clk * __init samsung_clk_register_pll36xx(const char *name,
> const char *pname, const void __iomem *con_reg)
>  {
> -	struct samsung_clk_pll36xx *pll;
> +	struct samsung_clk_pll *pll;
>  	struct clk *clk;
>  	struct clk_init_data init;

Looks good to me.

Reviewed-by: Tomasz Figa <t.figa@samsung.com>

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 1/7] clk: samsung: Introduce a common samsung_clk_pll struct
@ 2013-06-19 17:03     ` Tomasz Figa
  0 siblings, 0 replies; 34+ messages in thread
From: Tomasz Figa @ 2013-06-19 17:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 10 of June 2013 18:54:13 Yadwinder Singh Brar wrote:
> This patch unifies clk strutures used for PLL35xx & PLL36xx and
> adding an extra member lock_reg, so that common code can be factored
> out.
> 
> Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
> ---
>  drivers/clk/samsung/clk-pll.c |   30 ++++++++++++------------------
>  1 files changed, 12 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-pll.c
> b/drivers/clk/samsung/clk-pll.c index 89135f6..8224bde 100644
> --- a/drivers/clk/samsung/clk-pll.c
> +++ b/drivers/clk/samsung/clk-pll.c
> @@ -13,6 +13,14 @@
>  #include "clk.h"
>  #include "clk-pll.h"
> 
> +struct samsung_clk_pll {
> +	struct clk_hw		hw;
> +	void __iomem		*lock_reg;
> +	void __iomem		*con_reg;
> +};
> +
> +#define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
> +
>  /*
>   * PLL35xx Clock Type
>   */
> @@ -24,17 +32,10 @@
>  #define PLL35XX_PDIV_SHIFT      (8)
>  #define PLL35XX_SDIV_SHIFT      (0)
> 
> -struct samsung_clk_pll35xx {
> -	struct clk_hw		hw;
> -	const void __iomem	*con_reg;
> -};
> -
> -#define to_clk_pll35xx(_hw) container_of(_hw, struct
> samsung_clk_pll35xx, hw) -
>  static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
>  				unsigned long parent_rate)
>  {
> -	struct samsung_clk_pll35xx *pll = to_clk_pll35xx(hw);
> +	struct samsung_clk_pll *pll = to_clk_pll(hw);
>  	u32 mdiv, pdiv, sdiv, pll_con;
>  	u64 fvco = parent_rate;
> 
> @@ -56,7 +57,7 @@ static const struct clk_ops samsung_pll35xx_clk_ops =
> { struct clk * __init samsung_clk_register_pll35xx(const char *name,
> const char *pname, const void __iomem *con_reg)
>  {
> -	struct samsung_clk_pll35xx *pll;
> +	struct samsung_clk_pll *pll;
>  	struct clk *clk;
>  	struct clk_init_data init;
> 
> @@ -100,17 +101,10 @@ struct clk * __init
> samsung_clk_register_pll35xx(const char *name, #define
> PLL36XX_PDIV_SHIFT	(8)
>  #define PLL36XX_SDIV_SHIFT	(0)
> 
> -struct samsung_clk_pll36xx {
> -	struct clk_hw		hw;
> -	const void __iomem	*con_reg;
> -};
> -
> -#define to_clk_pll36xx(_hw) container_of(_hw, struct
> samsung_clk_pll36xx, hw) -
>  static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
>  				unsigned long parent_rate)
>  {
> -	struct samsung_clk_pll36xx *pll = to_clk_pll36xx(hw);
> +	struct samsung_clk_pll *pll = to_clk_pll(hw);
>  	u32 mdiv, pdiv, sdiv, kdiv, pll_con0, pll_con1;
>  	u64 fvco = parent_rate;
> 
> @@ -135,7 +129,7 @@ static const struct clk_ops samsung_pll36xx_clk_ops
> = { struct clk * __init samsung_clk_register_pll36xx(const char *name,
> const char *pname, const void __iomem *con_reg)
>  {
> -	struct samsung_clk_pll36xx *pll;
> +	struct samsung_clk_pll *pll;
>  	struct clk *clk;
>  	struct clk_init_data init;

Looks good to me.

Reviewed-by: Tomasz Figa <t.figa@samsung.com>

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v6 5/7] clk: samsung: Add set_rate() clk_ops for PLL36xx
  2013-06-10 13:24   ` Yadwinder Singh Brar
@ 2013-06-19 17:05     ` Tomasz Figa
  -1 siblings, 0 replies; 34+ messages in thread
From: Tomasz Figa @ 2013-06-19 17:05 UTC (permalink / raw)
  To: Yadwinder Singh Brar
  Cc: linux-samsung-soc, linux-arm-kernel, kgene.kim, mturquette,
	thomas.abraham, dianders, t.figa, vikas.sajjan, abrestic

On Monday 10 of June 2013 18:54:17 Yadwinder Singh Brar wrote:
> From: Vikas Sajjan <vikas.sajjan@linaro.org>
> 
> This patch adds set_rate and round_rate clk_ops for PLL36xx
> 
> Reviewed-by: Tomasz Figa <t.figa@samsung.com>
> Reviewed-by: Doug Anderson <dianders@chromium.org>
> Signed-off-by: Vikas Sajjan <vikas.sajjan@linaro.org>
> ---
>  drivers/clk/samsung/clk-pll.c |   79
> ++++++++++++++++++++++++++++++++++++++++- 1 files changed, 78
> insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-pll.c
> b/drivers/clk/samsung/clk-pll.c index e3e7f0c..2197004 100644
> --- a/drivers/clk/samsung/clk-pll.c
> +++ b/drivers/clk/samsung/clk-pll.c
> @@ -160,6 +160,8 @@ static const struct clk_ops
> samsung_pll35xx_clk_min_ops = { /*
>   * PLL36xx Clock Type
>   */
> +/* Maximum lock time can be 3000 * PDIV cycles */
> +#define PLL36XX_LOCK_FACTOR    (3000)
> 
>  #define PLL36XX_KDIV_MASK	(0xFFFF)
>  #define PLL36XX_MDIV_MASK	(0x1FF)
> @@ -168,6 +170,8 @@ static const struct clk_ops
> samsung_pll35xx_clk_min_ops = { #define PLL36XX_MDIV_SHIFT	(16)
>  #define PLL36XX_PDIV_SHIFT	(8)
>  #define PLL36XX_SDIV_SHIFT	(0)
> +#define PLL36XX_KDIV_SHIFT	(0)
> +#define PLL36XX_LOCK_STAT_SHIFT	(29)
> 
>  static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
>  				unsigned long parent_rate)
> @@ -190,8 +194,78 @@ static unsigned long
> samsung_pll36xx_recalc_rate(struct clk_hw *hw, return (unsigned
> long)fvco;
>  }
> 
> +static inline bool samsung_pll36xx_mpk_change(
> +	const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 
pll_con1)
> +{
> +	u32 old_mdiv, old_pdiv, old_kdiv;
> +
> +	old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
> +	old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
> +	old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
> +
> +	return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
> +		rate->kdiv != old_kdiv);
> +}
> +
> +static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long
> drate, +					unsigned long parent_rate)
> +{
> +	struct samsung_clk_pll *pll = to_clk_pll(hw);
> +	u32 tmp, pll_con0, pll_con1;
> +	const struct samsung_pll_rate_table *rate;
> +
> +	rate = samsung_get_pll_settings(pll, drate);
> +	if (!rate) {
> +		pr_err("%s: Invalid rate : %lu for pll clk %s\n", 
__func__,
> +			drate, __clk_get_name(hw->clk));
> +		return -EINVAL;
> +	}
> +
> +	pll_con0 = __raw_readl(pll->con_reg);
> +	pll_con1 = __raw_readl(pll->con_reg + 4);

Please define offset constants for these two registers.

Otherwise looks good.

Best regards,
Tomasz

> +
> +	if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
> +		/* If only s change, change just s value only*/
> +		pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
> +		pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
> +		__raw_writel(pll_con0, pll->con_reg);
> +
> +		return 0;
> +	}
> +
> +	/* Set PLL lock time. */
> +	__raw_writel(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
> +
> +	 /* Change PLL PMS values */
> +	pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
> +			(PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
> +			(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
> +	pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
> +			(rate->pdiv << PLL36XX_PDIV_SHIFT) |
> +			(rate->sdiv << PLL36XX_SDIV_SHIFT);
> +	__raw_writel(pll_con0, pll->con_reg);
> +
> +	pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
> +	pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
> +	__raw_writel(pll_con1, pll->con_reg + 4);
> +
> +	/* wait_lock_time */
> +	do {
> +		cpu_relax();
> +		tmp = __raw_readl(pll->con_reg);
> +	} while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT)));
> +
> +	return 0;
> +}
> +
>  static const struct clk_ops samsung_pll36xx_clk_ops = {
>  	.recalc_rate = samsung_pll36xx_recalc_rate,
> +	.set_rate = samsung_pll36xx_set_rate,
> +	.round_rate = samsung_pll_round_rate,
> +};
> +
> +static const struct clk_ops samsung_pll36xx_clk_min_ops = {
> +	.recalc_rate = samsung_pll36xx_recalc_rate,
>  };
> 
>  /*
> @@ -494,7 +568,10 @@ void __init samsung_clk_register_pll(struct
> samsung_pll_clock *clk_list, /* clk_ops for 36xx and 2650 are similar
> */
>  		case pll_36xx:
>  		case pll_2650:
> -			init.ops = &samsung_pll36xx_clk_ops;
> +			if (!pll->rate_table)
> +				init.ops = &samsung_pll36xx_clk_min_ops;
> +			else
> +				init.ops = &samsung_pll36xx_clk_ops;
>  			break;
>  		default:
>  			pr_warn("%s: Unknown pll type for pll clk %s\n",

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 5/7] clk: samsung: Add set_rate() clk_ops for PLL36xx
@ 2013-06-19 17:05     ` Tomasz Figa
  0 siblings, 0 replies; 34+ messages in thread
From: Tomasz Figa @ 2013-06-19 17:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 10 of June 2013 18:54:17 Yadwinder Singh Brar wrote:
> From: Vikas Sajjan <vikas.sajjan@linaro.org>
> 
> This patch adds set_rate and round_rate clk_ops for PLL36xx
> 
> Reviewed-by: Tomasz Figa <t.figa@samsung.com>
> Reviewed-by: Doug Anderson <dianders@chromium.org>
> Signed-off-by: Vikas Sajjan <vikas.sajjan@linaro.org>
> ---
>  drivers/clk/samsung/clk-pll.c |   79
> ++++++++++++++++++++++++++++++++++++++++- 1 files changed, 78
> insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-pll.c
> b/drivers/clk/samsung/clk-pll.c index e3e7f0c..2197004 100644
> --- a/drivers/clk/samsung/clk-pll.c
> +++ b/drivers/clk/samsung/clk-pll.c
> @@ -160,6 +160,8 @@ static const struct clk_ops
> samsung_pll35xx_clk_min_ops = { /*
>   * PLL36xx Clock Type
>   */
> +/* Maximum lock time can be 3000 * PDIV cycles */
> +#define PLL36XX_LOCK_FACTOR    (3000)
> 
>  #define PLL36XX_KDIV_MASK	(0xFFFF)
>  #define PLL36XX_MDIV_MASK	(0x1FF)
> @@ -168,6 +170,8 @@ static const struct clk_ops
> samsung_pll35xx_clk_min_ops = { #define PLL36XX_MDIV_SHIFT	(16)
>  #define PLL36XX_PDIV_SHIFT	(8)
>  #define PLL36XX_SDIV_SHIFT	(0)
> +#define PLL36XX_KDIV_SHIFT	(0)
> +#define PLL36XX_LOCK_STAT_SHIFT	(29)
> 
>  static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
>  				unsigned long parent_rate)
> @@ -190,8 +194,78 @@ static unsigned long
> samsung_pll36xx_recalc_rate(struct clk_hw *hw, return (unsigned
> long)fvco;
>  }
> 
> +static inline bool samsung_pll36xx_mpk_change(
> +	const struct samsung_pll_rate_table *rate, u32 pll_con0, u32 
pll_con1)
> +{
> +	u32 old_mdiv, old_pdiv, old_kdiv;
> +
> +	old_mdiv = (pll_con0 >> PLL36XX_MDIV_SHIFT) & PLL36XX_MDIV_MASK;
> +	old_pdiv = (pll_con0 >> PLL36XX_PDIV_SHIFT) & PLL36XX_PDIV_MASK;
> +	old_kdiv = (pll_con1 >> PLL36XX_KDIV_SHIFT) & PLL36XX_KDIV_MASK;
> +
> +	return (rate->mdiv != old_mdiv || rate->pdiv != old_pdiv ||
> +		rate->kdiv != old_kdiv);
> +}
> +
> +static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long
> drate, +					unsigned long parent_rate)
> +{
> +	struct samsung_clk_pll *pll = to_clk_pll(hw);
> +	u32 tmp, pll_con0, pll_con1;
> +	const struct samsung_pll_rate_table *rate;
> +
> +	rate = samsung_get_pll_settings(pll, drate);
> +	if (!rate) {
> +		pr_err("%s: Invalid rate : %lu for pll clk %s\n", 
__func__,
> +			drate, __clk_get_name(hw->clk));
> +		return -EINVAL;
> +	}
> +
> +	pll_con0 = __raw_readl(pll->con_reg);
> +	pll_con1 = __raw_readl(pll->con_reg + 4);

Please define offset constants for these two registers.

Otherwise looks good.

Best regards,
Tomasz

> +
> +	if (!(samsung_pll36xx_mpk_change(rate, pll_con0, pll_con1))) {
> +		/* If only s change, change just s value only*/
> +		pll_con0 &= ~(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT);
> +		pll_con0 |= (rate->sdiv << PLL36XX_SDIV_SHIFT);
> +		__raw_writel(pll_con0, pll->con_reg);
> +
> +		return 0;
> +	}
> +
> +	/* Set PLL lock time. */
> +	__raw_writel(rate->pdiv * PLL36XX_LOCK_FACTOR, pll->lock_reg);
> +
> +	 /* Change PLL PMS values */
> +	pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) |
> +			(PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) |
> +			(PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT));
> +	pll_con0 |= (rate->mdiv << PLL36XX_MDIV_SHIFT) |
> +			(rate->pdiv << PLL36XX_PDIV_SHIFT) |
> +			(rate->sdiv << PLL36XX_SDIV_SHIFT);
> +	__raw_writel(pll_con0, pll->con_reg);
> +
> +	pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
> +	pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
> +	__raw_writel(pll_con1, pll->con_reg + 4);
> +
> +	/* wait_lock_time */
> +	do {
> +		cpu_relax();
> +		tmp = __raw_readl(pll->con_reg);
> +	} while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT)));
> +
> +	return 0;
> +}
> +
>  static const struct clk_ops samsung_pll36xx_clk_ops = {
>  	.recalc_rate = samsung_pll36xx_recalc_rate,
> +	.set_rate = samsung_pll36xx_set_rate,
> +	.round_rate = samsung_pll_round_rate,
> +};
> +
> +static const struct clk_ops samsung_pll36xx_clk_min_ops = {
> +	.recalc_rate = samsung_pll36xx_recalc_rate,
>  };
> 
>  /*
> @@ -494,7 +568,10 @@ void __init samsung_clk_register_pll(struct
> samsung_pll_clock *clk_list, /* clk_ops for 36xx and 2650 are similar
> */
>  		case pll_36xx:
>  		case pll_2650:
> -			init.ops = &samsung_pll36xx_clk_ops;
> +			if (!pll->rate_table)
> +				init.ops = &samsung_pll36xx_clk_min_ops;
> +			else
> +				init.ops = &samsung_pll36xx_clk_ops;
>  			break;
>  		default:
>  			pr_warn("%s: Unknown pll type for pll clk %s\n",

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v6 6/7] clk: samsung: Reorder MUX registration for mout_vpllsrc
  2013-06-10 13:24   ` Yadwinder Singh Brar
@ 2013-06-19 17:05     ` Tomasz Figa
  -1 siblings, 0 replies; 34+ messages in thread
From: Tomasz Figa @ 2013-06-19 17:05 UTC (permalink / raw)
  To: Yadwinder Singh Brar
  Cc: linux-samsung-soc, linux-arm-kernel, kgene.kim, mturquette,
	thomas.abraham, dianders, t.figa, vikas.sajjan, abrestic

On Monday 10 of June 2013 18:54:18 Yadwinder Singh Brar wrote:
> From: Vikas Sajjan <vikas.sajjan@linaro.org>
> 
> While trying to get rate of "mout_vpllsrc" MUX (parent) for registering
> the "fout_vpll" (child), we found get rate was failing.
> 
> So this patch moves the mout_vpllsrc MUX out of the existing common list
> and registers the mout_vpllsrc MUX before the PLL registrations.
> 
> Reviewed-by: Tomasz Figa <t.figa@samsung.com>
> Signed-off-by: Vikas Sajjan <vikas.sajjan@linaro.org>
> Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
> ---
>  drivers/clk/samsung/clk-exynos5250.c |    7 ++++++-
>  1 files changed, 6 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-exynos5250.c
> b/drivers/clk/samsung/clk-exynos5250.c index 21f5491..6881810 100644
> --- a/drivers/clk/samsung/clk-exynos5250.c
> +++ b/drivers/clk/samsung/clk-exynos5250.c
> @@ -228,6 +228,10 @@ struct samsung_fixed_factor_clock
> exynos5250_fixed_factor_clks[] __initdata = { FFACTOR(none,
> "fout_bplldiv2", "fout_bpll", 1, 2, 0),
>  };
> 
> +struct samsung_mux_clock exynos5250_pll_pmux_clks[] __initdata = {
> +	MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1),
> +};
> +
>  struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
>  	MUX(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1),
>  	MUX(none, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1),
> @@ -235,7 +239,6 @@ struct samsung_mux_clock exynos5250_mux_clks[]
> __initdata = { MUX(none, "sclk_mpll", mout_mpll_p, SRC_CORE1, 8, 1),
>  	MUX(none, "mout_bpll_fout", mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1),
>  	MUX(none, "sclk_bpll", mout_bpll_p, SRC_CDREX, 0, 1),
> -	MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1),
>  	MUX(none, "sclk_vpll", mout_vpll_p, SRC_TOP2, 16, 1),
>  	MUX(none, "sclk_epll", mout_epll_p, SRC_TOP2, 12, 1),
>  	MUX(none, "sclk_cpll", mout_cpll_p, SRC_TOP2, 8, 1),
> @@ -526,6 +529,8 @@ void __init exynos5250_clk_init(struct device_node
> *np) samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks,
> ARRAY_SIZE(exynos5250_fixed_rate_ext_clks),
>  			ext_clk_match);
> +	samsung_clk_register_mux(exynos5250_pll_pmux_clks,
> +				ARRAY_SIZE(exynos5250_pll_pmux_clks));
>  	samsung_clk_register_pll(exynos5250_plls, 
ARRAY_SIZE(exynos5250_plls),
> reg_base);
>  	samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,

Reviewed-by: Tomasz Figa <t.figa@samsung.com>

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 6/7] clk: samsung: Reorder MUX registration for mout_vpllsrc
@ 2013-06-19 17:05     ` Tomasz Figa
  0 siblings, 0 replies; 34+ messages in thread
From: Tomasz Figa @ 2013-06-19 17:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 10 of June 2013 18:54:18 Yadwinder Singh Brar wrote:
> From: Vikas Sajjan <vikas.sajjan@linaro.org>
> 
> While trying to get rate of "mout_vpllsrc" MUX (parent) for registering
> the "fout_vpll" (child), we found get rate was failing.
> 
> So this patch moves the mout_vpllsrc MUX out of the existing common list
> and registers the mout_vpllsrc MUX before the PLL registrations.
> 
> Reviewed-by: Tomasz Figa <t.figa@samsung.com>
> Signed-off-by: Vikas Sajjan <vikas.sajjan@linaro.org>
> Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
> ---
>  drivers/clk/samsung/clk-exynos5250.c |    7 ++++++-
>  1 files changed, 6 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-exynos5250.c
> b/drivers/clk/samsung/clk-exynos5250.c index 21f5491..6881810 100644
> --- a/drivers/clk/samsung/clk-exynos5250.c
> +++ b/drivers/clk/samsung/clk-exynos5250.c
> @@ -228,6 +228,10 @@ struct samsung_fixed_factor_clock
> exynos5250_fixed_factor_clks[] __initdata = { FFACTOR(none,
> "fout_bplldiv2", "fout_bpll", 1, 2, 0),
>  };
> 
> +struct samsung_mux_clock exynos5250_pll_pmux_clks[] __initdata = {
> +	MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1),
> +};
> +
>  struct samsung_mux_clock exynos5250_mux_clks[] __initdata = {
>  	MUX(none, "mout_apll", mout_apll_p, SRC_CPU, 0, 1),
>  	MUX(none, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1),
> @@ -235,7 +239,6 @@ struct samsung_mux_clock exynos5250_mux_clks[]
> __initdata = { MUX(none, "sclk_mpll", mout_mpll_p, SRC_CORE1, 8, 1),
>  	MUX(none, "mout_bpll_fout", mout_bpll_fout_p, PLL_DIV2_SEL, 0, 1),
>  	MUX(none, "sclk_bpll", mout_bpll_p, SRC_CDREX, 0, 1),
> -	MUX(none, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP2, 0, 1),
>  	MUX(none, "sclk_vpll", mout_vpll_p, SRC_TOP2, 16, 1),
>  	MUX(none, "sclk_epll", mout_epll_p, SRC_TOP2, 12, 1),
>  	MUX(none, "sclk_cpll", mout_cpll_p, SRC_TOP2, 8, 1),
> @@ -526,6 +529,8 @@ void __init exynos5250_clk_init(struct device_node
> *np) samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks,
> ARRAY_SIZE(exynos5250_fixed_rate_ext_clks),
>  			ext_clk_match);
> +	samsung_clk_register_mux(exynos5250_pll_pmux_clks,
> +				ARRAY_SIZE(exynos5250_pll_pmux_clks));
>  	samsung_clk_register_pll(exynos5250_plls, 
ARRAY_SIZE(exynos5250_plls),
> reg_base);
>  	samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,

Reviewed-by: Tomasz Figa <t.figa@samsung.com>

Best regards,
Tomasz

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v6 7/7] clk: samsung: Add EPLL and VPLL freq table for exynos5250 SoC
  2013-06-10 13:24   ` Yadwinder Singh Brar
@ 2013-06-19 17:13     ` Tomasz Figa
  -1 siblings, 0 replies; 34+ messages in thread
From: Tomasz Figa @ 2013-06-19 17:13 UTC (permalink / raw)
  To: Yadwinder Singh Brar
  Cc: kgene.kim, mturquette, abrestic, t.figa, dianders,
	linux-samsung-soc, thomas.abraham, vikas.sajjan,
	linux-arm-kernel

On Monday 10 of June 2013 18:54:19 Yadwinder Singh Brar wrote:
> Adds the EPLL and VPLL freq table for exynos5250 SoC.
> 
> Signed-off-by: Vikas Sajjan <vikas.sajjan@linaro.org>
> Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
> ---
>  drivers/clk/samsung/clk-exynos5250.c |   42
> ++++++++++++++++++++++++++++++++- drivers/clk/samsung/clk.h           
> |    2 +
>  2 files changed, 42 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-exynos5250.c
> b/drivers/clk/samsung/clk-exynos5250.c index 6881810..13e293e 100644
> --- a/drivers/clk/samsung/clk-exynos5250.c
> +++ b/drivers/clk/samsung/clk-exynos5250.c
> @@ -493,6 +493,29 @@ static __initdata struct of_device_id
> ext_clk_match[] = { { },
>  };
> 
> +static __initdata struct samsung_pll_rate_table vpll_24mhz_tbl[] = {
> +	/* sorted in descending order */
> +	/* PLL_36XX_RATE(rate, m, p, s, k) */
> +	PLL_36XX_RATE(266000000, 266, 3, 3, 0),
> +	/* Not in UM, but need for eDP on snow */
> +	PLL_36XX_RATE(70500000, 94, 2, 4, 0),
> +	{ },
> +};
> +
> +static __initdata struct samsung_pll_rate_table epll_24mhz_tbl[] = {
> +	/* sorted in descending order */
> +	/* PLL_36XX_RATE(rate, m, p, s, k) */
> +	PLL_36XX_RATE(192000000, 64, 2, 2, 0),
> +	PLL_36XX_RATE(180633600, 90, 3, 2, 20762),
> +	PLL_36XX_RATE(180000000, 90, 3, 2, 0),
> +	PLL_36XX_RATE(73728000, 98, 2, 4, 19923),
> +	PLL_36XX_RATE(67737600, 90, 2, 4, 20762),
> +	PLL_36XX_RATE(49152000, 98, 3, 4, 19923),
> +	PLL_36XX_RATE(45158400, 90, 3, 4, 20762),
> +	PLL_36XX_RATE(32768000, 131, 3, 5, 4719)
> +	{ },
> +};
> +
>  struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = {
>  	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", 
APLL_LOCK,
> APLL_CON0, "fout_apll", NULL),
> @@ -506,14 +529,16 @@ struct __initdata samsung_pll_clock
> exynos5250_plls[nr_plls] = { CPLL_CON0, NULL),
>  	[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", 
EPLL_LOCK,
>  		EPLL_CON0, NULL),
> -	[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", 
VPLL_LOCK,
> -		VPLL_CON0, NULL),
> +	[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "mout_vpllsrc",
> +		VPLL_LOCK, VPLL_CON0, NULL),

IMHO the parent should be fixed in separate patch, as this doesn't seem to 
be related strictly to adding rate table.

>  };
> 
>  /* register exynox5250 clocks */
>  void __init exynos5250_clk_init(struct device_node *np)
>  {
>  	void __iomem *reg_base;
> +	struct clk *vpllsrc;
> +	unsigned long fin_pll_rate, mout_vpllsrc_rate = 0;
> 
>  	if (np) {
>  		reg_base = of_iomap(np, 0);
> @@ -531,6 +556,19 @@ void __init exynos5250_clk_init(struct device_node
> *np) ext_clk_match);
>  	samsung_clk_register_mux(exynos5250_pll_pmux_clks,
>  				ARRAY_SIZE(exynos5250_pll_pmux_clks));
> +
> +	fin_pll_rate = _get_rate("fin_pll");
> +
> +	if (fin_pll_rate == (24 * MHZ))

Nit: Unnecessary parentheses around 24 * MHZ.

> +		exynos5250_plls[epll].rate_table = epll_24mhz_tbl;
> +
> +	vpllsrc = __clk_lookup("mout_vpllsrc");
> +	if (vpllsrc)
> +		mout_vpllsrc_rate = clk_get_rate(vpllsrc);
> +
> +	if (mout_vpllsrc_rate == (24 * MHZ))

Ditto.

> +		exynos5250_plls[vpll].rate_table =  vpll_24mhz_tbl;
> +
>  	samsung_clk_register_pll(exynos5250_plls, 
ARRAY_SIZE(exynos5250_plls),
> reg_base);
>  	samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,
> diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
> index 3e6501c..378bf98 100644
> --- a/drivers/clk/samsung/clk.h
> +++ b/drivers/clk/samsung/clk.h
> @@ -40,6 +40,8 @@ struct samsung_clock_alias {
>  		.alias		= a,				\
>  	}
> 
> +#define MHZ (1000*1000)

Nit: (1000 * 1000)

Best regards,
Tomasz

> +
>  /**
>   * struct samsung_fixed_rate_clock: information about fixed-rate clock
>   * @id: platform specific id of the clock.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 7/7] clk: samsung: Add EPLL and VPLL freq table for exynos5250 SoC
@ 2013-06-19 17:13     ` Tomasz Figa
  0 siblings, 0 replies; 34+ messages in thread
From: Tomasz Figa @ 2013-06-19 17:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 10 of June 2013 18:54:19 Yadwinder Singh Brar wrote:
> Adds the EPLL and VPLL freq table for exynos5250 SoC.
> 
> Signed-off-by: Vikas Sajjan <vikas.sajjan@linaro.org>
> Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
> ---
>  drivers/clk/samsung/clk-exynos5250.c |   42
> ++++++++++++++++++++++++++++++++- drivers/clk/samsung/clk.h           
> |    2 +
>  2 files changed, 42 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/clk/samsung/clk-exynos5250.c
> b/drivers/clk/samsung/clk-exynos5250.c index 6881810..13e293e 100644
> --- a/drivers/clk/samsung/clk-exynos5250.c
> +++ b/drivers/clk/samsung/clk-exynos5250.c
> @@ -493,6 +493,29 @@ static __initdata struct of_device_id
> ext_clk_match[] = { { },
>  };
> 
> +static __initdata struct samsung_pll_rate_table vpll_24mhz_tbl[] = {
> +	/* sorted in descending order */
> +	/* PLL_36XX_RATE(rate, m, p, s, k) */
> +	PLL_36XX_RATE(266000000, 266, 3, 3, 0),
> +	/* Not in UM, but need for eDP on snow */
> +	PLL_36XX_RATE(70500000, 94, 2, 4, 0),
> +	{ },
> +};
> +
> +static __initdata struct samsung_pll_rate_table epll_24mhz_tbl[] = {
> +	/* sorted in descending order */
> +	/* PLL_36XX_RATE(rate, m, p, s, k) */
> +	PLL_36XX_RATE(192000000, 64, 2, 2, 0),
> +	PLL_36XX_RATE(180633600, 90, 3, 2, 20762),
> +	PLL_36XX_RATE(180000000, 90, 3, 2, 0),
> +	PLL_36XX_RATE(73728000, 98, 2, 4, 19923),
> +	PLL_36XX_RATE(67737600, 90, 2, 4, 20762),
> +	PLL_36XX_RATE(49152000, 98, 3, 4, 19923),
> +	PLL_36XX_RATE(45158400, 90, 3, 4, 20762),
> +	PLL_36XX_RATE(32768000, 131, 3, 5, 4719)
> +	{ },
> +};
> +
>  struct __initdata samsung_pll_clock exynos5250_plls[nr_plls] = {
>  	[apll] = PLL_A(pll_35xx, fout_apll, "fout_apll", "fin_pll", 
APLL_LOCK,
> APLL_CON0, "fout_apll", NULL),
> @@ -506,14 +529,16 @@ struct __initdata samsung_pll_clock
> exynos5250_plls[nr_plls] = { CPLL_CON0, NULL),
>  	[epll] = PLL(pll_36xx, fout_epll, "fout_epll", "fin_pll", 
EPLL_LOCK,
>  		EPLL_CON0, NULL),
> -	[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "fin_pll", 
VPLL_LOCK,
> -		VPLL_CON0, NULL),
> +	[vpll] = PLL(pll_36xx, fout_vpll, "fout_vpll", "mout_vpllsrc",
> +		VPLL_LOCK, VPLL_CON0, NULL),

IMHO the parent should be fixed in separate patch, as this doesn't seem to 
be related strictly to adding rate table.

>  };
> 
>  /* register exynox5250 clocks */
>  void __init exynos5250_clk_init(struct device_node *np)
>  {
>  	void __iomem *reg_base;
> +	struct clk *vpllsrc;
> +	unsigned long fin_pll_rate, mout_vpllsrc_rate = 0;
> 
>  	if (np) {
>  		reg_base = of_iomap(np, 0);
> @@ -531,6 +556,19 @@ void __init exynos5250_clk_init(struct device_node
> *np) ext_clk_match);
>  	samsung_clk_register_mux(exynos5250_pll_pmux_clks,
>  				ARRAY_SIZE(exynos5250_pll_pmux_clks));
> +
> +	fin_pll_rate = _get_rate("fin_pll");
> +
> +	if (fin_pll_rate == (24 * MHZ))

Nit: Unnecessary parentheses around 24 * MHZ.

> +		exynos5250_plls[epll].rate_table = epll_24mhz_tbl;
> +
> +	vpllsrc = __clk_lookup("mout_vpllsrc");
> +	if (vpllsrc)
> +		mout_vpllsrc_rate = clk_get_rate(vpllsrc);
> +
> +	if (mout_vpllsrc_rate == (24 * MHZ))

Ditto.

> +		exynos5250_plls[vpll].rate_table =  vpll_24mhz_tbl;
> +
>  	samsung_clk_register_pll(exynos5250_plls, 
ARRAY_SIZE(exynos5250_plls),
> reg_base);
>  	samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,
> diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h
> index 3e6501c..378bf98 100644
> --- a/drivers/clk/samsung/clk.h
> +++ b/drivers/clk/samsung/clk.h
> @@ -40,6 +40,8 @@ struct samsung_clock_alias {
>  		.alias		= a,				\
>  	}
> 
> +#define MHZ (1000*1000)

Nit: (1000 * 1000)

Best regards,
Tomasz

> +
>  /**
>   * struct samsung_fixed_rate_clock: information about fixed-rate clock
>   * @id: platform specific id of the clock.

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v6 2/7] clk: samsung: Define a common samsung_clk_register_pll()
  2013-06-19 16:54     ` Tomasz Figa
@ 2013-06-19 18:14       ` Yadwinder Singh Brar
  -1 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-19 18:14 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Yadwinder Singh Brar, linux-samsung-soc, linux-arm-kernel,
	Kukjin Kim, Mike Turquette, Thomas Abraham, Doug Anderson,
	Tomasz Figa, Vikas Sajjan, Andrew Bresticker

On Wed, Jun 19, 2013 at 10:24 PM, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Yadwinder,
>
> Generally looks really good, but some comments inline.
>
> On Monday 10 of June 2013 18:54:14 Yadwinder Singh Brar wrote:
>> This patch defines a common samsung_clk_register_pll() and its migrating
>> the PLL35xx & PLL36xx to use it. Other samsung PLL can also be migrated
>> to it. It also adds exynos5250 & exynos5420 PLLs to unique id list of
>> clocks. Since pll2550 & pll35xx and pll2650 & pll36xx have exactly same
>> clk ops implementation, added pll2550 and pll2650 also.

>> +void __init samsung_clk_register_pll(struct samsung_pll_clock
>> *clk_list, +                          unsigned int nr_pll, void __iomem
> *base)
>> +{
>> +     struct samsung_clk_pll *pll;
>> +     struct clk *clk;
>> +     struct clk_init_data init;
>> +     struct samsung_pll_clock *list = clk_list;
>> +     int cnt;
>> +
>> +     for (cnt = 0; cnt < nr_pll; cnt++, list++) {
>
> I'd suggest moving contents of this loop to a function like following?
>
> static int __init _samsung_clk_register_pll(struct samsung_pll_clock *pll,
>                                             void __iomem *base)
>
> This will make the code less indented and so more readable.
>

Yes, will do it.

>> +             pll = kzalloc(sizeof(*pll), GFP_KERNEL);
>> +             if (!pll) {
>> +                     pr_err("%s: could not allocate pll clk %s\n",
>> +                             __func__, list->name);
>> +                     continue;
>> +             }
>> +
>> +             init.name = list->name;
>> +             init.flags = list->flags;
>> +             init.parent_names = &list->parent_name;
>> +             init.num_parents = 1;
>> +
>> +             switch (list->type) {
>> +             /* clk_ops for 35xx and 2550 are similar */
>> +             case pll_35xx:
>> +             case pll_2550:
>> +                     init.ops = &samsung_pll35xx_clk_ops;
>> +                     break;
>> +             /* clk_ops for 36xx and 2650 are similar */
>> +             case pll_36xx:
>> +             case pll_2650:
>> +                     init.ops = &samsung_pll36xx_clk_ops;
>> +                     break;
>> +             default:
>> +                     pr_warn("%s: Unknown pll type for pll clk %s\n",
>> +                             __func__, list->name);
>> +             }
>> +
>> +             pll->hw.init = &init;
>> +             pll->type = list->type;
>> +             pll->lock_reg = base + list->lock_offset;
>> +             pll->con_reg = base + list->con_offset;
>> +
>> +             clk = clk_register(NULL, &pll->hw);
>> +             if (IS_ERR(clk)) {
>> +                     pr_err("%s: failed to register pll clock %s\n",
>> +                             __func__, list->name);
>> +                     kfree(pll);
>> +                     continue;
>> +             }
>> +
>> +             samsung_clk_add_lookup(clk, list->id);
>> +
>> +             if (list->alias)
>> +                     if (clk_register_clkdev(clk, list->alias,
>> +                             list->dev_name))
>
> What about
>
>                 if (!list->alias)
>                         return;
>
>                 ret = clk_register_clkdev(clk, list->alias, list-
>>dev_name);
>                 if (ret)
>                         pr_err("%s: failed to register lookup for %s",
>                                                 __func__, list->name);
>

its ok, but to me it looks more clear and precise inside if(){ },
as its length and indentation is not much deep.
If you really insist we can do it ?

>> +                             pr_err("%s: failed to register lookup for
> %s",
>> +                                     __func__, list->name);
>> +     }
>> +}

>> +struct samsung_pll_clock {
>> +     unsigned int            id;
>> +     const char              *dev_name;
>> +     const char              *name;
>> +     const char              *parent_name;
>> +     unsigned long           flags;
>> +     const int               con_offset;
>> +     const int               lock_offset;
>
> I don't see any point of having all those const qualifiers of non-
> pointers. This makes the struct useless for creating and initializing at
> runtime.
>

OK, will remove it.

>> +     enum                    samsung_pll_type type;
>
> IMHO the enum keyword shouldn't be separated from enum name like this.
>

Any specific reason?  Just to keep indentation same for all members, I
used tabs :).

> Otherwise the patch looks fine. Maybe it's a bit too big - things could be
> done a bit more gradually, like:
> 1) first add required structs and functions,
> 2) then move existing clock drivers to use the new API, possibly one patch
> per driver,
> 3) remove the old API.
>
> This would make the whole change easier to review and, in case of any
> regressions, easier to track down the problem.
>

OK, I will split it.

Thanks,
Yadwinder

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 2/7] clk: samsung: Define a common samsung_clk_register_pll()
@ 2013-06-19 18:14       ` Yadwinder Singh Brar
  0 siblings, 0 replies; 34+ messages in thread
From: Yadwinder Singh Brar @ 2013-06-19 18:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 19, 2013 at 10:24 PM, Tomasz Figa <tomasz.figa@gmail.com> wrote:
> Hi Yadwinder,
>
> Generally looks really good, but some comments inline.
>
> On Monday 10 of June 2013 18:54:14 Yadwinder Singh Brar wrote:
>> This patch defines a common samsung_clk_register_pll() and its migrating
>> the PLL35xx & PLL36xx to use it. Other samsung PLL can also be migrated
>> to it. It also adds exynos5250 & exynos5420 PLLs to unique id list of
>> clocks. Since pll2550 & pll35xx and pll2650 & pll36xx have exactly same
>> clk ops implementation, added pll2550 and pll2650 also.

>> +void __init samsung_clk_register_pll(struct samsung_pll_clock
>> *clk_list, +                          unsigned int nr_pll, void __iomem
> *base)
>> +{
>> +     struct samsung_clk_pll *pll;
>> +     struct clk *clk;
>> +     struct clk_init_data init;
>> +     struct samsung_pll_clock *list = clk_list;
>> +     int cnt;
>> +
>> +     for (cnt = 0; cnt < nr_pll; cnt++, list++) {
>
> I'd suggest moving contents of this loop to a function like following?
>
> static int __init _samsung_clk_register_pll(struct samsung_pll_clock *pll,
>                                             void __iomem *base)
>
> This will make the code less indented and so more readable.
>

Yes, will do it.

>> +             pll = kzalloc(sizeof(*pll), GFP_KERNEL);
>> +             if (!pll) {
>> +                     pr_err("%s: could not allocate pll clk %s\n",
>> +                             __func__, list->name);
>> +                     continue;
>> +             }
>> +
>> +             init.name = list->name;
>> +             init.flags = list->flags;
>> +             init.parent_names = &list->parent_name;
>> +             init.num_parents = 1;
>> +
>> +             switch (list->type) {
>> +             /* clk_ops for 35xx and 2550 are similar */
>> +             case pll_35xx:
>> +             case pll_2550:
>> +                     init.ops = &samsung_pll35xx_clk_ops;
>> +                     break;
>> +             /* clk_ops for 36xx and 2650 are similar */
>> +             case pll_36xx:
>> +             case pll_2650:
>> +                     init.ops = &samsung_pll36xx_clk_ops;
>> +                     break;
>> +             default:
>> +                     pr_warn("%s: Unknown pll type for pll clk %s\n",
>> +                             __func__, list->name);
>> +             }
>> +
>> +             pll->hw.init = &init;
>> +             pll->type = list->type;
>> +             pll->lock_reg = base + list->lock_offset;
>> +             pll->con_reg = base + list->con_offset;
>> +
>> +             clk = clk_register(NULL, &pll->hw);
>> +             if (IS_ERR(clk)) {
>> +                     pr_err("%s: failed to register pll clock %s\n",
>> +                             __func__, list->name);
>> +                     kfree(pll);
>> +                     continue;
>> +             }
>> +
>> +             samsung_clk_add_lookup(clk, list->id);
>> +
>> +             if (list->alias)
>> +                     if (clk_register_clkdev(clk, list->alias,
>> +                             list->dev_name))
>
> What about
>
>                 if (!list->alias)
>                         return;
>
>                 ret = clk_register_clkdev(clk, list->alias, list-
>>dev_name);
>                 if (ret)
>                         pr_err("%s: failed to register lookup for %s",
>                                                 __func__, list->name);
>

its ok, but to me it looks more clear and precise inside if(){ },
as its length and indentation is not much deep.
If you really insist we can do it ?

>> +                             pr_err("%s: failed to register lookup for
> %s",
>> +                                     __func__, list->name);
>> +     }
>> +}

>> +struct samsung_pll_clock {
>> +     unsigned int            id;
>> +     const char              *dev_name;
>> +     const char              *name;
>> +     const char              *parent_name;
>> +     unsigned long           flags;
>> +     const int               con_offset;
>> +     const int               lock_offset;
>
> I don't see any point of having all those const qualifiers of non-
> pointers. This makes the struct useless for creating and initializing at
> runtime.
>

OK, will remove it.

>> +     enum                    samsung_pll_type type;
>
> IMHO the enum keyword shouldn't be separated from enum name like this.
>

Any specific reason?  Just to keep indentation same for all members, I
used tabs :).

> Otherwise the patch looks fine. Maybe it's a bit too big - things could be
> done a bit more gradually, like:
> 1) first add required structs and functions,
> 2) then move existing clock drivers to use the new API, possibly one patch
> per driver,
> 3) remove the old API.
>
> This would make the whole change easier to review and, in case of any
> regressions, easier to track down the problem.
>

OK, I will split it.

Thanks,
Yadwinder

^ permalink raw reply	[flat|nested] 34+ messages in thread

* Re: [PATCH v6 2/7] clk: samsung: Define a common samsung_clk_register_pll()
  2013-06-19 18:14       ` Yadwinder Singh Brar
@ 2013-06-19 18:21         ` Tomasz Figa
  -1 siblings, 0 replies; 34+ messages in thread
From: Tomasz Figa @ 2013-06-19 18:21 UTC (permalink / raw)
  To: Yadwinder Singh Brar
  Cc: Yadwinder Singh Brar, linux-samsung-soc, linux-arm-kernel,
	Kukjin Kim, Mike Turquette, Thomas Abraham, Doug Anderson,
	Tomasz Figa, Vikas Sajjan, Andrew Bresticker

On Wednesday 19 of June 2013 23:44:47 Yadwinder Singh Brar wrote:
> On Wed, Jun 19, 2013 at 10:24 PM, Tomasz Figa <tomasz.figa@gmail.com> 
wrote:
> > Hi Yadwinder,
> > 
> > Generally looks really good, but some comments inline.
> > 
> > On Monday 10 of June 2013 18:54:14 Yadwinder Singh Brar wrote:
> >> This patch defines a common samsung_clk_register_pll() and its
> >> migrating the PLL35xx & PLL36xx to use it. Other samsung PLL can
> >> also be migrated to it. It also adds exynos5250 & exynos5420 PLLs to
> >> unique id list of clocks. Since pll2550 & pll35xx and pll2650 &
> >> pll36xx have exactly same clk ops implementation, added pll2550 and
> >> pll2650 also.
> >> 
> >> +void __init samsung_clk_register_pll(struct samsung_pll_clock
> >> *clk_list, +                          unsigned int nr_pll, void
> >> __iomem
> > 
> > *base)
> > 
> >> +{
> >> +     struct samsung_clk_pll *pll;
> >> +     struct clk *clk;
> >> +     struct clk_init_data init;
> >> +     struct samsung_pll_clock *list = clk_list;
> >> +     int cnt;
> >> +
> >> +     for (cnt = 0; cnt < nr_pll; cnt++, list++) {
> > 
> > I'd suggest moving contents of this loop to a function like following?
> > 
> > static int __init _samsung_clk_register_pll(struct samsung_pll_clock
> > *pll,> 
> >                                             void __iomem *base)
> > 
> > This will make the code less indented and so more readable.
> 
> Yes, will do it.
> 
> >> +             pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> >> +             if (!pll) {
> >> +                     pr_err("%s: could not allocate pll clk %s\n",
> >> +                             __func__, list->name);
> >> +                     continue;
> >> +             }
> >> +
> >> +             init.name = list->name;
> >> +             init.flags = list->flags;
> >> +             init.parent_names = &list->parent_name;
> >> +             init.num_parents = 1;
> >> +
> >> +             switch (list->type) {
> >> +             /* clk_ops for 35xx and 2550 are similar */
> >> +             case pll_35xx:
> >> +             case pll_2550:
> >> +                     init.ops = &samsung_pll35xx_clk_ops;
> >> +                     break;
> >> +             /* clk_ops for 36xx and 2650 are similar */
> >> +             case pll_36xx:
> >> +             case pll_2650:
> >> +                     init.ops = &samsung_pll36xx_clk_ops;
> >> +                     break;
> >> +             default:
> >> +                     pr_warn("%s: Unknown pll type for pll clk
> >> %s\n",
> >> +                             __func__, list->name);
> >> +             }
> >> +
> >> +             pll->hw.init = &init;
> >> +             pll->type = list->type;
> >> +             pll->lock_reg = base + list->lock_offset;
> >> +             pll->con_reg = base + list->con_offset;
> >> +
> >> +             clk = clk_register(NULL, &pll->hw);
> >> +             if (IS_ERR(clk)) {
> >> +                     pr_err("%s: failed to register pll clock %s\n",
> >> +                             __func__, list->name);
> >> +                     kfree(pll);
> >> +                     continue;
> >> +             }
> >> +
> >> +             samsung_clk_add_lookup(clk, list->id);
> >> +
> >> +             if (list->alias)
> >> +                     if (clk_register_clkdev(clk, list->alias,
> >> +                             list->dev_name))
> > 
> > What about
> > 
> >                 if (!list->alias)
> >                 
> >                         return;
> >                 
> >                 ret = clk_register_clkdev(clk, list->alias, list-
> >>
> >>dev_name);
> >>
> >                 if (ret)
> >                 
> >                         pr_err("%s: failed to register lookup for %s",
> >                         
> >                                                 __func__, list->name);
> 
> its ok, but to me it looks more clear and precise inside if(){ },
> as its length and indentation is not much deep.
> If you really insist we can do it ?

Well, you can read the code as the CPU does - if you are not interested in 
the alias you can see instantly that you don't have to read this function 
any more, because it returns if alias is NULL.

And it's always good to have lower indentation level. :)

> >> +                             pr_err("%s: failed to register lookup
> >> for
> > 
> > %s",
> > 
> >> +                                     __func__, list->name);
> >> +     }
> >> +}
> >> 
> >> +struct samsung_pll_clock {
> >> +     unsigned int            id;
> >> +     const char              *dev_name;
> >> +     const char              *name;
> >> +     const char              *parent_name;
> >> +     unsigned long           flags;
> >> +     const int               con_offset;
> >> +     const int               lock_offset;
> > 
> > I don't see any point of having all those const qualifiers of non-
> > pointers. This makes the struct useless for creating and initializing
> > at runtime.
> 
> OK, will remove it.
> 
> >> +     enum                    samsung_pll_type type;
> > 
> > IMHO the enum keyword shouldn't be separated from enum name like this.
> 
> Any specific reason?  Just to keep indentation same for all members, I
> used tabs :).

Well, "enum samsung_pll_type" is the type name, not "enum" and "type" is 
name of the member, not "samsung_pll_type type".

Just imagine "unsigned long x" separated to "unsigned" "long x". Isn't it 
a bit awkward?

Anyway, thanks for your good work on improving this patch series 
continuously. :)

Best regards,
Tomasz

> > Otherwise the patch looks fine. Maybe it's a bit too big - things
> > could be done a bit more gradually, like:
> > 1) first add required structs and functions,
> > 2) then move existing clock drivers to use the new API, possibly one
> > patch per driver,
> > 3) remove the old API.
> > 
> > This would make the whole change easier to review and, in case of any
> > regressions, easier to track down the problem.
> 
> OK, I will split it.
> 
> Thanks,
> Yadwinder

^ permalink raw reply	[flat|nested] 34+ messages in thread

* [PATCH v6 2/7] clk: samsung: Define a common samsung_clk_register_pll()
@ 2013-06-19 18:21         ` Tomasz Figa
  0 siblings, 0 replies; 34+ messages in thread
From: Tomasz Figa @ 2013-06-19 18:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 19 of June 2013 23:44:47 Yadwinder Singh Brar wrote:
> On Wed, Jun 19, 2013 at 10:24 PM, Tomasz Figa <tomasz.figa@gmail.com> 
wrote:
> > Hi Yadwinder,
> > 
> > Generally looks really good, but some comments inline.
> > 
> > On Monday 10 of June 2013 18:54:14 Yadwinder Singh Brar wrote:
> >> This patch defines a common samsung_clk_register_pll() and its
> >> migrating the PLL35xx & PLL36xx to use it. Other samsung PLL can
> >> also be migrated to it. It also adds exynos5250 & exynos5420 PLLs to
> >> unique id list of clocks. Since pll2550 & pll35xx and pll2650 &
> >> pll36xx have exactly same clk ops implementation, added pll2550 and
> >> pll2650 also.
> >> 
> >> +void __init samsung_clk_register_pll(struct samsung_pll_clock
> >> *clk_list, +                          unsigned int nr_pll, void
> >> __iomem
> > 
> > *base)
> > 
> >> +{
> >> +     struct samsung_clk_pll *pll;
> >> +     struct clk *clk;
> >> +     struct clk_init_data init;
> >> +     struct samsung_pll_clock *list = clk_list;
> >> +     int cnt;
> >> +
> >> +     for (cnt = 0; cnt < nr_pll; cnt++, list++) {
> > 
> > I'd suggest moving contents of this loop to a function like following?
> > 
> > static int __init _samsung_clk_register_pll(struct samsung_pll_clock
> > *pll,> 
> >                                             void __iomem *base)
> > 
> > This will make the code less indented and so more readable.
> 
> Yes, will do it.
> 
> >> +             pll = kzalloc(sizeof(*pll), GFP_KERNEL);
> >> +             if (!pll) {
> >> +                     pr_err("%s: could not allocate pll clk %s\n",
> >> +                             __func__, list->name);
> >> +                     continue;
> >> +             }
> >> +
> >> +             init.name = list->name;
> >> +             init.flags = list->flags;
> >> +             init.parent_names = &list->parent_name;
> >> +             init.num_parents = 1;
> >> +
> >> +             switch (list->type) {
> >> +             /* clk_ops for 35xx and 2550 are similar */
> >> +             case pll_35xx:
> >> +             case pll_2550:
> >> +                     init.ops = &samsung_pll35xx_clk_ops;
> >> +                     break;
> >> +             /* clk_ops for 36xx and 2650 are similar */
> >> +             case pll_36xx:
> >> +             case pll_2650:
> >> +                     init.ops = &samsung_pll36xx_clk_ops;
> >> +                     break;
> >> +             default:
> >> +                     pr_warn("%s: Unknown pll type for pll clk
> >> %s\n",
> >> +                             __func__, list->name);
> >> +             }
> >> +
> >> +             pll->hw.init = &init;
> >> +             pll->type = list->type;
> >> +             pll->lock_reg = base + list->lock_offset;
> >> +             pll->con_reg = base + list->con_offset;
> >> +
> >> +             clk = clk_register(NULL, &pll->hw);
> >> +             if (IS_ERR(clk)) {
> >> +                     pr_err("%s: failed to register pll clock %s\n",
> >> +                             __func__, list->name);
> >> +                     kfree(pll);
> >> +                     continue;
> >> +             }
> >> +
> >> +             samsung_clk_add_lookup(clk, list->id);
> >> +
> >> +             if (list->alias)
> >> +                     if (clk_register_clkdev(clk, list->alias,
> >> +                             list->dev_name))
> > 
> > What about
> > 
> >                 if (!list->alias)
> >                 
> >                         return;
> >                 
> >                 ret = clk_register_clkdev(clk, list->alias, list-
> >>
> >>dev_name);
> >>
> >                 if (ret)
> >                 
> >                         pr_err("%s: failed to register lookup for %s",
> >                         
> >                                                 __func__, list->name);
> 
> its ok, but to me it looks more clear and precise inside if(){ },
> as its length and indentation is not much deep.
> If you really insist we can do it ?

Well, you can read the code as the CPU does - if you are not interested in 
the alias you can see instantly that you don't have to read this function 
any more, because it returns if alias is NULL.

And it's always good to have lower indentation level. :)

> >> +                             pr_err("%s: failed to register lookup
> >> for
> > 
> > %s",
> > 
> >> +                                     __func__, list->name);
> >> +     }
> >> +}
> >> 
> >> +struct samsung_pll_clock {
> >> +     unsigned int            id;
> >> +     const char              *dev_name;
> >> +     const char              *name;
> >> +     const char              *parent_name;
> >> +     unsigned long           flags;
> >> +     const int               con_offset;
> >> +     const int               lock_offset;
> > 
> > I don't see any point of having all those const qualifiers of non-
> > pointers. This makes the struct useless for creating and initializing
> > at runtime.
> 
> OK, will remove it.
> 
> >> +     enum                    samsung_pll_type type;
> > 
> > IMHO the enum keyword shouldn't be separated from enum name like this.
> 
> Any specific reason?  Just to keep indentation same for all members, I
> used tabs :).

Well, "enum samsung_pll_type" is the type name, not "enum" and "type" is 
name of the member, not "samsung_pll_type type".

Just imagine "unsigned long x" separated to "unsigned" "long x". Isn't it 
a bit awkward?

Anyway, thanks for your good work on improving this patch series 
continuously. :)

Best regards,
Tomasz

> > Otherwise the patch looks fine. Maybe it's a bit too big - things
> > could be done a bit more gradually, like:
> > 1) first add required structs and functions,
> > 2) then move existing clock drivers to use the new API, possibly one
> > patch per driver,
> > 3) remove the old API.
> > 
> > This would make the whole change easier to review and, in case of any
> > regressions, easier to track down the problem.
> 
> OK, I will split it.
> 
> Thanks,
> Yadwinder

^ permalink raw reply	[flat|nested] 34+ messages in thread

end of thread, other threads:[~2013-06-19 18:21 UTC | newest]

Thread overview: 34+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-10 13:24 [PATCH v6 0/7] Add generic set_rate clk_ops for PLL35xx and PLL36xx for samsung SoCs Yadwinder Singh Brar
2013-06-10 13:24 ` Yadwinder Singh Brar
2013-06-10 13:24 ` [PATCH v6 1/7] clk: samsung: Introduce a common samsung_clk_pll struct Yadwinder Singh Brar
2013-06-10 13:24   ` Yadwinder Singh Brar
2013-06-19 17:03   ` Tomasz Figa
2013-06-19 17:03     ` Tomasz Figa
2013-06-10 13:24 ` [PATCH v6 2/7] clk: samsung: Define a common samsung_clk_register_pll() Yadwinder Singh Brar
2013-06-10 13:24   ` Yadwinder Singh Brar
2013-06-19 16:54   ` Tomasz Figa
2013-06-19 16:54     ` Tomasz Figa
2013-06-19 18:14     ` Yadwinder Singh Brar
2013-06-19 18:14       ` Yadwinder Singh Brar
2013-06-19 18:21       ` Tomasz Figa
2013-06-19 18:21         ` Tomasz Figa
2013-06-10 13:24 ` [PATCH v6 3/7] clk: samsung: Add support to register rate_table for samsung plls Yadwinder Singh Brar
2013-06-10 13:24   ` Yadwinder Singh Brar
2013-06-19 17:00   ` Tomasz Figa
2013-06-19 17:00     ` Tomasz Figa
2013-06-10 13:24 ` [PATCH v6 4/7] clk: samsung: Add set_rate() clk_ops for PLL35xx Yadwinder Singh Brar
2013-06-10 13:24   ` Yadwinder Singh Brar
2013-06-19 17:02   ` Tomasz Figa
2013-06-19 17:02     ` Tomasz Figa
2013-06-10 13:24 ` [PATCH v6 5/7] clk: samsung: Add set_rate() clk_ops for PLL36xx Yadwinder Singh Brar
2013-06-10 13:24   ` Yadwinder Singh Brar
2013-06-19 17:05   ` Tomasz Figa
2013-06-19 17:05     ` Tomasz Figa
2013-06-10 13:24 ` [PATCH v6 6/7] clk: samsung: Reorder MUX registration for mout_vpllsrc Yadwinder Singh Brar
2013-06-10 13:24   ` Yadwinder Singh Brar
2013-06-19 17:05   ` Tomasz Figa
2013-06-19 17:05     ` Tomasz Figa
2013-06-10 13:24 ` [PATCH v6 7/7] clk: samsung: Add EPLL and VPLL freq table for exynos5250 SoC Yadwinder Singh Brar
2013-06-10 13:24   ` Yadwinder Singh Brar
2013-06-19 17:13   ` Tomasz Figa
2013-06-19 17:13     ` Tomasz Figa

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.