Skip to contentSkip to conversation

clk: samsung: add support for 145xx and 1460x PLLs

PATCH New Naveen Krishna Chatradhi 5 participants 15 messages Aug 27, 2014 – Sep 3, 2014

Subsystems (6)
lore
Share & tools
lore
#0 lore raw

PATCH 1/14 clk: samsung: add support for 145xx and 1460x PLLs

By registers bits and offsets the 145xx PLL is similar to pll_type "pll_35xx". Also, 1460x PLL is similar to pll_type "pll_46xx".

Hence, reusing the functions defined for pll_35xx and pll_46xx to support 145xx and 1460x PLLs respectively.

Cc Tomasz Figa <[email protected]>
Cc Mike Turquette <[email protected]>
Cc Thomas Abraham <[email protected]>
---
 drivers/clk/samsung/clk-pll.c |   50 ++++++++++++++++++++++++++++++++---------
 drivers/clk/samsung/clk-pll.h |    4 ++++
 2 files changed, 43 insertions(+), 11 deletions(-)
drivers/clk/samsung/clk-pll.c +39 -11
index b07fad2..fe24e4d 100644
@@ -130,6 +130,7 @@ static const struct clk_ops samsung_pll3000_clk_ops = {
  */
 /* Maximum lock time can be 270 * PDIV cycles */
 #define PLL35XX_LOCK_FACTOR	(270)
+#define PLL145XX_LOCK_FACTOR	(150)
 
 #define PLL35XX_MDIV_MASK       (0x3FF)
 #define PLL35XX_PDIV_MASK       (0x3F)
@@ -139,6 +140,7 @@ static const struct clk_ops samsung_pll3000_clk_ops = {
 #define PLL35XX_PDIV_SHIFT      (8)
 #define PLL35XX_SDIV_SHIFT      (0)
 #define PLL35XX_LOCK_STAT_SHIFT	(29)
+#define PLL145XX_ENABLE		BIT(31)
 
 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
 				unsigned long parent_rate)
@@ -186,6 +188,10 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
 
 	tmp = __raw_readl(pll->con_reg);
 
+	/* Enable PLL */
+	if (pll->type == (pll_1450x || pll_1451x || pll_1452x))
+		tmp |= PLL145XX_ENABLE;
+
 	if (!(samsung_pll35xx_mp_change(rate, tmp))) {
 		/* If only s change, change just s value only*/
 		tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
@@ -196,8 +202,12 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
 	}
 
 	/* Set PLL lock time. */
-	__raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
-			pll->lock_reg);
+	if (pll->type == (pll_1450x || pll_1451x || pll_1452x))
+		__raw_writel(rate->pdiv * PLL145XX_LOCK_FACTOR,
+				pll->lock_reg);
+	else
+		__raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
+				pll->lock_reg);
 
 	/* Change PLL PMS values */
 	tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
