All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] Add generic set_rate clk_ops for PLL35XX and PLL36XX for samsung SoCs
@ 2013-05-24  4:52 Vikas Sajjan
  2013-05-24  4:52 ` [PATCH 3/5] clk: samsung: Add set_rate() clk_ops for PLL35XX Vikas Sajjan
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Vikas Sajjan @ 2013-05-24  4:52 UTC (permalink / raw)
  To: yadi.brar01, linux-samsung-soc
  Cc: dianders, tomasz.figa, kgene.kim, mturquette, thomas.abraham,
	patches, linaro-kernel

This patch series does the following: 

 1) Factors out possible common code, unifies the clk strutures used
    for PLL35XX & PLL36XX and usues clk->base instead of clk->con0

 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 PLL36XXX

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

And tested these patch on chromebook for EPLL settings for Audio on our chrome tree.

Vikas Sajjan (2):
  clk: samsung: Add set_rate() clk_ops for PLL36XX
  clk: samsung: Add EPLL and VPLL freq table for exynos5250 SoC

Yadwinder Singh Brar (3):
  clk: samsung: Use clk->base instead of directly using clk->con0 for
    PLL3XXX
  clk: samsung: Add support to register rate_table for PLL3XXX
  clk: samsung: Add set_rate() clk_ops for PLL35XX

 drivers/clk/samsung/clk-exynos4.c    |   10 +-
 drivers/clk/samsung/clk-exynos5250.c |   29 +++-
 drivers/clk/samsung/clk-pll.c        |  243 ++++++++++++++++++++++++++++++----
 drivers/clk/samsung/clk-pll.h        |   27 +++-
 4 files changed, 272 insertions(+), 37 deletions(-)

-- 
1.7.9.5

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

* [PATCH 3/5] clk: samsung: Add set_rate() clk_ops for PLL35XX
  2013-05-24  4:52 [PATCH 0/5] Add generic set_rate clk_ops for PLL35XX and PLL36XX for samsung SoCs Vikas Sajjan
@ 2013-05-24  4:52 ` Vikas Sajjan
  2013-05-24  4:52 ` [PATCH 4/5] clk: samsung: Add set_rate() clk_ops for PLL36XX Vikas Sajjan
  2013-05-24  4:52 ` [PATCH 5/5] clk: samsung: Add EPLL and VPLL freq table for exynos5250 SoC Vikas Sajjan
  2 siblings, 0 replies; 4+ messages in thread
From: Vikas Sajjan @ 2013-05-24  4:52 UTC (permalink / raw)
  To: yadi.brar01, linux-samsung-soc
  Cc: dianders, tomasz.figa, kgene.kim, mturquette, thomas.abraham,
	patches, linaro-kernel

From: Yadwinder Singh Brar <yadi.brar@samsung.com>

Adds set_rate() and round_rate() clk_ops for PLL35XX

The round_rate() implemenation as of now is dummy, it returns the same rate
which is passed as input.

Signed-off-by: Yadwinder Singh Brar <yadi.brar@samsung.com>
---
 drivers/clk/samsung/clk-pll.c |   95 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 94 insertions(+), 1 deletion(-)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index b8c0260..291cc9e 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -11,6 +11,7 @@
 
 #include <linux/errno.h>
 #include <linux/sort.h>
+#include <linux/bsearch.h>
 #include "clk.h"
 #include "clk-pll.h"
 
@@ -36,6 +37,21 @@ static int samsung_compare_rate(const void *_a, const void *_b)
 	return a->rate - b->rate;
 }
 
+static struct samsung_pll_rate_table *samsung_get_pll_settings(
+				struct samsung_clk_pll *pll, unsigned long rate)
+{
+	struct samsung_pll_rate_table req_rate, *tmp;
+
+	req_rate.rate = rate;
+	tmp = bsearch(&req_rate, pll->rate_table, pll->rate_count,
+			sizeof(struct samsung_pll_rate_table),
+			samsung_compare_rate);
+	if (tmp)
+		return tmp;
+
+	return NULL;
+}
+
 /*
  * PLL35xx Clock Type
  */
