Skip to contentSkip to conversation

Convert S3C2416 ad S3C2443 to common clock framework

PATCH Superseded Heiko Stübner 8 participants 23 messages Jul 9, 2013 – Aug 5, 2013

Subsystems (6)

v2 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v2 cover Convert S3C2416 ad S3C2443 to common clock framework

This series provides a clock driver for s3c2416, s3c2443 and s3c2450, which share a common clock tree, but differ fundamentally from earlier s3c24xx SoCs, and converts the mentioned SoCs to use it.

The clock driver itself follows the same scheme established by all other Samsung clock drivers.

It depends on the pwm cleanup series from Tomasz Figa, which gets rid of the declarations of the pwm-internal clocks.

Test on both non-dt and dt s3c2416.

Heiko Stuebner (6):
clk: samsung: move common plls registration into separate function
clk: samsung: fix error handling in pll register functions
clk: samsung: add plls used in s3c2416 and s3c2443
ARM: S3C24XX: enable legacy clock code only when SAMSUNG_CLOCK
selected
clk: samsung: add clock-driver for s3c2416, s3c2443 and s3c2450
ARM: S3C24XX: Convert s3c2416 and s3c2443 to common clock framework

 .../bindings/clock/samsung,s3c2443-clock.txt       |   48 ++
 arch/arm/boot/dts/s3c2416-smdk2416.dts             |    7 +
 arch/arm/boot/dts/s3c2416.dtsi                     |   42 ++
 arch/arm/mach-s3c24xx/Kconfig                      |   14 +-
 arch/arm/mach-s3c24xx/Makefile                     |    5 +-
 arch/arm/mach-s3c24xx/clock-s3c2416.c              |  171 -----
 arch/arm/mach-s3c24xx/clock-s3c2443.c              |  212 ------
 arch/arm/mach-s3c24xx/common-s3c2443.c             |  675 --------------------
 arch/arm/mach-s3c24xx/common.c                     |   20 +-
 arch/arm/mach-s3c24xx/common.h                     |    8 +
 arch/arm/mach-s3c24xx/mach-s3c2416-dt.c            |   45 +-
 arch/arm/mach-s3c24xx/mach-smdk2416.c              |    9 +-
 arch/arm/mach-s3c24xx/mach-smdk2443.c              |    9 +-
 drivers/clk/Kconfig                                |    1 +
 drivers/clk/samsung/Kconfig                        |    2 +
 drivers/clk/samsung/Makefile                       |    1 +
 drivers/clk/samsung/clk-pll.c                      |  374 +++++++++--
 drivers/clk/samsung/clk-pll.h                      |    8 +
 drivers/clk/samsung/clk-s3c2443.c                  |  422 ++++++++++++
 include/dt-bindings/clock/samsung,s3c2443-clock.h  |   96 +++
 20 files changed, 998 insertions(+), 1171 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2416.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2443.c
 delete mode 100644 arch/arm/mach-s3c24xx/common-s3c2443.c
 create mode 100644 drivers/clk/samsung/Kconfig
 create mode 100644 drivers/clk/samsung/clk-s3c2443.c
 create mode 100644 include/dt-bindings/clock/samsung,s3c2443-clock.h
Signature · 1 line
1.7.10.4
#1 lore raw

PATCH v2 1/6 clk: samsung: move common plls registration into separate function

All Samsung PLLs use similar code to register the clocks and clkdev lookups. Therefore move these into a separate function to reduce code duplication.

---
 drivers/clk/samsung/clk-pll.c |   68 +++++++++++++++++------------------------
 1 file changed, 28 insertions(+), 40 deletions(-)
drivers/clk/samsung/clk-pll.c +28 -40
index 362f12d..9153e46 100644
@@ -13,6 +13,24 @@
 #include "clk.h"
 #include "clk-pll.h"
 
+static inline struct clk *samsung_register_pll(struct clk_hw *hw)
+{
+	struct clk *clk;
+	const char *name = hw->init->name;
+
+	clk = clk_register(NULL, hw);
+	if (IS_ERR(clk)) {
+		pr_err("%s: failed to register pll clock %s\n", __func__,
+				name);
+		return clk;
+	}
+
+	if (clk_register_clkdev(clk, name, NULL))
+		pr_err("%s: failed to register lookup for %s", __func__, name);
+
+	return clk;
+}
+
 /*
  * PLL35xx Clock Type
  */
@@ -75,15 +93,9 @@ struct clk * __init samsung_clk_register_pll35xx(const char *name,
 	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);
+	clk = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
 		kfree(pll);
-	}
-
-	if (clk_register_clkdev(clk, name, NULL))
-		pr_err("%s: failed to register lookup for %s", __func__, name);
 
 	return clk;
 }
@@ -155,15 +167,9 @@ struct clk * __init samsung_clk_register_pll36xx(const char *name,
 	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);
+	clk = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
 		kfree(pll);
-	}
-
-	if (clk_register_clkdev(clk, name, NULL))
-		pr_err("%s: failed to register lookup for %s", __func__, name);
 
 	return clk;
 }
@@ -236,15 +242,9 @@ struct clk * __init samsung_clk_register_pll45xx(const char *name,
 	pll->con_reg = con_reg;
 	pll->type = type;
 
-	clk = clk_register(NULL, &pll->hw);
-	if (IS_ERR(clk)) {
-		pr_err("%s: failed to register pll clock %s\n", __func__,
-				name);
+	clk = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
 		kfree(pll);
-	}
-
-	if (clk_register_clkdev(clk, name, NULL))
-		pr_err("%s: failed to register lookup for %s", __func__, name);
 
 	return clk;
 }
@@ -323,15 +323,9 @@ struct clk * __init samsung_clk_register_pll46xx(const char *name,
 	pll->con_reg = con_reg;
 	pll->type = type;
 
-	clk = clk_register(NULL, &pll->hw);
-	if (IS_ERR(clk)) {
-		pr_err("%s: failed to register pll clock %s\n", __func__,
-				name);
+	clk = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
 		kfree(pll);
-	}
-
-	if (clk_register_clkdev(clk, name, NULL))
-		pr_err("%s: failed to register lookup for %s", __func__, name);
 
 	return clk;
 }
@@ -406,15 +400,9 @@ struct clk * __init samsung_clk_register_pll2550x(const char *name,
 	pll->reg_base = reg_base;
 	pll->offset = offset;
 
-	clk = clk_register(NULL, &pll->hw);
-	if (IS_ERR(clk)) {
-		pr_err("%s: failed to register pll clock %s\n", __func__,
-				name);
+	clk = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
 		kfree(pll);
-	}
-
-	if (clk_register_clkdev(clk, name, NULL))
-		pr_err("%s: failed to register lookup for %s", __func__, name);
 
 	return clk;
 }
Signature · 1 line
1.7.10.4
#2 lore raw

PATCH v2 1/6 clk: samsung: move common plls registration into separate function

Hi Heiko,

Quoted 6 lines · Heiko St?bner

All Samsung PLLs use similar code to register the clocks and clkdev lookups. Therefore move these into a separate function to reduce code duplication.

---

I have posted patch for adding common pll registration function which some how missed to get merged. I hope will get merged after rc1. Please give a look at that :
http://www.mail-archive.com/linux-samsung-soc at vger.kernel.org/msg19543.html

Regards,
Yadwinder

#3 lore raw

PATCH v2 1/6 clk: samsung: move common plls registration into separate function

Hi,

Quoted 7 lines · On Wednesday 10 of July 2013 22:29:13 Yadwinder Singh Brar wrote:

Hi Heiko,

Quoted 4 lines · Heiko St?bner

All Samsung PLLs use similar code to register the clocks and clkdev lookups. Therefore move these into a separate function to reduce code duplication.

Quoted 8 lines
Quoted 3 lines

---

I have posted patch for adding common pll registration function which some how missed to get merged. I hope will get merged after rc1. Please give a look at that :
http://www.mail-archive.com/linux-samsung-soc at vger.kernel.org/msg19543.html

Yeah, I was going to post a link to it, but I couldn't find it on any mailing list archive. I think we should go with the way of registration introduced by Yadwinder.

Best regards,
Tomasz

#4 lore raw

PATCH v2 1/6 clk: samsung: move common plls registration into separate function

Am Donnerstag, 11. Juli 2013, 09:46:53 schrieb Tomasz Figa:

Quoted 20 lines

Hi,

Quoted 11 lines · On Wednesday 10 of July 2013 22:29:13 Yadwinder Singh Brar wrote:

Hi Heiko,

Quoted 7 lines · Heiko St?bner

All Samsung PLLs use similar code to register the clocks and clkdev lookups. Therefore move these into a separate function to reduce code duplication.

---

Quoted 5 lines

I have posted patch for adding common pll registration function which some how missed to get merged. I hope will get merged after rc1. Please give a look at that :
http://www.mail-archive.com/linux-samsung-soc at vger.kernel.org/msg19543.ht ml

Quoted 3 lines

Yeah, I was going to post a link to it, but I couldn't find it on any mailing list archive. I think we should go with the way of registration introduced by Yadwinder.

the linked patch looks nice, thanks for the link. So I'll redo the plls against it in the next round.

Heiko

#5 lore raw

PATCH v2 1/6 clk: samsung: move common plls registration into separate function

Quoting Heiko St?bner (2013-07-11 01:52:13)

Quoted 21 lines

Am Donnerstag, 11. Juli 2013, 09:46:53 schrieb Tomasz Figa:

Quoted 20 lines

Hi,

Quoted 16 lines · On Wednesday 10 of July 2013 22:29:13 Yadwinder Singh Brar wrote:

Hi Heiko,

Quoted 7 lines · Heiko St?bner

All Samsung PLLs use similar code to register the clocks and clkdev lookups. Therefore move these into a separate function to reduce code duplication.

---

I have posted patch for adding common pll registration function which some how missed to get merged. I hope will get merged after rc1. Please give a look at that :
http://www.mail-archive.com/linux-samsung-soc at vger.kernel.org/msg19543.ht ml

Quoted 6 lines
Quoted 3 lines

Yeah, I was going to post a link to it, but I couldn't find it on any mailing list archive. I think we should go with the way of registration introduced by Yadwinder.

the linked patch looks nice, thanks for the link. So I'll redo the plls against it in the next round.

I just took that series into clk-next, so you can base v2 of this series against clk-next.

Regards,
Mike

Quoted 3 lines

Heiko

#6 lore raw

PATCH v2 2/6 clk: samsung: fix error handling in pll register functions

In reply to Heiko Stübner

kmalloc has its own error reporting when the allocation fails and the register functions also should return the correct ERR_PTR(-ENOMEM) when it happens.

---
 drivers/clk/samsung/clk-pll.c |   30 ++++++++++--------------------
 1 file changed, 10 insertions(+), 20 deletions(-)
drivers/clk/samsung/clk-pll.c +10 -20
index 9153e46..0afaec6 100644
@@ -79,10 +79,8 @@ struct clk * __init samsung_clk_register_pll35xx(const char *name,
 	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;
-	}
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
 
 	init.name = name;
 	init.ops = &samsung_pll35xx_clk_ops;
@@ -153,10 +151,8 @@ struct clk * __init samsung_clk_register_pll36xx(const char *name,
 	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;
-	}
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
 
 	init.name = name;
 	init.ops = &samsung_pll36xx_clk_ops;
@@ -227,10 +223,8 @@ struct clk * __init samsung_clk_register_pll45xx(const char *name,
 	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;
-	}
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
 
 	init.name = name;
 	init.ops = &samsung_pll45xx_clk_ops;
@@ -308,10 +302,8 @@ struct clk * __init samsung_clk_register_pll46xx(const char *name,
 	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;
-	}
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
 
 	init.name = name;
 	init.ops = &samsung_pll46xx_clk_ops;
@@ -385,10 +377,8 @@ struct clk * __init samsung_clk_register_pll2550x(const char *name,
 	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;
-	}
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
 
 	init.name = name;
 	init.ops = &samsung_pll2550x_clk_ops;
Signature · 1 line
1.7.10.4
#7 lore raw

PATCH v2 2/6 clk: samsung: fix error handling in pll register functions

Hi Heiko,

Quoted 8 lines · On Wednesday 10 of July 2013 00:58:13 Heiko St?bner wrote:

kmalloc has its own error reporting when the allocation fails and the register functions also should return the correct ERR_PTR(-ENOMEM) when it happens.

---
 drivers/clk/samsung/clk-pll.c |   30 ++++++++++--------------------
 1 file changed, 10 insertions(+), 20 deletions(-)

This patch looks pretty good, but I'm not sure if this problem still exists after applying Yadwinder's patches that completely changes the way of PLL registration.

Best regards,
Tomasz

Quoted 69 lines
drivers/clk/samsung/clk-pll.c +10 -20
index 9153e46..0afaec6 100644
@@ -79,10 +79,8 @@ struct clk * __init samsung_clk_register_pll35xx(const
 char *name, 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;
-	}
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
 
 	init.name = name;
 	init.ops = &samsung_pll35xx_clk_ops;
@@ -153,10 +151,8 @@ struct clk * __init samsung_clk_register_pll36xx(const
 char *name, 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;
-	}
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
 
 	init.name = name;
 	init.ops = &samsung_pll36xx_clk_ops;
@@ -227,10 +223,8 @@ struct clk * __init samsung_clk_register_pll45xx(const
 char *name, 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;
-	}
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
 
 	init.name = name;
 	init.ops = &samsung_pll45xx_clk_ops;
@@ -308,10 +302,8 @@ struct clk * __init samsung_clk_register_pll46xx(const
 char *name, 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;
-	}
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
 
 	init.name = name;
 	init.ops = &samsung_pll46xx_clk_ops;
@@ -385,10 +377,8 @@ struct clk * __init samsung_clk_register_pll2550x(const
 char *name, 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;
-	}
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
 
 	init.name = name;
 	init.ops = &samsung_pll2550x_clk_ops;
#8 lore raw

PATCH v2 3/6 clk: samsung: add plls used in s3c2416 and s3c2443

In reply to Heiko Stübner

This adds support for pll2126x, pll3000x, pll6552x and pll6553x.

---
 drivers/clk/samsung/clk-pll.c |  280 +++++++++++++++++++++++++++++++++++++++++
 drivers/clk/samsung/clk-pll.h |    8 ++
 2 files changed, 288 insertions(+)