@@ -356,7 +366,6 @@ static const struct clk_ops samsung_pll36xx_clk_min_ops = {
 
 #define PLL45XX_ENABLE		BIT(31)
 #define PLL45XX_LOCKED		BIT(29)
-
 static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
 				unsigned long parent_rate)
 {
@@ -482,6 +491,8 @@ static const struct clk_ops samsung_pll45xx_clk_min_ops = {
 
 #define PLL46XX_VSEL_MASK	(1)
 #define PLL46XX_MDIV_MASK	(0x1FF)
+#define PLL1460X_MDIV_MASK	(0x3FF)
+
 #define PLL46XX_PDIV_MASK	(0x3F)
 #define PLL46XX_SDIV_MASK	(0x7)
 #define PLL46XX_VSEL_SHIFT	(27)
@@ -511,13 +522,14 @@ static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
 
 	pll_con0 = __raw_readl(pll->con_reg);
 	pll_con1 = __raw_readl(pll->con_reg + 4);
-	mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
+	mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & ((pll->type == pll_1460x) ?
+				PLL1460X_MDIV_MASK : PLL46XX_MDIV_MASK);
 	pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
 	sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
-	kdiv = pll->type == pll_4650c ? pll_con1 & PLL4650C_KDIV_MASK :
+	kdiv = (pll->type == pll_4650c) ? pll_con1 & PLL4650C_KDIV_MASK :
 					pll_con1 & PLL46XX_KDIV_MASK;
 
-	shift = pll->type == pll_4600 ? 16 : 10;
+	shift = (pll->type == (pll_4600 || pll_1460x)) ? 16 : 10;
 	fvco *= (mdiv << shift) + kdiv;
 	do_div(fvco, (pdiv << sdiv));
 	fvco >>= shift;
@@ -526,11 +538,14 @@ static unsigned long samsung_pll46xx_recalc_rate(struct clk_hw *hw,
 }
 
 static bool samsung_pll46xx_mpk_change(u32 pll_con0, u32 pll_con1,
-				const struct samsung_pll_rate_table *rate)
+				const struct samsung_pll_rate_table *rate,
+				struct samsung_clk_pll *pll)
 {
 	u32 old_mdiv, old_pdiv, old_kdiv;
 
-	old_mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
+	old_mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) &
+			((pll->type == pll_1460x) ?
+			PLL1460X_MDIV_MASK : PLL46XX_MDIV_MASK);
 	old_pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
 	old_kdiv = (pll_con1 >> PLL46XX_KDIV_SHIFT) & PLL46XX_KDIV_MASK;
 
@@ -557,7 +572,7 @@ static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
 	con0 = __raw_readl(pll->con_reg);
 	con1 = __raw_readl(pll->con_reg + 0x4);
 
-	if (!(samsung_pll46xx_mpk_change(con0, con1, rate))) {
+	if (!(samsung_pll46xx_mpk_change(con0, con1, rate, pll))) {
 		/* If only s change, change just s value only*/
 		con0 &= ~(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
 		con0 |= rate->sdiv << PLL46XX_SDIV_SHIFT;
@@ -573,14 +588,23 @@ static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
 		lock = 0xffff;
 
 	/* Set PLL PMS and VSEL values. */
-	con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
+	if (pll->type == pll_1460x) {
+		con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
+			(PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
+			(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT));
+		con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
+			(rate->pdiv << PLL46XX_PDIV_SHIFT) |
+			(rate->sdiv << PLL46XX_SDIV_SHIFT);
+	} else {
+		con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
 			(PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT) |
 			(PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT) |
 			(PLL46XX_VSEL_MASK << PLL46XX_VSEL_SHIFT));
-	con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
+		con0 |= (rate->mdiv << PLL46XX_MDIV_SHIFT) |
 			(rate->pdiv << PLL46XX_PDIV_SHIFT) |
 			(rate->sdiv << PLL46XX_SDIV_SHIFT) |
 			(rate->vsel << PLL46XX_VSEL_SHIFT);
+	}
 
 	/* Set PLL K, MFR and MRR values. */
 	con1 = __raw_readl(pll->con_reg + 0x4);
@@ -1190,6 +1214,9 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	/* clk_ops for 35xx and 2550 are similar */
 	case pll_35xx:
 	case pll_2550:
+	case pll_1450x:
+	case pll_1451x:
+	case pll_1452x:
 		if (!pll->rate_table)
 			init.ops = &samsung_pll35xx_clk_min_ops;
 		else
@@ -1223,6 +1250,7 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 	case pll_4600:
 	case pll_4650:
 	case pll_4650c:
+	case pll_1460x:
 		if (!pll->rate_table)
 			init.ops = &samsung_pll46xx_clk_min_ops;
 		else
drivers/clk/samsung/clk-pll.h +4 -0
index c0ed4d4..213de9a 100644
@@ -33,6 +33,10 @@ enum samsung_pll_type {
 	pll_s3c2440_mpll,
 	pll_2550xx,
 	pll_2650xx,
+	pll_1450x,
+	pll_1451x,
+	pll_1452x,
+	pll_1460x,
 };
 
 #define PLL_35XX_RATE(_rate, _m, _p, _s)			\
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH 2/14 clk: samsung: Factor out the common code to clk.c

This patch factors out the code that can be reused from clk-exynos5260.c to clk-samsung/clk.c and clk-samsung/clk.h

As Clock controller in Exynos7 support various blocks in CMU. The common functions and structures can be reused to support Clock controller in Exynos7.

Cc Tomasz Figa <[email protected]>
Cc Mike Turquette <[email protected]>
Cc Thomas Abraham <[email protected]>
---
 drivers/clk/samsung/clk-exynos5260.c |  181 +++++-----------------------------
 drivers/clk/samsung/clk.c            |  101 +++++++++++++++++++
 drivers/clk/samsung/clk.h            |   34 +++++++
 3 files changed, 161 insertions(+), 155 deletions(-)
drivers/clk/samsung/clk-exynos5260.c +26 -155
index ce3de97..7655d4e 100644
@@ -22,39 +22,6 @@
 
 #include <dt-bindings/clock/exynos5260-clk.h>
 
-static LIST_HEAD(clock_reg_cache_list);
-
-struct exynos5260_clock_reg_cache {
-	struct list_head node;
-	void __iomem *reg_base;
-	struct samsung_clk_reg_dump *rdump;
-	unsigned int rd_num;
-};
-
-struct exynos5260_cmu_info {
-	/* list of pll clocks and respective count */
-	struct samsung_pll_clock *pll_clks;
-	unsigned int nr_pll_clks;
-	/* list of mux clocks and respective count */
-	struct samsung_mux_clock *mux_clks;
-	unsigned int nr_mux_clks;
-	/* list of div clocks and respective count */
-	struct samsung_div_clock *div_clks;
-	unsigned int nr_div_clks;
-	/* list of gate clocks and respective count */
-	struct samsung_gate_clock *gate_clks;
-	unsigned int nr_gate_clks;
-	/* list of fixed clocks and respective count */
-	struct samsung_fixed_rate_clock *fixed_clks;
-	unsigned int nr_fixed_clks;
-	/* total number of clocks with IDs assigned*/
-	unsigned int nr_clk_ids;
-
-	/* list and number of clocks registers */
-	unsigned long *clk_regs;
-	unsigned int nr_clk_regs;
-};
-
 /*
  * Applicable for all 2550 Type PLLS for Exynos5260, listed below
  * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL.
@@ -115,102 +82,6 @@ static struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initdata = {
 
 #ifdef CONFIG_PM_SLEEP
 
-static int exynos5260_clk_suspend(void)
-{
-	struct exynos5260_clock_reg_cache *cache;
-
-	list_for_each_entry(cache, &clock_reg_cache_list, node)
-		samsung_clk_save(cache->reg_base, cache->rdump,
-				cache->rd_num);
-
-	return 0;
-}
-
-static void exynos5260_clk_resume(void)
-{
-	struct exynos5260_clock_reg_cache *cache;
-
-	list_for_each_entry(cache, &clock_reg_cache_list, node)
-		samsung_clk_restore(cache->reg_base, cache->rdump,
-				cache->rd_num);
-}
-
-static struct syscore_ops exynos5260_clk_syscore_ops = {
-	.suspend = exynos5260_clk_suspend,
-	.resume = exynos5260_clk_resume,
-};
-
-static void exynos5260_clk_sleep_init(void __iomem *reg_base,
-			unsigned long *rdump,
-			unsigned long nr_rdump)
-{
-	struct exynos5260_clock_reg_cache *reg_cache;
-
-	reg_cache = kzalloc(sizeof(struct exynos5260_clock_reg_cache),
-			GFP_KERNEL);
-	if (!reg_cache)
-		panic("could not allocate register cache.\n");
-
-	reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump);
-
-	if (!reg_cache->rdump)
-		panic("could not allocate register dump storage.\n");
-
-	if (list_empty(&clock_reg_cache_list))
-		register_syscore_ops(&exynos5260_clk_syscore_ops);
-
-	reg_cache->rd_num = nr_rdump;
-	reg_cache->reg_base = reg_base;
-	list_add_tail(&reg_cache->node, &clock_reg_cache_list);
-}
-
-#else
-static void exynos5260_clk_sleep_init(void __iomem *reg_base,
-			unsigned long *rdump,
-			unsigned long nr_rdump){}
-#endif
-
-/*
- * Common function which registers plls, muxes, dividers and gates
- * for each CMU. It also add CMU register list to register cache.
- */
-
-void __init exynos5260_cmu_register_one(struct device_node *np,
-			struct exynos5260_cmu_info *cmu)
-{
-	void __iomem *reg_base;
-	struct samsung_clk_provider *ctx;
-
-	reg_base = of_iomap(np, 0);
-	if (!reg_base)
-		panic("%s: failed to map registers\n", __func__);
-
-	ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids);
-	if (!ctx)
-		panic("%s: unable to alllocate ctx\n", __func__);
-
-	if (cmu->pll_clks)
-		samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks,
-			reg_base);
-	if (cmu->mux_clks)
-		samsung_clk_register_mux(ctx,  cmu->mux_clks,
-			cmu->nr_mux_clks);
-	if (cmu->div_clks)
-		samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks);
-	if (cmu->gate_clks)
-		samsung_clk_register_gate(ctx, cmu->gate_clks,
-			cmu->nr_gate_clks);
-	if (cmu->fixed_clks)
-		samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks,
-			cmu->nr_fixed_clks);
-	if (cmu->clk_regs)
-		exynos5260_clk_sleep_init(reg_base, cmu->clk_regs,
-			cmu->nr_clk_regs);
-
-	samsung_clk_of_add_provider(np, ctx);
-}
-
-
 /* CMU_AUD */
 
 static unsigned long aud_clk_regs[] __initdata = {
@@ -268,7 +139,7 @@ struct samsung_gate_clock aud_gate_clks[] __initdata = {
 
 static void __init exynos5260_clk_aud_init(struct device_node *np)
 {
-	struct exynos5260_cmu_info cmu = {0};
+	struct exynos_cmu_info cmu = {0};
 
 	cmu.mux_clks = aud_mux_clks;
 	cmu.nr_mux_clks = ARRAY_SIZE(aud_mux_clks);
@@ -280,7 +151,7 @@ static void __init exynos5260_clk_aud_init(struct device_node *np)
 	cmu.clk_regs = aud_clk_regs;
 	cmu.nr_clk_regs = ARRAY_SIZE(aud_clk_regs);
 
-	exynos5260_cmu_register_one(np, &cmu);
+	exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_aud, "samsung,exynos5260-clock-aud",
@@ -458,7 +329,7 @@ struct samsung_gate_clock disp_gate_clks[] __initdata = {
 
 static void __init exynos5260_clk_disp_init(struct device_node *np)
 {
-	struct exynos5260_cmu_info cmu = {0};
+	struct exynos_cmu_info cmu = {0};
 
 	cmu.mux_clks = disp_mux_clks;
 	cmu.nr_mux_clks = ARRAY_SIZE(disp_mux_clks);
@@ -470,7 +341,7 @@ static void __init exynos5260_clk_disp_init(struct device_node *np)
 	cmu.clk_regs = disp_clk_regs;
 	cmu.nr_clk_regs = ARRAY_SIZE(disp_clk_regs);
 
-	exynos5260_cmu_register_one(np, &cmu);
+	exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_disp, "samsung,exynos5260-clock-disp",
@@ -522,7 +393,7 @@ static struct samsung_pll_clock egl_pll_clks[] __initdata = {
 
 static void __init exynos5260_clk_egl_init(struct device_node *np)
 {
-	struct exynos5260_cmu_info cmu = {0};
+	struct exynos_cmu_info cmu = {0};
 
 	cmu.pll_clks = egl_pll_clks;
 	cmu.nr_pll_clks =  ARRAY_SIZE(egl_pll_clks);
@@ -534,7 +405,7 @@ static void __init exynos5260_clk_egl_init(struct device_node *np)
 	cmu.clk_regs = egl_clk_regs;
 	cmu.nr_clk_regs = ARRAY_SIZE(egl_clk_regs);
 
-	exynos5260_cmu_register_one(np, &cmu);
+	exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_egl, "samsung,exynos5260-clock-egl",
@@ -624,7 +495,7 @@ struct samsung_gate_clock fsys_gate_clks[] __initdata = {
 
 static void __init exynos5260_clk_fsys_init(struct device_node *np)
 {
-	struct exynos5260_cmu_info cmu = {0};
+	struct exynos_cmu_info cmu = {0};
 
 	cmu.mux_clks = fsys_mux_clks;
 	cmu.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks);
@@ -634,7 +505,7 @@ static void __init exynos5260_clk_fsys_init(struct device_node *np)
 	cmu.clk_regs = fsys_clk_regs;
 	cmu.nr_clk_regs = ARRAY_SIZE(fsys_clk_regs);
 
-	exynos5260_cmu_register_one(np, &cmu);
+	exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_fsys, "samsung,exynos5260-clock-fsys",
@@ -713,7 +584,7 @@ struct samsung_gate_clock g2d_gate_clks[] __initdata = {
 
 static void __init exynos5260_clk_g2d_init(struct device_node *np)
 {
-	struct exynos5260_cmu_info cmu = {0};
+	struct exynos_cmu_info cmu = {0};
 
 	cmu.mux_clks = g2d_mux_clks;
 	cmu.nr_mux_clks = ARRAY_SIZE(g2d_mux_clks);
@@ -725,7 +596,7 @@ static void __init exynos5260_clk_g2d_init(struct device_node *np)
 	cmu.clk_regs = g2d_clk_regs;
 	cmu.nr_clk_regs = ARRAY_SIZE(g2d_clk_regs);
 
-	exynos5260_cmu_register_one(np, &cmu);
+	exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_g2d, "samsung,exynos5260-clock-g2d",
@@ -774,7 +645,7 @@ static struct samsung_pll_clock g3d_pll_clks[] __initdata = {
 
 static void __init exynos5260_clk_g3d_init(struct device_node *np)
 {
-	struct exynos5260_cmu_info cmu = {0};
+	struct exynos_cmu_info cmu = {0};
 
 	cmu.pll_clks = g3d_pll_clks;
 	cmu.nr_pll_clks =  ARRAY_SIZE(g3d_pll_clks);
@@ -788,7 +659,7 @@ static void __init exynos5260_clk_g3d_init(struct device_node *np)
 	cmu.clk_regs = g3d_clk_regs;
 	cmu.nr_clk_regs = ARRAY_SIZE(g3d_clk_regs);
 
-	exynos5260_cmu_register_one(np, &cmu);
+	exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_g3d, "samsung,exynos5260-clock-g3d",
@@ -909,7 +780,7 @@ struct samsung_gate_clock gscl_gate_clks[] __initdata = {
 
 static void __init exynos5260_clk_gscl_init(struct device_node *np)
 {
-	struct exynos5260_cmu_info cmu = {0};
+	struct exynos_cmu_info cmu = {0};
 
 	cmu.mux_clks = gscl_mux_clks;
 	cmu.nr_mux_clks = ARRAY_SIZE(gscl_mux_clks);
@@ -921,7 +792,7 @@ static void __init exynos5260_clk_gscl_init(struct device_node *np)
 	cmu.clk_regs = gscl_clk_regs;
 	cmu.nr_clk_regs = ARRAY_SIZE(gscl_clk_regs);
 
-	exynos5260_cmu_register_one(np, &cmu);
+	exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_gscl, "samsung,exynos5260-clock-gscl",
@@ -1028,7 +899,7 @@ struct samsung_gate_clock isp_gate_clks[] __initdata = {
 
 static void __init exynos5260_clk_isp_init(struct device_node *np)
 {
-	struct exynos5260_cmu_info cmu = {0};
+	struct exynos_cmu_info cmu = {0};
 
 	cmu.mux_clks = isp_mux_clks;
 	cmu.nr_mux_clks = ARRAY_SIZE(isp_mux_clks);
@@ -1040,7 +911,7 @@ static void __init exynos5260_clk_isp_init(struct device_node *np)
 	cmu.clk_regs = isp_clk_regs;
 	cmu.nr_clk_regs = ARRAY_SIZE(isp_clk_regs);
 
-	exynos5260_cmu_register_one(np, &cmu);
+	exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_isp, "samsung,exynos5260-clock-isp",
@@ -1092,7 +963,7 @@ static struct samsung_pll_clock kfc_pll_clks[] __initdata = {
 
 static void __init exynos5260_clk_kfc_init(struct device_node *np)
 {
-	struct exynos5260_cmu_info cmu = {0};
+	struct exynos_cmu_info cmu = {0};
 
 	cmu.pll_clks = kfc_pll_clks;
 	cmu.nr_pll_clks =  ARRAY_SIZE(kfc_pll_clks);
@@ -1104,7 +975,7 @@ static void __init exynos5260_clk_kfc_init(struct device_node *np)
 	cmu.clk_regs = kfc_clk_regs;
 	cmu.nr_clk_regs = ARRAY_SIZE(kfc_clk_regs);
 
-	exynos5260_cmu_register_one(np, &cmu);
+	exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_kfc, "samsung,exynos5260-clock-kfc",
@@ -1148,7 +1019,7 @@ struct samsung_gate_clock mfc_gate_clks[] __initdata = {
 
 static void __init exynos5260_clk_mfc_init(struct device_node *np)
 {
-	struct exynos5260_cmu_info cmu = {0};
+	struct exynos_cmu_info cmu = {0};
 
 	cmu.mux_clks = mfc_mux_clks;
 	cmu.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks);
@@ -1160,7 +1031,7 @@ static void __init exynos5260_clk_mfc_init(struct device_node *np)
 	cmu.clk_regs = mfc_clk_regs;
 	cmu.nr_clk_regs = ARRAY_SIZE(mfc_clk_regs);
 
-	exynos5260_cmu_register_one(np, &cmu);
+	exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_mfc, "samsung,exynos5260-clock-mfc",
@@ -1295,7 +1166,7 @@ static struct samsung_pll_clock mif_pll_clks[] __initdata = {
 
 static void __init exynos5260_clk_mif_init(struct device_node *np)
 {
-	struct exynos5260_cmu_info cmu = {0};
+	struct exynos_cmu_info cmu = {0};
 
 	cmu.pll_clks = mif_pll_clks;
 	cmu.nr_pll_clks =  ARRAY_SIZE(mif_pll_clks);
@@ -1309,7 +1180,7 @@ static void __init exynos5260_clk_mif_init(struct device_node *np)
 	cmu.clk_regs = mif_clk_regs;
 	cmu.nr_clk_regs = ARRAY_SIZE(mif_clk_regs);
 
-	exynos5260_cmu_register_one(np, &cmu);
+	exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_mif, "samsung,exynos5260-clock-mif",
@@ -1503,7 +1374,7 @@ struct samsung_gate_clock peri_gate_clks[] __initdata = {
 
 static void __init exynos5260_clk_peri_init(struct device_node *np)
 {
-	struct exynos5260_cmu_info cmu = {0};
+	struct exynos_cmu_info cmu = {0};
 
 	cmu.mux_clks = peri_mux_clks;
 	cmu.nr_mux_clks = ARRAY_SIZE(peri_mux_clks);
@@ -1515,7 +1386,7 @@ static void __init exynos5260_clk_peri_init(struct device_node *np)
 	cmu.clk_regs = peri_clk_regs;
 	cmu.nr_clk_regs = ARRAY_SIZE(peri_clk_regs);
 
-	exynos5260_cmu_register_one(np, &cmu);
+	exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_peri, "samsung,exynos5260-clock-peri",
@@ -1959,7 +1830,7 @@ static struct samsung_pll_clock top_pll_clks[] __initdata = {
 
 static void __init exynos5260_clk_top_init(struct device_node *np)
 {
-	struct exynos5260_cmu_info cmu = {0};
+	struct exynos_cmu_info cmu = {0};
 
 	cmu.pll_clks = top_pll_clks;
 	cmu.nr_pll_clks =  ARRAY_SIZE(top_pll_clks);
@@ -1975,7 +1846,7 @@ static void __init exynos5260_clk_top_init(struct device_node *np)
 	cmu.clk_regs = top_clk_regs;
 	cmu.nr_clk_regs = ARRAY_SIZE(top_clk_regs);
 
-	exynos5260_cmu_register_one(np, &cmu);
+	exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_top, "samsung,exynos5260-clock-top",
drivers/clk/samsung/clk.c +101 -0

113 lines not on this page · raw message

drivers/clk/samsung/clk.h +34 -0
index 66ab36b..552d155 100644
@@ -324,6 +324,37 @@ struct samsung_pll_clock {
 	__PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,	\
 		_lock, _con, _rtable, _alias)
 
+struct exynos_clock_reg_cache {
+	struct list_head node;
+	void __iomem *reg_base;
+	struct samsung_clk_reg_dump *rdump;
+	unsigned int rd_num;
+};
+
+struct exynos_cmu_info {
+	/* list of pll clocks and respective count */
+	struct samsung_pll_clock *pll_clks;
+	unsigned int nr_pll_clks;
+	/* list of mux clocks and respective count */
+	struct samsung_mux_clock *mux_clks;
+	unsigned int nr_mux_clks;
+	/* list of div clocks and respective count */
+	struct samsung_div_clock *div_clks;
+	unsigned int nr_div_clks;
+	/* list of gate clocks and respective count */
+	struct samsung_gate_clock *gate_clks;
+	unsigned int nr_gate_clks;
+	/* list of fixed clocks and respective count */
+	struct samsung_fixed_rate_clock *fixed_clks;
+	unsigned int nr_fixed_clks;
+	/* total number of clocks with IDs assigned*/
+	unsigned int nr_clk_ids;
+
+	/* list and number of clocks registers */
+	unsigned long *clk_regs;
+	unsigned int nr_clk_regs;
+};
+
 extern struct samsung_clk_provider *__init samsung_clk_init(
 			struct device_node *np, void __iomem *base,
 			unsigned long nr_clks);
@@ -362,6 +393,9 @@ extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
 			struct samsung_pll_clock *pll_list,
 			unsigned int nr_clk, void __iomem *base);
 
+extern void __init exynos_cmu_register_one(struct device_node *,
+			struct exynos_cmu_info *);
+
 extern unsigned long _get_rate(const char *clk_name);
 
 extern void samsung_clk_save(void __iomem *base,
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH 2/14 clk: samsung: Factor out the common code to clk.c

Hello All,

Quoted 11 lines · Naveen Krishna Chatradhi

This patch factors out the code that can be reused from clk-exynos5260.c to clk-samsung/clk.c and clk-samsung/clk.h

As Clock controller in Exynos7 support various blocks in CMU. The common functions and structures can be reused to support Clock controller in Exynos7.

Cc Tomasz Figa <[email protected]>
Cc Mike Turquette <[email protected]>
Cc Thomas Abraham <[email protected]>

Not tested on Exynos5260.. Tested-by would be appreciated.

Quoted 561 lines
---
 drivers/clk/samsung/clk-exynos5260.c |  181 +++++-----------------------------
 drivers/clk/samsung/clk.c            |  101 +++++++++++++++++++
 drivers/clk/samsung/clk.h            |   34 +++++++
 3 files changed, 161 insertions(+), 155 deletions(-)
drivers/clk/samsung/clk-exynos5260.c +26 -155
index ce3de97..7655d4e 100644
@@ -22,39 +22,6 @@
 
 #include <dt-bindings/clock/exynos5260-clk.h>
 
-static LIST_HEAD(clock_reg_cache_list);
-
-struct exynos5260_clock_reg_cache {
-       struct list_head node;
-       void __iomem *reg_base;
-       struct samsung_clk_reg_dump *rdump;
-       unsigned int rd_num;
-};
-
-struct exynos5260_cmu_info {
-       /* list of pll clocks and respective count */
-       struct samsung_pll_clock *pll_clks;
-       unsigned int nr_pll_clks;
-       /* list of mux clocks and respective count */
-       struct samsung_mux_clock *mux_clks;
-       unsigned int nr_mux_clks;
-       /* list of div clocks and respective count */
-       struct samsung_div_clock *div_clks;
-       unsigned int nr_div_clks;
-       /* list of gate clocks and respective count */
-       struct samsung_gate_clock *gate_clks;
-       unsigned int nr_gate_clks;
-       /* list of fixed clocks and respective count */
-       struct samsung_fixed_rate_clock *fixed_clks;
-       unsigned int nr_fixed_clks;
-       /* total number of clocks with IDs assigned*/
-       unsigned int nr_clk_ids;
-
-       /* list and number of clocks registers */
-       unsigned long *clk_regs;
-       unsigned int nr_clk_regs;
-};
-
 /*
  * Applicable for all 2550 Type PLLS for Exynos5260, listed below
  * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL.
@@ -115,102 +82,6 @@ static struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initdata = {
 
 #ifdef CONFIG_PM_SLEEP
 
-static int exynos5260_clk_suspend(void)
-{
-       struct exynos5260_clock_reg_cache *cache;
-
-       list_for_each_entry(cache, &clock_reg_cache_list, node)
-               samsung_clk_save(cache->reg_base, cache->rdump,
-                               cache->rd_num);
-
-       return 0;
-}
-
-static void exynos5260_clk_resume(void)
-{
-       struct exynos5260_clock_reg_cache *cache;
-
-       list_for_each_entry(cache, &clock_reg_cache_list, node)
-               samsung_clk_restore(cache->reg_base, cache->rdump,
-                               cache->rd_num);
-}
-
-static struct syscore_ops exynos5260_clk_syscore_ops = {
-       .suspend = exynos5260_clk_suspend,
-       .resume = exynos5260_clk_resume,
-};
-
-static void exynos5260_clk_sleep_init(void __iomem *reg_base,
-                       unsigned long *rdump,
-                       unsigned long nr_rdump)
-{
-       struct exynos5260_clock_reg_cache *reg_cache;
-
-       reg_cache = kzalloc(sizeof(struct exynos5260_clock_reg_cache),
-                       GFP_KERNEL);
-       if (!reg_cache)
-               panic("could not allocate register cache.\n");
-
-       reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump);
-
-       if (!reg_cache->rdump)
-               panic("could not allocate register dump storage.\n");
-
-       if (list_empty(&clock_reg_cache_list))
-               register_syscore_ops(&exynos5260_clk_syscore_ops);
-
-       reg_cache->rd_num = nr_rdump;
-       reg_cache->reg_base = reg_base;
-       list_add_tail(&reg_cache->node, &clock_reg_cache_list);
-}
-
-#else
-static void exynos5260_clk_sleep_init(void __iomem *reg_base,
-                       unsigned long *rdump,
-                       unsigned long nr_rdump){}
-#endif
-
-/*
- * Common function which registers plls, muxes, dividers and gates
- * for each CMU. It also add CMU register list to register cache.
- */
-
-void __init exynos5260_cmu_register_one(struct device_node *np,
-                       struct exynos5260_cmu_info *cmu)
-{
-       void __iomem *reg_base;
-       struct samsung_clk_provider *ctx;
-
-       reg_base = of_iomap(np, 0);
-       if (!reg_base)
-               panic("%s: failed to map registers\n", __func__);
-
-       ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids);
-       if (!ctx)
-               panic("%s: unable to alllocate ctx\n", __func__);
-
-       if (cmu->pll_clks)
-               samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks,
-                       reg_base);
-       if (cmu->mux_clks)
-               samsung_clk_register_mux(ctx,  cmu->mux_clks,
-                       cmu->nr_mux_clks);
-       if (cmu->div_clks)
-               samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks);
-       if (cmu->gate_clks)
-               samsung_clk_register_gate(ctx, cmu->gate_clks,
-                       cmu->nr_gate_clks);
-       if (cmu->fixed_clks)
-               samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks,
-                       cmu->nr_fixed_clks);
-       if (cmu->clk_regs)
-               exynos5260_clk_sleep_init(reg_base, cmu->clk_regs,
-                       cmu->nr_clk_regs);
-
-       samsung_clk_of_add_provider(np, ctx);
-}
-
-
 /* CMU_AUD */
 
 static unsigned long aud_clk_regs[] __initdata = {
@@ -268,7 +139,7 @@ struct samsung_gate_clock aud_gate_clks[] __initdata = {
 
 static void __init exynos5260_clk_aud_init(struct device_node *np)
 {
-       struct exynos5260_cmu_info cmu = {0};
+       struct exynos_cmu_info cmu = {0};
 
        cmu.mux_clks = aud_mux_clks;
        cmu.nr_mux_clks = ARRAY_SIZE(aud_mux_clks);
@@ -280,7 +151,7 @@ static void __init exynos5260_clk_aud_init(struct device_node *np)
        cmu.clk_regs = aud_clk_regs;
        cmu.nr_clk_regs = ARRAY_SIZE(aud_clk_regs);
 
-       exynos5260_cmu_register_one(np, &cmu);
+       exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_aud, "samsung,exynos5260-clock-aud",
@@ -458,7 +329,7 @@ struct samsung_gate_clock disp_gate_clks[] __initdata = {
 
 static void __init exynos5260_clk_disp_init(struct device_node *np)
 {
-       struct exynos5260_cmu_info cmu = {0};
+       struct exynos_cmu_info cmu = {0};
 
        cmu.mux_clks = disp_mux_clks;
        cmu.nr_mux_clks = ARRAY_SIZE(disp_mux_clks);
@@ -470,7 +341,7 @@ static void __init exynos5260_clk_disp_init(struct device_node *np)
        cmu.clk_regs = disp_clk_regs;
        cmu.nr_clk_regs = ARRAY_SIZE(disp_clk_regs);
 
-       exynos5260_cmu_register_one(np, &cmu);
+       exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_disp, "samsung,exynos5260-clock-disp",
@@ -522,7 +393,7 @@ static struct samsung_pll_clock egl_pll_clks[] __initdata = {
 
 static void __init exynos5260_clk_egl_init(struct device_node *np)
 {
-       struct exynos5260_cmu_info cmu = {0};
+       struct exynos_cmu_info cmu = {0};
 
        cmu.pll_clks = egl_pll_clks;
        cmu.nr_pll_clks =  ARRAY_SIZE(egl_pll_clks);
@@ -534,7 +405,7 @@ static void __init exynos5260_clk_egl_init(struct device_node *np)
        cmu.clk_regs = egl_clk_regs;
        cmu.nr_clk_regs = ARRAY_SIZE(egl_clk_regs);
 
-       exynos5260_cmu_register_one(np, &cmu);
+       exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_egl, "samsung,exynos5260-clock-egl",
@@ -624,7 +495,7 @@ struct samsung_gate_clock fsys_gate_clks[] __initdata = {
 
 static void __init exynos5260_clk_fsys_init(struct device_node *np)
 {
-       struct exynos5260_cmu_info cmu = {0};
+       struct exynos_cmu_info cmu = {0};
 
        cmu.mux_clks = fsys_mux_clks;
        cmu.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks);
@@ -634,7 +505,7 @@ static void __init exynos5260_clk_fsys_init(struct device_node *np)
        cmu.clk_regs = fsys_clk_regs;
        cmu.nr_clk_regs = ARRAY_SIZE(fsys_clk_regs);
 
-       exynos5260_cmu_register_one(np, &cmu);
+       exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_fsys, "samsung,exynos5260-clock-fsys",
@@ -713,7 +584,7 @@ struct samsung_gate_clock g2d_gate_clks[] __initdata = {
 
 static void __init exynos5260_clk_g2d_init(struct device_node *np)
 {
-       struct exynos5260_cmu_info cmu = {0};
+       struct exynos_cmu_info cmu = {0};
 
        cmu.mux_clks = g2d_mux_clks;
        cmu.nr_mux_clks = ARRAY_SIZE(g2d_mux_clks);
@@ -725,7 +596,7 @@ static void __init exynos5260_clk_g2d_init(struct device_node *np)
        cmu.clk_regs = g2d_clk_regs;
        cmu.nr_clk_regs = ARRAY_SIZE(g2d_clk_regs);
 
-       exynos5260_cmu_register_one(np, &cmu);
+       exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_g2d, "samsung,exynos5260-clock-g2d",
@@ -774,7 +645,7 @@ static struct samsung_pll_clock g3d_pll_clks[] __initdata = {
 
 static void __init exynos5260_clk_g3d_init(struct device_node *np)
 {
-       struct exynos5260_cmu_info cmu = {0};
+       struct exynos_cmu_info cmu = {0};
 
        cmu.pll_clks = g3d_pll_clks;
        cmu.nr_pll_clks =  ARRAY_SIZE(g3d_pll_clks);
@@ -788,7 +659,7 @@ static void __init exynos5260_clk_g3d_init(struct device_node *np)
        cmu.clk_regs = g3d_clk_regs;
        cmu.nr_clk_regs = ARRAY_SIZE(g3d_clk_regs);
 
-       exynos5260_cmu_register_one(np, &cmu);
+       exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_g3d, "samsung,exynos5260-clock-g3d",
@@ -909,7 +780,7 @@ struct samsung_gate_clock gscl_gate_clks[] __initdata = {
 
 static void __init exynos5260_clk_gscl_init(struct device_node *np)
 {
-       struct exynos5260_cmu_info cmu = {0};
+       struct exynos_cmu_info cmu = {0};
 
        cmu.mux_clks = gscl_mux_clks;
        cmu.nr_mux_clks = ARRAY_SIZE(gscl_mux_clks);
@@ -921,7 +792,7 @@ static void __init exynos5260_clk_gscl_init(struct device_node *np)
        cmu.clk_regs = gscl_clk_regs;
        cmu.nr_clk_regs = ARRAY_SIZE(gscl_clk_regs);
 
-       exynos5260_cmu_register_one(np, &cmu);
+       exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_gscl, "samsung,exynos5260-clock-gscl",
@@ -1028,7 +899,7 @@ struct samsung_gate_clock isp_gate_clks[] __initdata = {
 
 static void __init exynos5260_clk_isp_init(struct device_node *np)
 {
-       struct exynos5260_cmu_info cmu = {0};
+       struct exynos_cmu_info cmu = {0};
 
        cmu.mux_clks = isp_mux_clks;
        cmu.nr_mux_clks = ARRAY_SIZE(isp_mux_clks);
@@ -1040,7 +911,7 @@ static void __init exynos5260_clk_isp_init(struct device_node *np)
        cmu.clk_regs = isp_clk_regs;
        cmu.nr_clk_regs = ARRAY_SIZE(isp_clk_regs);
 
-       exynos5260_cmu_register_one(np, &cmu);
+       exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_isp, "samsung,exynos5260-clock-isp",
@@ -1092,7 +963,7 @@ static struct samsung_pll_clock kfc_pll_clks[] __initdata = {
 
 static void __init exynos5260_clk_kfc_init(struct device_node *np)
 {
-       struct exynos5260_cmu_info cmu = {0};
+       struct exynos_cmu_info cmu = {0};
 
        cmu.pll_clks = kfc_pll_clks;
        cmu.nr_pll_clks =  ARRAY_SIZE(kfc_pll_clks);
@@ -1104,7 +975,7 @@ static void __init exynos5260_clk_kfc_init(struct device_node *np)
        cmu.clk_regs = kfc_clk_regs;
        cmu.nr_clk_regs = ARRAY_SIZE(kfc_clk_regs);
 
-       exynos5260_cmu_register_one(np, &cmu);
+       exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_kfc, "samsung,exynos5260-clock-kfc",
@@ -1148,7 +1019,7 @@ struct samsung_gate_clock mfc_gate_clks[] __initdata = {
 
 static void __init exynos5260_clk_mfc_init(struct device_node *np)
 {
-       struct exynos5260_cmu_info cmu = {0};
+       struct exynos_cmu_info cmu = {0};
 
        cmu.mux_clks = mfc_mux_clks;
        cmu.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks);
@@ -1160,7 +1031,7 @@ static void __init exynos5260_clk_mfc_init(struct device_node *np)
        cmu.clk_regs = mfc_clk_regs;
        cmu.nr_clk_regs = ARRAY_SIZE(mfc_clk_regs);
 
-       exynos5260_cmu_register_one(np, &cmu);
+       exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_mfc, "samsung,exynos5260-clock-mfc",
@@ -1295,7 +1166,7 @@ static struct samsung_pll_clock mif_pll_clks[] __initdata = {
 
 static void __init exynos5260_clk_mif_init(struct device_node *np)
 {
-       struct exynos5260_cmu_info cmu = {0};
+       struct exynos_cmu_info cmu = {0};
 
        cmu.pll_clks = mif_pll_clks;
        cmu.nr_pll_clks =  ARRAY_SIZE(mif_pll_clks);
@@ -1309,7 +1180,7 @@ static void __init exynos5260_clk_mif_init(struct device_node *np)
        cmu.clk_regs = mif_clk_regs;
        cmu.nr_clk_regs = ARRAY_SIZE(mif_clk_regs);
 
-       exynos5260_cmu_register_one(np, &cmu);
+       exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_mif, "samsung,exynos5260-clock-mif",
@@ -1503,7 +1374,7 @@ struct samsung_gate_clock peri_gate_clks[] __initdata = {
 
 static void __init exynos5260_clk_peri_init(struct device_node *np)
 {
-       struct exynos5260_cmu_info cmu = {0};
+       struct exynos_cmu_info cmu = {0};
 
        cmu.mux_clks = peri_mux_clks;
        cmu.nr_mux_clks = ARRAY_SIZE(peri_mux_clks);
@@ -1515,7 +1386,7 @@ static void __init exynos5260_clk_peri_init(struct device_node *np)
        cmu.clk_regs = peri_clk_regs;
        cmu.nr_clk_regs = ARRAY_SIZE(peri_clk_regs);
 
-       exynos5260_cmu_register_one(np, &cmu);
+       exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_peri, "samsung,exynos5260-clock-peri",
@@ -1959,7 +1830,7 @@ static struct samsung_pll_clock top_pll_clks[] __initdata = {
 
 static void __init exynos5260_clk_top_init(struct device_node *np)
 {
-       struct exynos5260_cmu_info cmu = {0};
+       struct exynos_cmu_info cmu = {0};
 
        cmu.pll_clks = top_pll_clks;
        cmu.nr_pll_clks =  ARRAY_SIZE(top_pll_clks);
@@ -1975,7 +1846,7 @@ static void __init exynos5260_clk_top_init(struct device_node *np)
        cmu.clk_regs = top_clk_regs;
        cmu.nr_clk_regs = ARRAY_SIZE(top_clk_regs);
 
-       exynos5260_cmu_register_one(np, &cmu);
+       exynos_cmu_register_one(np, &cmu);
 }
 
 CLK_OF_DECLARE(exynos5260_clk_top, "samsung,exynos5260-clock-top",
drivers/clk/samsung/clk.c +101 -0
index deab84d..ef73edf 100644
@@ -11,9 +11,14 @@
  * clock framework for Samsung platforms.
 */
 
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
 #include <linux/syscore_ops.h>
 #include "clk.h"
 
+static LIST_HEAD(clock_reg_cache_list);
+
 void samsung_clk_save(void __iomem *base,
                                    struct samsung_clk_reg_dump *rd,
                                    unsigned int num_regs)
@@ -313,3 +318,99 @@ unsigned long _get_rate(const char *clk_name)
 
        return clk_get_rate(clk);
 }
+
+#ifdef CONFIG_PM_SLEEP
+static int exynos_clk_suspend(void)
+{
+       struct exynos_clock_reg_cache *reg_cache;
+
+       list_for_each_entry(reg_cache, &clock_reg_cache_list, node)
+               samsung_clk_save(reg_cache->reg_base, reg_cache->rdump,
+                               reg_cache->rd_num);
+       return 0;
+}
+
+static void exynos_clk_resume(void)
+{
+       struct exynos_clock_reg_cache *reg_cache;
+
+       list_for_each_entry(reg_cache, &clock_reg_cache_list, node)
+               samsung_clk_restore(reg_cache->reg_base, reg_cache->rdump,
+                               reg_cache->rd_num);
+}
+
+static struct syscore_ops exynos_clk_syscore_ops = {
+       .suspend = exynos_clk_suspend,
+       .resume = exynos_clk_resume,
+};
+
+static void exynos_clk_sleep_init(void __iomem *reg_base,
+               const unsigned long *rdump,
+               unsigned long nr_rdump)
+{
+       struct exynos_clock_reg_cache *reg_cache;
+
+       reg_cache = kzalloc(sizeof(struct exynos_clock_reg_cache),
+                       GFP_KERNEL);
+       if (!reg_cache)
+               panic("could not allocate register reg_cache.\n");
+       reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump);
+
+       if (!reg_cache->rdump)
+               panic("could not allocate register dump storage.\n");
+
+       /* since we should register syscore_ops only once
+        * check for list emptyness
+        */
+       if (list_empty(&clock_reg_cache_list))
+               register_syscore_ops(&exynos_clk_syscore_ops);
+
+       reg_cache->reg_base = reg_base;
+       reg_cache->rd_num = nr_rdump;
+       list_add_tail(&reg_cache->node, &clock_reg_cache_list);
+}
+
+#else
+static void exynos_clk_sleep_init(void __iomem *reg_base,
+               const unsigned long *rdump,
+               unsigned long nr_rdump) {}
+#endif
+
+/*
+ * Common function which registers plls, muxes, dividers and gates
+ * for each CMU. It also add CMU register list to register cache.
+ */
+void __init exynos_cmu_register_one(struct device_node *np,
+                       struct exynos_cmu_info *cmu)
+{
+       void __iomem *reg_base;
+       struct samsung_clk_provider *ctx;
+
+       reg_base = of_iomap(np, 0);
+       if (!reg_base)
+               panic("%s: failed to map registers\n", __func__);
+
+       ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids);
+       if (!ctx)
+               panic("%s: unable to alllocate ctx\n", __func__);
+
+       if (cmu->pll_clks)
+               samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks,
+                       reg_base);
+       if (cmu->mux_clks)
+               samsung_clk_register_mux(ctx, cmu->mux_clks,
+                       cmu->nr_mux_clks);
+       if (cmu->div_clks)
+               samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks);
+       if (cmu->gate_clks)
+               samsung_clk_register_gate(ctx, cmu->gate_clks,
+                       cmu->nr_gate_clks);
+       if (cmu->fixed_clks)
+               samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks,
+                       cmu->nr_fixed_clks);
+       if (cmu->clk_regs)
+               exynos_clk_sleep_init(reg_base, cmu->clk_regs,
+                       cmu->nr_clk_regs);
+
+       samsung_clk_of_add_provider(np, ctx);
+}
drivers/clk/samsung/clk.h +34 -1
index 66ab36b..552d155 100644
@@ -324,6 +324,37 @@ struct samsung_pll_clock {
        __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE,     \
                _lock, _con, _rtable, _alias)
 
+struct exynos_clock_reg_cache {
+       struct list_head node;
+       void __iomem *reg_base;
+       struct samsung_clk_reg_dump *rdump;
+       unsigned int rd_num;
+};
+
+struct exynos_cmu_info {
+       /* list of pll clocks and respective count */
+       struct samsung_pll_clock *pll_clks;
+       unsigned int nr_pll_clks;
+       /* list of mux clocks and respective count */
+       struct samsung_mux_clock *mux_clks;
+       unsigned int nr_mux_clks;
+       /* list of div clocks and respective count */
+       struct samsung_div_clock *div_clks;
+       unsigned int nr_div_clks;
+       /* list of gate clocks and respective count */
+       struct samsung_gate_clock *gate_clks;
+       unsigned int nr_gate_clks;
+       /* list of fixed clocks and respective count */
+       struct samsung_fixed_rate_clock *fixed_clks;
+       unsigned int nr_fixed_clks;
+       /* total number of clocks with IDs assigned*/
+       unsigned int nr_clk_ids;
+
+       /* list and number of clocks registers */
+       unsigned long *clk_regs;
+       unsigned int nr_clk_regs;
+};
+
 extern struct samsung_clk_provider *__init samsung_clk_init(
                        struct device_node *np, void __iomem *base,
                        unsigned long nr_clks);
@@ -362,6 +393,9 @@ extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx,
                        struct samsung_pll_clock *pll_list,
                        unsigned int nr_clk, void __iomem *base);
 
+extern void __init exynos_cmu_register_one(struct device_node *,
+                       struct exynos_cmu_info *);
+
 extern unsigned long _get_rate(const char *clk_name);
 
 extern void samsung_clk_save(void __iomem *base,
--

1.7.9.5

Signature · 2 lines
Shine bright,
(: Nav :)
#3 lore raw

PATCH 3/14 clk: samsung: Add fixed_factor_clocks field to struct exynos_cmu_info

In reply to Naveen Krishna Chatradhi

This patch adds the needed fields "fixed_factor_clks" and "nr_fixed_factor_clks" to "struct exynos_cmu_info"

The same fields are used in the function exynos_cmu_register_one() for registering the fixed factor clocks.

Cc Tomasz Figa <[email protected]>
Cc Mike Turquette <[email protected]>
Cc Thomas Abraham <[email protected]>
---
 drivers/clk/samsung/clk.c |    3 +++
 drivers/clk/samsung/clk.h |    3 +++
 2 files changed, 6 insertions(+)
drivers/clk/samsung/clk.c +3 -0
index ef73edf..ed907cf 100644
@@ -408,6 +408,9 @@ void __init exynos_cmu_register_one(struct device_node *np,
 	if (cmu->fixed_clks)
 		samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks,
 			cmu->nr_fixed_clks);
+	if (cmu->fixed_factor_clks)
+		samsung_clk_register_fixed_factor(ctx, cmu->fixed_factor_clks,
+			cmu->nr_fixed_factor_clks);
 	if (cmu->clk_regs)
 		exynos_clk_sleep_init(reg_base, cmu->clk_regs,
 			cmu->nr_clk_regs);
drivers/clk/samsung/clk.h +3 -0
index 552d155..993b51c 100644
@@ -347,6 +347,9 @@ struct exynos_cmu_info {
 	/* list of fixed clocks and respective count */
 	struct samsung_fixed_rate_clock *fixed_clks;
 	unsigned int nr_fixed_clks;
+	/* list of fixed factor clocks and respective count */
+	struct samsung_fixed_factor_clock *fixed_factor_clks;
+	unsigned int nr_fixed_factor_clks;
 	/* total number of clocks with IDs assigned*/
 	unsigned int nr_clk_ids;
 
Signature · 1 line
1.7.9.5
#4 lore raw

PATCH 4/14 clk: samsung: Add clock description for basic CMU blocks

In reply to Naveen Krishna Chatradhi

This patch adds clock description for MUX, DIV, GATE and PLL clocks available in TOPC, TOP0, TOP1, BUS0, BUS1, FSYS0, FSYS1, CCORE, PERIC0, PERIC1, PERIS, DISP, G3D, MSCL and MFC blocks.

Adds Gate clocks for UART, HSI2C, SPI, SPDIF, TMU, PWM, WDT, USB, MMC, RTC and DISP block clocks.

This patch adds PLL tables for the following PLLs 1450x PLL which drives A57, DPHY block
1451x PLL which drives BUS0 block
1452x PLL which drives BUS1, MFC, G3D, HSIC blocks 1460x PLL which drives AUD, DISP blocks on Exynos7 SoC.

Also adds the documentation for device tree bindings

Cc Tomasz Figa <[email protected]>
Cc Mike Turquette <[email protected]>
Cc Thomas Abraham <[email protected]>

---
Currently about 13 CMU blocks have been described in clk-exynos7.c If required, I can split it and group them to different files.

 .../devicetree/bindings/clock/exynos7-clock.txt    |  209 +++
 drivers/clk/samsung/Makefile                       |    1 +
 drivers/clk/samsung/clk-exynos7.c                  | 1929 ++++++++++++++++++++
 include/dt-bindings/clock/exynos7-clk.h            |  236 +++
 4 files changed, 2375 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/exynos7-clock.txt
 create mode 100644 drivers/clk/samsung/clk-exynos7.c
 create mode 100644 include/dt-bindings/clock/exynos7-clk.h
Documentation/devicetree/bindings/clock/exynos7-clock.txt new file +209 -0
new file mode 100644
index 0000000..c361525
@@ -0,0 +1,209 @@
+* Samsung Exynos7 Clock Controller
+
+Exynos7 clock controller has 25 blocks which are instantiated
+independently from the device-tree. These clock controllers
+generate and supply clocks to various hardware blocks within
+the SoC.
+
+Each clock is assigned an identifier and client nodes can use
+this identifier to specify the clock which they consume. All
+available clocks are defined as preprocessor macros in
+dt-bindings/clock/exynos7-clk.h header and can be used in
+device tree sources.
+
+External clocks:
+
+There are several clocks that are generated outside the SoC. It
+is expected that they are defined using standard clock bindings
+with following clock-output-names:
+
+ - "fin_pll" - PLL input clock from XXTI
+
+Phy clocks:
+
+There are several clocks which are generated by specific PHYs.
+These clocks are fed into the clock controller and then routed to
+the hardware blocks. These clocks are defined as fixed clocks in the
+driver with following names:
+
+Required Properties for Clock Controller:
+
+ - compatible: should be one of the following.
+	1) "samsung,exynos7-clock-topc"
+	2) "samsung,exynos7-clock-top0"
+	3) "samsung,exynos7-clock-top1"
+	4) "samsung,exynos7-clock-atlas"
+	5) "samsung,exynos7-clock-ccore"
+	6) "samsung,exynos7-clock-imem"
+	7) "samsung,exynos7-clock-g3d"
+	8) "samsung,exynos7-clock-mif0"
+	9) "samsung,exynos7-clock-mif1"
+	10) "samsung,exynos7-clock-mif2"
+	11) "samsung,exynos7-clock-mif3"
+	12) "samsung,exynos7-clock-peric0"
+	13) "samsung,exynos7-clock-peric1"
+	14) "samsung,exynos7-clock-peris"
+	15) "samsung,exynos7-clock-bus0"
+	16) "samsung,exynos7-clock-bus1"
+	17) "samsung,exynos7-clock-fsys0"
+	18) "samsung,exynos7-clock-fsys1"
+	19) "samsung,exynos7-clock-disp"
+	20) "samsung,exynos7-clock-aud"
+	21) "samsung,exynos7-clock-mscl"
+	22) "samsung,exynos7-clock-mfc"
+
+ - reg: physical base address of the controller and the length of
+	memory mapped region.
+
+ - #clock-cells: should be 1.
+
+ - clocks: list of clock identifiers which are fed as the input to
+	the given clock controller. Please refer the next section to find
+	the input clocks for a given controller.
+
+ - clock-names: list of names of clocks which are fed as the input
+	to the given clock controller.
+
+Input clocks for topc clock controller:
+	- fin_pll
+	- fout_aud_pll
+	- fout_bus0_pl
+	- fout_bus1_pl
+	- fout_cc_pll
+	- fout_mfc_pll
+	- dout_sclk_cmu_apbif
+
+Input clocks for top0 clock controller:
+	- fin_pll
+	- fout_mif01_pll
+	- sclk_bus0_pll_mif
+	- sclk_bus0_pll_a
+	- sclk_bus1_pll_a
+	- sclk_cc_pll_a
+	- sclk_mfc_pll_a
+	- sclk_aud_pll
+	- sclk_cmu_apbif
+	- ioclk_audiocdclk0
+	- ioclk_audiocdclk1
+	- ioclk_spdif_extclk
+
+Input clocks for top1 clock controller:
+	- fin_pll
+	- fout_mif23_pll
+	- sclk_bus0_pll_mif
+	- sclk_bus0_pll_b
+	- sclk_bus1_pll_b
+	- sclk_cc_pll_b
+	- sclk_mfc_pll_b
+	- sclk_cmu_apbif
+
+Input clocks for ccore clock controller:
+	- fin_pll
+	- aclk_ccore_532
+	- aclk_ccore_133
+
+Input clocks for peric0 clock controller:
+	- fin_pll
+	- aclk_peric0_66
+	- sclk_uart0
+
+Input clocks for peric1 clock controller:
+	- fin_pll
+	- aclk_peric01_66
+	- sclk_uart1
+	- sclk_uart2
+	- sclk_uart3
+	- sclk_spi0
+	- sclk_spi1
+	- sclk_spi2
+	- sclk_spi3
+	- sclk_spi4
+	- sclk_i2s1
+	- sclk_pcm1
+	- sclk_spdif
+	- ioclk_i2s1_bclk
+	- ioclk_spi0_clk
+	- ioclk_spi1_clk
+	- ioclk_spi2_clk
+	- ioclk_spi3_clk
+	- ioclk_spi4_clk
+
+Input clocks for peris clock controller:
+	- fin_pll
+	- aclk_peris_66
+	- rtclk (blk_rtc)
+
+Input clocks for bus0 clock controller:
+	- fin_pll
+	- aclk_bus0_532
+
+Input clocks for bus1 clock controller:
+	- fin_pll
+	- aclk_bus1_200
+	- aclk_bus1_532
+
+Input clocks for fsys0 clock controller:
+	- fin_pll
+	- fout_hsic_pll
+	- aclk_fsys0_200
+	- sclk_phy_fsys0_26m
+	- aclk_usbdrd200
+	- sclk_mmc2
+	- sclk_ufsunipro11
+	- sclk_phy_fsys0
+	- phyclk_usbdrd300_udrd30_phyclock
+	- phyclk_usbdrd300_udrd30_pipe_pclk
+	- phyclk_usbhost20_phy_freeclk_hsic1
+	- phyclk_usbhost20_phy_phyclk_hsic1
+	- phyclk_ufs_tx0_symbol
+	- phyclk_ufs_rx0_symbol
+	- phyclk_lli_tx0_symbol
+	- phyclk_lli_rx0_symbol
+	- phyclk_pcie_tx0
+	- phyclk_pcie_rx0
+
+Input clocks for fsys1 clock controller:
+	- fin_pll
+	- aclk_fsys1_200
+	- sclk_phy_fsys1_26m
+	- sclk_mmc0
+	- sclk_mmc1
+	- sclk_ufsunipro20
+	- sclk_phy_fsys1
+	- sclk_txl400_wifi1
+	- phyclk_ufs20_tx0_symbol
+	- phyclk_ufs20_rx0_symbol
+	- phyclk_ufs20_rx1_symbol
+	- phyclk_pcie_wifi1_tx0
+	- phyclk_pcie_wifi1_rx0
+
+Input clocks for disp clock controller:
+	- fin_pll
+	- fout_disp_pll
+	- fout_dphy_pll
+	- aclk_disp_400
+	- sclk_dsd
+	- sclk_hdmi_spdif
+	- sclk_decon_int_eclk
+	- sclk_decon_ext_eclk
+	- sclk_decon_vclk
+	- phyclk_mipidphy0_rxclkesc0
+	- phyclk_mipidphy0_bitclkdiv8
+	- phyclk_mipidphy1_rxclkesc0
+	- phyclk_mipidphy1_bitclkdiv8
+	- sclk_rgb_vclk_dsim0
+	- sclk_rgb_vclk_dsim1
+	- sclk_decon_ext_vclk
+	- phyclk_dpphy_ch3_txd_clk
+	- phyclk_dpphy_ch2_txd_clk
+	- phyclk_dpphy_ch1_txd_clk
+	- phyclk_dpphy_ch0_txd_clk
+	- phyclk_hdmi_phy_tmds_clko
+	- phyclk_hdmi_phy_pixel_clko
+
+Input clocks for audio clock controller:
+	- fin_pll
+	- fout_aud_pll
+	- ioclk_audiocdclk0
+	- ioclk_slimbus_clk
+	- ioclk_i2s_bclk
drivers/clk/samsung/Makefile +1 -0
index 6fb4bc6..5da0ba9 100644
@@ -18,3 +18,4 @@ obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
 obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
 obj-$(CONFIG_ARCH_S3C64XX)	+= clk-s3c64xx.o
 obj-$(CONFIG_ARCH_S5PV210)	+= clk-s5pv210.o clk-s5pv210-audss.o
+obj-$(CONFIG_ARCH_EXYNOS7)	+= clk-exynos7.o
drivers/clk/samsung/clk-exynos7.c new file +1929 -0

1,929 lines not on this page · raw message

include/dt-bindings/clock/exynos7-clk.h new file +236 -0

236 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#5 lore raw

PATCH 4/14 clk: samsung: Add clock description for basic CMU blocks

Quoted 3 lines · Naveen Krishna Chatradhi

This patch adds clock description for MUX, DIV, GATE and PLL clocks available in TOPC, TOP0, TOP1, BUS0, BUS1, FSYS0, FSYS1, CCORE, PERIC0, PERIC1, PERIS, DISP, G3D, MSCL and MFC blocks.

[snip]

Documentation/devicetree/bindings/clock/exynos7-clock.txt line 28

Quoted 7 lines
Documentation/devicetree/bindings/clock/exynos7-clock.txt new file +7 -0
+Phy clocks:
+
+There are several clocks which are generated by specific PHYs.
+These clocks are fed into the clock controller and then routed to
+the hardware blocks. These clocks are defined as fixed clocks in the
+driver with following names:
+

The names are missing?

Quoted 8 lines
Documentation/devicetree/bindings/clock/exynos7-clock.txt new file +8 -0
+Required Properties for Clock Controller:
+
+ - compatible: should be one of the following.
+	1) "samsung,exynos7-clock-topc"
+	2) "samsung,exynos7-clock-top0"
+	3) "samsung,exynos7-clock-top1"
+	4) "samsung,exynos7-clock-atlas"
+	5) "samsung,exynos7-clock-ccore"

[snip]

Documentation/devicetree/bindings/clock/exynos7-clock.txt line 65

Quoted 6 lines

+ - clocks: list of clock identifiers which are fed as the input to

Documentation/devicetree/bindings/clock/exynos7-clock.txt new file +5 -0
+	the given clock controller. Please refer the next section to find
+	the input clocks for a given controller.
+
+ - clock-names: list of names of clocks which are fed as the input
+	to the given clock controller.

In the dtsi file added by patch 11/14, I don't see those being specified.

Quoted 4 lines
Documentation/devicetree/bindings/clock/exynos7-clock.txt new file +4 -0
+
+Input clocks for topc clock controller:
+	- fin_pll
+	- fout_aud_pll

[snip]

drivers/clk/samsung/clk-exynos7.c line 26

Quoted 4 lines
drivers/clk/samsung/clk-exynos7.c new file +4 -0
+/* PMS values for PLL 1451x */
+static const struct samsung_pll_rate_table pll1451x_24mhz_tbl[] = {
+	/* rate, m, p, s */
+	PLL_35XX_RATE(660000000, 165, 3, 1),

This array needs to be sorted by output rate. However you might want to rebase this series onto series [1] to eliminate this requirement. Be aware that mentioned series might need a respin, though.

Also the rates seem to be too nicely rounded. Are they the real values that can be obtained using the PLL equation (what is required by the PLL framework) or a copy paste from the documentation? Similarly, series [1] lessens the requirement a bit, due to recalculation of rates from specified coefficients and warning about incorrect entries.

[1]
https://www.mail-archive.com/linux-samsung-soc at vger.kernel.org/msg35188.html

Quoted 10 lines
drivers/clk/samsung/clk-exynos7.c new file +10 -0
+	PLL_35XX_RATE(1800000000, 150, 2, 0),
+	PLL_35XX_RATE(1700000000, 425, 6, 0),
+	PLL_35XX_RATE(1600000000, 200, 3, 0),
+	PLL_35XX_RATE(1500000000, 125, 2, 0),
+	PLL_35XX_RATE(1400000000, 175, 3, 0),
+	PLL_35XX_RATE(1380000000, 115, 2, 0),
+	PLL_35XX_RATE(1300000000, 325, 6, 0),
+	PLL_35XX_RATE(1200000000, 100, 2, 0),
+	PLL_35XX_RATE(1180000000, 295, 6, 0),
+	PLL_35XX_RATE(1104000000, 276, 6, 0),

[snip]

drivers/clk/samsung/clk-exynos7.c line 377

Quoted 6 lines
drivers/clk/samsung/clk-exynos7.c new file +6 -0
+	DIV(0, "dout_sclk_aud_pll", "mout_aud_pll_ctrl", DIV_TOPC3, 28, 3),
+};
+
+static struct samsung_gate_clock topc_gate_clks[] __initdata = {
+	GATE(ACLK_CCORE_532, "aclk_ccore_532", "dout_aclk_ccore_532",
+		ENABLE_ACLK_TOPC0, 0, CLK_IGNORE_UNUSED, 0),

Why CLK_IGNORE_UNUSED? (The same question for all the gate clocks defined with it in the driver.)

Best regards,
Tomasz

#6 lore raw

PATCH 4/14 clk: samsung: Add clock description for basic CMU blocks

Hi Tomasz,

Quoted 7 lines · Tomasz Figa
Quoted 3 lines · Naveen Krishna Chatradhi

This patch adds clock description for MUX, DIV, GATE and PLL clocks available in TOPC, TOP0, TOP1, BUS0, BUS1, FSYS0, FSYS1, CCORE, PERIC0, PERIC1, PERIS, DISP, G3D, MSCL and MFC blocks.

[snip]

Quoted 9 lines

Documentation/devicetree/bindings/clock/exynos7-clock.txt line 28

Quoted 7 lines
Documentation/devicetree/bindings/clock/exynos7-clock.txt new file +7 -0
+Phy clocks:
+
+There are several clocks which are generated by specific PHYs.
+These clocks are fed into the clock controller and then routed to
+the hardware blocks. These clocks are defined as fixed clocks in the
+driver with following names:
+

The names are missing?

Ok. Will fix.

Quoted 12 lines
Quoted 9 lines
Documentation/devicetree/bindings/clock/exynos7-clock.txt new file +8 -0
+Required Properties for Clock Controller:
+
+ - compatible: should be one of the following.
+     1) "samsung,exynos7-clock-topc"
+     2) "samsung,exynos7-clock-top0"
+     3) "samsung,exynos7-clock-top1"
+     4) "samsung,exynos7-clock-atlas"
+     5) "samsung,exynos7-clock-ccore"

[snip]

Quoted 8 lines

Documentation/devicetree/bindings/clock/exynos7-clock.txt line 65

Quoted 6 lines

+ - clocks: list of clock identifiers which are fed as the input to

Documentation/devicetree/bindings/clock/exynos7-clock.txt new file +5 -0
+     the given clock controller. Please refer the next section to find
+     the input clocks for a given controller.
+
+ - clock-names: list of names of clocks which are fed as the input
+     to the given clock controller.

In the dtsi file added by patch 11/14, I don't see those being specified.

Ok.

Quoted 8 lines
Quoted 5 lines
Documentation/devicetree/bindings/clock/exynos7-clock.txt new file +4 -0
+
+Input clocks for topc clock controller:
+     - fin_pll
+     - fout_aud_pll

[snip]

Quoted 8 lines

drivers/clk/samsung/clk-exynos7.c line 26

Quoted 4 lines
drivers/clk/samsung/clk-exynos7.c new file +4 -0
+/* PMS values for PLL 1451x */
+static const struct samsung_pll_rate_table pll1451x_24mhz_tbl[] = {
+     /* rate, m, p, s */
+     PLL_35XX_RATE(660000000, 165, 3, 1),

This array needs to be sorted by output rate. However you might want to rebase this series onto series [1] to eliminate this requirement. Be aware that mentioned series might need a respin, though.

Ok. Thanks for the pointer.

Quoted 6 lines

Also the rates seem to be too nicely rounded. Are they the real values that can be obtained using the PLL equation (what is required by the PLL framework) or a copy paste from the documentation? Similarly, series [1] lessens the requirement a bit, due to recalculation of rates from specified coefficients and warning about incorrect entries.

These rates are from the user manual. I will check in detail about these rates.

Quoted 17 lines

[1]
https://www.mail-archive.com/linux-samsung-soc at vger.kernel.org/msg35188.html

Quoted 10 lines
drivers/clk/samsung/clk-exynos7.c new file +10 -0
+     PLL_35XX_RATE(1800000000, 150, 2, 0),
+     PLL_35XX_RATE(1700000000, 425, 6, 0),
+     PLL_35XX_RATE(1600000000, 200, 3, 0),
+     PLL_35XX_RATE(1500000000, 125, 2, 0),
+     PLL_35XX_RATE(1400000000, 175, 3, 0),
+     PLL_35XX_RATE(1380000000, 115, 2, 0),
+     PLL_35XX_RATE(1300000000, 325, 6, 0),
+     PLL_35XX_RATE(1200000000, 100, 2, 0),
+     PLL_35XX_RATE(1180000000, 295, 6, 0),
+     PLL_35XX_RATE(1104000000, 276, 6, 0),

[snip]

Quoted 9 lines

drivers/clk/samsung/clk-exynos7.c line 377

Quoted 6 lines
drivers/clk/samsung/clk-exynos7.c new file +6 -0
+     DIV(0, "dout_sclk_aud_pll", "mout_aud_pll_ctrl", DIV_TOPC3, 28, 3),
+};
+
+static struct samsung_gate_clock topc_gate_clks[] __initdata = {
+     GATE(ACLK_CCORE_532, "aclk_ccore_532", "dout_aclk_ccore_532",
+             ENABLE_ACLK_TOPC0, 0, CLK_IGNORE_UNUSED, 0),

Why CLK_IGNORE_UNUSED? (The same question for all the gate clocks defined with it in the driver.)

Ok. Fixed.

Thanks.

Quoted 3 lines

Best regards,
Tomasz

Signature · 2 lines
Shine bright,
(: Nav :)
#7 lore raw

PATCH 5/14 pinctrl: exynos: Add driver data for Exynos7

In reply to Naveen Krishna Chatradhi

This patch adds driver data for Exynos7
to pinctrl-exynos driver. Exynos7 includes 229 multi-functional input/output ports. There are 40 general port groups.

Cc Tomasz Figa <[email protected]>
Cc linus.walleij at linaro.org
Cc Thomas Abraham <[email protected]>
---
 .../bindings/pinctrl/samsung-pinctrl.txt           |    1 +
 drivers/pinctrl/samsung/Kconfig                    |    2 +-
 drivers/pinctrl/samsung/pinctrl-exynos.c           |  145 ++++++++++++++++++++
 drivers/pinctrl/samsung/pinctrl-samsung.c          |    2 +
 drivers/pinctrl/samsung/pinctrl-samsung.h          |    1 +
 5 files changed, 150 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/pinctrl/samsung-pinctrl.txt +1 -0
index e82aaf4..2da258f 100644
@@ -18,6 +18,7 @@ Required Properties:
   - "samsung,exynos5250-pinctrl": for Exynos5250 compatible pin-controller.
   - "samsung,exynos5260-pinctrl": for Exynos5260 compatible pin-controller.
   - "samsung,exynos5420-pinctrl": for Exynos5420 compatible pin-controller.
+  - "samsung,exynos7-pinctrl": for Exynos7 compatible pin-controller.
 
 - reg: Base address of the pin controller hardware module and length of
   the address space it occupies.
drivers/pinctrl/samsung/Kconfig +1 -1
index d0461cd..c660d31 100644
@@ -8,7 +8,7 @@ config PINCTRL_SAMSUNG
 
 config PINCTRL_EXYNOS
 	bool "Pinctrl driver data for Samsung EXYNOS SoCs other than 5440"
-	depends on OF && GPIOLIB && (ARCH_EXYNOS || ARCH_S5PV210)
+	depends on OF && GPIOLIB && (ARCH_EXYNOS || ARCH_S5PV210 || ARCH_EXYNOS7)
 	select PINCTRL_SAMSUNG
 
 config PINCTRL_EXYNOS5440
drivers/pinctrl/samsung/pinctrl-exynos.c +145 -0

148 lines not on this page · raw message

drivers/pinctrl/samsung/pinctrl-samsung.c +2 -0
index b07406d..dd996b2f 100644
@@ -1232,6 +1232,8 @@ static const struct of_device_id samsung_pinctrl_dt_match[] = {
 		.data = (void *)exynos5420_pin_ctrl },
 	{ .compatible = "samsung,s5pv210-pinctrl",
 		.data = (void *)s5pv210_pin_ctrl },
+	{ .compatible = "samsung,exynos7-pinctrl",
+		.data = (void *)exynos7_pin_ctrl },
 #endif
 #ifdef CONFIG_PINCTRL_S3C64XX
 	{ .compatible = "samsung,s3c64xx-pinctrl",
drivers/pinctrl/samsung/pinctrl-samsung.h +1 -0
index 2b88232..d070a6d 100644
@@ -241,6 +241,7 @@ extern struct samsung_pin_ctrl exynos4x12_pin_ctrl[];
 extern struct samsung_pin_ctrl exynos5250_pin_ctrl[];
 extern struct samsung_pin_ctrl exynos5260_pin_ctrl[];
 extern struct samsung_pin_ctrl exynos5420_pin_ctrl[];
+extern struct samsung_pin_ctrl exynos7_pin_ctrl[];
 extern struct samsung_pin_ctrl s3c64xx_pin_ctrl[];
 extern struct samsung_pin_ctrl s3c2412_pin_ctrl[];
 extern struct samsung_pin_ctrl s3c2416_pin_ctrl[];
Signature · 1 line
1.7.9.5
#8 lore raw

PATCH 5/14 pinctrl: exynos: Add driver data for Exynos7

Quoted 8 lines · Naveen Krishna Chatradhi

This patch adds driver data for Exynos7
to pinctrl-exynos driver. Exynos7 includes 229 multi-functional input/output ports. There are 40 general port groups.

Cc Tomasz Figa <[email protected]>
Cc linus.walleij at linaro.org
Cc Thomas Abraham <[email protected]>

Tomasz can you have a look at this (from your private mail...)?

Yours,
Linus Walleij

#9 lore raw

PATCH 5/14 pinctrl: exynos: Add driver data for Exynos7

Hi Linus,

Quoted 7 lines · Linus Walleij
Quoted 4 lines · Naveen Krishna Chatradhi

This patch adds driver data for Exynos7
to pinctrl-exynos driver. Exynos7 includes 229 multi-functional input/output ports. There are 40 general port groups.

Quoted 6 lines
Quoted 4 lines
Cc Tomasz Figa <[email protected]>
Cc linus.walleij at linaro.org
Cc Thomas Abraham <[email protected]>

Tomasz can you have a look at this (from your private mail...)?

Sure. In fact I already took a look last week, and this patch in particular looks good. However I'm waiting for replies to my other comments in this thread, as some of them affect also this patch.

Best regards,
Tomasz

#10 lore raw

PATCH 6/14 pinctrl: samsung: use CONFIG_PINCTRL_SAMSUNG symbol in makefile

In reply to Naveen Krishna Chatradhi

Samsung Exynos7 is a ARM64bit processor. Which does not select the CONFIG_PLAT_SAMSUNG symbol. CONFIG_PINCTRL_SAMSUNG is being selected for both PLAT_SAMSUNG and ARCH_EXYNOS7 symbols.

This patch modifes the pinctrl/Makefile to use CONFIG_PINCTRL_SAMSUNG symbol to compile the pinctrl/samsung/*.c

Cc Tomasz Figa <[email protected]>
Cc linus.walleij at linaro.org
Cc Thomas Abraham <[email protected]>
---
 drivers/pinctrl/Makefile |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/pinctrl/Makefile +1 -1
index 05d2275..801777e 100644
@@ -58,7 +58,7 @@ obj-$(CONFIG_ARCH_BERLIN)	+= berlin/
 obj-$(CONFIG_PLAT_ORION)        += mvebu/
 obj-y				+= nomadik/
 obj-$(CONFIG_ARCH_QCOM)		+= qcom/
-obj-$(CONFIG_PLAT_SAMSUNG)	+= samsung/
+obj-$(CONFIG_PINCTRL_SAMSUNG)	+= samsung/
 obj-$(CONFIG_ARCH_SHMOBILE)	+= sh-pfc/
 obj-$(CONFIG_SUPERH)		+= sh-pfc/
 obj-$(CONFIG_PLAT_SPEAR)	+= spear/
Signature · 1 line
1.7.9.5
#11 lore raw

PATCH 6/14 pinctrl: samsung: use CONFIG_PINCTRL_SAMSUNG symbol in makefile

Quoted 11 lines · Naveen Krishna Chatradhi

Samsung Exynos7 is a ARM64bit processor. Which does not select the CONFIG_PLAT_SAMSUNG symbol. CONFIG_PINCTRL_SAMSUNG is being selected for both PLAT_SAMSUNG and ARCH_EXYNOS7 symbols.

This patch modifes the pinctrl/Makefile to use CONFIG_PINCTRL_SAMSUNG symbol to compile the pinctrl/samsung/*.c

Cc Tomasz Figa <[email protected]>
Cc linus.walleij at linaro.org
Cc Thomas Abraham <[email protected]>

Excellent catch, thanks, patch applied!

I should use this pattern on more places in the Makefile, I was confused by logically thinking that Kconfig symbols used in Makefile cannot be from a Kconfig one level below.

Yours,
Linus Walleij

#12 lore raw

PATCH 6/14 pinctrl: samsung: use CONFIG_PINCTRL_SAMSUNG symbol in makefile

Quoted 10 lines · Linus Walleij
Quoted 7 lines · Naveen Krishna Chatradhi

Samsung Exynos7 is a ARM64bit processor. Which does not select the CONFIG_PLAT_SAMSUNG symbol. CONFIG_PINCTRL_SAMSUNG is being selected for both PLAT_SAMSUNG and ARCH_EXYNOS7 symbols.

This patch modifes the pinctrl/Makefile to use CONFIG_PINCTRL_SAMSUNG symbol to compile the pinctrl/samsung/*.c

Quoted 6 lines
Quoted 4 lines
Cc Tomasz Figa <[email protected]>
Cc linus.walleij at linaro.org
Cc Thomas Abraham <[email protected]>

Excellent catch, thanks, patch applied!

Thanks Linus.

Quoted 7 lines

I should use this pattern on more places in the Makefile, I was confused by logically thinking that Kconfig symbols used in Makefile cannot be from a Kconfig one level below.

Yours,
Linus Walleij

Signature · 2 lines
Shine bright,
(: Nav :)
#13 lore raw

PATCH 1/14 clk: samsung: add support for 145xx and 1460x PLLs

In reply to Naveen Krishna Chatradhi
Quoted 6 lines · Naveen Krishna Chatradhi

By registers bits and offsets the 145xx PLL is similar to pll_type "pll_35xx". Also, 1460x PLL is similar to pll_type "pll_46xx".

Hence, reusing the functions defined for pll_35xx and pll_46xx to support 145xx and 1460x PLLs respectively.

[snip]

drivers/clk/samsung/clk-pll.c static const struct clk_ops samsung_pll3000_clk_ops = { · line 143

Quoted 5 lines
drivers/clk/samsung/clk-pll.c +1 -0
@@ -139,6 +140,7 @@ static const struct clk_ops samsung_pll3000_clk_ops = {
 #define PLL35XX_PDIV_SHIFT      (8)
 #define PLL35XX_SDIV_SHIFT      (0)
 #define PLL35XX_LOCK_STAT_SHIFT	(29)
+#define PLL145XX_ENABLE		BIT(31)

The same bit is also present in PLL35XX.

drivers/clk/samsung/clk-pll.c static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate, · line 193

Quoted 10 lines
drivers/clk/samsung/clk-pll.c +3 -0
 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
 				unsigned long parent_rate)
@@ -186,6 +188,10 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
 
 	tmp = __raw_readl(pll->con_reg);
 
+	/* Enable PLL */
+	if (pll->type == (pll_1450x || pll_1451x || pll_1452x))
+		tmp |= PLL145XX_ENABLE;

I believe that the need to enable the PLL is not really specific to pll_145xx. Any PLL which is initially disabled, should be enabled before trying to wait until it stabilizes.

drivers/clk/samsung/clk-pll.c static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate, · line 207

Quoted 13 lines
drivers/clk/samsung/clk-pll.c +4 -2
+
 	if (!(samsung_pll35xx_mp_change(rate, tmp))) {
 		/* If only s change, change just s value only*/
 		tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
@@ -196,8 +202,12 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
 	}
 
 	/* Set PLL lock time. */
-	__raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
-			pll->lock_reg);
+	if (pll->type == (pll_1450x || pll_1451x || pll_1452x))
+		__raw_writel(rate->pdiv * PLL145XX_LOCK_FACTOR,
+				pll->lock_reg);

If we already have lock_reg in pll, then maybe lock_factor could be added there too and this code simply parametrized?

drivers/clk/samsung/clk-pll.c static const struct clk_ops samsung_pll36xx_clk_min_ops = { · line 359

Quoted 11 lines
drivers/clk/samsung/clk-pll.c +3 -1
+	else
+		__raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
+				pll->lock_reg);
 
 	/* Change PLL PMS values */
 	tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
@@ -356,7 +366,6 @@ static const struct clk_ops samsung_pll36xx_clk_min_ops = {
 
 #define PLL45XX_ENABLE		BIT(31)
 #define PLL45XX_LOCKED		BIT(29)
-

Stray change?

Quoted 3 lines
drivers/clk/samsung/clk-pll.c +0 -0
 static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
 				unsigned long parent_rate)
 {

[snip]

drivers/clk/samsung/clk-pll.c static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate, · line 592

Quoted 7 lines
drivers/clk/samsung/clk-pll.c +2 -1
@@ -573,14 +588,23 @@ static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
 		lock = 0xffff;
 
 	/* Set PLL PMS and VSEL values. */
-	con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
+	if (pll->type == pll_1460x) {
+		con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |

Shouldn't PLL1460X_MDIV_MASK be used here instead?

Best regards,
Tomasz

#14 lore raw

PATCH 1/14 clk: samsung: add support for 145xx and 1460x PLLs

Hi Tomasz,

Quoted 25 lines · Tomasz Figa
Quoted 6 lines · Naveen Krishna Chatradhi

By registers bits and offsets the 145xx PLL is similar to pll_type "pll_35xx". Also, 1460x PLL is similar to pll_type "pll_46xx".

Hence, reusing the functions defined for pll_35xx and pll_46xx to support 145xx and 1460x PLLs respectively.

[snip]

drivers/clk/samsung/clk-pll.c static const struct clk_ops samsung_pll3000_clk_ops = { · line 143

Quoted 5 lines
drivers/clk/samsung/clk-pll.c +1 -0
@@ -139,6 +140,7 @@ static const struct clk_ops samsung_pll3000_clk_ops = {
 #define PLL35XX_PDIV_SHIFT      (8)
 #define PLL35XX_SDIV_SHIFT      (0)
 #define PLL35XX_LOCK_STAT_SHIFT      (29)
+#define PLL145XX_ENABLE              BIT(31)

The same bit is also present in PLL35XX.

Quoted 7 lines
drivers/clk/samsung/clk-pll.c +0 -0
 static unsigned long samsung_pll35xx_recalc_rate(struct clk_hw *hw,
                              unsigned long parent_rate)
@@ -186,6 +188,10 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
 
      tmp = __raw_readl(pll->con_reg);
 
Quoted 7 lines

drivers/clk/samsung/clk-pll.c static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate, · line 193

Quoted 3 lines
drivers/clk/samsung/clk-pll.c +3 -0
+     /* Enable PLL */
+     if (pll->type == (pll_1450x || pll_1451x || pll_1452x))
+             tmp |= PLL145XX_ENABLE;

I believe that the need to enable the PLL is not really specific to pll_145xx. Any PLL which is initially disabled, should be enabled before trying to wait until it stabilizes.

Yes, all other PLL types would also need this. Since I was adding support specifically for 145xx PLL, I put this in here. The 'if' check can be removed and used for 45xx PLL as well.

Quoted 8 lines
Quoted 8 lines
drivers/clk/samsung/clk-pll.c +1 -0
+
      if (!(samsung_pll35xx_mp_change(rate, tmp))) {
              /* If only s change, change just s value only*/
              tmp &= ~(PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT);
@@ -196,8 +202,12 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
      }
 
Quoted 9 lines

drivers/clk/samsung/clk-pll.c static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate, · line 207

Quoted 6 lines
drivers/clk/samsung/clk-pll.c +3 -2
      /* Set PLL lock time. */
-     __raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
-                     pll->lock_reg);
+     if (pll->type == (pll_1450x || pll_1451x || pll_1452x))
+             __raw_writel(rate->pdiv * PLL145XX_LOCK_FACTOR,
+                             pll->lock_reg);

If we already have lock_reg in pll, then maybe lock_factor could be added there too and this code simply parametrized?

Ok.

Quoted 9 lines
Quoted 9 lines
drivers/clk/samsung/clk-pll.c +3 -0
+     else
+             __raw_writel(rate->pdiv * PLL35XX_LOCK_FACTOR,
+                             pll->lock_reg);
 
      /* Change PLL PMS values */
      tmp &= ~((PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT) |
@@ -356,7 +366,6 @@ static const struct clk_ops samsung_pll36xx_clk_min_ops = {
 
Quoted 5 lines

drivers/clk/samsung/clk-pll.c static const struct clk_ops samsung_pll36xx_clk_min_ops = { · line 359

Quoted 3 lines
drivers/clk/samsung/clk-pll.c +0 -1
 #define PLL45XX_ENABLE               BIT(31)
 #define PLL45XX_LOCKED               BIT(29)
-

Stray change?

Yes. Fixed.

Quoted 10 lines
Quoted 4 lines
drivers/clk/samsung/clk-pll.c +0 -0
 static unsigned long samsung_pll45xx_recalc_rate(struct clk_hw *hw,
                              unsigned long parent_rate)
 {

[snip]

Quoted 3 lines
drivers/clk/samsung/clk-pll.c +0 -0
@@ -573,14 +588,23 @@ static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
              lock = 0xffff;
 
Quoted 6 lines

drivers/clk/samsung/clk-pll.c static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate, · line 592

Quoted 4 lines
drivers/clk/samsung/clk-pll.c +2 -1
      /* Set PLL PMS and VSEL values. */
-     con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |
+     if (pll->type == pll_1460x) {
+             con0 &= ~((PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT) |

Shouldn't PLL1460X_MDIV_MASK be used here instead?

Ok. Fixed.

Thanks.

Quoted 3 lines

Best regards,
Tomasz

Signature · 2 lines
Shine bright,
(: Nav )