@@ -46,9 +62,15 @@ static int samsung_compare_rate(const void *_a, const void *_b)
 #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)
+
+#define PLL35XX_MDIV(_tmp) ((_tmp) & (PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT))
+#define PLL35XX_PDIV(_tmp) ((_tmp) & (PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT))
+#define PLL35XX_SDIV(_tmp) ((_tmp) & (PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT))
 
 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
 				unsigned long parent_rate)
@@ -68,8 +90,76 @@ static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
 	return (unsigned long)fvco;
 }
 
-static const struct clk_ops samsung_pll35xx_clk_ops = {
+static inline bool samsung_pll35xx_mp_change(u32 mdiv, u32 pdiv, u32 pll_con)
+{
+	if ((mdiv != PLL35XX_MDIV(pll_con)) || (pdiv != PLL35XX_PDIV(pll_con)))
+		return 1;
+	else
+		return 0;
+}
+
+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);
+	struct samsung_pll_rate_table *rate;
+
+	u32 tmp, mdiv, pdiv, sdiv;
+
+	/* 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;
+	}
+
+	mdiv = PLL35XX_MDIV(rate->pll_con0);
+	pdiv = PLL35XX_PDIV(rate->pll_con0);
+	sdiv = PLL35XX_SDIV(rate->pll_con0);
+
+	tmp = pll_readl(pll, PLL35XX_CON0_OFFSET);
+
+	if (!(samsung_pll35xx_mp_change(mdiv, pdiv, tmp))) {
+		/* If only s change, change just s value only*/
+		tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
+		tmp |= sdiv;
+		pll_writel(pll, tmp, PLL35XX_CON0_OFFSET);
+	} else {
+		/* Set PLL lock time.
+		   Maximum lock time can be 270 * PDIV cycles */
+		pll_writel(pll, (pdiv >> PLL35XX_PDIV_SHIFT) * 270,
+				PLL35XX_LOCK_OFFSET);
+
+		/* Change PLL PMS values */
+		tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
+				(PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT) |
+				(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT));
+		tmp |= mdiv | pdiv | sdiv;
+		pll_writel(pll, tmp, PLL35XX_CON0_OFFSET);
+
+		/* wait_lock_time */
+		do {
+			cpu_relax();
+			tmp = pll_readl(pll, PLL35XX_CON0_OFFSET);
+		} while (!(tmp & (PLL35XX_LOCK_STAT_MASK
+				<< PLL35XX_LOCK_STAT_SHIFT)));
+	}
+
+	return 0;
+}
+
+static long samsung_pll35xx_round_rate(struct clk_hw *hw,
+			unsigned long drate, unsigned long *prate)
+{
+	/* Clock framework cries without this, so implemented dummy */
+	return drate;
+}
+
+static struct clk_ops samsung_pll35xx_clk_ops = {
 	.recalc_rate = samsung_pll35xx_recalc_rate,
+	.round_rate = samsung_pll35xx_round_rate,
+	.set_rate = samsung_pll35xx_set_rate,
 };
 
 struct clk * __init samsung_clk_register_pll35xx(const char *name,
@@ -102,6 +192,9 @@ struct clk * __init samsung_clk_register_pll35xx(const char *name,
 		sort(pll->rate_table, pll->rate_count,
 			sizeof(struct samsung_pll_rate_table),
 			samsung_compare_rate, NULL);
+	} else {
+		samsung_pll35xx_clk_ops.round_rate = NULL;
+		samsung_pll35xx_clk_ops.set_rate = NULL;
 	}
 
 	clk = clk_register(NULL, &pll->hw);
-- 
1.7.9.5

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

* [PATCH 4/5] clk: samsung: Add set_rate() clk_ops for PLL36XX
  2013-05-24  4:52 [PATCH 0/5] Add generic set_rate clk_ops for PLL35XX and PLL36XX for samsung SoCs Vikas Sajjan
  2013-05-24  4:52 ` [PATCH 3/5] clk: samsung: Add set_rate() clk_ops for PLL35XX Vikas Sajjan
@ 2013-05-24  4:52 ` Vikas Sajjan
  2013-05-24  4:52 ` [PATCH 5/5] clk: samsung: Add EPLL and VPLL freq table for exynos5250 SoC Vikas Sajjan
  2 siblings, 0 replies; 4+ messages in thread
From: Vikas Sajjan @ 2013-05-24  4:52 UTC (permalink / raw)
  To: yadi.brar01, linux-samsung-soc
  Cc: dianders, tomasz.figa, kgene.kim, mturquette, thomas.abraham,
	patches, linaro-kernel

This patch adds set_rate and round_rate clk_ops for PLL36XX.
The round_rate() implementation as of now is dummy, it returns the same rate
which is passed as input.

Signed-off-by: Vikas Sajjan <vikas.sajjan@linaro.org>
---
 drivers/clk/samsung/clk-pll.c |   67 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 291cc9e..55ff5fd 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -224,6 +224,13 @@ struct clk * __init samsung_clk_register_pll35xx(const char *name,
 #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)
+
+#define PLL36XX_MDIV(_tmp) ((_tmp) & (PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT))
+#define PLL36XX_PDIV(_tmp) ((_tmp) & (PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT))
+#define PLL36XX_SDIV(_tmp) ((_tmp) & (PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT))
+#define PLL36XX_KDIV(_tmp) ((_tmp) & (PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT))
 
 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
 				unsigned long parent_rate)
@@ -246,8 +253,65 @@ static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
 	return (unsigned long)fvco;
 }
 
+static long samsung_pll36xx_round_rate(struct clk_hw *hw, unsigned long drate,
+					unsigned long *prate)
+{
+	/* retruns the same 'drate' whichs comes as input */
+	return drate;
+}
+
+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, mdiv, pdiv, sdiv, kdiv;
+	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;
+	}
+
+	mdiv = PLL36XX_MDIV(rate->pll_con0);
+	pdiv = PLL36XX_PDIV(rate->pll_con0);
+	sdiv = PLL36XX_SDIV(rate->pll_con0);
+	kdiv = PLL36XX_KDIV(rate->pll_con1);
+
+	pll_con0 = pll_readl(pll, PLL36XX_CON0_OFFSET);
+	pll_con1 = pll_readl(pll, PLL36XX_CON1_OFFSET);
+
+	pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT);
+
+	/* Set PLL lock time.
+	   Maximum lock time can be 3000 * PDIV cycles */
+	pll_writel(pll, ((pdiv >> PLL36XX_PDIV_SHIFT) * 3000),
+			PLL36XX_LOCK_OFFSET);
+
+	 /* 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 |= mdiv | pdiv | sdiv;
+	pll_writel(pll, pll_con0, PLL36XX_CON0_OFFSET);
+
+	pll_con1 |= kdiv;
+	pll_writel(pll, pll_con1, PLL36XX_CON1_OFFSET);
+
+	/* wait_lock_time */
+	do {
+		cpu_relax();
+		tmp = pll_readl(pll, PLL36XX_CON0_OFFSET);
+	} 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_pll36xx_round_rate,
 };
 
 struct clk * __init samsung_clk_register_pll36xx(const char *name,
@@ -280,6 +344,9 @@ struct clk * __init samsung_clk_register_pll36xx(const char *name,
 		sort(pll->rate_table, pll->rate_count,
 			sizeof(struct samsung_pll_rate_table),
 			samsung_compare_rate, NULL);
+	} else {
+		samsung_pll35xx_clk_ops.round_rate = NULL;
+		samsung_pll35xx_clk_ops.set_rate = NULL;
 	}
 
 	clk = clk_register(NULL, &pll->hw);
-- 
1.7.9.5

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

* [PATCH 5/5] clk: samsung: Add EPLL and VPLL freq table for exynos5250 SoC
  2013-05-24  4:52 [PATCH 0/5] Add generic set_rate clk_ops for PLL35XX and PLL36XX for samsung SoCs Vikas Sajjan
  2013-05-24  4:52 ` [PATCH 3/5] clk: samsung: Add set_rate() clk_ops for PLL35XX Vikas Sajjan
  2013-05-24  4:52 ` [PATCH 4/5] clk: samsung: Add set_rate() clk_ops for PLL36XX Vikas Sajjan
@ 2013-05-24  4:52 ` Vikas Sajjan
  2 siblings, 0 replies; 4+ messages in thread
From: Vikas Sajjan @ 2013-05-24  4:52 UTC (permalink / raw)
  To: yadi.brar01, linux-samsung-soc
  Cc: dianders, tomasz.figa, kgene.kim, mturquette, thomas.abraham,
	patches, linaro-kernel

Adds the EPLL and VPLL freq table for exynos5250 SoC.

Signed-off-by: Vikas Sajjan <vikas.sajjan@linaro.org>
---
 drivers/clk/samsung/clk-exynos5250.c |   19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c
index ddf10ca..00d1fa6 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -469,6 +469,21 @@ static __initdata struct of_device_id ext_clk_match[] = {
 	{ },
 };
 
+static struct samsung_pll_rate_table vpll_tbl[] = {
+	PLL_36XX_RATE(70500000, 2, 94, 4, 0),
+};
+
+static struct samsung_pll_rate_table epll_tbl[] = {
+	PLL_36XX_RATE(192000000, 48, 3, 1, 0),
+	PLL_36XX_RATE(180000000, 45, 3, 1, 0),
+	PLL_36XX_RATE(73728000, 73, 3, 3, 47710),
+	PLL_36XX_RATE(67737600, 90, 4, 3, 20762),
+	PLL_36XX_RATE(49152000, 49, 3, 3, 9961),
+	PLL_36XX_RATE(45158400, 45, 3, 3, 10381),
+	PLL_36XX_RATE(180633600, 45, 3, 1, 10381),
+	PLL_36XX_RATE(32768000, 131, 3, 5, 4719),
+};
+
 /* register exynox5250 clocks */
 void __init exynos5250_clk_init(struct device_node *np)
 {
@@ -501,9 +516,9 @@ void __init exynos5250_clk_init(struct device_node *np)
 	cpll = samsung_clk_register_pll35xx("fout_cpll", "fin_pll",
 			reg_base + 0x10020, NULL, 0);
 	epll = samsung_clk_register_pll36xx("fout_epll", "fin_pll",
-			reg_base + 0x10030, NULL, 0);
+			reg_base + 0x10030, epll_tbl, ARRAY_SIZE(epll_tbl));
 	vpll = samsung_clk_register_pll36xx("fout_vpll", "mout_vpllsrc",
-			reg_base + 0x10040, NULL, 0);
+			reg_base + 0x10040, vpll_tbl, ARRAY_SIZE(vpll_tbl));
 
 	samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,
 			ARRAY_SIZE(exynos5250_fixed_rate_clks));
-- 
1.7.9.5

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

end of thread, other threads:[~2013-05-24  4:53 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-24  4:52 [PATCH 0/5] Add generic set_rate clk_ops for PLL35XX and PLL36XX for samsung SoCs Vikas Sajjan
2013-05-24  4:52 ` [PATCH 3/5] clk: samsung: Add set_rate() clk_ops for PLL35XX Vikas Sajjan
2013-05-24  4:52 ` [PATCH 4/5] clk: samsung: Add set_rate() clk_ops for PLL36XX Vikas Sajjan
2013-05-24  4:52 ` [PATCH 5/5] clk: samsung: Add EPLL and VPLL freq table for exynos5250 SoC Vikas Sajjan

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.