drivers/clk/samsung/clk-pll.c +280 -0
index 0afaec6..35c15a1 100644
@@ -323,6 +323,73 @@ struct clk * __init samsung_clk_register_pll46xx(const char *name,
 }
 
 /*
+ * PLL2126x Clock Type
+ */
+
+#define PLL2126X_MDIV_MASK	(0xFF)
+#define PLL2126X_PDIV_MASK	(0x3)
+#define PLL2126X_SDIV_MASK	(0x3)
+#define PLL2126X_MDIV_SHIFT	(16)
+#define PLL2126X_PDIV_SHIFT	(8)
+#define PLL2126X_SDIV_SHIFT	(0)
+
+struct samsung_clk_pll2126x {
+	struct clk_hw		hw;
+	const void __iomem	*con_reg;
+};
+
+#define to_clk_pll2126x(_hw) container_of(_hw, struct samsung_clk_pll2126x, hw)
+
+static unsigned long samsung_pll2126x_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct samsung_clk_pll2126x *pll = to_clk_pll2126x(hw);
+	u32 pll_con, mdiv, pdiv, sdiv;
+	u64 fvco = parent_rate;
+
+	pll_con = __raw_readl(pll->con_reg);
+	mdiv = (pll_con >> PLL2126X_MDIV_SHIFT) & PLL2126X_MDIV_MASK;
+	pdiv = (pll_con >> PLL2126X_PDIV_SHIFT) & PLL2126X_PDIV_MASK;
+	sdiv = (pll_con >> PLL2126X_SDIV_SHIFT) & PLL2126X_SDIV_MASK;
+
+	fvco *= (mdiv + 8);
+	do_div(fvco, (pdiv + 2) << sdiv);
+
+	return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll2126x_clk_ops = {
+	.recalc_rate = samsung_pll2126x_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll2126x(const char *name,
+			const char *pname, const void __iomem *con_reg)
+{
+	struct samsung_clk_pll2126x *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &samsung_pll2126x_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 = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+
+/*
  * PLL2550x Clock Type
  */
 
@@ -396,3 +463,216 @@ struct clk * __init samsung_clk_register_pll2550x(const char *name,
 
 	return clk;
 }
+
+/*
+ * PLL3000x Clock Type
+ */
+
+#define PLL3000X_MDIV_MASK	(0xFF)
+#define PLL3000X_PDIV_MASK	(0x3)
+#define PLL3000X_SDIV_MASK	(0x3)
+#define PLL3000X_MDIV_SHIFT	(16)
+#define PLL3000X_PDIV_SHIFT	(8)
+#define PLL3000X_SDIV_SHIFT	(0)
+
+struct samsung_clk_pll3000x {
+	struct clk_hw		hw;
+	const void __iomem	*con_reg;
+};
+
+#define to_clk_pll3000x(_hw) container_of(_hw, struct samsung_clk_pll3000x, hw)
+
+static unsigned long samsung_pll3000x_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct samsung_clk_pll3000x *pll = to_clk_pll3000x(hw);
+	u32 pll_con, mdiv, pdiv, sdiv;
+	u64 fvco = parent_rate;
+
+	pll_con = __raw_readl(pll->con_reg);
+	mdiv = (pll_con >> PLL3000X_MDIV_SHIFT) & PLL3000X_MDIV_MASK;
+	pdiv = (pll_con >> PLL3000X_PDIV_SHIFT) & PLL3000X_PDIV_MASK;
+	sdiv = (pll_con >> PLL3000X_SDIV_SHIFT) & PLL3000X_SDIV_MASK;
+
+	fvco *= (2 * (mdiv + 8));
+	do_div(fvco, pdiv << sdiv);
+
+	return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll3000x_clk_ops = {
+	.recalc_rate = samsung_pll3000x_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll3000x(const char *name,
+			const char *pname, const void __iomem *con_reg)
+{
+	struct samsung_clk_pll3000x *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &samsung_pll3000x_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 = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+
+/*
+ * PLL6552x Clock Type
+ */
+
+#define PLL6552X_MDIV_MASK	(0x3FF)
+#define PLL6552X_PDIV_MASK	(0x3F)
+#define PLL6552X_SDIV_MASK	(0x7)
+#define PLL6552X_MDIV_SHIFT	(14)
+#define PLL6552X_PDIV_SHIFT	(5)
+#define PLL6552X_SDIV_SHIFT	(0)
+
+struct samsung_clk_pll6552x {
+	struct clk_hw		hw;
+	const void __iomem	*con_reg;
+};
+
+#define to_clk_pll6552x(_hw) container_of(_hw, struct samsung_clk_pll6552x, hw)
+
+static unsigned long samsung_pll6552x_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct samsung_clk_pll6552x *pll = to_clk_pll6552x(hw);
+	u32 pll_con, mdiv, pdiv, sdiv;
+	u64 fvco = parent_rate;
+
+	pll_con = __raw_readl(pll->con_reg);
+	mdiv = (pll_con >> PLL6552X_MDIV_SHIFT) & PLL6552X_MDIV_MASK;
+	pdiv = (pll_con >> PLL6552X_PDIV_SHIFT) & PLL6552X_PDIV_MASK;
+	sdiv = (pll_con >> PLL6552X_SDIV_SHIFT) & PLL6552X_SDIV_MASK;
+
+	fvco *= mdiv;
+	do_div(fvco, (pdiv << sdiv));
+
+	return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll6552x_clk_ops = {
+	.recalc_rate = samsung_pll6552x_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll6552x(const char *name,
+			const char *pname, const void __iomem *con_reg)
+{
+	struct samsung_clk_pll6552x *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &samsung_pll6552x_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 = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+
+/*
+ * PLL6553x Clock Type
+ */
+
+#define PLL6553X_MDIV_MASK	(0x7F)
+#define PLL6553X_PDIV_MASK	(0x1F)
+#define PLL6553X_SDIV_MASK	(0x3)
+#define PLL6553X_KDIV_MASK	(0xFFFF)
+#define PLL6553X_MDIV_SHIFT	(16)
+#define PLL6553X_PDIV_SHIFT	(8)
+#define PLL6553X_SDIV_SHIFT	(0)
+
+struct samsung_clk_pll6553x {
+	struct clk_hw		hw;
+	const void __iomem	*con_reg;
+};
+
+#define to_clk_pll6553x(_hw) container_of(_hw, struct samsung_clk_pll6553x, hw)
+
+static unsigned long samsung_pll6553x_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct samsung_clk_pll6553x *pll = to_clk_pll6553x(hw);
+	u32 pll_con0, pll_con1, mdiv, pdiv, sdiv, kdiv;
+	u64 fvco = parent_rate;
+
+	pll_con0 = __raw_readl(pll->con_reg);
+	pll_con1 = __raw_readl(pll->con_reg + 4);
+	mdiv = (pll_con0 >> PLL6553X_MDIV_SHIFT) & PLL6553X_MDIV_MASK;
+	pdiv = (pll_con0 >> PLL6553X_PDIV_SHIFT) & PLL6553X_PDIV_MASK;
+	sdiv = (pll_con0 >> PLL6553X_SDIV_SHIFT) & PLL6553X_SDIV_MASK;
+	kdiv = pll_con1 & PLL6553X_KDIV_MASK;
+
+	/*
+	 * We need to multiple parent_rate by mdiv (the integer part) and kdiv
+	 * which is in 2^16ths, so shift mdiv up (does not overflow) and
+	 * add kdiv before multiplying. The use of tmp is to avoid any
+	 * overflows before shifting bac down into result when multipling
+	 * by the mdiv and kdiv pair.
+	 */
+
+	fvco *= (mdiv << 16) + kdiv;
+	do_div(fvco, (pdiv << sdiv));
+	fvco >>= 16;
+
+	return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll6553x_clk_ops = {
+	.recalc_rate = samsung_pll6553x_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll6553x(const char *name,
+			const char *pname, const void __iomem *con_reg)
+{
+	struct samsung_clk_pll6553x *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &samsung_pll6553x_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 = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
drivers/clk/samsung/clk-pll.h +8 -0
index f33786e..465ee6f 100644
@@ -34,8 +34,16 @@ extern struct clk * __init samsung_clk_register_pll45xx(const char *name,
 extern struct clk * __init samsung_clk_register_pll46xx(const char *name,
 			const char *pname, const void __iomem *con_reg,
 			enum pll46xx_type type);
+extern struct clk * __init samsung_clk_register_pll2126x(const char *name,
+			const char *pname, const void __iomem *con_reg);
 extern struct clk * __init samsung_clk_register_pll2550x(const char *name,
 			const char *pname, const void __iomem *reg_base,
 			const unsigned long offset);
+extern struct clk * __init samsung_clk_register_pll3000x(const char *name,
+			const char *pname, const void __iomem *con_reg);
+extern struct clk * __init samsung_clk_register_pll6552x(const char *name,
+			const char *pname, const void __iomem *con_reg);
+extern struct clk * __init samsung_clk_register_pll6553x(const char *name,
+			const char *pname, const void __iomem *con_reg);
 
 #endif /* __SAMSUNG_CLK_PLL_H */
Signature · 1 line
1.7.10.4
#9 lore raw

PATCH v2 3/6 clk: samsung: add plls used in s3c2416 and s3c2443

Hi Heiko,

Quoted 8 lines · On Wednesday 10 of July 2013 00:59:08 Heiko St?bner wrote:

This adds support for pll2126x, pll3000x, pll6552x and pll6553x.

---
 drivers/clk/samsung/clk-pll.c |  280
+++++++++++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk-pll.h |  
 8 ++
 2 files changed, 288 insertions(+)

Generally the patch looks good, but I have some comments to the part related to 655xx PLLs.

I had a patch adding support for them too, but we can go with yours, since the way of registration has been changed by Yadwinder's patches and mine would have to be updated anyway.

Quoted 151 lines
drivers/clk/samsung/clk-pll.c +16 -0
index 0afaec6..35c15a1 100644
@@ -323,6 +323,73 @@ struct clk * __init samsung_clk_register_pll46xx(const
 char *name, }
 
 /*
+ * PLL2126x Clock Type
+ */
+
+#define PLL2126X_MDIV_MASK	(0xFF)
+#define PLL2126X_PDIV_MASK	(0x3)
+#define PLL2126X_SDIV_MASK	(0x3)
+#define PLL2126X_MDIV_SHIFT	(16)
+#define PLL2126X_PDIV_SHIFT	(8)
+#define PLL2126X_SDIV_SHIFT	(0)
+
+struct samsung_clk_pll2126x {
+	struct clk_hw		hw;
+	const void __iomem	*con_reg;
+};
+
+#define to_clk_pll2126x(_hw) container_of(_hw, struct samsung_clk_pll2126x,

hw) +

drivers/clk/samsung/clk-pll.c +68 -0
+static unsigned long samsung_pll2126x_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct samsung_clk_pll2126x *pll = to_clk_pll2126x(hw);
+	u32 pll_con, mdiv, pdiv, sdiv;
+	u64 fvco = parent_rate;
+
+	pll_con = __raw_readl(pll->con_reg);
+	mdiv = (pll_con >> PLL2126X_MDIV_SHIFT) & PLL2126X_MDIV_MASK;
+	pdiv = (pll_con >> PLL2126X_PDIV_SHIFT) & PLL2126X_PDIV_MASK;
+	sdiv = (pll_con >> PLL2126X_SDIV_SHIFT) & PLL2126X_SDIV_MASK;
+
+	fvco *= (mdiv + 8);
+	do_div(fvco, (pdiv + 2) << sdiv);
+
+	return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll2126x_clk_ops = {
+	.recalc_rate = samsung_pll2126x_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll2126x(const char *name,
+			const char *pname, const void __iomem *con_reg)
+{
+	struct samsung_clk_pll2126x *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &samsung_pll2126x_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 = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+
+/*
  * PLL2550x Clock Type
  */
@@ -396,3 +463,216 @@ struct clk * __init
 samsung_clk_register_pll2550x(const char *name,
 
 	return clk;
 }
+
+/*
+ * PLL3000x Clock Type
+ */
+
+#define PLL3000X_MDIV_MASK	(0xFF)
+#define PLL3000X_PDIV_MASK	(0x3)
+#define PLL3000X_SDIV_MASK	(0x3)
+#define PLL3000X_MDIV_SHIFT	(16)
+#define PLL3000X_PDIV_SHIFT	(8)
+#define PLL3000X_SDIV_SHIFT	(0)
+
+struct samsung_clk_pll3000x {
+	struct clk_hw		hw;
+	const void __iomem	*con_reg;
+};
+
+#define to_clk_pll3000x(_hw) container_of(_hw, struct samsung_clk_pll3000x,

hw) +

drivers/clk/samsung/clk-pll.c +49 -0
+static unsigned long samsung_pll3000x_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct samsung_clk_pll3000x *pll = to_clk_pll3000x(hw);
+	u32 pll_con, mdiv, pdiv, sdiv;
+	u64 fvco = parent_rate;
+
+	pll_con = __raw_readl(pll->con_reg);
+	mdiv = (pll_con >> PLL3000X_MDIV_SHIFT) & PLL3000X_MDIV_MASK;
+	pdiv = (pll_con >> PLL3000X_PDIV_SHIFT) & PLL3000X_PDIV_MASK;
+	sdiv = (pll_con >> PLL3000X_SDIV_SHIFT) & PLL3000X_SDIV_MASK;
+
+	fvco *= (2 * (mdiv + 8));
+	do_div(fvco, pdiv << sdiv);
+
+	return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll3000x_clk_ops = {
+	.recalc_rate = samsung_pll3000x_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll3000x(const char *name,
+			const char *pname, const void __iomem *con_reg)
+{
+	struct samsung_clk_pll3000x *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &samsung_pll3000x_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 = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+

drivers/clk/samsung/clk-pll.c struct clk * __init samsung_clk_register_pll2550x(const char *name, · line 543

Quoted 10 lines
drivers/clk/samsung/clk-pll.c +10 -0
+/*
+ * PLL6552x Clock Type
+ */
+
+#define PLL6552X_MDIV_MASK	(0x3FF)
+#define PLL6552X_PDIV_MASK	(0x3F)
+#define PLL6552X_SDIV_MASK	(0x7)
+#define PLL6552X_MDIV_SHIFT	(14)
+#define PLL6552X_PDIV_SHIFT	(5)
+#define PLL6552X_SDIV_SHIFT	(0)

Are you sure about those bitfields?

In S3C6410 User's Manual they are different. You can look at my patch for a comparison:

http://thread.gmane.org/gmane.linux.usb.general/87571/focus=88344

Quoted 57 lines
drivers/clk/samsung/clk-pll.c +6 -0
+struct samsung_clk_pll6552x {
+	struct clk_hw		hw;
+	const void __iomem	*con_reg;
+};
+
+#define to_clk_pll6552x(_hw) container_of(_hw, struct samsung_clk_pll6552x,

hw) +

drivers/clk/samsung/clk-pll.c +50 -0
+static unsigned long samsung_pll6552x_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct samsung_clk_pll6552x *pll = to_clk_pll6552x(hw);
+	u32 pll_con, mdiv, pdiv, sdiv;
+	u64 fvco = parent_rate;
+
+	pll_con = __raw_readl(pll->con_reg);
+	mdiv = (pll_con >> PLL6552X_MDIV_SHIFT) & PLL6552X_MDIV_MASK;
+	pdiv = (pll_con >> PLL6552X_PDIV_SHIFT) & PLL6552X_PDIV_MASK;
+	sdiv = (pll_con >> PLL6552X_SDIV_SHIFT) & PLL6552X_SDIV_MASK;
+
+	fvco *= mdiv;
+	do_div(fvco, (pdiv << sdiv));
+
+	return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll6552x_clk_ops = {
+	.recalc_rate = samsung_pll6552x_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll6552x(const char *name,
+			const char *pname, const void __iomem *con_reg)
+{
+	struct samsung_clk_pll6552x *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &samsung_pll6552x_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 = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+
+/*

drivers/clk/samsung/clk-pll.c struct clk * __init samsung_clk_register_pll2550x(const char *name, · line 611

Quoted 10 lines
drivers/clk/samsung/clk-pll.c +10 -0
+ * PLL6553x Clock Type
+ */
+
+#define PLL6553X_MDIV_MASK	(0x7F)
+#define PLL6553X_PDIV_MASK	(0x1F)
+#define PLL6553X_SDIV_MASK	(0x3)
+#define PLL6553X_KDIV_MASK	(0xFFFF)
+#define PLL6553X_MDIV_SHIFT	(16)
+#define PLL6553X_PDIV_SHIFT	(8)
+#define PLL6553X_SDIV_SHIFT	(0)

Same about those bitfields. They seem to be different on S3C64xx.

Best regards,
Tomasz

#10 lore raw

PATCH v2 3/6 clk: samsung: add plls used in s3c2416 and s3c2443

Am Donnerstag, 11. Juli 2013, 10:16:41 schrieb Tomasz Figa:

Quoted 31 lines

Hi Heiko,

Quoted 11 lines · On Wednesday 10 of July 2013 00:59:08 Heiko St?bner wrote:

This adds support for pll2126x, pll3000x, pll6552x and pll6553x.

---

 drivers/clk/samsung/clk-pll.c |  280

+++++++++++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk-pll.h |

8 ++

 2 files changed, 288 insertions(+)

Generally the patch looks good, but I have some comments to the part related to 655xx PLLs.

I had a patch adding support for them too, but we can go with yours, since the way of registration has been changed by Yadwinder's patches and mine would have to be updated anyway.

Quoted 9 lines
(quoted diff) +0 -0

b/drivers/clk/samsung/clk-pll.c index 0afaec6..35c15a1 100644

drivers/clk/samsung/clk-pll.c +0 -0
@@ -323,6 +323,73 @@ struct clk * __init
 samsung_clk_register_pll46xx(const char *name, }
 
 /*
 
Quoted 9 lines

drivers/clk/samsung/clk-pll.c struct clk * __init samsung_clk_register_pll46xx(const char *name, · line 334

Quoted 9 lines
drivers/clk/samsung/clk-pll.c +9 -0
+ * PLL2126x Clock Type
+ */
+
+#define PLL2126X_MDIV_MASK	(0xFF)
+#define PLL2126X_PDIV_MASK	(0x3)
+#define PLL2126X_SDIV_MASK	(0x3)
+#define PLL2126X_MDIV_SHIFT	(16)
+#define PLL2126X_PDIV_SHIFT	(8)
+#define PLL2126X_SDIV_SHIFT	(0)

+#define PLL2126X_PDIV_MASK (0x3F)

is the correct value.

Quoted 69 lines
Quoted 69 lines
drivers/clk/samsung/clk-pll.c +7 -0
+
+struct samsung_clk_pll2126x {
+	struct clk_hw		hw;
+	const void __iomem	*con_reg;
+};
+
+#define to_clk_pll2126x(_hw) container_of(_hw, struct

samsung_clk_pll2126x, hw) +

drivers/clk/samsung/clk-pll.c +50 -0
+static unsigned long samsung_pll2126x_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct samsung_clk_pll2126x *pll = to_clk_pll2126x(hw);
+	u32 pll_con, mdiv, pdiv, sdiv;
+	u64 fvco = parent_rate;
+
+	pll_con = __raw_readl(pll->con_reg);
+	mdiv = (pll_con >> PLL2126X_MDIV_SHIFT) & PLL2126X_MDIV_MASK;
+	pdiv = (pll_con >> PLL2126X_PDIV_SHIFT) & PLL2126X_PDIV_MASK;
+	sdiv = (pll_con >> PLL2126X_SDIV_SHIFT) & PLL2126X_SDIV_MASK;
+
+	fvco *= (mdiv + 8);
+	do_div(fvco, (pdiv + 2) << sdiv);
+
+	return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll2126x_clk_ops = {
+	.recalc_rate = samsung_pll2126x_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll2126x(const char *name,
+			const char *pname, const void __iomem *con_reg)
+{
+	struct samsung_clk_pll2126x *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &samsung_pll2126x_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 = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+
+/*
 
  * PLL2550x Clock Type
  */
@@ -396,3 +463,216 @@ struct clk * __init
 samsung_clk_register_pll2550x(const char *name,
 
 	return clk;
 
 }
Quoted 11 lines

drivers/clk/samsung/clk-pll.c struct clk * __init samsung_clk_register_pll2550x(const char *name, · line 476

Quoted 11 lines
drivers/clk/samsung/clk-pll.c +11 -0
+
+/*
+ * PLL3000x Clock Type
+ */
+
+#define PLL3000X_MDIV_MASK	(0xFF)
+#define PLL3000X_PDIV_MASK	(0x3)
+#define PLL3000X_SDIV_MASK	(0x3)
+#define PLL3000X_MDIV_SHIFT	(16)
+#define PLL3000X_PDIV_SHIFT	(8)
+#define PLL3000X_SDIV_SHIFT	(0)

these are correct.

Quoted 70 lines
Quoted 57 lines
drivers/clk/samsung/clk-pll.c +7 -0
+
+struct samsung_clk_pll3000x {
+	struct clk_hw		hw;
+	const void __iomem	*con_reg;
+};
+
+#define to_clk_pll3000x(_hw) container_of(_hw, struct

samsung_clk_pll3000x, hw) +

drivers/clk/samsung/clk-pll.c +49 -0
+static unsigned long samsung_pll3000x_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct samsung_clk_pll3000x *pll = to_clk_pll3000x(hw);
+	u32 pll_con, mdiv, pdiv, sdiv;
+	u64 fvco = parent_rate;
+
+	pll_con = __raw_readl(pll->con_reg);
+	mdiv = (pll_con >> PLL3000X_MDIV_SHIFT) & PLL3000X_MDIV_MASK;
+	pdiv = (pll_con >> PLL3000X_PDIV_SHIFT) & PLL3000X_PDIV_MASK;
+	sdiv = (pll_con >> PLL3000X_SDIV_SHIFT) & PLL3000X_SDIV_MASK;
+
+	fvco *= (2 * (mdiv + 8));
+	do_div(fvco, pdiv << sdiv);
+
+	return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll3000x_clk_ops = {
+	.recalc_rate = samsung_pll3000x_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll3000x(const char *name,
+			const char *pname, const void __iomem *con_reg)
+{
+	struct samsung_clk_pll3000x *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &samsung_pll3000x_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 = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+

drivers/clk/samsung/clk-pll.c struct clk * __init samsung_clk_register_pll2550x(const char *name, · line 543

Quoted 10 lines
drivers/clk/samsung/clk-pll.c +10 -0
+/*
+ * PLL6552x Clock Type
+ */
+
+#define PLL6552X_MDIV_MASK	(0x3FF)
+#define PLL6552X_PDIV_MASK	(0x3F)
+#define PLL6552X_SDIV_MASK	(0x7)
+#define PLL6552X_MDIV_SHIFT	(14)
+#define PLL6552X_PDIV_SHIFT	(5)
+#define PLL6552X_SDIV_SHIFT	(0)

Are you sure about those bitfields?

Quoted 4 lines

In S3C6410 User's Manual they are different. You can look at my patch for a comparison:

http://thread.gmane.org/gmane.linux.usb.general/87571/focus=88344

The numbers where taken from the previous pll code, but I now again checked them against the datasheet of the s3c2416 and the s3c2450.

When comparing with your patch, it really seems that the bit offsets in the register are different for the pdiv and mdiv - the above values are correct according the the datasheet (and also produce the expected results in the clock tree).

Quoted 61 lines
Quoted 61 lines
drivers/clk/samsung/clk-pll.c +6 -0
+struct samsung_clk_pll6552x {
+	struct clk_hw		hw;
+	const void __iomem	*con_reg;
+};
+
+#define to_clk_pll6552x(_hw) container_of(_hw, struct

samsung_clk_pll6552x, hw) +

drivers/clk/samsung/clk-pll.c +54 -0
+static unsigned long samsung_pll6552x_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct samsung_clk_pll6552x *pll = to_clk_pll6552x(hw);
+	u32 pll_con, mdiv, pdiv, sdiv;
+	u64 fvco = parent_rate;
+
+	pll_con = __raw_readl(pll->con_reg);
+	mdiv = (pll_con >> PLL6552X_MDIV_SHIFT) & PLL6552X_MDIV_MASK;
+	pdiv = (pll_con >> PLL6552X_PDIV_SHIFT) & PLL6552X_PDIV_MASK;
+	sdiv = (pll_con >> PLL6552X_SDIV_SHIFT) & PLL6552X_SDIV_MASK;
+
+	fvco *= mdiv;
+	do_div(fvco, (pdiv << sdiv));
+
+	return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll6552x_clk_ops = {
+	.recalc_rate = samsung_pll6552x_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll6552x(const char *name,
+			const char *pname, const void __iomem *con_reg)
+{
+	struct samsung_clk_pll6552x *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &samsung_pll6552x_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 = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+
+/*
+ * PLL6553x Clock Type
+ */
+
+#define PLL6553X_MDIV_MASK	(0x7F)
Quoted 8 lines

drivers/clk/samsung/clk-pll.c struct clk * __init samsung_clk_register_pll2550x(const char *name, · line 611

Quoted 6 lines
drivers/clk/samsung/clk-pll.c +6 -0
+#define PLL6553X_PDIV_MASK	(0x1F)
+#define PLL6553X_SDIV_MASK	(0x3)
+#define PLL6553X_KDIV_MASK	(0xFFFF)
+#define PLL6553X_MDIV_SHIFT	(16)
+#define PLL6553X_PDIV_SHIFT	(8)
+#define PLL6553X_SDIV_SHIFT	(0)

Same about those bitfields. They seem to be different on S3C64xx.

Here it seems the values were off in the original code. According to the datasheet the values in your patch are correct. Thanks for the catch.

+#define PLL6553X_MDIV_MASK (0xFF)
+#define PLL6553X_PDIV_MASK (0x3F)
+#define PLL6553X_SDIV_MASK (0x7)

This leaves the problem on what to do with the 6552X and its different bit offsets. Is the pll in question really a 6552X? In the s3c2416 manual its name is explicitly stated.

Thanks
Heiko

#11 lore raw

PATCH v2 3/6 clk: samsung: add plls used in s3c2416 and s3c2443

Quoted 292 lines · On Thursday 11 of July 2013 10:50:39 Heiko St?bner wrote:

Am Donnerstag, 11. Juli 2013, 10:16:41 schrieb Tomasz Figa:

Quoted 32 lines

Hi Heiko,

Quoted 5 lines · On Wednesday 10 of July 2013 00:59:08 Heiko St?bner wrote:

This adds support for pll2126x, pll3000x, pll6552x and pll6553x.

---

Quoted 7 lines
 drivers/clk/samsung/clk-pll.c |  280

+++++++++++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk-pll.h |

8 ++

 2 files changed, 288 insertions(+)

Generally the patch looks good, but I have some comments to the part related to 655xx PLLs.

I had a patch adding support for them too, but we can go with yours, since the way of registration has been changed by Yadwinder's patches and mine would have to be updated anyway.

Quoted 9 lines
(quoted diff) +0 -0

b/drivers/clk/samsung/clk-pll.c index 0afaec6..35c15a1 100644

drivers/clk/samsung/clk-pll.c +0 -0
@@ -323,6 +323,73 @@ struct clk * __init
 samsung_clk_register_pll46xx(const char *name, }
 
 /*
 
Quoted 9 lines

drivers/clk/samsung/clk-pll.c struct clk * __init samsung_clk_register_pll46xx(const char *name, · line 334

Quoted 9 lines
drivers/clk/samsung/clk-pll.c +9 -0
+ * PLL2126x Clock Type
+ */
+
+#define PLL2126X_MDIV_MASK	(0xFF)
+#define PLL2126X_PDIV_MASK	(0x3)
+#define PLL2126X_SDIV_MASK	(0x3)
+#define PLL2126X_MDIV_SHIFT	(16)
+#define PLL2126X_PDIV_SHIFT	(8)
+#define PLL2126X_SDIV_SHIFT	(0)

+#define PLL2126X_PDIV_MASK (0x3F)

is the correct value.

Quoted 69 lines
Quoted 69 lines
drivers/clk/samsung/clk-pll.c +7 -0
+
+struct samsung_clk_pll2126x {
+	struct clk_hw		hw;
+	const void __iomem	*con_reg;
+};
+
+#define to_clk_pll2126x(_hw) container_of(_hw, struct

samsung_clk_pll2126x, hw) +

drivers/clk/samsung/clk-pll.c +50 -0
+static unsigned long samsung_pll2126x_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct samsung_clk_pll2126x *pll = to_clk_pll2126x(hw);
+	u32 pll_con, mdiv, pdiv, sdiv;
+	u64 fvco = parent_rate;
+
+	pll_con = __raw_readl(pll->con_reg);
+	mdiv = (pll_con >> PLL2126X_MDIV_SHIFT) & PLL2126X_MDIV_MASK;
+	pdiv = (pll_con >> PLL2126X_PDIV_SHIFT) & PLL2126X_PDIV_MASK;
+	sdiv = (pll_con >> PLL2126X_SDIV_SHIFT) & PLL2126X_SDIV_MASK;
+
+	fvco *= (mdiv + 8);
+	do_div(fvco, (pdiv + 2) << sdiv);
+
+	return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll2126x_clk_ops = {
+	.recalc_rate = samsung_pll2126x_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll2126x(const char *name,
+			const char *pname, const void __iomem *con_reg)
+{
+	struct samsung_clk_pll2126x *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &samsung_pll2126x_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 = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+
+/*
 
  * PLL2550x Clock Type
  */
@@ -396,3 +463,216 @@ struct clk * __init
 samsung_clk_register_pll2550x(const char *name,
 
 	return clk;
 
 }
Quoted 11 lines

drivers/clk/samsung/clk-pll.c struct clk * __init samsung_clk_register_pll2550x(const char *name, · line 476

Quoted 11 lines
drivers/clk/samsung/clk-pll.c +11 -0
+
+/*
+ * PLL3000x Clock Type
+ */
+
+#define PLL3000X_MDIV_MASK	(0xFF)
+#define PLL3000X_PDIV_MASK	(0x3)
+#define PLL3000X_SDIV_MASK	(0x3)
+#define PLL3000X_MDIV_SHIFT	(16)
+#define PLL3000X_PDIV_SHIFT	(8)
+#define PLL3000X_SDIV_SHIFT	(0)

these are correct.

Quoted 70 lines
Quoted 57 lines
drivers/clk/samsung/clk-pll.c +7 -0
+
+struct samsung_clk_pll3000x {
+	struct clk_hw		hw;
+	const void __iomem	*con_reg;
+};
+
+#define to_clk_pll3000x(_hw) container_of(_hw, struct

samsung_clk_pll3000x, hw) +

drivers/clk/samsung/clk-pll.c +49 -0
+static unsigned long samsung_pll3000x_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct samsung_clk_pll3000x *pll = to_clk_pll3000x(hw);
+	u32 pll_con, mdiv, pdiv, sdiv;
+	u64 fvco = parent_rate;
+
+	pll_con = __raw_readl(pll->con_reg);
+	mdiv = (pll_con >> PLL3000X_MDIV_SHIFT) & PLL3000X_MDIV_MASK;
+	pdiv = (pll_con >> PLL3000X_PDIV_SHIFT) & PLL3000X_PDIV_MASK;
+	sdiv = (pll_con >> PLL3000X_SDIV_SHIFT) & PLL3000X_SDIV_MASK;
+
+	fvco *= (2 * (mdiv + 8));
+	do_div(fvco, pdiv << sdiv);
+
+	return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll3000x_clk_ops = {
+	.recalc_rate = samsung_pll3000x_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll3000x(const char *name,
+			const char *pname, const void __iomem *con_reg)
+{
+	struct samsung_clk_pll3000x *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &samsung_pll3000x_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 = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+

drivers/clk/samsung/clk-pll.c struct clk * __init samsung_clk_register_pll2550x(const char *name, · line 543

Quoted 10 lines
drivers/clk/samsung/clk-pll.c +10 -0
+/*
+ * PLL6552x Clock Type
+ */
+
+#define PLL6552X_MDIV_MASK	(0x3FF)
+#define PLL6552X_PDIV_MASK	(0x3F)
+#define PLL6552X_SDIV_MASK	(0x7)
+#define PLL6552X_MDIV_SHIFT	(14)
+#define PLL6552X_PDIV_SHIFT	(5)
+#define PLL6552X_SDIV_SHIFT	(0)

Are you sure about those bitfields?

Quoted 5 lines

In S3C6410 User's Manual they are different. You can look at my patch for a
comparison:

http://thread.gmane.org/gmane.linux.usb.general/87571/focus=88344

The numbers where taken from the previous pll code, but I now again checked them against the datasheet of the s3c2416 and the s3c2450.

When comparing with your patch, it really seems that the bit offsets in the register are different for the pdiv and mdiv - the above values are correct according the the datasheet (and also produce the expected results in the clock tree).

Quoted 61 lines
Quoted 61 lines
drivers/clk/samsung/clk-pll.c +6 -0
+struct samsung_clk_pll6552x {
+	struct clk_hw		hw;
+	const void __iomem	*con_reg;
+};
+
+#define to_clk_pll6552x(_hw) container_of(_hw, struct

samsung_clk_pll6552x, hw) +

drivers/clk/samsung/clk-pll.c +54 -0
+static unsigned long samsung_pll6552x_recalc_rate(struct clk_hw *hw,
+				unsigned long parent_rate)
+{
+	struct samsung_clk_pll6552x *pll = to_clk_pll6552x(hw);
+	u32 pll_con, mdiv, pdiv, sdiv;
+	u64 fvco = parent_rate;
+
+	pll_con = __raw_readl(pll->con_reg);
+	mdiv = (pll_con >> PLL6552X_MDIV_SHIFT) & PLL6552X_MDIV_MASK;
+	pdiv = (pll_con >> PLL6552X_PDIV_SHIFT) & PLL6552X_PDIV_MASK;
+	sdiv = (pll_con >> PLL6552X_SDIV_SHIFT) & PLL6552X_SDIV_MASK;
+
+	fvco *= mdiv;
+	do_div(fvco, (pdiv << sdiv));
+
+	return (unsigned long)fvco;
+}
+
+static const struct clk_ops samsung_pll6552x_clk_ops = {
+	.recalc_rate = samsung_pll6552x_recalc_rate,
+};
+
+struct clk * __init samsung_clk_register_pll6552x(const char *name,
+			const char *pname, const void __iomem *con_reg)
+{
+	struct samsung_clk_pll6552x *pll;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	pll = kzalloc(sizeof(*pll), GFP_KERNEL);
+	if (!pll)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &samsung_pll6552x_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 = samsung_register_pll(&pll->hw);
+	if (IS_ERR(clk))
+		kfree(pll);
+
+	return clk;
+}
+
+/*
+ * PLL6553x Clock Type
+ */
+
+#define PLL6553X_MDIV_MASK	(0x7F)
Quoted 8 lines

drivers/clk/samsung/clk-pll.c struct clk * __init samsung_clk_register_pll2550x(const char *name, · line 611

Quoted 6 lines
drivers/clk/samsung/clk-pll.c +6 -0
+#define PLL6553X_PDIV_MASK	(0x1F)
+#define PLL6553X_SDIV_MASK	(0x3)
+#define PLL6553X_KDIV_MASK	(0xFFFF)
+#define PLL6553X_MDIV_SHIFT	(16)
+#define PLL6553X_PDIV_SHIFT	(8)
+#define PLL6553X_SDIV_SHIFT	(0)

Same about those bitfields. They seem to be different on S3C64xx.

Here it seems the values were off in the original code. According to the datasheet the values in your patch are correct. Thanks for the catch.

(quoted diff) +3 -0
+#define PLL6553X_MDIV_MASK	(0xFF)
+#define PLL6553X_PDIV_MASK	(0x3F)
+#define PLL6553X_SDIV_MASK	(0x7)
Quoted 3 lines

This leaves the problem on what to do with the 6552X and its different bit offsets. Is the pll in question really a 6552X? In the s3c2416 manual its name is explicitly stated.

So is it in S3C6410 User's Manual.

If you look at the old plat/pll.h header, you can see that none of S3C2416_PLL (which I believe corresponds to your 6552X) and S3C6400_PLL (which is the PLL6552x that can be found on S3C64xx) is labelled as PLL6552x explicitly.

Best regards,
Tomasz

#12 lore raw

PATCH v2 4/6 ARM: S3C24XX: enable legacy clock code only when SAMSUNG_CLOCK selected

In reply to Heiko Stübner

This enables a smooth transition, as not all S3C24XX SoCs need to be converted at the same time and can instead simply exchange their select SAMSUNG_CLOCK with a select COMMON_CLK after the conversion.

---
 arch/arm/mach-s3c24xx/common-s3c2443.c |    2 ++
 arch/arm/mach-s3c24xx/common.c         |    2 ++
 2 files changed, 4 insertions(+)
arch/arm/mach-s3c24xx/common-s3c2443.c +2 -0
index f6b9f2e..b5bbeb7 100644
@@ -28,6 +28,7 @@
 #include <plat/cpu-freq.h>
 
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 static int s3c2443_gate(void __iomem *reg, struct clk *clk, int enable)
 {
 	u32 ctrlbit = clk->ctrlbit;
@@ -673,3 +674,4 @@ void __init s3c2443_common_init_clocks(int xtal, pll_fn get_mpll,
 
 	s3c2443_common_setup_clocks(get_mpll);
 }
+#endif
arch/arm/mach-s3c24xx/common.c +2 -0
index 457261c..0fe0254 100644
@@ -317,6 +317,7 @@ struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
 
 /* initialise all the clocks */
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 void __init_or_cpufreq s3c24xx_setup_clocks(unsigned long fclk,
 					   unsigned long hclk,
 					   unsigned long pclk)
@@ -329,3 +330,4 @@ void __init_or_cpufreq s3c24xx_setup_clocks(unsigned long fclk,
 	clk_p.rate = pclk;
 	clk_f.rate = fclk;
 }
+#endif
Signature · 1 line
1.7.10.4
#13 lore raw

PATCH v2 5/6 clk: samsung: add clock-driver for s3c2416, s3c2443 and s3c2450

In reply to Heiko Stübner

The three SoCs share a common clock tree which only differs in the existence of some special clocks.

As with all parts common to these three SoCs the driver is named after the s3c2443, as it was the first SoC introducing this structure and there exists no other label to describe this s3c24xx epoch.

The clock structure is built according to the manuals of the included SoCs and might include changes in comparison to the previous clock structure. As an example the sclk_uart gate was never handled previously and the div_uart was made to be the clock used by the serial driver.

---
 .../bindings/clock/samsung,s3c2443-clock.txt       |   48 +++
 drivers/clk/Kconfig                                |    1 +
 drivers/clk/samsung/Kconfig                        |    2 +
 drivers/clk/samsung/Makefile                       |    1 +
 drivers/clk/samsung/clk-s3c2443.c                  |  422 ++++++++++++++++++++
 include/dt-bindings/clock/samsung,s3c2443-clock.h  |   96 +++++
 6 files changed, 570 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt
 create mode 100644 drivers/clk/samsung/Kconfig
 create mode 100644 drivers/clk/samsung/clk-s3c2443.c
 create mode 100644 include/dt-bindings/clock/samsung,s3c2443-clock.h
Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt new file +48 -0
new file mode 100644
index 0000000..a61d8d1
@@ -0,0 +1,48 @@
+* Samsung S3C2443 Clock Controller
+
+The S3C2443 clock controller generates and supplies clock to various controllers
+within the SoC. The clock binding described here is applicable to all SoCs in
+the s3c24x family starting with the s3c2443.
+
+Required Properties:
+
+- comptible: should be one of the following.
+  - "samsung,s3c2416-clock" - controller compatible with S3C2416 SoC.
+  - "samsung,s3c2443-clock" - controller compatible with S3C2443 SoC.
+  - "samsung,s3c2450-clock" - controller compatible with S3C2450 SoC.
+
+- reg: physical base address of the controller and length of memory mapped
+  region.
+
+- #clock-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes can use this identifier
+to specify the clock which they consume. Some of the clocks are available only
+on a particular SoC.
+
+All available clocks are defined as preprocessor macros in
+dt-bindings/clock/samsung,s3c2443-clock.h header and can be used in device
+tree sources.
+
+Example: Clock controller node:
+
+	clocks: clock-controller at 4c000000 {
+		compatible = "samsung,s3c2416-clock";
+		reg = <0x4c000000 0x40>;
+		#clock-cells = <1>;
+	};
+
+Example: UART controller node that consumes the clock generated by the clock
+  controller (refer to the standard clock bindings for information about
+  "clocks" and "clock-names" properties):
+
+	serial at 50004000 {
+		compatible = "samsung,s3c2440-uart";
+		reg = <0x50004000 0x4000>;
+		interrupts = <1 23 3 4>, <1 23 4 4>;
+		clock-names = "uart", "clk_uart_baud2",
+				"clk_uart_baud3";
+		clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>,
+				<&clocks SCLK_UART>;
+		status = "disabled";
+	};
drivers/clk/Kconfig +1 -0
index 0357ac4..b2fdd68 100644
@@ -84,3 +84,4 @@ config COMMON_CLK_AXI_CLKGEN
 endmenu
 
 source "drivers/clk/mvebu/Kconfig"
+source "drivers/clk/samsung/Kconfig"
drivers/clk/samsung/Kconfig new file +2 -0
new file mode 100644
index 0000000..0cfbb29
@@ -0,0 +1,2 @@
+config COMMON_CLK_S3C2443
+       bool
drivers/clk/samsung/Makefile +1 -0
index 5d4d432..1c7932c 100644
@@ -8,3 +8,4 @@ obj-$(CONFIG_SOC_EXYNOS5250)	+= clk-exynos5250.o
 obj-$(CONFIG_SOC_EXYNOS5420)	+= clk-exynos5420.o
 obj-$(CONFIG_SOC_EXYNOS5440)	+= clk-exynos5440.o
 obj-$(CONFIG_ARCH_EXYNOS)	+= clk-exynos-audss.o
+obj-$(CONFIG_COMMON_CLK_S3C2443)+= clk-s3c2443.o
drivers/clk/samsung/clk-s3c2443.c new file +422 -0

422 lines not on this page · raw message

include/dt-bindings/clock/samsung,s3c2443-clock.h new file +96 -0

96 lines not on this page · raw message

Signature · 1 line
1.7.10.4
#14 lore raw

PATCH v2 5/6 clk: samsung: add clock-driver for s3c2416, s3c2443 and s3c2450

Hi Heiko,

Looks mostly good, but please see my comments inline.

Quoted 41 lines · On Wednesday 10 of July 2013 01:00:00 Heiko St?bner wrote:

The three SoCs share a common clock tree which only differs in the existence of some special clocks.

As with all parts common to these three SoCs the driver is named after the s3c2443, as it was the first SoC introducing this structure and there exists no other label to describe this s3c24xx epoch.

The clock structure is built according to the manuals of the included SoCs and might include changes in comparison to the previous clock structure. As an example the sclk_uart gate was never handled previously and the div_uart was made to be the clock used by the serial driver.

---
 .../bindings/clock/samsung,s3c2443-clock.txt       |   48 +++
 drivers/clk/Kconfig                                |    1 +
 drivers/clk/samsung/Kconfig                        |    2 +
 drivers/clk/samsung/Makefile                       |    1 +
 drivers/clk/samsung/clk-s3c2443.c                  |  422
++++++++++++++++++++ include/dt-bindings/clock/samsung,s3c2443-clock.h  |  
96 +++++
 6 files changed, 570 insertions(+)
 create mode 100644
Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt create
mode 100644 drivers/clk/samsung/Kconfig
 create mode 100644 drivers/clk/samsung/clk-s3c2443.c
 create mode 100644 include/dt-bindings/clock/samsung,s3c2443-clock.h

diff --git a/Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt b/Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt new file mode 100644
index 0000000..a61d8d1

Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt new file +3 -0
@@ -0,0 +1,48 @@
+* Samsung S3C2443 Clock Controller
+
+The S3C2443 clock controller generates and supplies clock to various

controllers +within the SoC. The clock binding described here is applicable to all SoCs in +the s3c24x family starting with the s3c2443.

Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt line 9

Quoted 4 lines
Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt new file +4 -0
+
+Required Properties:
+
+- comptible: should be one of the following.

nit: compatible

Quoted 54 lines
Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt new file +10 -0
+  - "samsung,s3c2416-clock" - controller compatible with S3C2416 SoC.
+  - "samsung,s3c2443-clock" - controller compatible with S3C2443 SoC.
+  - "samsung,s3c2450-clock" - controller compatible with S3C2450 SoC.
+
+- reg: physical base address of the controller and length of memory mapped
+  region.
+
+- #clock-cells: should be 1.
+
+Each clock is assigned an identifier and client nodes can use this

identifier +to specify the clock which they consume. Some of the clocks are available only +on a particular SoC.

Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt new file +14 -0
+
+All available clocks are defined as preprocessor macros in
+dt-bindings/clock/samsung,s3c2443-clock.h header and can be used in device
+tree sources.
+
+Example: Clock controller node:
+
+	clocks: clock-controller at 4c000000 {
+		compatible = "samsung,s3c2416-clock";
+		reg = <0x4c000000 0x40>;
+		#clock-cells = <1>;
+	};
+
+Example: UART controller node that consumes the clock generated by the

clock + controller (refer to the standard clock bindings for information about + "clocks" and "clock-names" properties):

Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt new file +11 -0
+
+	serial at 50004000 {
+		compatible = "samsung,s3c2440-uart";
+		reg = <0x50004000 0x4000>;
+		interrupts = <1 23 3 4>, <1 23 4 4>;
+		clock-names = "uart", "clk_uart_baud2",
+				"clk_uart_baud3";
+		clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>,
+				<&clocks SCLK_UART>;
+		status = "disabled";
+	};
drivers/clk/Kconfig +1 -0
index 0357ac4..b2fdd68 100644
@@ -84,3 +84,4 @@ config COMMON_CLK_AXI_CLKGEN
 endmenu
 
 source "drivers/clk/mvebu/Kconfig"
+source "drivers/clk/samsung/Kconfig"
drivers/clk/samsung/Kconfig new file +0 -0
new file mode 100644
index 0000000..0cfbb29

drivers/clk/samsung/Kconfig line 2

Quoted 2 lines
drivers/clk/samsung/Kconfig new file +2 -0
@@ -0,0 +1,2 @@
+config COMMON_CLK_S3C2443
+       bool

Do you need to introduce a new Kconfig file for this? I guess it's just a matter of preference, but since it's here just temporarily, I would just put this Kconfig entry into the top level clk Kconfig file or even in arch/arm/mach- s3c24xx/Kconfig.

Quoted 77 lines
drivers/clk/samsung/Makefile +1 -0
index 5d4d432..1c7932c 100644
@@ -8,3 +8,4 @@ obj-$(CONFIG_SOC_EXYNOS5250)	+= clk-exynos5250.o
 obj-$(CONFIG_SOC_EXYNOS5420)	+= clk-exynos5420.o
 obj-$(CONFIG_SOC_EXYNOS5440)	+= clk-exynos5440.o
 obj-$(CONFIG_ARCH_EXYNOS)	+= clk-exynos-audss.o
+obj-$(CONFIG_COMMON_CLK_S3C2443)+= clk-s3c2443.o
(quoted diff) +0 -0

b/drivers/clk/samsung/clk-s3c2443.c new file mode 100644 index 0000000..7d57b08

drivers/clk/samsung/clk-s3c2443.c new file +62 -0
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 2013 Heiko Stuebner <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Common Clock Framework support for S3C2443 and following SoCs.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <dt-bindings/clock/samsung,s3c2443-clock.h>
+
+#include "clk.h"
+#include "clk-pll.h"
+
+/* S3C2416 clock controller register offsets */
+#define MPLLCON		0x10
+#define EPLLCON		0x18
+#define EPLLCON_K	0x1C
+#define CLKSRC		0x20
+#define CLKDIV0		0x24
+#define CLKDIV1		0x28
+#define CLKDIV2		0x2C
+#define HCLKCON		0x30
+#define PCLKCON		0x34
+#define SCLKCON		0x38
+
+/* the soc types */
+enum supported_socs {
+	S3C2416,
+	S3C2443,
+	S3C2450,
+};
+
+/*
+ * list of controller registers to be saved and restored during a
+ * suspend/resume cycle.
+ */
+static __initdata unsigned long s3c2443_clk_regs[] = {
+	MPLLCON,
+	EPLLCON,
+	EPLLCON_K,
+	CLKSRC,
+	CLKDIV0,
+	CLKDIV1,
+	CLKDIV2,
+	PCLKCON,
+	HCLKCON,
+	SCLKCON,
+};
+
+PNAME(epllref_p) = { "mpllref", "mpllref", "xti", "ext" };
+PNAME(esysclk_p) = { "epllref", "epll" };
+PNAME(msysclk_p) = { "mpllref, mdivclk", "mpll", "mpll" };
+PNAME(armclk_p) = { "armdiv" , "hclk" };
+PNAME(i2s0_p) = { "div_i2s0", "ext_i2s", "epllref", "epllref" };

drivers/clk/samsung/clk-s3c2443.c line 72

Quoted 10 lines
drivers/clk/samsung/clk-s3c2443.c new file +10 -0
+
+/* fixed rate clocks generated outside the soc */
+struct samsung_fixed_rate_clock s3c2443_common_frate_clks[] __initdata = {
+	FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0),
+	FRATE(EXT, "ext", NULL, CLK_IS_ROOT, 0),
+	FRATE(EXT_I2S, "ext_i2s", NULL, CLK_IS_ROOT, 0),
+	FRATE(EXT_UART, "ext_uart", NULL, CLK_IS_ROOT, 0),
+};
+
+/* mpllref is a direct descendant of clk_xtal by default, but it is not

nit: The preferred style of multiline comments is:

/*
* mpllref is a...

drivers/clk/samsung/clk-s3c2443.c line 78

Quoted 6 lines
drivers/clk/samsung/clk-s3c2443.c new file +6 -0
+ * elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
+ * such directly equating the two source clocks is impossible.
+ */
+struct samsung_fixed_factor_clock s3c2443_common_ffactor[] __initdata = {
+	FFACTOR(0, "mpllref", "xti", 1, 1, 0),
+};

Hmm, I don't understand the reason for having this fixed factor clock. Why can't xti be used directly instead?

Quoted 4 lines
drivers/clk/samsung/clk-s3c2443.c new file +4 -0
+struct samsung_mux_clock s3c2443_common_muxes[] __initdata = {
+	MUX(0, "epllref", epllref_p, CLKSRC, 7, 2),
+	MUX(ESYSCLK, "esysclk", esysclk_p, CLKSRC, 6, 1),
+	MUX_A(MSYSCLK, "msysclk", msysclk_p, CLKSRC, 3, 2, "msysclk"),

drivers/clk/samsung/clk-s3c2443.c line 93

Quoted 10 lines
drivers/clk/samsung/clk-s3c2443.c new file +10 -0
+	MUX_A(ARMCLK, "armclk", armclk_p, CLKDIV0, 13, 1, "armclk"),
+	MUX(0, "mux_i2s0", i2s0_p, CLKSRC, 14, 2),
+};
+
+static struct clk_div_table hclk_d[] = {
+	{ .val = 0, .div = 1 },
+	{ .val = 1, .div = 2 },
+	{ .val = 3, .div = 4 },
+	{ .div = 0 },
+};

Hmm, this makes me rethink some of the code I made for S3C64xx. There are few dividers that have additional constraints, like only even divisors, or so, but they are just normal linear dividers, so can be registered as simple divider clocks.

Originally I registered them as simple dividers, but now I'm thinking if they shouldn't be constrained by a table.

Quoted 34 lines
drivers/clk/samsung/clk-s3c2443.c new file +34 -0
+static struct clk_div_table mdivclk_d[] = {
+	{ .val = 0, .div = 1 },
+	{ .val = 1, .div = 3 },
+	{ .val = 2, .div = 5 },
+	{ .val = 3, .div = 7 },
+	{ .val = 4, .div = 9 },
+	{ .val = 5, .div = 11 },
+	{ .val = 6, .div = 13 },
+	{ .val = 7, .div = 15 },
+	{ .div = 0 },
+};
+
+struct samsung_div_clock s3c2443_common_dividers[] __initdata = {
+	DIV_T(0, "mdivclk", "mpllref", CLKDIV0, 6, 3, mdivclk_d),
+	DIV(0, "prediv", "msysclk", CLKDIV0, 4, 2),
+	DIV_T(HCLK, "hclk", "prediv", CLKDIV0, 0, 2, hclk_d),
+	DIV(PCLK, "pclk", "hclk", CLKDIV0, 2, 1),
+	DIV(0, "div_hsspi0_epll", "esysclk", CLKDIV1, 24, 2),
+	DIV(0, "div_fimd", "esysclk", CLKDIV1, 16, 8),
+	DIV(0, "div_i2s0", "esysclk", CLKDIV1, 12, 4),
+	DIV(0, "div_uart", "esysclk", CLKDIV1, 8, 4),
+	DIV(0, "div_hsmmc1", "esysclk", CLKDIV1, 6, 2),
+	DIV(0, "div_usbhost", "esysclk", CLKDIV1, 4, 2),
+};
+
+struct samsung_gate_clock s3c2443_common_gates[] __initdata = {
+	GATE(SCLK_HSMMC_EXT, "sclk_hsmmcext", "ext", SCLKCON, 13, 0, 0),
+	GATE(SCLK_HSMMC1, "sclk_hsmmc1", "div_hsmmc1", SCLKCON, 12, 0, 0),
+	GATE(SCLK_FIMD, "sclk_fimd", "div_fimd", SCLKCON, 10, 0, 0),
+	GATE(SCLK_I2S0, "sclk_i2s0", "mux_i2s0", SCLKCON, 9, 0, 0),
+	GATE(SCLK_UART, "sclk_uart", "div_uart", SCLKCON, 8, 0, 0),
+	GATE(SCLK_USBH, "sclk_usbhost", "div_usbhost", SCLKCON, 1, 0, 0),
+	GATE(HCLK_DRAM, "dram", "hclk", HCLKCON, 19, CLK_IGNORE_UNUSED, 0),
+	GATE(HCLK_SSMC, "ssmc", "hclk", HCLKCON, 18, CLK_IGNORE_UNUSED, 0),

drivers/clk/samsung/clk-s3c2443.c line 138

Quoted 10 lines
drivers/clk/samsung/clk-s3c2443.c new file +10 -0
+	GATE(HCLK_HSMMC1, "hsmmc1", "hclk", HCLKCON, 16, 0, 0),
+	GATE(HCLK_USBD, "usb-device", "hclk", HCLKCON, 12, 0, 0),
+	GATE(HCLK_USBH, "usb-host", "hclk", HCLKCON, 11, 0, 0),
+	GATE(HCLK_LCD, "lcd", "hclk", HCLKCON, 9, 0, 0),
+	GATE(HCLK_DMA5, "dma5", "hclk", HCLKCON, 5, CLK_IGNORE_UNUSED, 0),
+	GATE(HCLK_DMA4, "dma4", "hclk", HCLKCON, 4, CLK_IGNORE_UNUSED, 0),
+	GATE(HCLK_DMA3, "dma3", "hclk", HCLKCON, 3, CLK_IGNORE_UNUSED, 0),
+	GATE(HCLK_DMA2, "dma2", "hclk", HCLKCON, 2, CLK_IGNORE_UNUSED, 0),
+	GATE(HCLK_DMA1, "dma1", "hclk", HCLKCON, 1, CLK_IGNORE_UNUSED, 0),
+	GATE(HCLK_DMA0, "dma0", "hclk", HCLKCON, 0, CLK_IGNORE_UNUSED, 0),

Hmm, I guess these CLK_IGNORE_UNUSED flags are needed because the old DMA driver doesn't handle clocks, right?

By the way, do you have some plans to continue working on the DMA engine driver for s3c24xx you posted some time ago? This would be really helpful, as we could then switch all the drivers using currently the Samsung-specific DMA API to the generic DMA engine API. (Actually I already have some patches for Samsung sound drivers. Will probably post an RFC soon.)

Quoted 182 lines
drivers/clk/samsung/clk-s3c2443.c new file +182 -0
+	GATE(PCLK_GPIO, "gpio", "pclk", PCLKCON, 13, CLK_IGNORE_UNUSED, 0),
+	GATE(PCLK_RTC, "rtc", "pclk", PCLKCON, 12, 0, 0),
+	GATE(PCLK_WDT, "wdt", "pclk", PCLKCON, 11, 0, 0),
+	GATE(PCLK_PWM, "pwm", "pclk", PCLKCON, 10, 0, 0),
+	GATE(PCLK_I2S0, "i2s0", "pclk", PCLKCON, 9, 0, 0),
+	GATE(PCLK_AC97, "ac97", "pclk", PCLKCON, 8, 0, 0),
+	GATE(PCLK_ADC, "adc", "pclk", PCLKCON, 7, 0, 0),
+	GATE(PCLK_SPI0, "spi0", "pclk", PCLKCON, 6, 0, 0),
+	GATE(PCLK_I2C0, "i2c0", "pclk", PCLKCON, 4, 0, 0),
+	GATE(PCLK_UART3, "uart3", "pclk", PCLKCON, 3, 0, 0),
+	GATE(PCLK_UART2, "uart2", "pclk", PCLKCON, 2, 0, 0),
+	GATE(PCLK_UART1, "uart1", "pclk", PCLKCON, 1, 0, 0),
+	GATE(PCLK_UART0, "uart0", "pclk", PCLKCON, 0, 0, 0),
+};
+
+struct samsung_clock_alias s3c2443_common_aliases[] __initdata = {
+	ALIAS(HCLK, NULL, "hclk"),
+	ALIAS(HCLK_SSMC, NULL, "nand"),
+	ALIAS(PCLK_UART0, "s3c2440-uart.0", "uart"),
+	ALIAS(PCLK_UART1, "s3c2440-uart.1", "uart"),
+	ALIAS(PCLK_UART2, "s3c2440-uart.2", "uart"),
+	ALIAS(PCLK_UART3, "s3c2440-uart.3", "uart"),
+	ALIAS(EXT_UART, NULL, "clk_uart_baud1"),
+	ALIAS(PCLK_UART0, "s3c2440-uart.0", "clk_uart_baud2"),
+	ALIAS(PCLK_UART1, "s3c2440-uart.1", "clk_uart_baud2"),
+	ALIAS(PCLK_UART2, "s3c2440-uart.2", "clk_uart_baud2"),
+	ALIAS(PCLK_UART3, "s3c2440-uart.3", "clk_uart_baud2"),
+	ALIAS(SCLK_UART, NULL, "clk_uart_baud3"),
+	ALIAS(PCLK_PWM, NULL, "timers"),
+	ALIAS(PCLK_RTC, NULL, "rtc"),
+	ALIAS(PCLK_WDT, NULL, "watchdog"),
+	ALIAS(PCLK_ADC, NULL, "adc"),
+	ALIAS(PCLK_I2C0, "s3c2410-i2c.0", "i2c"),
+	ALIAS(HCLK_USBD, NULL, "usb-device"),
+	ALIAS(HCLK_USBH, NULL, "usb-host"),
+	ALIAS(SCLK_USBH, NULL, "usb-bus-host"),
+	ALIAS(PCLK_SPI0, "s3c2443-spi.0", "spi"),
+	ALIAS(PCLK_SPI0, "s3c2443-spi.0", "spi_busclk0"),
+	ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "hsmmc"),
+	ALIAS(HCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.0"),
+	ALIAS(PCLK_I2S0, "samsung-i2s.0", "iis"),
+	ALIAS(SCLK_I2S0, NULL, "i2s-if"),
+	ALIAS(HCLK_LCD, NULL, "lcd"),
+	ALIAS(SCLK_FIMD, NULL, "sclk_fimd"),
+};
+
+/* S3C2416 specific clocks */
+
+PNAME(s3c2416_hsmmc0_p) = { "sclk_hsmmc0", "sclk_hsmmcext" };
+PNAME(s3c2416_hsmmc1_p) = { "sclk_hsmmc1", "sclk_hsmmcext" };
+PNAME(s3c2416_hsspi0_p) = { "hsspi0_epll", "hsspi0_mpll" };
+
+static struct clk_div_table armdiv_s3c2416_d[] = {
+	{ .val = 0, .div = 1 },
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 3 },
+	{ .val = 3, .div = 4 },
+	{ .val = 5, .div = 6 },
+	{ .val = 7, .div = 8 },
+	{ .div = 0 },
+};
+
+struct samsung_div_clock s3c2416_dividers[] __initdata = {
+	DIV_T(ARMDIV, "armdiv", "msysclk", CLKDIV0, 9, 3, armdiv_s3c2416_d),
+	DIV(0, "div_hsspi0_mpll", "msysclk", CLKDIV2, 0, 4),
+	DIV(0, "div_hsmmc0", "esysclk", CLKDIV2, 6, 2),
+};
+
+struct samsung_mux_clock s3c2416_muxes[] __initdata = {
+	MUX(MUX_HSMMC0, "mux_hsmmc0", s3c2416_hsmmc0_p, CLKSRC, 16, 1),
+	MUX(MUX_HSMMC1, "mux_hsmmc1", s3c2416_hsmmc1_p, CLKSRC, 17, 1),
+	MUX(MUX_HSSPI0, "mux_hsspi0", s3c2416_hsspi0_p, CLKSRC, 18, 1),
+};
+
+struct samsung_gate_clock s3c2416_gates[] __initdata = {
+	GATE(0, "hsspi0_mpll", "div_hsspi0_mpll", SCLKCON, 19, 0, 0),
+	GATE(0, "hsspi0_epll", "div_hsspi0_epll", SCLKCON, 14, 0, 0),
+	GATE(0, "sclk_hsmmc0", "div_hsmmc0", SCLKCON, 6, 0, 0),
+	GATE(HCLK_2D, "2d", "hclk", HCLKCON, 20, 0, 0),
+	GATE(HCLK_HSMMC0, "hsmmc0", "hclk", HCLKCON, 15, 0, 0),
+	GATE(HCLK_IROM, "irom", "hclk", HCLKCON, 13, CLK_IGNORE_UNUSED, 0),
+	GATE(PCLK_PCM, "pcm", "pclk", PCLKCON, 19, 0, 0),
+};
+
+struct samsung_clock_alias s3c2416_aliases[] __initdata = {
+	ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "hsmmc"),
+	ALIAS(HCLK_HSMMC0, "s3c-sdhci.0", "mmc_busclk.0"),
+	ALIAS(MUX_HSMMC0, "s3c-sdhci.0", "mmc_busclk.2"),
+	ALIAS(MUX_HSMMC1, "s3c-sdhci.1", "mmc_busclk.2"),
+	ALIAS(MUX_HSSPI0, "s3c2443-spi.0", "spi_busclk2"),
+	ALIAS(ARMDIV, NULL, "armdiv"),
+};
+
+/* S3C2443 specific clocks */
+
+static struct clk_div_table armdiv_s3c2443_d[] = {
+	{ .val = 0, .div = 1 },
+	{ .val = 8, .div = 2 },
+	{ .val = 2, .div = 3 },
+	{ .val = 9, .div = 4 },
+	{ .val = 10, .div = 6 },
+	{ .val = 11, .div = 8 },
+	{ .val = 13, .div = 12 },
+	{ .val = 15, .div = 16 },
+	{ .div = 0 },
+};
+
+struct samsung_div_clock s3c2443_dividers[] __initdata = {
+	DIV_T(ARMDIV, "armdiv", "msysclk", CLKDIV0, 9, 4, armdiv_s3c2443_d),
+	DIV(0, "div_cam", "esysclk", CLKDIV1, 26, 4),
+};
+
+struct samsung_gate_clock s3c2443_gates[] __initdata = {
+	GATE(SCLK_HSSPI0, "sclk_hsspi0", "div_hsspi0_epll", SCLKCON, 14, 0, 0),
+	GATE(SCLK_CAM, "sclk_cam", "div_cam", SCLKCON, 11, 0, 0),
+	GATE(HCLK_CFC, "cfc", "hclk", HCLKCON, 17, CLK_IGNORE_UNUSED, 0),
+	GATE(HCLK_CAM, "cam", "hclk", HCLKCON, 8, 0, 0),
+	GATE(PCLK_SPI1, "spi1", "pclk", PCLKCON, 15, 0, 0),
+	GATE(PCLK_SDI, "sdi", "pclk", PCLKCON, 5, 0, 0),
+};
+
+struct samsung_clock_alias s3c2443_aliases[] __initdata = {
+	ALIAS(SCLK_HSSPI0, "s3c2443-spi.0", "spi_busclk2"),
+	ALIAS(SCLK_HSMMC1, "s3c-sdhci.1", "mmc_busclk.2"),
+	ALIAS(SCLK_CAM, NULL, "camif-upll"),
+	ALIAS(PCLK_SPI1, "s3c2410-spi.0", "spi"),
+	ALIAS(PCLK_SDI, NULL, "sdi"),
+	ALIAS(HCLK_CFC, NULL, "cfc"),
+	ALIAS(ARMDIV, NULL, "armdiv"),
+};
+
+/* S3C2450 specific clocks */
+
+PNAME(s3c2450_cam_p) = { "div_cam", "hclk" };
+PNAME(s3c2450_hsspi1_p) = { "hsspi1_epll", "hsspi1_mpll" };
+PNAME(i2s1_p) = { "div_i2s1", "ext_i2s", "epllref", "epllref" };
+
+struct samsung_div_clock s3c2450_dividers[] __initdata = {
+	DIV(0, "div_cam", "esysclk", CLKDIV1, 26, 4),
+	DIV(0, "div_hsspi1_epll", "esysclk", CLKDIV2, 24, 2),
+	DIV(0, "div_hsspi1_mpll", "msysclk", CLKDIV2, 16, 4),
+	DIV(0, "div_i2s1", "esysclk", CLKDIV2, 12, 4),
+};
+
+struct samsung_mux_clock s3c2450_muxes[] __initdata = {
+	MUX(0, "mux_cam", s3c2450_cam_p, CLKSRC, 20, 1),
+	MUX(MUX_HSSPI1, "mux_hsspi1", s3c2450_hsspi1_p, CLKSRC, 19, 1),
+	MUX(0, "mux_i2s1", i2s1_p, CLKSRC, 12, 2),
+};
+
+struct samsung_gate_clock s3c2450_gates[] __initdata = {
+	GATE(SCLK_I2S1, "sclk_i2s1", "div_i2s1", SCLKCON, 5, 0, 0),
+	GATE(HCLK_CFC, "cfc", "hclk", HCLKCON, 17, 0, 0),
+	GATE(HCLK_CAM, "cam", "hclk", HCLKCON, 8, 0, 0),
+	GATE(HCLK_DMA7, "dma7", "hclk", HCLKCON, 7, CLK_IGNORE_UNUSED, 0),
+	GATE(HCLK_DMA6, "dma6", "hclk", HCLKCON, 6, CLK_IGNORE_UNUSED, 0),
+	GATE(PCLK_I2S1, "i2s1", "pclk", PCLKCON, 17, 0, 0),
+	GATE(PCLK_I2C1, "i2c1", "pclk", PCLKCON, 16, 0, 0),
+	GATE(PCLK_SPI1, "spi1", "pclk", PCLKCON, 14, 0, 0),
+};
+
+struct samsung_clock_alias s3c2450_aliases[] __initdata = {
+	ALIAS(PCLK_SPI1, "s3c2443-spi.1", "spi"),
+	ALIAS(PCLK_SPI1, "s3c2443-spi.1", "spi_busclk0"),
+	ALIAS(MUX_HSSPI1, "s3c2443-spi.1", "spi_busclk2"),
+	ALIAS(PCLK_I2C1, "s3c2410-i2c.1", "i2c"),
+};
+
+/*
+ * This function allows non-dt platforms to specify the clock speed of the
+ * xti and ext clocks.
+ */
+void __init s3c2443_clk_register_fixed_ext(unsigned long xti_f,
+				unsigned long ext_f, unsigned long i2s_f,
+				unsigned long uart_f)
+{
+	s3c2443_common_frate_clks[0].fixed_rate = xti_f;
+	s3c2443_common_frate_clks[1].fixed_rate = ext_f;
+	s3c2443_common_frate_clks[2].fixed_rate = i2s_f;
+	s3c2443_common_frate_clks[3].fixed_rate = uart_f;
+
+	samsung_clk_register_fixed_rate(s3c2443_common_frate_clks,

drivers/clk/samsung/clk-s3c2443.c line 330

Quoted 10 lines
drivers/clk/samsung/clk-s3c2443.c new file +10 -0
+			ARRAY_SIZE(s3c2443_common_frate_clks));
+}
+
+static __initdata struct of_device_id ext_clk_match[] = {
+	{ .compatible = "samsung,clock-xti", .data = (void *)0, },
+	{ .compatible = "samsung,clock-ext", .data = (void *)1, },
+	{ .compatible = "samsung,clock-ext-i2s", .data = (void *)2, },
+	{ .compatible = "samsung,clock-ext-uart", .data = (void *)3, },
+	{},
+};

I wonder if we shouldn't use the generic clock bindings to define these instead of introducing platform specific binding. I know this has been already done for Exynos (and even in my patches for S3C64xx - I need to fix this), but I think the preferred way now (or maybe even the only allowed) is to use the generic bindings.

Quoted 63 lines
drivers/clk/samsung/clk-s3c2443.c new file +2 -0
+
+void __init s3c2443_common_clk_init(struct device_node *np, int

current_soc, + void __iomem *reg_base)

drivers/clk/samsung/clk-s3c2443.c new file +60 -0
+{
+	struct clk *mpll, *epll;
+
+	if (np) {
+		reg_base = of_iomap(np, 0);
+		if (!reg_base)
+			panic("%s: failed to map registers\n", __func__);
+	}
+
+	samsung_clk_init(np, reg_base, NR_CLKS,
+		s3c2443_clk_regs, ARRAY_SIZE(s3c2443_clk_regs), NULL, 0);
+
+	if (np)
+		samsung_clk_of_register_fixed_ext(s3c2443_common_frate_clks,
+			ARRAY_SIZE(s3c2443_common_frate_clks),
+			ext_clk_match);
+
+	samsung_clk_register_fixed_factor(s3c2443_common_ffactor,
+			ARRAY_SIZE(s3c2443_common_ffactor));
+
+	if (current_soc == S3C2416 || current_soc == S3C2450) {
+		mpll = samsung_clk_register_pll6552x("mpll", "mpllref",
+					reg_base + MPLLCON);
+		epll = samsung_clk_register_pll6553x("epll", "epllref",
+					reg_base + EPLLCON);
+	} else {
+		mpll = samsung_clk_register_pll3000x("mpll", "mpllref",
+					reg_base + MPLLCON);
+		epll = samsung_clk_register_pll2126x("epll", "epllref",
+					reg_base + EPLLCON);
+	}
+
+	samsung_clk_register_mux(s3c2443_common_muxes,
+			ARRAY_SIZE(s3c2443_common_muxes));
+	samsung_clk_register_div(s3c2443_common_dividers,
+			ARRAY_SIZE(s3c2443_common_dividers));
+	samsung_clk_register_gate(s3c2443_common_gates,
+		ARRAY_SIZE(s3c2443_common_gates));
+	samsung_clk_register_alias(s3c2443_common_aliases,
+		ARRAY_SIZE(s3c2443_common_aliases));
+
+	if (current_soc == S3C2416 || current_soc == S3C2450) {
+		samsung_clk_register_div(s3c2416_dividers,
+				ARRAY_SIZE(s3c2416_dividers));
+		samsung_clk_register_mux(s3c2416_muxes,
+				ARRAY_SIZE(s3c2416_muxes));
+		samsung_clk_register_gate(s3c2416_gates,
+				ARRAY_SIZE(s3c2416_gates));
+		samsung_clk_register_alias(s3c2416_aliases,
+				ARRAY_SIZE(s3c2416_aliases));
+	} else {
+		samsung_clk_register_div(s3c2443_dividers,
+				ARRAY_SIZE(s3c2443_dividers));
+		samsung_clk_register_gate(s3c2443_gates,
+				ARRAY_SIZE(s3c2443_gates));
+		samsung_clk_register_alias(s3c2443_aliases,
+				ARRAY_SIZE(s3c2443_aliases));
+	}
+
+	/* s3c2450 extends the s3c2416 clocks */

drivers/clk/samsung/clk-s3c2443.c line 403

Quoted 10 lines
drivers/clk/samsung/clk-s3c2443.c new file +10 -0
+	if (current_soc == S3C2450) {
+		samsung_clk_register_div(s3c2450_dividers,
+				ARRAY_SIZE(s3c2450_dividers));
+		samsung_clk_register_mux(s3c2450_muxes,
+				ARRAY_SIZE(s3c2450_muxes));
+		samsung_clk_register_gate(s3c2450_gates,
+				ARRAY_SIZE(s3c2450_gates));
+		samsung_clk_register_alias(s3c2450_aliases,
+				ARRAY_SIZE(s3c2450_aliases));
+	}

nit: What about using a switch statement, like:

	switch (current_soc) {
	case S3C2450:
		/* register 2450 specific clocks */
		/* fall through */
	case S3C2416:
		/* register clocks common to 2416 and 2450 */
		break;
	case S3C2443:
		/* register 2443 specific clocks */
		break;
	}

Still, I guess it's just a matter of preference, so just feel free to leave it as it is.

Best regards,
Tomasz

#15 lore raw

PATCH v2 6/6 ARM: S3C24XX: Convert s3c2416 and s3c2443 to common clock framework

In reply to Heiko Stübner

This converts the mentioned platforms to use the newly introduced driver for the common clock framework for them.

With this the whole legacy clock structure can go away too.

---
 arch/arm/boot/dts/s3c2416-smdk2416.dts  |    7 +
 arch/arm/boot/dts/s3c2416.dtsi          |   42 ++
 arch/arm/mach-s3c24xx/Kconfig           |   14 +-
 arch/arm/mach-s3c24xx/Makefile          |    5 +-
 arch/arm/mach-s3c24xx/clock-s3c2416.c   |  171 --------
 arch/arm/mach-s3c24xx/clock-s3c2443.c   |  212 ----------
 arch/arm/mach-s3c24xx/common-s3c2443.c  |  677 -------------------------------
 arch/arm/mach-s3c24xx/common.c          |   18 +-
 arch/arm/mach-s3c24xx/common.h          |    8 +
 arch/arm/mach-s3c24xx/mach-s3c2416-dt.c |   45 +-
 arch/arm/mach-s3c24xx/mach-smdk2416.c   |    9 +-
 arch/arm/mach-s3c24xx/mach-smdk2443.c   |    9 +-
 12 files changed, 102 insertions(+), 1115 deletions(-)
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2416.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2443.c
 delete mode 100644 arch/arm/mach-s3c24xx/common-s3c2443.c
arch/arm/boot/dts/s3c2416-smdk2416.dts +7 -0
index 59594cf..9caeb89 100644
@@ -19,6 +19,13 @@
 		reg =  <0x30000000 0x4000000>;
 	};
 
+	fixed-rate-clocks {
+		xti {
+			compatible = "samsung,clock-xti";
+			clock-frequency = <12000000>;
+		};
+	};
+
 	serial at 50000000 {
 		status = "okay";
 		pinctrl-names = "default";
arch/arm/boot/dts/s3c2416.dtsi +42 -0

98 lines not on this page · raw message

arch/arm/mach-s3c24xx/Kconfig +4 -10
index b8ec0ec..37cbe5f 100644
@@ -49,9 +49,9 @@ config CPU_S3C2416
 	select CPU_ARM926T
 	select CPU_LLSERIAL_S3C2440
 	select S3C2416_PM if PM
-	select S3C2443_COMMON
 	select S3C2443_DMA if S3C24XX_DMA
-	select SAMSUNG_CLKSRC
+	select COMMON_CLK
+	select COMMON_CLK_S3C2443
 	help
 	  Support for the S3C2416 SoC from the S3C24XX line
 
@@ -83,9 +83,9 @@ config CPU_S3C2443
 	bool "SAMSUNG S3C2443"
 	select CPU_ARM920T
 	select CPU_LLSERIAL_S3C2440
-	select S3C2443_COMMON
 	select S3C2443_DMA if S3C24XX_DMA
-	select SAMSUNG_CLKSRC
+	select COMMON_CLK
+	select COMMON_CLK_S3C2443
 	help
 	  Support for the S3C2443 SoC from the S3C24XX line
 
@@ -663,12 +663,6 @@ endif	# CPU_S3C2442
 
 if CPU_S3C2443 || CPU_S3C2416
 
-config S3C2443_COMMON
-	bool
-	help
-	  Common code for the S3C2443 and similar processors, which includes
-	  the S3C2416 and S3C2450.
-
 config S3C2443_DMA
 	bool
 	help
arch/arm/mach-s3c24xx/Makefile +2 -3
index 7f54e5b..ba0e547 100644
@@ -26,7 +26,7 @@ obj-$(CONFIG_S3C2412_DMA)	+= dma-s3c2412.o
 obj-$(CONFIG_S3C2412_PM)	+= pm-s3c2412.o
 obj-$(CONFIG_S3C2412_PM_SLEEP)	+= sleep-s3c2412.o
 
-obj-$(CONFIG_CPU_S3C2416)	+= s3c2416.o clock-s3c2416.o
+obj-$(CONFIG_CPU_S3C2416)	+= s3c2416.o
 obj-$(CONFIG_S3C2416_PM)	+= pm-s3c2416.o
 
 obj-$(CONFIG_CPU_S3C2440)	+= s3c2440.o clock-s3c2440.o
@@ -36,7 +36,7 @@ obj-$(CONFIG_S3C2440_DMA)	+= dma-s3c2440.o
 obj-$(CONFIG_S3C2440_PLL_12000000) += pll-s3c2440-12000000.o
 obj-$(CONFIG_S3C2440_PLL_16934400) += pll-s3c2440-16934400.o
 
-obj-$(CONFIG_CPU_S3C2443)	+= s3c2443.o clock-s3c2443.o
+obj-$(CONFIG_CPU_S3C2443)	+= s3c2443.o
 
 # PM
 
@@ -53,7 +53,6 @@ obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += cpufreq-utils.o
 obj-$(CONFIG_S3C2410_IOTIMING)	+= iotiming-s3c2410.o
 obj-$(CONFIG_S3C2412_IOTIMING)	+= iotiming-s3c2412.o
 
-obj-$(CONFIG_S3C2443_COMMON)	+= common-s3c2443.o
 obj-$(CONFIG_S3C2443_DMA)	+= dma-s3c2443.o
 
 #
arch/arm/mach-s3c24xx/clock-s3c2416.c deleted +0 -171

171 lines not on this page · raw message

arch/arm/mach-s3c24xx/clock-s3c2443.c deleted +0 -212

212 lines not on this page · raw message

arch/arm/mach-s3c24xx/common-s3c2443.c deleted +0 -677

677 lines not on this page · raw message

arch/arm/mach-s3c24xx/common.c +16 -2
index 0fe0254..6eae7a1 100644
@@ -143,7 +143,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idcode		= 0x32450003,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2416_map_io,
-		.init_clocks	= s3c2416_init_clocks,
 		.init_uarts	= s3c2416_init_uarts,
 		.init		= s3c2416_init,
 		.name		= name_s3c2416,
@@ -152,7 +151,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idcode		= 0x32443001,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2443_map_io,
-		.init_clocks	= s3c2443_init_clocks,
 		.init_uarts	= s3c2443_init_uarts,
 		.init		= s3c2443_init,
 		.name		= name_s3c2443,
@@ -331,3 +329,19 @@ void __init_or_cpufreq s3c24xx_setup_clocks(unsigned long fclk,
 	clk_f.rate = fclk;
 }
 #endif
+
+#if defined(CONFIG_COMMON_CLK) && defined(CONFIG_CPU_S3C2416)
+void __init s3c2416_init_clocks(int xtal)
+{
+	s3c2443_common_clk_init(NULL, 0, S3C24XX_VA_CLKPWR);
+	s3c2443_clk_register_fixed_ext(xtal, 0, 0, 0);
+}
+#endif
+
+#if defined(CONFIG_COMMON_CLK) && defined(CONFIG_CPU_S3C2443)
+void __init s3c2443_init_clocks(int xtal)
+{
+	s3c2443_common_clk_init(NULL, 1, S3C24XX_VA_CLKPWR);
+	s3c2443_clk_register_fixed_ext(xtal, 0, 0, 0);
+}
+#endif
arch/arm/mach-s3c24xx/common.h +8 -0
index 307c371..2cbcec3 100644
@@ -107,4 +107,12 @@ extern void s3c2443_init_irq(void);
 
 extern struct syscore_ops s3c24xx_irq_syscore_ops;
 
+#ifdef CONFIG_COMMON_CLK_S3C2443
+extern void s3c2443_clk_register_fixed_ext(unsigned long xti_f,
+				unsigned long ext_f, unsigned long i2s_f,
+				unsigned long uart_f);
+void __init s3c2443_common_clk_init(struct device_node *np, int current_soc,
+			     void __iomem *reg_base);
+#endif
+
 #endif /* __ARCH_ARM_MACH_S3C24XX_COMMON_H */
arch/arm/mach-s3c24xx/mach-s3c2416-dt.c +9 -36

69 lines not on this page · raw message

arch/arm/mach-s3c24xx/mach-smdk2416.c +7 -2
index cb46847..077d44c 100644
@@ -217,10 +217,15 @@ static struct platform_device *smdk2416_devices[] __initdata = {
 	&s3c_device_usb_hsudc,
 };
 
+static void __init smdk2416_init_time(void)
+{
+	s3c2416_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init smdk2416_map_io(void)
 {
 	s3c24xx_init_io(smdk2416_iodesc, ARRAY_SIZE(smdk2416_iodesc));
-	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_uarts(smdk2416_uartcfgs, ARRAY_SIZE(smdk2416_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
@@ -255,6 +260,6 @@ MACHINE_START(SMDK2416, "SMDK2416")
 	.init_irq	= s3c2416_init_irq,
 	.map_io		= smdk2416_map_io,
 	.init_machine	= smdk2416_machine_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= smdk2416_init_time,
 	.restart	= s3c2416_restart,
 MACHINE_END
arch/arm/mach-s3c24xx/mach-smdk2443.c +7 -2
index 9435c3b..0dbf470 100644
@@ -120,11 +120,16 @@ static struct platform_device *smdk2443_devices[] __initdata = {
 static void __init smdk2443_map_io(void)
 {
 	s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc));
-	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init smdk2443_init_time(void)
+{
+	s3c2443_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init smdk2443_machine_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
@@ -144,6 +149,6 @@ MACHINE_START(SMDK2443, "SMDK2443")
 	.init_irq	= s3c2443_init_irq,
 	.map_io		= smdk2443_map_io,
 	.init_machine	= smdk2443_machine_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= smdk2443_init_time,
 	.restart	= s3c2443_restart,
 MACHINE_END
Signature · 1 line
1.7.10.4
#16 lore raw

PATCH v2 6/6 ARM: S3C24XX: Convert s3c2416 and s3c2443 to common clock framework

Quoted 15 lines · Heiko St?bner

This converts the mentioned platforms to use the newly introduced driver for the common clock framework for them.

With this the whole legacy clock structure can go away too.

---
 arch/arm/boot/dts/s3c2416-smdk2416.dts  |    7 +
 arch/arm/boot/dts/s3c2416.dtsi          |   42 ++
 arch/arm/mach-s3c24xx/Kconfig           |   14 +-
 arch/arm/mach-s3c24xx/Makefile          |    5 +-
 arch/arm/mach-s3c24xx/clock-s3c2416.c   |  171 --------
 arch/arm/mach-s3c24xx/clock-s3c2443.c   |  212 ----------
 arch/arm/mach-s3c24xx/common-s3c2443.c  |  677 ---------------------------
Quoted 1 line

----

In this case, to use '-D' in format-patch would be better :-)

Quoted 43 lines
 arch/arm/mach-s3c24xx/common.c          |   18 +-
 arch/arm/mach-s3c24xx/common.h          |    8 +
 arch/arm/mach-s3c24xx/mach-s3c2416-dt.c |   45 +-
 arch/arm/mach-s3c24xx/mach-smdk2416.c   |    9 +-
 arch/arm/mach-s3c24xx/mach-smdk2443.c   |    9 +-
 12 files changed, 102 insertions(+), 1115 deletions(-)
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2416.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2443.c
 delete mode 100644 arch/arm/mach-s3c24xx/common-s3c2443.c
arch/arm/boot/dts/s3c2416-smdk2416.dts +7 -0
index 59594cf..9caeb89 100644
@@ -19,6 +19,13 @@
 		reg =  <0x30000000 0x4000000>;
 	};
 
+	fixed-rate-clocks {
+		xti {
+			compatible = "samsung,clock-xti";
+			clock-frequency = <12000000>;
+		};
+	};
+
 	serial at 50000000 {
 		status = "okay";
 		pinctrl-names = "default";
arch/arm/boot/dts/s3c2416.dtsi +1 -0
index e6555bd..c19d99c 100644
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <dt-bindings/clock/samsung,s3c2443-clock.h>
 #include "s3c24xx.dtsi"
 #include "s3c2416-pinctrl.dtsi"
 

arch/arm/boot/dts/s3c2416.dtsi line 32

Quoted 4 lines
arch/arm/boot/dts/s3c2416.dtsi +1 -0
@@ -28,26 +29,53 @@
 		compatible = "samsung,s3c2416-irq";
 	};
 
+	clocks: clock-controller at 0x4c000000 {

+ clock: clock-controller at 0x4c000000 {

for keeping same format for Samsung stuff...

arch/arm/boot/dts/s3c2416.dtsi line 43

Quoted 11 lines
arch/arm/boot/dts/s3c2416.dtsi +7 -0
+		compatible = "samsung,s3c2416-clock";
+		reg = <0x4c000000 0x40>;
+		#clock-cells = <1>;
+	};
+
 	pinctrl at 56000000 {
 		compatible = "samsung,s3c2416-pinctrl";
 	};
 
+	timer at 51000000 {
+		clocks = <&clocks PCLK_PWM>;

+ clocks = <&clock PCLK_PWM>;

And I'm not sure using definition PCLK_PWM is better here...

arch/arm/boot/dts/s3c2416.dtsi line 52

Quoted 9 lines
arch/arm/boot/dts/s3c2416.dtsi +7 -0
+		clock-names = "timers";
+	};
+
 	serial at 50000000 {
 		compatible = "samsung,s3c2440-uart";
+		clock-names = "uart", "clk_uart_baud2",
+				"clk_uart_baud3";
+		clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>,
+				<&clocks SCLK_UART>;

Please use same ordering...for 'clocks' and 'clock-names'. See above the timers...'clocks' then 'clock-names'...

arch/arm/boot/dts/s3c2416.dtsi line 60

Quoted 8 lines
arch/arm/boot/dts/s3c2416.dtsi +4 -0
 	};
 
 	serial at 50004000 {
 		compatible = "samsung,s3c2440-uart";
+		clock-names = "uart", "clk_uart_baud2",
+				"clk_uart_baud3";
+		clocks = <&clocks PCLK_UART1>, <&clocks PCLK_UART1>,
+				<&clocks SCLK_UART>;

Same as above.

arch/arm/boot/dts/s3c2416.dtsi line 68

Quoted 8 lines
arch/arm/boot/dts/s3c2416.dtsi +4 -0
 	};
 
 	serial at 50008000 {
 		compatible = "samsung,s3c2440-uart";
+		clock-names = "uart", "clk_uart_baud2",
+				"clk_uart_baud3";
+		clocks = <&clocks PCLK_UART2>, <&clocks PCLK_UART2>,
+				<&clocks SCLK_UART>;

Same as above.

arch/arm/boot/dts/s3c2416.dtsi line 78

Quoted 10 lines
arch/arm/boot/dts/s3c2416.dtsi +4 -0
 	};
 
 	serial at 5000C000 {
 		compatible = "samsung,s3c2440-uart";
 		reg = <0x5000C000 0x4000>;
 		interrupts = <1 18 24 4>, <1 18 25 4>;
+		clock-names = "uart", "clk_uart_baud2",
+				"clk_uart_baud3";
+		clocks = <&clocks PCLK_UART3>, <&clocks PCLK_UART3>,
+				<&clocks SCLK_UART>;

Same as above.

arch/arm/boot/dts/s3c2416.dtsi line 89

Quoted 11 lines
arch/arm/boot/dts/s3c2416.dtsi +4 -0
 		status = "disabled";
 	};
 
@@ -55,6 +83,10 @@
 		compatible = "samsung,s3c6410-sdhci";
 		reg = <0x4AC00000 0x100>;
 		interrupts = <0 0 21 3>;
+		clock-names = "hsmmc", "mmc_busclk.0",
+				"mmc_busclk.2";
+		clocks = <&clocks HCLK_HSMMC0>, <&clocks HCLK_HSMMC0>,
+				<&clocks MUX_HSMMC0>;

Same.

arch/arm/boot/dts/s3c2416.dtsi line 100

Quoted 11 lines
arch/arm/boot/dts/s3c2416.dtsi +4 -0
 		status = "disabled";
 	};
 
@@ -62,18 +94,28 @@
 		compatible = "samsung,s3c6410-sdhci";
 		reg = <0x4A800000 0x100>;
 		interrupts = <0 0 20 3>;
+		clock-names = "hsmmc", "mmc_busclk.0",
+				"mmc_busclk.2";
+		clocks = <&clocks HCLK_HSMMC1>, <&clocks HCLK_HSMMC1>,
+				<&clocks MUX_HSMMC1>;

Same.

Quoted 26 lines
arch/arm/boot/dts/s3c2416.dtsi +6 -0
 		status = "disabled";
 	};
 
 	watchdog at 53000000 {
 		interrupts = <1 9 27 3>;
+		clocks = <&clocks PCLK_WDT>;
+		clock-names = "watchdog";
 	};
 
 	rtc at 57000000 {
 		compatible = "samsung,s3c2416-rtc";
+		clocks = <&clocks PCLK_RTC>;
+		clock-names = "rtc";
 	};
 
 	i2c at 54000000 {
 		compatible = "samsung,s3c2440-i2c";
+		clocks = <&clocks PCLK_I2C0>;
+		clock-names = "i2c";
 	};
 };
arch/arm/mach-s3c24xx/Kconfig +0 -0
index b8ec0ec..37cbe5f 100644

arch/arm/mach-s3c24xx/Kconfig config CPU_S3C2416 · line 54

Quoted 8 lines
arch/arm/mach-s3c24xx/Kconfig +2 -2
@@ -49,9 +49,9 @@ config CPU_S3C2416
 	select CPU_ARM926T
 	select CPU_LLSERIAL_S3C2440
 	select S3C2416_PM if PM
-	select S3C2443_COMMON
 	select S3C2443_DMA if S3C24XX_DMA
-	select SAMSUNG_CLKSRC
+	select COMMON_CLK
+	select COMMON_CLK_S3C2443

Please put them in alphabetical ordering...

arch/arm/mach-s3c24xx/Kconfig config CPU_S3C2443 · line 88

Quoted 12 lines
arch/arm/mach-s3c24xx/Kconfig +2 -2
 	help
 	  Support for the S3C2416 SoC from the S3C24XX line
 
@@ -83,9 +83,9 @@ config CPU_S3C2443
 	bool "SAMSUNG S3C2443"
 	select CPU_ARM920T
 	select CPU_LLSERIAL_S3C2440
-	select S3C2443_COMMON
 	select S3C2443_DMA if S3C24XX_DMA
-	select SAMSUNG_CLKSRC
+	select COMMON_CLK
+	select COMMON_CLK_S3C2443

Same as above.

Quoted 12 lines
arch/arm/mach-s3c24xx/Kconfig +0 -4
 	help
 	  Support for the S3C2443 SoC from the S3C24XX line
 
@@ -663,12 +663,6 @@ endif	# CPU_S3C2442
 
 if CPU_S3C2443 || CPU_S3C2416
 
-config S3C2443_COMMON
-	bool
-	help
-	  Common code for the S3C2443 and similar processors, which

includes

arch/arm/mach-s3c24xx/Kconfig endif # CPU_S3C2442 · line 668

Quoted 5 lines
arch/arm/mach-s3c24xx/Kconfig +0 -2
-	  the S3C2416 and S3C2450.
-
 config S3C2443_DMA
 	bool
 	help

[...]

Thanks,
- Kukjin

#17 lore raw

PATCH v2 6/6 ARM: S3C24XX: Convert s3c2416 and s3c2443 to common clock framework

Quoted 81 lines · On Tuesday 16 of July 2013 16:09:24 Kukjin Kim wrote:
Quoted 16 lines · Heiko St?bner

This converts the mentioned platforms to use the newly introduced driver
for the common clock framework for them.

With this the whole legacy clock structure can go away too.

---

 arch/arm/boot/dts/s3c2416-smdk2416.dts  |    7 +
 arch/arm/boot/dts/s3c2416.dtsi          |   42 ++
 arch/arm/mach-s3c24xx/Kconfig           |   14 +-
 arch/arm/mach-s3c24xx/Makefile          |    5 +-
 arch/arm/mach-s3c24xx/clock-s3c2416.c   |  171 --------
 arch/arm/mach-s3c24xx/clock-s3c2443.c   |  212 ----------
 arch/arm/mach-s3c24xx/common-s3c2443.c  |  677
Quoted 2 lines

--------------------------->
----

In this case, to use '-D' in format-patch would be better :-)

Quoted 56 lines
 arch/arm/mach-s3c24xx/common.c          |   18 +-
 arch/arm/mach-s3c24xx/common.h          |    8 +
 arch/arm/mach-s3c24xx/mach-s3c2416-dt.c |   45 +-
 arch/arm/mach-s3c24xx/mach-smdk2416.c   |    9 +-
 arch/arm/mach-s3c24xx/mach-smdk2443.c   |    9 +-
 12 files changed, 102 insertions(+), 1115 deletions(-)
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2416.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2443.c
 delete mode 100644 arch/arm/mach-s3c24xx/common-s3c2443.c
arch/arm/boot/dts/s3c2416-smdk2416.dts +7 -0
index 59594cf..9caeb89 100644
@@ -19,6 +19,13 @@
 
 		reg =  <0x30000000 0x4000000>;
 
 	};
 
+	fixed-rate-clocks {
+		xti {
+			compatible = "samsung,clock-xti";
+			clock-frequency = <12000000>;
+		};
+	};
+
 
arch/arm/boot/dts/s3c2416-smdk2416.dts +0 -0
 	serial at 50000000 {
 
 		status = "okay";
 		pinctrl-names = "default";
arch/arm/boot/dts/s3c2416.dtsi +1 -0
index e6555bd..c19d99c 100644
@@ -8,6 +8,7 @@
 
  * published by the Free Software Foundation.
  */
 
+#include <dt-bindings/clock/samsung,s3c2443-clock.h>
 
 #include "s3c24xx.dtsi"

#include "s3c2416-pinctrl.dtsi"

arch/arm/boot/dts/s3c2416.dtsi +1 -0
@@ -28,26 +29,53 @@
 
 		compatible = "samsung,s3c2416-irq";
 
 	};
 
+	clocks: clock-controller at 0x4c000000 {
(quoted diff) +1 -0
+	clock: clock-controller at 0x4c000000 {
Quoted 2 lines

for keeping same format for Samsung stuff...

Also please remove the "0x" from node name.

Quoted 17 lines
Quoted 14 lines
arch/arm/boot/dts/s3c2416.dtsi +7 -0
+		compatible = "samsung,s3c2416-clock";
+		reg = <0x4c000000 0x40>;
+		#clock-cells = <1>;
+	};
+
 
 	pinctrl at 56000000 {
 
 		compatible = "samsung,s3c2416-pinctrl";
 
 	};
 
+	timer at 51000000 {
+		clocks = <&clocks PCLK_PWM>;
(quoted diff) +1 -0
+		clocks = <&clock PCLK_PWM>;
Quoted 1 line

And I'm not sure using definition PCLK_PWM is better here...

Care to explain your doubts about it? I think this is fine.

Best regards,
Tomasz

#18 lore raw

PATCH v2 6/6 ARM: S3C24XX: Convert s3c2416 and s3c2443 to common clock framework

Tomasz Figa wrote:

[...]

Quoted 9 lines
Quoted 6 lines
Quoted 2 lines
arch/arm/boot/dts/s3c2416.dtsi +2 -0
+	timer at 51000000 {
+		clocks = <&clocks PCLK_PWM>;
(quoted diff) +1 -0
+		clocks = <&clock PCLK_PWM>;

And I'm not sure using definition PCLK_PWM is better here...

Care to explain your doubts about it? I think this is fine.

I mean I don't know why someone use a hard value(number) and someone use the definition...

- Kukjin

#19 lore raw

PATCH v2 6/6 ARM: S3C24XX: Convert s3c2416 and s3c2443 to common clock framework

Quoted 9 lines · On Wednesday 24 of July 2013 21:59:45 Kukjin Kim wrote:

Tomasz Figa wrote:

[...]

Quoted 5 lines
Quoted 5 lines
Quoted 2 lines
arch/arm/boot/dts/s3c2416.dtsi +2 -0
+	timer at 51000000 {
+		clocks = <&clocks PCLK_PWM>;
(quoted diff) +1 -0
+		clocks = <&clock PCLK_PWM>;
Quoted 6 lines
Quoted 3 lines
Quoted 1 line

And I'm not sure using definition PCLK_PWM is better here...

Care to explain your doubts about it? I think this is fine.

I mean I don't know why someone use a hard value(number) and someone use the definition...

Since preprocessor support for dts files was introduced, definitions are preferred, wherever possible to specify constants.

Best regards,
Tomasz

#20 lore raw

PATCH v2 6/6 ARM: S3C24XX: Convert s3c2416 and s3c2443 to common clock framework

In reply to Tomasz Figa
Quoted 1 line · Tomasz Figa

On Tuesday 16 of July 2013 16:09:24 Kukjin Kim wrote:

[...]

Quoted 9 lines
Quoted 6 lines
Quoted 2 lines
(quoted diff) +2 -0
+	timer at 51000000 {
+		clocks =<&clocks PCLK_PWM>;
(quoted diff) +1 -0
+		clocks =<&clock PCLK_PWM>;

And I'm not sure using definition PCLK_PWM is better here...

Care to explain your doubts about it? I think this is fine.

I mean just would be better to use hard coded number here instead of PCLK_PWM like others.

- Kukjin

#21 lore raw

v2 cover Convert S3C2416 ad S3C2443 to common clock framework

In reply to Heiko Stübner
Quoted 50 lines · Heiko St?bner

This series provides a clock driver for s3c2416, s3c2443 and s3c2450, which share a common clock tree, but differ fundamentally from earlier s3c24xx SoCs, and converts the mentioned SoCs to use it.

The clock driver itself follows the same scheme established by all other Samsung clock drivers.

It depends on the pwm cleanup series from Tomasz Figa, which gets rid of the declarations of the pwm-internal clocks.

Test on both non-dt and dt s3c2416.

Heiko Stuebner (6):
clk: samsung: move common plls registration into separate function
clk: samsung: fix error handling in pll register functions
clk: samsung: add plls used in s3c2416 and s3c2443
ARM: S3C24XX: enable legacy clock code only when SAMSUNG_CLOCK
selected
clk: samsung: add clock-driver for s3c2416, s3c2443 and s3c2450
ARM: S3C24XX: Convert s3c2416 and s3c2443 to common clock framework

 .../bindings/clock/samsung,s3c2443-clock.txt       |   48 ++
 arch/arm/boot/dts/s3c2416-smdk2416.dts             |    7 +
 arch/arm/boot/dts/s3c2416.dtsi                     |   42 ++
 arch/arm/mach-s3c24xx/Kconfig                      |   14 +-
 arch/arm/mach-s3c24xx/Makefile                     |    5 +-
 arch/arm/mach-s3c24xx/clock-s3c2416.c              |  171 -----
 arch/arm/mach-s3c24xx/clock-s3c2443.c              |  212 ------
 arch/arm/mach-s3c24xx/common-s3c2443.c             |  675 --------------------
 arch/arm/mach-s3c24xx/common.c                     |   20 +-
 arch/arm/mach-s3c24xx/common.h                     |    8 +
 arch/arm/mach-s3c24xx/mach-s3c2416-dt.c            |   45 +-
 arch/arm/mach-s3c24xx/mach-smdk2416.c              |    9 +-
 arch/arm/mach-s3c24xx/mach-smdk2443.c              |    9 +-
 drivers/clk/Kconfig                                |    1 +
 drivers/clk/samsung/Kconfig                        |    2 +
 drivers/clk/samsung/Makefile                       |    1 +
 drivers/clk/samsung/clk-pll.c                      |  374 +++++++++--
 drivers/clk/samsung/clk-pll.h                      |    8 +
 drivers/clk/samsung/clk-s3c2443.c                  |  422 ++++++++++++
 include/dt-bindings/clock/samsung,s3c2443-clock.h  |   96 +++
 20 files changed, 998 insertions(+), 1171 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2416.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2443.c
 delete mode 100644 arch/arm/mach-s3c24xx/common-s3c2443.c
 create mode 100644 drivers/clk/samsung/Kconfig
 create mode 100644 drivers/clk/samsung/clk-s3c2443.c
 create mode 100644 include/dt-bindings/clock/samsung,s3c2443-clock.h
Quoted 3 lines

--
1.7.10.4

Thanks for consolidating pll registrations.
For patches 1 to 3:

#22 lore raw

v2 cover Convert S3C2416 ad S3C2443 to common clock framework

In reply to Heiko Stübner
Quoted 42 lines · Heiko St?bner

This series provides a clock driver for s3c2416, s3c2443 and s3c2450, which share a common clock tree, but differ fundamentally from earlier s3c24xx SoCs, and converts the mentioned SoCs to use it.

The clock driver itself follows the same scheme established by all other Samsung clock drivers.

It depends on the pwm cleanup series from Tomasz Figa, which gets rid of the declarations of the pwm-internal clocks.

Test on both non-dt and dt s3c2416.

Heiko Stuebner (6):
clk: samsung: move common plls registration into separate function
clk: samsung: fix error handling in pll register functions
clk: samsung: add plls used in s3c2416 and s3c2443
ARM: S3C24XX: enable legacy clock code only when SAMSUNG_CLOCK
selected
clk: samsung: add clock-driver for s3c2416, s3c2443 and s3c2450
ARM: S3C24XX: Convert s3c2416 and s3c2443 to common clock framework

  .../bindings/clock/samsung,s3c2443-clock.txt       |   48 ++
  arch/arm/boot/dts/s3c2416-smdk2416.dts             |    7 +
  arch/arm/boot/dts/s3c2416.dtsi                     |   42 ++
  arch/arm/mach-s3c24xx/Kconfig                      |   14 +-
  arch/arm/mach-s3c24xx/Makefile                     |    5 +-
  arch/arm/mach-s3c24xx/clock-s3c2416.c              |  171 -----
  arch/arm/mach-s3c24xx/clock-s3c2443.c              |  212 ------
  arch/arm/mach-s3c24xx/common-s3c2443.c             |  675 --------------------
  arch/arm/mach-s3c24xx/common.c                     |   20 +-
  arch/arm/mach-s3c24xx/common.h                     |    8 +
  arch/arm/mach-s3c24xx/mach-s3c2416-dt.c            |   45 +-
  arch/arm/mach-s3c24xx/mach-smdk2416.c              |    9 +-
  arch/arm/mach-s3c24xx/mach-smdk2443.c              |    9 +-
  drivers/clk/Kconfig                                |    1 +
  drivers/clk/samsung/Kconfig                        |    2 +
  drivers/clk/samsung/Makefile                       |    1 +
  drivers/clk/samsung/clk-pll.c                      |  374 +++++++++--
  drivers/clk/samsung/clk-pll.h                      |    8 +
  drivers/clk/samsung/clk-s3c2443.c                  |  422 ++++++++++++
  include/dt-bindings/clock/samsung,s3c2443-clock.h  |   96 +++
  20 files changed, 998 insertions(+), 1171 deletions(-)
Quoted 8 lines

create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2416.c
delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2443.c
delete mode 100644 arch/arm/mach-s3c24xx/common-s3c2443.c
create mode 100644 drivers/clk/samsung/Kconfig
create mode 100644 drivers/clk/samsung/clk-s3c2443.c
create mode 100644 include/dt-bindings/clock/samsung,s3c2443-clock.h

Heiko, please respin this series so that this could be sent to upstream for v3.12.

Thanks,
Kukjin