All of lore.kernel.org
 help / color / mirror / Atom feed
From: Naveen Krishna Ch <naveenkrishna.ch@gmail.com>
To: linux-samsung-soc@vger.kernel.org, linux-arm-kernel@lists.infradead.org
Cc: jassisinghbrar@gmail.com, sbkim73@samsung.com,
	sw.youn@samsung.com, kgene.kim@samsung.com
Subject: Re: [PATCH v2 3/3] ARM: EXYNOS4: Add EPLL clock operations
Date: Wed, 22 Jun 2011 12:21:43 +0530	[thread overview]
Message-ID: <BANLkTim_0yj8hSefv5BUg5Z1vLh5SWhqjA@mail.gmail.com> (raw)
In-Reply-To: <1308655463-8787-4-git-send-email-ch.naveen@samsung.com>

[-- Attachment #1: Type: text/plain, Size: 9860 bytes --]

Hi Every one,

1. Both S5P6440 and S5P6450 uses PLL90XX for EPLL.
  However, the same epll_ops is duplicated in the following files
  arch/arm/mach-s5p64x0/clock-s5p6440.c
  arch/arm/mach-s5p64x0/clock-s5p6450.c

  Please find attached patch which moves it to the common clock.c
  Attachment: "0001-ARM-S5P64X0-Move-duplicated-epll-code.patch"

2. Also, S5PV210, C110, C100, 6450/6440 and EXYNOS4 define their own
  epll_ops.

  The following attachment consolidates the same on the basis of PLL types
  "Eg: PLL90XX. PLL46XX, PLL45XX and PLL65XX"

  Kindly, review the approach and comment.
  Attachment: "0001-ARM-Samsung-organize-duplicated-EPLL-code.patch"

Thanks & Best regards,
Naveen Krishna Chatradhi

On 21 June 2011 16:54, Naveen Krishna Chatradhi <ch.naveen@samsung.com> wrote:
> S5PV210 and EXYNOS4 uses similar PLL(PLL46XX) for EPLL.
> So, The EPLL set rate function is duplicated.
>
> Note: Moved common code to plat-s5p, as commented by Kukjin Kim.
>
> Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com>
> ---
>  arch/arm/mach-exynos4/clock.c        |    1 +
>  arch/arm/mach-s5pv210/clock.c        |   78 +---------------------------------
>  arch/arm/plat-s5p/clock.c            |   77 +++++++++++++++++++++++++++++++++
>  arch/arm/plat-s5p/include/plat/pll.h |    3 +
>  4 files changed, 82 insertions(+), 77 deletions(-)
>
> diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
> index feeb27e..7687087 100644
> --- a/arch/arm/mach-exynos4/clock.c
> +++ b/arch/arm/mach-exynos4/clock.c
> @@ -1294,6 +1294,7 @@ void __init_or_cpufreq exynos4_setup_clocks(void)
>                                __raw_readl(S5P_VPLL_CON1), pll_4650);
>
>        clk_fout_apll.ops = &exynos4_fout_apll_ops;
> +       clk_fout_epll.ops = &pll46xx_epll_ops;
>        clk_fout_mpll.rate = mpll;
>        clk_fout_epll.rate = epll;
>        clk_fout_vpll.rate = vpll;
> diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
> index ae72f87..dd77c2c 100644
> --- a/arch/arm/mach-s5pv210/clock.c
> +++ b/arch/arm/mach-s5pv210/clock.c
> @@ -979,82 +979,6 @@ static struct clksrc_clk *sysclks[] = {
>        &clk_sclk_spdif,
>  };
>
> -static u32 epll_div[][6] = {
> -       {  48000000, 0, 48, 3, 3, 0 },
> -       {  96000000, 0, 48, 3, 2, 0 },
> -       { 144000000, 1, 72, 3, 2, 0 },
> -       { 192000000, 0, 48, 3, 1, 0 },
> -       { 288000000, 1, 72, 3, 1, 0 },
> -       {  32750000, 1, 65, 3, 4, 35127 },
> -       {  32768000, 1, 65, 3, 4, 35127 },
> -       {  45158400, 0, 45, 3, 3, 10355 },
> -       {  45000000, 0, 45, 3, 3, 10355 },
> -       {  45158000, 0, 45, 3, 3, 10355 },
> -       {  49125000, 0, 49, 3, 3, 9961 },
> -       {  49152000, 0, 49, 3, 3, 9961 },
> -       {  67737600, 1, 67, 3, 3, 48366 },
> -       {  67738000, 1, 67, 3, 3, 48366 },
> -       {  73800000, 1, 73, 3, 3, 47710 },
> -       {  73728000, 1, 73, 3, 3, 47710 },
> -       {  36000000, 1, 32, 3, 4, 0 },
> -       {  60000000, 1, 60, 3, 3, 0 },
> -       {  72000000, 1, 72, 3, 3, 0 },
> -       {  80000000, 1, 80, 3, 3, 0 },
> -       {  84000000, 0, 42, 3, 2, 0 },
> -       {  50000000, 0, 50, 3, 3, 0 },
> -};
> -
> -static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate)
> -{
> -       unsigned int epll_con, epll_con_k;
> -       unsigned int i;
> -
> -       /* Return if nothing changed */
> -       if (clk->rate == rate)
> -               return 0;
> -
> -       epll_con = __raw_readl(S5P_EPLL_CON);
> -       epll_con_k = __raw_readl(S5P_EPLL_CON1);
> -
> -       epll_con_k &= ~PLL46XX_KDIV_MASK;
> -       epll_con &= ~(1 << 27 |
> -                       PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |
> -                       PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |
> -                       PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
> -
> -       for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
> -               if (epll_div[i][0] == rate) {
> -                       epll_con_k |= epll_div[i][5] << 0;
> -                       epll_con |= (epll_div[i][1] << 27 |
> -                                       epll_div[i][2] << PLL46XX_MDIV_SHIFT |
> -                                       epll_div[i][3] << PLL46XX_PDIV_SHIFT |
> -                                       epll_div[i][4] << PLL46XX_SDIV_SHIFT);
> -                       break;
> -               }
> -       }
> -
> -       if (i == ARRAY_SIZE(epll_div)) {
> -               printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
> -                               __func__);
> -               return -EINVAL;
> -       }
> -
> -       __raw_writel(epll_con, S5P_EPLL_CON);
> -       __raw_writel(epll_con_k, S5P_EPLL_CON1);
> -
> -       printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
> -                       clk->rate, rate);
> -
> -       clk->rate = rate;
> -
> -       return 0;
> -}
> -
> -static struct clk_ops s5pv210_epll_ops = {
> -       .set_rate = s5pv210_epll_set_rate,
> -       .get_rate = s5p_epll_get_rate,
> -};
> -
>  void __init_or_cpufreq s5pv210_setup_clocks(void)
>  {
>        struct clk *xtal_clk;
> @@ -1075,7 +999,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
>
>        /* Set functions for clk_fout_epll */
>        clk_fout_epll.enable = s5p_epll_enable;
> -       clk_fout_epll.ops = &s5pv210_epll_ops;
> +       clk_fout_epll.ops = &pll46xx_epll_ops;
>
>        printk(KERN_DEBUG "%s: registering clocks\n", __func__);
>
> diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c
> index 02af235..2a4678d 100644
> --- a/arch/arm/plat-s5p/clock.c
> +++ b/arch/arm/plat-s5p/clock.c
> @@ -24,6 +24,7 @@
>  #include <mach/regs-clock.h>
>
>  #include <plat/clock.h>
> +#include <plat/pll.h>
>  #include <plat/clock-clksrc.h>
>  #include <plat/s5p-clock.h>
>
> @@ -203,6 +204,82 @@ struct clk_ops s5p_sclk_spdif_ops = {
>        .get_rate       = s5p_spdif_get_rate,
>  };
>
> +static u32 epll_div[][6] = {
> +       {  48000000, 0, 48, 3, 3, 0 },
> +       {  96000000, 0, 48, 3, 2, 0 },
> +       { 144000000, 1, 72, 3, 2, 0 },
> +       { 192000000, 0, 48, 3, 1, 0 },
> +       { 288000000, 1, 72, 3, 1, 0 },
> +       {  32750000, 1, 65, 3, 4, 35127 },
> +       {  32768000, 1, 65, 3, 4, 35127 },
> +       {  45158400, 0, 45, 3, 3, 10355 },
> +       {  45000000, 0, 45, 3, 3, 10355 },
> +       {  45158000, 0, 45, 3, 3, 10355 },
> +       {  49125000, 0, 49, 3, 3, 9961 },
> +       {  49152000, 0, 49, 3, 3, 9961 },
> +       {  67737600, 1, 67, 3, 3, 48366 },
> +       {  67738000, 1, 67, 3, 3, 48366 },
> +       {  73800000, 1, 73, 3, 3, 47710 },
> +       {  73728000, 1, 73, 3, 3, 47710 },
> +       {  36000000, 1, 32, 3, 4, 0 },
> +       {  60000000, 1, 60, 3, 3, 0 },
> +       {  72000000, 1, 72, 3, 3, 0 },
> +       {  80000000, 1, 80, 3, 3, 0 },
> +       {  84000000, 0, 42, 3, 2, 0 },
> +       {  50000000, 0, 50, 3, 3, 0 },
> +};
> +
> +int pll46xx_epll_set_rate(struct clk *clk, unsigned long rate)
> +{
> +       unsigned int epll_con, epll_con_k;
> +       unsigned int i;
> +
> +       /* Return if nothing changed */
> +       if (clk->rate == rate)
> +               return 0;
> +
> +       epll_con = __raw_readl(S5P_EPLL_CON);
> +       epll_con_k = __raw_readl(S5P_EPLL_CON1);
> +
> +       epll_con_k &= ~PLL46XX_KDIV_MASK;
> +       epll_con &= ~(1 << 27 |
> +                       PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |
> +                       PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |
> +                       PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
> +
> +       for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
> +               if (epll_div[i][0] == rate) {
> +                       epll_con_k |= epll_div[i][5] << 0;
> +                       epll_con |= (epll_div[i][1] << 27 |
> +                                       epll_div[i][2] << PLL46XX_MDIV_SHIFT |
> +                                       epll_div[i][3] << PLL46XX_PDIV_SHIFT |
> +                                       epll_div[i][4] << PLL46XX_SDIV_SHIFT);
> +                       break;
> +               }
> +       }
> +
> +       if (i == ARRAY_SIZE(epll_div)) {
> +               printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
> +                               __func__);
> +               return -EINVAL;
> +       }
> +
> +       __raw_writel(epll_con, S5P_EPLL_CON);
> +       __raw_writel(epll_con_k, S5P_EPLL_CON1);
> +
> +       printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
> +                       clk->rate, rate);
> +
> +       clk->rate = rate;
> +
> +       return 0;
> +}
> +
> +struct clk_ops pll46xx_epll_ops = {
> +       .set_rate = pll46xx_epll_set_rate,
> +       .get_rate = s5p_epll_get_rate,
> +};
> +
>  static struct clk *s5p_clks[] __initdata = {
>        &clk_ext_xtal_mux,
>        &clk_48m,
> diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h
> index bf28fad..911a20e 100644
> --- a/arch/arm/plat-s5p/include/plat/pll.h
> +++ b/arch/arm/plat-s5p/include/plat/pll.h
> @@ -94,6 +94,9 @@ static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
>        return result;
>  }
>
> +extern int pll46xx_epll_set_rate(struct clk *clk, unsigned long rate);
> +extern struct clk_ops pll46xx_epll_ops;
> +
>  #define PLL90XX_MDIV_MASK      (0xFF)
>  #define PLL90XX_PDIV_MASK      (0x3F)
>  #define PLL90XX_SDIV_MASK      (0x7)
> --
> 1.7.2.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>



-- 
Shine bright,
(: Nav :)

[-- Attachment #2: 0001-ARM-S5P64X0-Move-duplicated-epll-code.patch --]
[-- Type: application/octet-stream, Size: 7902 bytes --]

From 766548132c0226ea90b9d3dfff8ac41c7dcb287e Mon Sep 17 00:00:00 2001
From: Naveen Krishna Chatradhi <ch.naveen@samsung.com>
Date: Wed, 22 Jun 2011 11:42:26 +0530
Subject: [PATCH] ARM: S5P64X0: Move duplicated epll code

S5P6440 and S5P6450 uses similar PLL(PLL90XX) for EPLL.
So, The EPLL set rate function is duplicated.

Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com>
---
 arch/arm/mach-s5p64x0/clock-s5p6440.c           |   61 +----------------------
 arch/arm/mach-s5p64x0/clock-s5p6450.c           |   53 +-------------------
 arch/arm/mach-s5p64x0/clock.c                   |   62 +++++++++++++++++++++++
 arch/arm/mach-s5p64x0/include/mach/regs-clock.h |    1 +
 arch/arm/plat-s5p/include/plat/pll.h            |    3 +
 5 files changed, 68 insertions(+), 112 deletions(-)

diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
index 0e9cd30..1d242f2 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6440.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -33,65 +33,6 @@
 #include <plat/clock-clksrc.h>
 #include <plat/s5p6440.h>
 
-static u32 epll_div[][5] = {
-	{ 36000000,	0,	48, 1, 4 },
-	{ 48000000,	0,	32, 1, 3 },
-	{ 60000000,	0,	40, 1, 3 },
-	{ 72000000,	0,	48, 1, 3 },
-	{ 84000000,	0,	28, 1, 2 },
-	{ 96000000,	0,	32, 1, 2 },
-	{ 32768000,	45264,	43, 1, 4 },
-	{ 45158000,	6903,	30, 1, 3 },
-	{ 49152000,	50332,	32, 1, 3 },
-	{ 67738000,	10398,	45, 1, 3 },
-	{ 73728000,	9961,	49, 1, 3 }
-};
-
-static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned int epll_con, epll_con_k;
-	unsigned int i;
-
-	if (clk->rate == rate)	/* Return if nothing changed */
-		return 0;
-
-	epll_con = __raw_readl(S5P64X0_EPLL_CON);
-	epll_con_k = __raw_readl(S5P64X0_EPLL_CON_K);
-
-	epll_con_k &= ~(PLL90XX_KDIV_MASK);
-	epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
-
-	for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
-		 if (epll_div[i][0] == rate) {
-			epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
-			epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
-				    (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
-				    (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
-			break;
-		}
-	}
-
-	if (i == ARRAY_SIZE(epll_div)) {
-		printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
-		return -EINVAL;
-	}
-
-	__raw_writel(epll_con, S5P64X0_EPLL_CON);
-	__raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
-
-	printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
-			clk->rate, rate);
-
-	clk->rate = rate;
-
-	return 0;
-}
-
-static struct clk_ops s5p6440_epll_ops = {
-	.get_rate = s5p_epll_get_rate,
-	.set_rate = s5p6440_epll_set_rate,
-};
-
 static struct clksrc_clk clk_hclk = {
 	.clk	= {
 		.name		= "clk_hclk",
@@ -518,7 +459,7 @@ void __init_or_cpufreq s5p6440_setup_clocks(void)
 	/* Set S5P6440 functions for clk_fout_epll */
 
 	clk_fout_epll.enable = s5p_epll_enable;
-	clk_fout_epll.ops = &s5p6440_epll_ops;
+	clk_fout_epll.ops = &pll90xx_epll_ops;
 
 	clk_48m.enable = s5p64x0_clk48m_ctrl;
 
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
index d9dc16c..eec6026 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6450.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -41,57 +41,6 @@ static struct clksrc_clk clk_mout_dpll = {
 	.reg_src	= { .reg = S5P64X0_CLK_SRC0, .shift = 5, .size = 1 },
 };
 
-static u32 epll_div[][5] = {
-	{ 133000000,	27307,	55, 2, 2 },
-	{ 100000000,	43691,	41, 2, 2 },
-	{ 480000000,	0,	80, 2, 0 },
-};
-
-static int s5p6450_epll_set_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned int epll_con, epll_con_k;
-	unsigned int i;
-
-	if (clk->rate == rate)	/* Return if nothing changed */
-		return 0;
-
-	epll_con = __raw_readl(S5P64X0_EPLL_CON);
-	epll_con_k = __raw_readl(S5P64X0_EPLL_CON_K);
-
-	epll_con_k &= ~(PLL90XX_KDIV_MASK);
-	epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
-
-	for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
-		 if (epll_div[i][0] == rate) {
-			epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
-			epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
-				    (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
-				    (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
-			break;
-		}
-	}
-
-	if (i == ARRAY_SIZE(epll_div)) {
-		printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
-		return -EINVAL;
-	}
-
-	__raw_writel(epll_con, S5P64X0_EPLL_CON);
-	__raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
-
-	printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
-			clk->rate, rate);
-
-	clk->rate = rate;
-
-	return 0;
-}
-
-static struct clk_ops s5p6450_epll_ops = {
-	.get_rate = s5p_epll_get_rate,
-	.set_rate = s5p6450_epll_set_rate,
-};
-
 static struct clksrc_clk clk_dout_epll = {
 	.clk	= {
 		.name		= "dout_epll",
@@ -573,7 +522,7 @@ void __init_or_cpufreq s5p6450_setup_clocks(void)
 	/* Set S5P6450 functions for clk_fout_epll */
 
 	clk_fout_epll.enable = s5p_epll_enable;
-	clk_fout_epll.ops = &s5p6450_epll_ops;
+	clk_fout_epll.ops = &pll90xx_epll_ops;
 
 	clk_48m.enable = s5p64x0_clk48m_ctrl;
 
diff --git a/arch/arm/mach-s5p64x0/clock.c b/arch/arm/mach-s5p64x0/clock.c
index b52c6e2..9ec2e03 100644
--- a/arch/arm/mach-s5p64x0/clock.c
+++ b/arch/arm/mach-s5p64x0/clock.c
@@ -233,3 +233,65 @@ int s5p64x0_clk48m_ctrl(struct clk *clk, int enable)
 
 	return 0;
 }
+
+static u32 epll_div[][5] = {
+	{ 36000000,	0,	48, 1, 4 },
+	{ 48000000,	0,	32, 1, 3 },
+	{ 60000000,	0,	40, 1, 3 },
+	{ 72000000,	0,	48, 1, 3 },
+	{ 84000000,	0,	28, 1, 2 },
+	{ 96000000,	0,	32, 1, 2 },
+	{ 32768000,	45264,	43, 1, 4 },
+	{ 45158000,	6903,	30, 1, 3 },
+	{ 49152000,	50332,	32, 1, 3 },
+	{ 67738000,	10398,	45, 1, 3 },
+	{ 73728000,	9961,	49, 1, 3 },
+	{ 100000000,	43691,	41, 2, 2 },
+	{ 133000000,	27307,	55, 2, 2 },
+	{ 480000000,	0,	80, 2, 0 },
+};
+
+int pll90xx_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned int con, con_k;
+	unsigned int i;
+
+	if (clk->rate == rate)	/* Return if nothing changed */
+		return 0;
+
+	con = __raw_readl(S5P_EPLL_CON);
+	con_k = __raw_readl(S5P_EPLL_CON1);
+
+	con_k &= ~(PLL90XX_KDIV_MASK);
+	con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
+
+	for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+		if (epll_div[i][0] == rate) {
+			con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
+			con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
+				    (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
+				    (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(epll_div)) {
+		printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
+		return -EINVAL;
+	}
+
+	__raw_writel(con, S5P_EPLL_CON);
+	__raw_writel(con_k, S5P_EPLL_CON1);
+
+	printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
+			clk->rate, rate);
+
+	clk->rate = rate;
+
+	return 0;
+}
+
+struct clk_ops pll90xx_epll_ops = {
+	.get_rate = s5p_epll_get_rate,
+	.set_rate = pll90xx_epll_set_rate,
+};
diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
index a133f22..38ddad0 100644
--- a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
@@ -61,5 +61,6 @@
 #define ARM_DIV_MASK			(0xF << ARM_DIV_RATIO_SHIFT)
 
 #define S5P_EPLL_CON			S5P64X0_EPLL_CON
+#define S5P_EPLL_CON1			S5P64X0_EPLL_CON_K
 
 #endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h
index 911a20e..5344d9f 100644
--- a/arch/arm/plat-s5p/include/plat/pll.h
+++ b/arch/arm/plat-s5p/include/plat/pll.h
@@ -133,6 +133,9 @@ static inline unsigned long s5p_get_pll90xx(unsigned long baseclk,
 	return result;
 }
 
+extern int pll90xx_epll_set_rate(struct clk *clk, unsigned long rate);
+extern struct clk_ops pll90xx_epll_ops;
+
 #define PLL65XX_MDIV_MASK	(0x3FF)
 #define PLL65XX_PDIV_MASK	(0x3F)
 #define PLL65XX_SDIV_MASK	(0x7)
-- 
1.7.2.3


[-- Attachment #3: 0001-ARM-Samsung-organize-duplicated-EPLL-code.patch --]
[-- Type: application/octet-stream, Size: 30606 bytes --]

From 280aa323a7c7b464588197f490d86acf9ecc8c27 Mon Sep 17 00:00:00 2001
From: Naveen Krishna Chatradhi <ch.naveen@samsung.com>
Date: Tue, 21 Jun 2011 14:06:22 +0530
Subject: [RFC][PATCH] ARM: Samsung: organize duplicated EPLL code

The S5PV210/C110,C100,6450/6440 and EXYNOS4 defines custom
EPLL set_rate function. The same can be reorganized on the basis
of the PLL used.
Eg: PLL90XX. PLL46XX, PLL45XX and PLL65XX.

Also, Adds the epll ops for EXYNOS4.
Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com>
---
 arch/arm/mach-exynos4/Kconfig                   |    2 +
 arch/arm/mach-exynos4/clock.c                   |    7 +
 arch/arm/mach-s5p64x0/Kconfig                   |    5 +
 arch/arm/mach-s5p64x0/clock-s5p6440.c           |   56 +--------
 arch/arm/mach-s5p64x0/clock-s5p6450.c           |   48 +-------
 arch/arm/mach-s5p64x0/include/mach/regs-clock.h |    1 +
 arch/arm/mach-s5pc100/Kconfig                   |    1 +
 arch/arm/mach-s5pc100/clock.c                   |   60 +---------
 arch/arm/mach-s5pv210/Kconfig                   |    2 +
 arch/arm/mach-s5pv210/clock.c                   |   73 +-----------
 arch/arm/plat-s5p/Kconfig                       |   21 +++
 arch/arm/plat-s5p/Makefile                      |    6 +
 arch/arm/plat-s5p/include/plat/pll.h            |  153 +++--------------------
 arch/arm/plat-s5p/pll_45xx.c                    |   50 ++++++++
 arch/arm/plat-s5p/pll_46xx.c                    |  138 ++++++++++++++++++++
 arch/arm/plat-s5p/pll_65xx.c                    |  102 +++++++++++++++
 arch/arm/plat-s5p/pll_90xx.c                    |  115 +++++++++++++++++
 17 files changed, 474 insertions(+), 366 deletions(-)
 create mode 100644 arch/arm/plat-s5p/pll_45xx.c
 create mode 100644 arch/arm/plat-s5p/pll_46xx.c
 create mode 100644 arch/arm/plat-s5p/pll_65xx.c
 create mode 100644 arch/arm/plat-s5p/pll_90xx.c

diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index 1435fc3..a36c198 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -12,6 +12,8 @@ if ARCH_EXYNOS4
 config CPU_EXYNOS4210
 	bool
 	select S3C_PL330_DMA
+	select PLL_45XX
+	select PLL_46XX
 	help
 	  Enable EXYNOS4210 CPU support
 
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
index feeb27e..778501f 100644
--- a/arch/arm/mach-exynos4/clock.c
+++ b/arch/arm/mach-exynos4/clock.c
@@ -1243,6 +1243,11 @@ static struct clksrc_clk *sysclks[] = {
 	&clk_sclk_spdif,
 };
 
+static struct clk_ops exynos4_epll_ops = {
+	.set_rate = pll46xx_epll_set_rate,
+	.get_rate = s5p_epll_get_rate,
+};
+
 static int xtal_rate;
 
 static unsigned long exynos4_fout_apll_get_rate(struct clk *clk)
@@ -1321,6 +1326,8 @@ void __init_or_cpufreq exynos4_setup_clocks(void)
 	for (ptr = 0; ptr < ARRAY_SIZE(clksrcs); ptr++)
 		s3c_set_clksrc(&clksrcs[ptr], true);
 
+	clk_fout_epll.ops = &exynos4_epll_ops;
+
 	clk_audiocdclk0.rate = PCM_EXTCLK0;
 	clk_set_parent(&clk_sclk_audio0.clk, &clk_audiocdclk0);
 }
diff --git a/arch/arm/mach-s5p64x0/Kconfig b/arch/arm/mach-s5p64x0/Kconfig
index 017af4c..221a3a0 100644
--- a/arch/arm/mach-s5p64x0/Kconfig
+++ b/arch/arm/mach-s5p64x0/Kconfig
@@ -10,6 +10,8 @@ if ARCH_S5P64X0
 config CPU_S5P6440
 	bool
 	select S3C_PL330_DMA
+	select PLL_45XX
+	select PLL_90XX
 	select S5P_HRT
 	help
 	  Enable S5P6440 CPU support
@@ -18,6 +20,9 @@ config CPU_S5P6450
 	bool
 	select S3C_PL330_DMA
 	select S5P_HRT
+	select PLL_45XX
+	select PLL_46XX
+	select PLL_90XX
 	help
 	  Enable S5P6450 CPU support
 
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c
index 0e9cd30..713e612 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6440.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c
@@ -33,63 +33,9 @@
 #include <plat/clock-clksrc.h>
 #include <plat/s5p6440.h>
 
-static u32 epll_div[][5] = {
-	{ 36000000,	0,	48, 1, 4 },
-	{ 48000000,	0,	32, 1, 3 },
-	{ 60000000,	0,	40, 1, 3 },
-	{ 72000000,	0,	48, 1, 3 },
-	{ 84000000,	0,	28, 1, 2 },
-	{ 96000000,	0,	32, 1, 2 },
-	{ 32768000,	45264,	43, 1, 4 },
-	{ 45158000,	6903,	30, 1, 3 },
-	{ 49152000,	50332,	32, 1, 3 },
-	{ 67738000,	10398,	45, 1, 3 },
-	{ 73728000,	9961,	49, 1, 3 }
-};
-
-static int s5p6440_epll_set_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned int epll_con, epll_con_k;
-	unsigned int i;
-
-	if (clk->rate == rate)	/* Return if nothing changed */
-		return 0;
-
-	epll_con = __raw_readl(S5P64X0_EPLL_CON);
-	epll_con_k = __raw_readl(S5P64X0_EPLL_CON_K);
-
-	epll_con_k &= ~(PLL90XX_KDIV_MASK);
-	epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
-
-	for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
-		 if (epll_div[i][0] == rate) {
-			epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
-			epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
-				    (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
-				    (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
-			break;
-		}
-	}
-
-	if (i == ARRAY_SIZE(epll_div)) {
-		printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
-		return -EINVAL;
-	}
-
-	__raw_writel(epll_con, S5P64X0_EPLL_CON);
-	__raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
-
-	printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
-			clk->rate, rate);
-
-	clk->rate = rate;
-
-	return 0;
-}
-
 static struct clk_ops s5p6440_epll_ops = {
 	.get_rate = s5p_epll_get_rate,
-	.set_rate = s5p6440_epll_set_rate,
+	.set_rate = pll90xx_epll_set_rate,
 };
 
 static struct clksrc_clk clk_hclk = {
diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c
index d9dc16c..00841ca 100644
--- a/arch/arm/mach-s5p64x0/clock-s5p6450.c
+++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c
@@ -41,55 +41,9 @@ static struct clksrc_clk clk_mout_dpll = {
 	.reg_src	= { .reg = S5P64X0_CLK_SRC0, .shift = 5, .size = 1 },
 };
 
-static u32 epll_div[][5] = {
-	{ 133000000,	27307,	55, 2, 2 },
-	{ 100000000,	43691,	41, 2, 2 },
-	{ 480000000,	0,	80, 2, 0 },
-};
-
-static int s5p6450_epll_set_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned int epll_con, epll_con_k;
-	unsigned int i;
-
-	if (clk->rate == rate)	/* Return if nothing changed */
-		return 0;
-
-	epll_con = __raw_readl(S5P64X0_EPLL_CON);
-	epll_con_k = __raw_readl(S5P64X0_EPLL_CON_K);
-
-	epll_con_k &= ~(PLL90XX_KDIV_MASK);
-	epll_con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
-
-	for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
-		 if (epll_div[i][0] == rate) {
-			epll_con_k |= (epll_div[i][1] << PLL90XX_KDIV_SHIFT);
-			epll_con |= (epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
-				    (epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
-				    (epll_div[i][4] << PLL90XX_SDIV_SHIFT);
-			break;
-		}
-	}
-
-	if (i == ARRAY_SIZE(epll_div)) {
-		printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
-		return -EINVAL;
-	}
-
-	__raw_writel(epll_con, S5P64X0_EPLL_CON);
-	__raw_writel(epll_con_k, S5P64X0_EPLL_CON_K);
-
-	printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
-			clk->rate, rate);
-
-	clk->rate = rate;
-
-	return 0;
-}
-
 static struct clk_ops s5p6450_epll_ops = {
 	.get_rate = s5p_epll_get_rate,
-	.set_rate = s5p6450_epll_set_rate,
+	.set_rate = pll90xx_epll_set_rate,
 };
 
 static struct clksrc_clk clk_dout_epll = {
diff --git a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
index a133f22..38ddad0 100644
--- a/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5p64x0/include/mach/regs-clock.h
@@ -61,5 +61,6 @@
 #define ARM_DIV_MASK			(0xF << ARM_DIV_RATIO_SHIFT)
 
 #define S5P_EPLL_CON			S5P64X0_EPLL_CON
+#define S5P_EPLL_CON1			S5P64X0_EPLL_CON_K
 
 #endif /* __ASM_ARCH_REGS_CLOCK_H */
diff --git a/arch/arm/mach-s5pc100/Kconfig b/arch/arm/mach-s5pc100/Kconfig
index 608722f..7bdb9d5 100644
--- a/arch/arm/mach-s5pc100/Kconfig
+++ b/arch/arm/mach-s5pc100/Kconfig
@@ -11,6 +11,7 @@ config CPU_S5PC100
 	bool
 	select S5P_EXT_INT
 	select S3C_PL330_DMA
+	select PLL_65XX
 	help
 	  Enable S5PC100 CPU support
 
diff --git a/arch/arm/mach-s5pc100/clock.c b/arch/arm/mach-s5pc100/clock.c
index ff5cbb3..d3a87c2 100644
--- a/arch/arm/mach-s5pc100/clock.c
+++ b/arch/arm/mach-s5pc100/clock.c
@@ -251,67 +251,9 @@ static struct clksrc_clk clk_div_hdmi = {
 	.reg_div = { .reg = S5P_CLK_DIV3, .shift = 28, .size = 4 },
 };
 
-static u32 epll_div[][4] = {
-	{ 32750000,	131, 3, 4 },
-	{ 32768000,	131, 3, 4 },
-	{ 36000000,	72,  3, 3 },
-	{ 45000000,	90,  3, 3 },
-	{ 45158000,	90,  3, 3 },
-	{ 45158400,	90,  3, 3 },
-	{ 48000000,	96,  3, 3 },
-	{ 49125000,	131, 4, 3 },
-	{ 49152000,	131, 4, 3 },
-	{ 60000000,	120, 3, 3 },
-	{ 67737600,	226, 5, 3 },
-	{ 67738000,	226, 5, 3 },
-	{ 73800000,	246, 5, 3 },
-	{ 73728000,	246, 5, 3 },
-	{ 72000000,	144, 3, 3 },
-	{ 84000000,	168, 3, 3 },
-	{ 96000000,	96,  3, 2 },
-	{ 144000000,	144, 3, 2 },
-	{ 192000000,	96,  3, 1 }
-};
-
-static int s5pc100_epll_set_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned int epll_con;
-	unsigned int i;
-
-	if (clk->rate == rate)	/* Return if nothing changed */
-		return 0;
-
-	epll_con = __raw_readl(S5P_EPLL_CON);
-
-	epll_con &= ~(PLL65XX_MDIV_MASK | PLL65XX_PDIV_MASK | PLL65XX_SDIV_MASK);
-
-	for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
-		if (epll_div[i][0] == rate) {
-			epll_con |= (epll_div[i][1] << PLL65XX_MDIV_SHIFT) |
-				    (epll_div[i][2] << PLL65XX_PDIV_SHIFT) |
-				    (epll_div[i][3] << PLL65XX_SDIV_SHIFT);
-			break;
-		}
-	}
-
-	if (i == ARRAY_SIZE(epll_div)) {
-		printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
-		return -EINVAL;
-	}
-
-	__raw_writel(epll_con, S5P_EPLL_CON);
-
-	printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
-			clk->rate, rate);
-
-	clk->rate = rate;
-
-	return 0;
-}
-
 static struct clk_ops s5pc100_epll_ops = {
 	.get_rate = s5p_epll_get_rate,
-	.set_rate = s5pc100_epll_set_rate,
+	.set_rate = pll65xx_epll_set_rate,
 };
 
 static int s5pc100_d0_0_ctrl(struct clk *clk, int enable)
diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 37b5a97..523ddc9 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -15,6 +15,8 @@ config CPU_S5PV210
 	select S5P_EXT_INT
 	select S5P_HRT
 	select S5PV210_PM if PM
+	select PLL_45XX
+	select PLL_46XX
 	help
 	  Enable S5PV210 CPU support
 
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index ae72f87..a1ba857 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -979,79 +979,8 @@ static struct clksrc_clk *sysclks[] = {
 	&clk_sclk_spdif,
 };
 
-static u32 epll_div[][6] = {
-	{  48000000, 0, 48, 3, 3, 0 },
-	{  96000000, 0, 48, 3, 2, 0 },
-	{ 144000000, 1, 72, 3, 2, 0 },
-	{ 192000000, 0, 48, 3, 1, 0 },
-	{ 288000000, 1, 72, 3, 1, 0 },
-	{  32750000, 1, 65, 3, 4, 35127 },
-	{  32768000, 1, 65, 3, 4, 35127 },
-	{  45158400, 0, 45, 3, 3, 10355 },
-	{  45000000, 0, 45, 3, 3, 10355 },
-	{  45158000, 0, 45, 3, 3, 10355 },
-	{  49125000, 0, 49, 3, 3, 9961 },
-	{  49152000, 0, 49, 3, 3, 9961 },
-	{  67737600, 1, 67, 3, 3, 48366 },
-	{  67738000, 1, 67, 3, 3, 48366 },
-	{  73800000, 1, 73, 3, 3, 47710 },
-	{  73728000, 1, 73, 3, 3, 47710 },
-	{  36000000, 1, 32, 3, 4, 0 },
-	{  60000000, 1, 60, 3, 3, 0 },
-	{  72000000, 1, 72, 3, 3, 0 },
-	{  80000000, 1, 80, 3, 3, 0 },
-	{  84000000, 0, 42, 3, 2, 0 },
-	{  50000000, 0, 50, 3, 3, 0 },
-};
-
-static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned int epll_con, epll_con_k;
-	unsigned int i;
-
-	/* Return if nothing changed */
-	if (clk->rate == rate)
-		return 0;
-
-	epll_con = __raw_readl(S5P_EPLL_CON);
-	epll_con_k = __raw_readl(S5P_EPLL_CON1);
-
-	epll_con_k &= ~PLL46XX_KDIV_MASK;
-	epll_con &= ~(1 << 27 |
-			PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |
-			PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |
-			PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
-
-	for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
-		if (epll_div[i][0] == rate) {
-			epll_con_k |= epll_div[i][5] << 0;
-			epll_con |= (epll_div[i][1] << 27 |
-					epll_div[i][2] << PLL46XX_MDIV_SHIFT |
-					epll_div[i][3] << PLL46XX_PDIV_SHIFT |
-					epll_div[i][4] << PLL46XX_SDIV_SHIFT);
-			break;
-		}
-	}
-
-	if (i == ARRAY_SIZE(epll_div)) {
-		printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
-				__func__);
-		return -EINVAL;
-	}
-
-	__raw_writel(epll_con, S5P_EPLL_CON);
-	__raw_writel(epll_con_k, S5P_EPLL_CON1);
-
-	printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
-			clk->rate, rate);
-
-	clk->rate = rate;
-
-	return 0;
-}
-
 static struct clk_ops s5pv210_epll_ops = {
-	.set_rate = s5pv210_epll_set_rate,
+	.set_rate = pll46xx_epll_set_rate,
 	.get_rate = s5p_epll_get_rate,
 };
 
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index 7f9ff2a..a5cd0fc 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -95,3 +95,24 @@ config S5P_SETUP_MIPIPHY
 	bool
 	help
 	  Compile in common setup code for MIPI-CSIS and MIPI-DSIM devices
+
+config PLL_45XX
+	bool
+	help
+	  Compile in definitions for 45XX series PLL's
+
+config PLL_46XX
+	bool
+	help
+	  Compile in definitions for 46XX series PLL's
+
+config PLL_65XX
+	bool
+	help
+	  Compile in definitions for 65XX series PLL's
+
+config PLL_90XX
+	bool
+	help
+	  Compile in definitions for 90XX series PLL's
+
diff --git a/arch/arm/plat-s5p/Makefile b/arch/arm/plat-s5p/Makefile
index e234cc4..f50ada8 100644
--- a/arch/arm/plat-s5p/Makefile
+++ b/arch/arm/plat-s5p/Makefile
@@ -35,3 +35,9 @@ obj-$(CONFIG_S5P_DEV_CSIS0)	+= dev-csis0.o
 obj-$(CONFIG_S5P_DEV_CSIS1)	+= dev-csis1.o
 obj-$(CONFIG_S5P_DEV_USB_EHCI)	+= dev-ehci.o
 obj-$(CONFIG_S5P_SETUP_MIPIPHY)	+= setup-mipiphy.o
+
+# PLL Drivers
+obj-$(CONFIG_PLL_45XX)		+= pll_45xx.o
+obj-$(CONFIG_PLL_46XX)		+= pll_46xx.o
+obj-$(CONFIG_PLL_65XX)		+= pll_65xx.o
+obj-$(CONFIG_PLL_90XX)		+= pll_90xx.o
diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h
index bf28fad..517c4b4 100644
--- a/arch/arm/plat-s5p/include/plat/pll.h
+++ b/arch/arm/plat-s5p/include/plat/pll.h
@@ -1,25 +1,15 @@
 /* arch/arm/plat-s5p/include/plat/pll.h
  *
- * Copyright (c) 2009 Samsung Electronics Co., Ltd.
- *		http://www.samsung.com/
+ * Copyright (C) 2011 Samsung Electronics Co.Ltd
  *
- * S5P PLL code
- *
- * Based on arch/arm/plat-s3c64xx/include/plat/pll.h
- *
- * 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.
-*/
-
-#define PLL45XX_MDIV_MASK	(0x3FF)
-#define PLL45XX_PDIV_MASK	(0x3F)
-#define PLL45XX_SDIV_MASK	(0x7)
-#define PLL45XX_MDIV_SHIFT	(16)
-#define PLL45XX_PDIV_SHIFT	(8)
-#define PLL45XX_SDIV_SHIFT	(0)
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
 
-#include <asm/div64.h>
+#ifndef __PLAT_S5P_PLL_H
+#define __PLAT_S5P_PLL_H
 
 enum pll45xx_type_t {
 	pll_4500,
@@ -27,127 +17,24 @@ enum pll45xx_type_t {
 	pll_4508
 };
 
-static inline unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
-					    enum pll45xx_type_t pll_type)
-{
-	u32 mdiv, pdiv, sdiv;
-	u64 fvco = baseclk;
-
-	mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
-	pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
-	sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
-
-	if (pll_type == pll_4508)
-		sdiv = sdiv - 1;
-
-	fvco *= mdiv;
-	do_div(fvco, (pdiv << sdiv));
-
-	return (unsigned long)fvco;
-}
-
-#define PLL46XX_KDIV_MASK	(0xFFFF)
-#define PLL4650C_KDIV_MASK	(0xFFF)
-#define PLL46XX_MDIV_MASK	(0x1FF)
-#define PLL46XX_PDIV_MASK	(0x3F)
-#define PLL46XX_SDIV_MASK	(0x7)
-#define PLL46XX_MDIV_SHIFT	(16)
-#define PLL46XX_PDIV_SHIFT	(8)
-#define PLL46XX_SDIV_SHIFT	(0)
-
 enum pll46xx_type_t {
 	pll_4600,
 	pll_4650,
 	pll_4650c,
 };
 
-static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
-					    u32 pll_con0, u32 pll_con1,
-					    enum pll46xx_type_t pll_type)
-{
-	unsigned long result;
-	u32 mdiv, pdiv, sdiv, kdiv;
-	u64 tmp;
-
-	mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
-	pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
-	sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
-	kdiv = pll_con1 & PLL46XX_KDIV_MASK;
-
-	if (pll_type == pll_4650c)
-		kdiv = pll_con1 & PLL4650C_KDIV_MASK;
-	else
-		kdiv = pll_con1 & PLL46XX_KDIV_MASK;
-
-	tmp = baseclk;
-
-	if (pll_type == pll_4600) {
-		tmp *= (mdiv << 16) + kdiv;
-		do_div(tmp, (pdiv << sdiv));
-		result = tmp >> 16;
-	} else {
-		tmp *= (mdiv << 10) + kdiv;
-		do_div(tmp, (pdiv << sdiv));
-		result = tmp >> 10;
-	}
-
-	return result;
-}
-
-#define PLL90XX_MDIV_MASK	(0xFF)
-#define PLL90XX_PDIV_MASK	(0x3F)
-#define PLL90XX_SDIV_MASK	(0x7)
-#define PLL90XX_KDIV_MASK	(0xffff)
-#define PLL90XX_MDIV_SHIFT	(16)
-#define PLL90XX_PDIV_SHIFT	(8)
-#define PLL90XX_SDIV_SHIFT	(0)
-#define PLL90XX_KDIV_SHIFT	(0)
-
-static inline unsigned long s5p_get_pll90xx(unsigned long baseclk,
-					    u32 pll_con, u32 pll_conk)
-{
-	unsigned long result;
-	u32 mdiv, pdiv, sdiv, kdiv;
-	u64 tmp;
-
-	mdiv = (pll_con >> PLL90XX_MDIV_SHIFT) & PLL90XX_MDIV_MASK;
-	pdiv = (pll_con >> PLL90XX_PDIV_SHIFT) & PLL90XX_PDIV_MASK;
-	sdiv = (pll_con >> PLL90XX_SDIV_SHIFT) & PLL90XX_SDIV_MASK;
-	kdiv = pll_conk & PLL90XX_KDIV_MASK;
-
-	/* We need to multiple baseclk 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.
-	 */
-
-	tmp = baseclk;
-	tmp *= (mdiv << 16) + kdiv;
-	do_div(tmp, (pdiv << sdiv));
-	result = tmp >> 16;
-
-	return result;
-}
-
-#define PLL65XX_MDIV_MASK	(0x3FF)
-#define PLL65XX_PDIV_MASK	(0x3F)
-#define PLL65XX_SDIV_MASK	(0x7)
-#define PLL65XX_MDIV_SHIFT	(16)
-#define PLL65XX_PDIV_SHIFT	(8)
-#define PLL65XX_SDIV_SHIFT	(0)
-
-static inline unsigned long s5p_get_pll65xx(unsigned long baseclk, u32 pll_con)
-{
-	u32 mdiv, pdiv, sdiv;
-	u64 fvco = baseclk;
+extern unsigned long s5p_get_pll90xx(unsigned long baseclk, u32 pll_con,
+				     u32 pll_conk);
+extern int pll90xx_epll_set_rate(struct clk *clk, unsigned long rate);
 
-	mdiv = (pll_con >> PLL65XX_MDIV_SHIFT) & PLL65XX_MDIV_MASK;
-	pdiv = (pll_con >> PLL65XX_PDIV_SHIFT) & PLL65XX_PDIV_MASK;
-	sdiv = (pll_con >> PLL65XX_SDIV_SHIFT) & PLL65XX_SDIV_MASK;
+extern unsigned long s5p_get_pll46xx(unsigned long baseclk,
+				     u32 pll_con0, u32 pll_con1,
+				     enum pll46xx_type_t pll_type);
+extern int pll46xx_epll_set_rate(struct clk *clk, unsigned long rate);
 
-	fvco *= mdiv;
-	do_div(fvco, (pdiv << sdiv));
+extern unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
+				     enum pll45xx_type_t pll_type);
+extern int pll65xx_epll_set_rate(struct clk *clk, unsigned long rate);
+extern unsigned long s5p_get_pll65xx(unsigned long baseclk, u32 pll_con);
 
-	return (unsigned long)fvco;
-}
+#endif /* __PLAT_S5P_PLL_H */
diff --git a/arch/arm/plat-s5p/pll_45xx.c b/arch/arm/plat-s5p/pll_45xx.c
new file mode 100644
index 0000000..4f4243b
--- /dev/null
+++ b/arch/arm/plat-s5p/pll_45xx.c
@@ -0,0 +1,50 @@
+/* arch/arm/plat-s5p/pll_45xx.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P PLL45XX code
+ *
+ * splitting arch/arm/plat-s5p/include/plat/pll.h
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/regs-clock.h>
+#include <plat/clock.h>
+#include <plat/s5p-clock.h>
+#include <plat/pll.h>
+
+#define PLL45XX_MDIV_MASK	(0x3FF)
+#define PLL45XX_PDIV_MASK	(0x3F)
+#define PLL45XX_SDIV_MASK	(0x7)
+#define PLL45XX_MDIV_SHIFT	(16)
+#define PLL45XX_PDIV_SHIFT	(8)
+#define PLL45XX_SDIV_SHIFT	(0)
+
+#include <asm/div64.h>
+
+unsigned long s5p_get_pll45xx(unsigned long baseclk, u32 pll_con,
+			      enum pll45xx_type_t pll_type)
+{
+	u32 mdiv, pdiv, sdiv;
+	u64 fvco = baseclk;
+
+	mdiv = (pll_con >> PLL45XX_MDIV_SHIFT) & PLL45XX_MDIV_MASK;
+	pdiv = (pll_con >> PLL45XX_PDIV_SHIFT) & PLL45XX_PDIV_MASK;
+	sdiv = (pll_con >> PLL45XX_SDIV_SHIFT) & PLL45XX_SDIV_MASK;
+
+	if (pll_type == pll_4508)
+		sdiv = sdiv - 1;
+
+	fvco *= mdiv;
+	do_div(fvco, (pdiv << sdiv));
+
+	return (unsigned long)fvco;
+}
diff --git a/arch/arm/plat-s5p/pll_46xx.c b/arch/arm/plat-s5p/pll_46xx.c
new file mode 100644
index 0000000..e956d05
--- /dev/null
+++ b/arch/arm/plat-s5p/pll_46xx.c
@@ -0,0 +1,138 @@
+/* arch/arm/plat-s5p/pll_46xx.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P PLL46XX code
+ *
+ * splitting arch/arm/plat-s5p/include/plat/pll.h
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/regs-clock.h>
+#include <plat/clock.h>
+#include <plat/s5p-clock.h>
+#include <plat/pll.h>
+
+#define PLL46XX_KDIV_MASK	(0xFFFF)
+#define PLL4650C_KDIV_MASK	(0xFFF)
+#define PLL46XX_MDIV_MASK	(0x1FF)
+#define PLL46XX_PDIV_MASK	(0x3F)
+#define PLL46XX_SDIV_MASK	(0x7)
+#define PLL46XX_VSEL_EN		(1)
+#define PLL46XX_VSEL_SHFIT	(27)
+#define PLL46XX_MDIV_SHIFT	(16)
+#define PLL46XX_PDIV_SHIFT	(8)
+#define PLL46XX_SDIV_SHIFT	(0)
+#define PLL46XX_KDIV_SHIFT	(0)
+
+static u32 epll_div[][6] = {
+	{  48000000, 0, 48, 3, 3, 0 },
+	{  96000000, 0, 48, 3, 2, 0 },
+	{ 144000000, 1, 72, 3, 2, 0 },
+	{ 192000000, 0, 48, 3, 1, 0 },
+	{ 288000000, 1, 72, 3, 1, 0 },
+	{  32750000, 1, 65, 3, 4, 35127 },
+	{  32768000, 1, 65, 3, 4, 35127 },
+	{  45158400, 0, 45, 3, 3, 10355 },
+	{  45000000, 0, 45, 3, 3, 10355 },
+	{  45158000, 0, 45, 3, 3, 10355 },
+	{  49125000, 0, 49, 3, 3, 9961 },
+	{  49152000, 0, 49, 3, 3, 9961 },
+	{  67737600, 1, 67, 3, 3, 48366 },
+	{  67738000, 1, 67, 3, 3, 48366 },
+	{  73800000, 1, 73, 3, 3, 47710 },
+	{  73728000, 1, 73, 3, 3, 47710 },
+	{  36000000, 1, 32, 3, 4, 0 },
+	{  60000000, 1, 60, 3, 3, 0 },
+	{  72000000, 1, 72, 3, 3, 0 },
+	{  80000000, 1, 80, 3, 3, 0 },
+	{  84000000, 0, 42, 3, 2, 0 },
+	{  50000000, 0, 50, 3, 3, 0 },
+};
+
+int pll46xx_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+	int i;
+	unsigned int con0, con1;
+
+	/* Return if nothing changed */
+	if (clk->rate == rate)
+		return 0;
+
+	con0 = __raw_readl(S5P_EPLL_CON);
+	con1 = __raw_readl(S5P_EPLL_CON1);
+
+	con0 &= ~(PLL46XX_VSEL_EN << PLL46XX_VSEL_SHFIT |
+		  PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |
+		  PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |
+		  PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
+	con1 &= ~PLL46XX_KDIV_MASK;
+
+	for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+		if (epll_div[i][0] == rate) {
+			con1 |= epll_div[i][5] << PLL46XX_KDIV_SHIFT;
+			con0 |= (epll_div[i][1] << PLL46XX_VSEL_SHFIT |
+				 epll_div[i][2] << PLL46XX_MDIV_SHIFT |
+				 epll_div[i][3] << PLL46XX_PDIV_SHIFT |
+				 epll_div[i][4] << PLL46XX_SDIV_SHIFT);
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(epll_div)) {
+		printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
+		return -EINVAL;
+	}
+
+	__raw_writel(con0, S5P_EPLL_CON);
+	__raw_writel(con1, S5P_EPLL_CON1);
+
+	printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
+			clk->rate, rate);
+
+	clk->rate = rate;
+
+	return 0;
+}
+
+unsigned long s5p_get_pll46xx(unsigned long baseclk,
+			      u32 pll_con0, u32 pll_con1,
+			      enum pll46xx_type_t pll_type)
+{
+	unsigned long result;
+	u32 mdiv, pdiv, sdiv, kdiv;
+	u64 tmp;
+
+	mdiv = (pll_con0 >> PLL46XX_MDIV_SHIFT) & PLL46XX_MDIV_MASK;
+	pdiv = (pll_con0 >> PLL46XX_PDIV_SHIFT) & PLL46XX_PDIV_MASK;
+	sdiv = (pll_con0 >> PLL46XX_SDIV_SHIFT) & PLL46XX_SDIV_MASK;
+	kdiv = pll_con1 & PLL46XX_KDIV_MASK;
+
+	if (pll_type == pll_4650c)
+		kdiv = pll_con1 & PLL4650C_KDIV_MASK;
+	else
+		kdiv = pll_con1 & PLL46XX_KDIV_MASK;
+
+	tmp = baseclk;
+
+	if (pll_type == pll_4600) {
+		tmp *= (mdiv << 16) + kdiv;
+		do_div(tmp, (pdiv << sdiv));
+		result = tmp >> 16;
+	} else {
+		tmp *= (mdiv << 10) + kdiv;
+		do_div(tmp, (pdiv << sdiv));
+		result = tmp >> 10;
+	}
+
+	return result;
+}
+
diff --git a/arch/arm/plat-s5p/pll_65xx.c b/arch/arm/plat-s5p/pll_65xx.c
new file mode 100644
index 0000000..480ca4b
--- /dev/null
+++ b/arch/arm/plat-s5p/pll_65xx.c
@@ -0,0 +1,102 @@
+/* arch/arm/plat-s5p/pll_65xx.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P PLL65XX code
+ *
+ * splitting arch/arm/plat-s5p/include/plat/pll.h
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/regs-clock.h>
+#include <plat/clock.h>
+#include <plat/s5p-clock.h>
+#include <plat/pll.h>
+
+#define PLL65XX_MDIV_MASK	(0x3FF)
+#define PLL65XX_PDIV_MASK	(0x3F)
+#define PLL65XX_SDIV_MASK	(0x7)
+#define PLL65XX_MDIV_SHIFT	(16)
+#define PLL65XX_PDIV_SHIFT	(8)
+#define PLL65XX_SDIV_SHIFT	(0)
+
+static u32 epll_div[][4] = {
+	{ 32750000,	131, 3, 4 },
+	{ 32768000,	131, 3, 4 },
+	{ 36000000,	72,  3, 3 },
+	{ 45000000,	90,  3, 3 },
+	{ 45158000,	90,  3, 3 },
+	{ 45158400,	90,  3, 3 },
+	{ 48000000,	96,  3, 3 },
+	{ 49125000,	131, 4, 3 },
+	{ 49152000,	131, 4, 3 },
+	{ 60000000,	120, 3, 3 },
+	{ 67737600,	226, 5, 3 },
+	{ 67738000,	226, 5, 3 },
+	{ 73800000,	246, 5, 3 },
+	{ 73728000,	246, 5, 3 },
+	{ 72000000,	144, 3, 3 },
+	{ 84000000,	168, 3, 3 },
+	{ 96000000,	96,  3, 2 },
+	{ 144000000,	144, 3, 2 },
+	{ 192000000,	96,  3, 1 }
+};
+
+int pll65xx_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+	int i;
+	unsigned int con;
+
+	if (clk->rate == rate)	/* Return if nothing changed */
+		return 0;
+
+	con = __raw_readl(S5P_EPLL_CON);
+
+	con &= ~(PLL65XX_MDIV_MASK | PLL65XX_PDIV_MASK | PLL65XX_SDIV_MASK);
+
+	for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+		if (epll_div[i][0] == rate) {
+			con |= (epll_div[i][1] << PLL65XX_MDIV_SHIFT) |
+			       (epll_div[i][2] << PLL65XX_PDIV_SHIFT) |
+			       (epll_div[i][3] << PLL65XX_SDIV_SHIFT);
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(pll65xx_epll_div)) {
+		printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
+		return -EINVAL;
+	}
+
+	__raw_writel(con, S5P_EPLL_CON);
+
+	printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
+			clk->rate, rate);
+
+	clk->rate = rate;
+
+	return 0;
+}
+
+unsigned long s5p_get_pll65xx(unsigned long baseclk, u32 pll_con)
+{
+	u32 mdiv, pdiv, sdiv;
+	u64 fvco = baseclk;
+
+	mdiv = (pll_con >> PLL65XX_MDIV_SHIFT) & PLL65XX_MDIV_MASK;
+	pdiv = (pll_con >> PLL65XX_PDIV_SHIFT) & PLL65XX_PDIV_MASK;
+	sdiv = (pll_con >> PLL65XX_SDIV_SHIFT) & PLL65XX_SDIV_MASK;
+
+	fvco *= mdiv;
+	do_div(fvco, (pdiv << sdiv));
+
+	return (unsigned long)fvco;
+}
diff --git a/arch/arm/plat-s5p/pll_90xx.c b/arch/arm/plat-s5p/pll_90xx.c
new file mode 100644
index 0000000..e0e2cac
--- /dev/null
+++ b/arch/arm/plat-s5p/pll_90xx.c
@@ -0,0 +1,115 @@
+/* arch/arm/plat-s5p/pll_90xx.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com/
+ *
+ * S5P PLL90XX code
+ *
+ * splitting arch/arm/plat-s5p/include/plat/pll.h
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/io.h>
+
+#include <mach/regs-clock.h>
+#include <plat/clock.h>
+#include <plat/s5p-clock.h>
+#include <plat/pll.h>
+
+#define PLL90XX_MDIV_MASK	(0xFF)
+#define PLL90XX_PDIV_MASK	(0x3F)
+#define PLL90XX_SDIV_MASK	(0x7)
+#define PLL90XX_KDIV_MASK	(0xffff)
+#define PLL90XX_MDIV_SHIFT	(16)
+#define PLL90XX_PDIV_SHIFT	(8)
+#define PLL90XX_SDIV_SHIFT	(0)
+#define PLL90XX_KDIV_SHIFT	(0)
+
+static u32 epll_div[][5] = {
+	{ 36000000,	0,	48, 1, 4 },
+	{ 48000000,	0,	32, 1, 3 },
+	{ 60000000,	0,	40, 1, 3 },
+	{ 72000000,	0,	48, 1, 3 },
+	{ 84000000,	0,	28, 1, 2 },
+	{ 96000000,	0,	32, 1, 2 },
+	{ 32768000,	45264,	43, 1, 4 },
+	{ 45158000,	6903,	30, 1, 3 },
+	{ 49152000,	50332,	32, 1, 3 },
+	{ 67738000,	10398,	45, 1, 3 },
+	{ 73728000,	9961,	49, 1, 3 },
+	{ 100000000,	43691,	41, 2, 2 },
+	{ 133000000,	27307,	55, 2, 2 },
+	{ 480000000,	0,	80, 2, 0 },
+};
+
+int pll90xx_epll_set_rate(struct clk *clk, unsigned long rate)
+{
+	unsigned int con, con_k;
+	int i;
+
+	if (clk->rate == rate)	/* Return if nothing changed */
+		return 0;
+
+	con = __raw_readl(S5P_EPLL_CON);
+	con_k = __raw_readl(S5P_EPLL_CON1);
+
+	con &= ~(PLL90XX_MDIV_MASK | PLL90XX_PDIV_MASK | PLL90XX_SDIV_MASK);
+	con_k &= ~(PLL90XX_KDIV_MASK);
+
+	for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
+		if (epll_div[i][0] == rate) {
+			con_k |= epll_div[i][1] << PLL90XX_KDIV_SHIFT;
+			con |=	(epll_div[i][2] << PLL90XX_MDIV_SHIFT) |
+				(epll_div[i][3] << PLL90XX_PDIV_SHIFT) |
+				(epll_div[i][4] << PLL90XX_SDIV_SHIFT);
+			break;
+		}
+	}
+
+	if (i == ARRAY_SIZE(epll_div)) {
+		printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n", __func__);
+		return -EINVAL;
+	}
+
+	__raw_writel(con, S5P_EPLL_CON);
+	__raw_writel(con_k, S5P_EPLL_CON1);
+
+	printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
+			clk->rate, rate);
+
+	clk->rate = rate;
+
+	return 0;
+}
+
+unsigned long s5p_get_pll90xx(unsigned long baseclk, u32 pll_con,
+			      u32 pll_conk)
+{
+	unsigned long result;
+	u32 mdiv, pdiv, sdiv, kdiv;
+	u64 tmp;
+
+	mdiv = (pll_con >> PLL90XX_MDIV_SHIFT) & PLL90XX_MDIV_MASK;
+	pdiv = (pll_con >> PLL90XX_PDIV_SHIFT) & PLL90XX_PDIV_MASK;
+	sdiv = (pll_con >> PLL90XX_SDIV_SHIFT) & PLL90XX_SDIV_MASK;
+	kdiv = pll_conk & PLL90XX_KDIV_MASK;
+
+	/* We need to multiple baseclk 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.
+	 */
+
+	tmp = baseclk;
+	tmp *= (mdiv << 16) + kdiv;
+	do_div(tmp, (pdiv << sdiv));
+	result = tmp >> 16;
+
+	return result;
+}
-- 
1.7.2.3


WARNING: multiple messages have this Message-ID (diff)
From: naveenkrishna.ch@gmail.com (Naveen Krishna Ch)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v2 3/3] ARM: EXYNOS4: Add EPLL clock operations
Date: Wed, 22 Jun 2011 12:21:43 +0530	[thread overview]
Message-ID: <BANLkTim_0yj8hSefv5BUg5Z1vLh5SWhqjA@mail.gmail.com> (raw)
In-Reply-To: <1308655463-8787-4-git-send-email-ch.naveen@samsung.com>

Hi Every one,

1. Both S5P6440 and S5P6450 uses PLL90XX for EPLL.
  However, the same epll_ops is duplicated in the following files
  arch/arm/mach-s5p64x0/clock-s5p6440.c
  arch/arm/mach-s5p64x0/clock-s5p6450.c

  Please find attached patch which moves it to the common clock.c
  Attachment: "0001-ARM-S5P64X0-Move-duplicated-epll-code.patch"

2. Also, S5PV210, C110, C100, 6450/6440 and EXYNOS4 define their own
  epll_ops.

  The following attachment consolidates the same on the basis of PLL types
  "Eg: PLL90XX. PLL46XX, PLL45XX and PLL65XX"

  Kindly, review the approach and comment.
  Attachment: "0001-ARM-Samsung-organize-duplicated-EPLL-code.patch"

Thanks & Best regards,
Naveen Krishna Chatradhi

On 21 June 2011 16:54, Naveen Krishna Chatradhi <ch.naveen@samsung.com> wrote:
> S5PV210 and EXYNOS4 uses similar PLL(PLL46XX) for EPLL.
> So, The EPLL set rate function is duplicated.
>
> Note: Moved common code to plat-s5p, as commented by Kukjin Kim.
>
> Signed-off-by: Naveen Krishna Chatradhi <ch.naveen@samsung.com>
> ---
> ?arch/arm/mach-exynos4/clock.c ? ? ? ?| ? ?1 +
> ?arch/arm/mach-s5pv210/clock.c ? ? ? ?| ? 78 +---------------------------------
> ?arch/arm/plat-s5p/clock.c ? ? ? ? ? ?| ? 77 +++++++++++++++++++++++++++++++++
> ?arch/arm/plat-s5p/include/plat/pll.h | ? ?3 +
> ?4 files changed, 82 insertions(+), 77 deletions(-)
>
> diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
> index feeb27e..7687087 100644
> --- a/arch/arm/mach-exynos4/clock.c
> +++ b/arch/arm/mach-exynos4/clock.c
> @@ -1294,6 +1294,7 @@ void __init_or_cpufreq exynos4_setup_clocks(void)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?__raw_readl(S5P_VPLL_CON1), pll_4650);
>
> ? ? ? ?clk_fout_apll.ops = &exynos4_fout_apll_ops;
> + ? ? ? clk_fout_epll.ops = &pll46xx_epll_ops;
> ? ? ? ?clk_fout_mpll.rate = mpll;
> ? ? ? ?clk_fout_epll.rate = epll;
> ? ? ? ?clk_fout_vpll.rate = vpll;
> diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
> index ae72f87..dd77c2c 100644
> --- a/arch/arm/mach-s5pv210/clock.c
> +++ b/arch/arm/mach-s5pv210/clock.c
> @@ -979,82 +979,6 @@ static struct clksrc_clk *sysclks[] = {
> ? ? ? ?&clk_sclk_spdif,
> ?};
>
> -static u32 epll_div[][6] = {
> - ? ? ? { ?48000000, 0, 48, 3, 3, 0 },
> - ? ? ? { ?96000000, 0, 48, 3, 2, 0 },
> - ? ? ? { 144000000, 1, 72, 3, 2, 0 },
> - ? ? ? { 192000000, 0, 48, 3, 1, 0 },
> - ? ? ? { 288000000, 1, 72, 3, 1, 0 },
> - ? ? ? { ?32750000, 1, 65, 3, 4, 35127 },
> - ? ? ? { ?32768000, 1, 65, 3, 4, 35127 },
> - ? ? ? { ?45158400, 0, 45, 3, 3, 10355 },
> - ? ? ? { ?45000000, 0, 45, 3, 3, 10355 },
> - ? ? ? { ?45158000, 0, 45, 3, 3, 10355 },
> - ? ? ? { ?49125000, 0, 49, 3, 3, 9961 },
> - ? ? ? { ?49152000, 0, 49, 3, 3, 9961 },
> - ? ? ? { ?67737600, 1, 67, 3, 3, 48366 },
> - ? ? ? { ?67738000, 1, 67, 3, 3, 48366 },
> - ? ? ? { ?73800000, 1, 73, 3, 3, 47710 },
> - ? ? ? { ?73728000, 1, 73, 3, 3, 47710 },
> - ? ? ? { ?36000000, 1, 32, 3, 4, 0 },
> - ? ? ? { ?60000000, 1, 60, 3, 3, 0 },
> - ? ? ? { ?72000000, 1, 72, 3, 3, 0 },
> - ? ? ? { ?80000000, 1, 80, 3, 3, 0 },
> - ? ? ? { ?84000000, 0, 42, 3, 2, 0 },
> - ? ? ? { ?50000000, 0, 50, 3, 3, 0 },
> -};
> -
> -static int s5pv210_epll_set_rate(struct clk *clk, unsigned long rate)
> -{
> - ? ? ? unsigned int epll_con, epll_con_k;
> - ? ? ? unsigned int i;
> -
> - ? ? ? /* Return if nothing changed */
> - ? ? ? if (clk->rate == rate)
> - ? ? ? ? ? ? ? return 0;
> -
> - ? ? ? epll_con = __raw_readl(S5P_EPLL_CON);
> - ? ? ? epll_con_k = __raw_readl(S5P_EPLL_CON1);
> -
> - ? ? ? epll_con_k &= ~PLL46XX_KDIV_MASK;
> - ? ? ? epll_con &= ~(1 << 27 |
> - ? ? ? ? ? ? ? ? ? ? ? PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |
> - ? ? ? ? ? ? ? ? ? ? ? PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |
> - ? ? ? ? ? ? ? ? ? ? ? PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
> -
> - ? ? ? for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
> - ? ? ? ? ? ? ? if (epll_div[i][0] == rate) {
> - ? ? ? ? ? ? ? ? ? ? ? epll_con_k |= epll_div[i][5] << 0;
> - ? ? ? ? ? ? ? ? ? ? ? epll_con |= (epll_div[i][1] << 27 |
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? epll_div[i][2] << PLL46XX_MDIV_SHIFT |
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? epll_div[i][3] << PLL46XX_PDIV_SHIFT |
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? epll_div[i][4] << PLL46XX_SDIV_SHIFT);
> - ? ? ? ? ? ? ? ? ? ? ? break;
> - ? ? ? ? ? ? ? }
> - ? ? ? }
> -
> - ? ? ? if (i == ARRAY_SIZE(epll_div)) {
> - ? ? ? ? ? ? ? printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? __func__);
> - ? ? ? ? ? ? ? return -EINVAL;
> - ? ? ? }
> -
> - ? ? ? __raw_writel(epll_con, S5P_EPLL_CON);
> - ? ? ? __raw_writel(epll_con_k, S5P_EPLL_CON1);
> -
> - ? ? ? printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
> - ? ? ? ? ? ? ? ? ? ? ? clk->rate, rate);
> -
> - ? ? ? clk->rate = rate;
> -
> - ? ? ? return 0;
> -}
> -
> -static struct clk_ops s5pv210_epll_ops = {
> - ? ? ? .set_rate = s5pv210_epll_set_rate,
> - ? ? ? .get_rate = s5p_epll_get_rate,
> -};
> -
> ?void __init_or_cpufreq s5pv210_setup_clocks(void)
> ?{
> ? ? ? ?struct clk *xtal_clk;
> @@ -1075,7 +999,7 @@ void __init_or_cpufreq s5pv210_setup_clocks(void)
>
> ? ? ? ?/* Set functions for clk_fout_epll */
> ? ? ? ?clk_fout_epll.enable = s5p_epll_enable;
> - ? ? ? clk_fout_epll.ops = &s5pv210_epll_ops;
> + ? ? ? clk_fout_epll.ops = &pll46xx_epll_ops;
>
> ? ? ? ?printk(KERN_DEBUG "%s: registering clocks\n", __func__);
>
> diff --git a/arch/arm/plat-s5p/clock.c b/arch/arm/plat-s5p/clock.c
> index 02af235..2a4678d 100644
> --- a/arch/arm/plat-s5p/clock.c
> +++ b/arch/arm/plat-s5p/clock.c
> @@ -24,6 +24,7 @@
> ?#include <mach/regs-clock.h>
>
> ?#include <plat/clock.h>
> +#include <plat/pll.h>
> ?#include <plat/clock-clksrc.h>
> ?#include <plat/s5p-clock.h>
>
> @@ -203,6 +204,82 @@ struct clk_ops s5p_sclk_spdif_ops = {
> ? ? ? ?.get_rate ? ? ? = s5p_spdif_get_rate,
> ?};
>
> +static u32 epll_div[][6] = {
> + ? ? ? { ?48000000, 0, 48, 3, 3, 0 },
> + ? ? ? { ?96000000, 0, 48, 3, 2, 0 },
> + ? ? ? { 144000000, 1, 72, 3, 2, 0 },
> + ? ? ? { 192000000, 0, 48, 3, 1, 0 },
> + ? ? ? { 288000000, 1, 72, 3, 1, 0 },
> + ? ? ? { ?32750000, 1, 65, 3, 4, 35127 },
> + ? ? ? { ?32768000, 1, 65, 3, 4, 35127 },
> + ? ? ? { ?45158400, 0, 45, 3, 3, 10355 },
> + ? ? ? { ?45000000, 0, 45, 3, 3, 10355 },
> + ? ? ? { ?45158000, 0, 45, 3, 3, 10355 },
> + ? ? ? { ?49125000, 0, 49, 3, 3, 9961 },
> + ? ? ? { ?49152000, 0, 49, 3, 3, 9961 },
> + ? ? ? { ?67737600, 1, 67, 3, 3, 48366 },
> + ? ? ? { ?67738000, 1, 67, 3, 3, 48366 },
> + ? ? ? { ?73800000, 1, 73, 3, 3, 47710 },
> + ? ? ? { ?73728000, 1, 73, 3, 3, 47710 },
> + ? ? ? { ?36000000, 1, 32, 3, 4, 0 },
> + ? ? ? { ?60000000, 1, 60, 3, 3, 0 },
> + ? ? ? { ?72000000, 1, 72, 3, 3, 0 },
> + ? ? ? { ?80000000, 1, 80, 3, 3, 0 },
> + ? ? ? { ?84000000, 0, 42, 3, 2, 0 },
> + ? ? ? { ?50000000, 0, 50, 3, 3, 0 },
> +};
> +
> +int pll46xx_epll_set_rate(struct clk *clk, unsigned long rate)
> +{
> + ? ? ? unsigned int epll_con, epll_con_k;
> + ? ? ? unsigned int i;
> +
> + ? ? ? /* Return if nothing changed */
> + ? ? ? if (clk->rate == rate)
> + ? ? ? ? ? ? ? return 0;
> +
> + ? ? ? epll_con = __raw_readl(S5P_EPLL_CON);
> + ? ? ? epll_con_k = __raw_readl(S5P_EPLL_CON1);
> +
> + ? ? ? epll_con_k &= ~PLL46XX_KDIV_MASK;
> + ? ? ? epll_con &= ~(1 << 27 |
> + ? ? ? ? ? ? ? ? ? ? ? PLL46XX_MDIV_MASK << PLL46XX_MDIV_SHIFT |
> + ? ? ? ? ? ? ? ? ? ? ? PLL46XX_PDIV_MASK << PLL46XX_PDIV_SHIFT |
> + ? ? ? ? ? ? ? ? ? ? ? PLL46XX_SDIV_MASK << PLL46XX_SDIV_SHIFT);
> +
> + ? ? ? for (i = 0; i < ARRAY_SIZE(epll_div); i++) {
> + ? ? ? ? ? ? ? if (epll_div[i][0] == rate) {
> + ? ? ? ? ? ? ? ? ? ? ? epll_con_k |= epll_div[i][5] << 0;
> + ? ? ? ? ? ? ? ? ? ? ? epll_con |= (epll_div[i][1] << 27 |
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? epll_div[i][2] << PLL46XX_MDIV_SHIFT |
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? epll_div[i][3] << PLL46XX_PDIV_SHIFT |
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? epll_div[i][4] << PLL46XX_SDIV_SHIFT);
> + ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? ? ? ? ? }
> + ? ? ? }
> +
> + ? ? ? if (i == ARRAY_SIZE(epll_div)) {
> + ? ? ? ? ? ? ? printk(KERN_ERR "%s: Invalid Clock EPLL Frequency\n",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? __func__);
> + ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? }
> +
> + ? ? ? __raw_writel(epll_con, S5P_EPLL_CON);
> + ? ? ? __raw_writel(epll_con_k, S5P_EPLL_CON1);
> +
> + ? ? ? printk(KERN_WARNING "EPLL Rate changes from %lu to %lu\n",
> + ? ? ? ? ? ? ? ? ? ? ? clk->rate, rate);
> +
> + ? ? ? clk->rate = rate;
> +
> + ? ? ? return 0;
> +}
> +
> +struct clk_ops pll46xx_epll_ops = {
> + ? ? ? .set_rate = pll46xx_epll_set_rate,
> + ? ? ? .get_rate = s5p_epll_get_rate,
> +};
> +
> ?static struct clk *s5p_clks[] __initdata = {
> ? ? ? ?&clk_ext_xtal_mux,
> ? ? ? ?&clk_48m,
> diff --git a/arch/arm/plat-s5p/include/plat/pll.h b/arch/arm/plat-s5p/include/plat/pll.h
> index bf28fad..911a20e 100644
> --- a/arch/arm/plat-s5p/include/plat/pll.h
> +++ b/arch/arm/plat-s5p/include/plat/pll.h
> @@ -94,6 +94,9 @@ static inline unsigned long s5p_get_pll46xx(unsigned long baseclk,
> ? ? ? ?return result;
> ?}
>
> +extern int pll46xx_epll_set_rate(struct clk *clk, unsigned long rate);
> +extern struct clk_ops pll46xx_epll_ops;
> +
> ?#define PLL90XX_MDIV_MASK ? ? ?(0xFF)
> ?#define PLL90XX_PDIV_MASK ? ? ?(0x3F)
> ?#define PLL90XX_SDIV_MASK ? ? ?(0x7)
> --
> 1.7.2.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-samsung-soc" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>



-- 
Shine bright,
(: Nav :)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-ARM-S5P64X0-Move-duplicated-epll-code.patch
Type: application/octet-stream
Size: 7901 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110622/a315f4a7/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-ARM-Samsung-organize-duplicated-EPLL-code.patch
Type: application/octet-stream
Size: 30605 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110622/a315f4a7/attachment-0003.obj>

  reply	other threads:[~2011-06-22  6:52 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-06-21 11:24 [PATCH V2 0/3] ARM: Add SPDIF support for EXYNOS4 Naveen Krishna Chatradhi
2011-06-21 11:24 ` Naveen Krishna Chatradhi
2011-06-21 11:24 ` [PATCH v2 1/3] ARM: Samsung: Move duplicate code Naveen Krishna Chatradhi
2011-06-21 11:24   ` Naveen Krishna Chatradhi
2011-07-18  5:35   ` Kukjin Kim
2011-07-18  5:35     ` Kukjin Kim
2011-06-21 11:24 ` [PATCH v2 2/3] ARM: EXYNOS4: Add sclk_spdif clocks Naveen Krishna Chatradhi
2011-06-21 11:24   ` Naveen Krishna Chatradhi
2011-07-18  5:33   ` Kukjin Kim
2011-07-18  5:33     ` Kukjin Kim
2011-07-18 11:25     ` Naveen Krishna Ch
2011-07-18 11:25       ` Naveen Krishna Ch
2011-07-20  9:52       ` Naveen Krishna Ch
2011-07-20  9:52         ` Naveen Krishna Ch
2011-06-21 11:24 ` [PATCH v2 3/3] ARM: EXYNOS4: Add EPLL clock operations Naveen Krishna Chatradhi
2011-06-21 11:24   ` Naveen Krishna Chatradhi
2011-06-22  6:51   ` Naveen Krishna Ch [this message]
2011-06-22  6:51     ` Naveen Krishna Ch
2011-06-22  8:01     ` Seungwhan Youn
2011-06-22  8:01       ` Seungwhan Youn
2011-06-30  5:51       ` Naveen Krishna Ch
2011-06-30  5:51         ` Naveen Krishna Ch
2011-06-30  7:28         ` Seungwhan Youn
2011-06-30  7:28           ` Seungwhan Youn
2011-07-18  5:52   ` Kukjin Kim
2011-07-18  5:52     ` Kukjin Kim
2011-07-18 11:44     ` Naveen Krishna Ch
2011-07-18 11:44       ` Naveen Krishna Ch
2011-06-30  5:54 ` [PATCH V2 0/3] ARM: Add SPDIF support for EXYNOS4 Naveen Krishna Ch
2011-06-30  5:54   ` Naveen Krishna Ch

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=BANLkTim_0yj8hSefv5BUg5Z1vLh5SWhqjA@mail.gmail.com \
    --to=naveenkrishna.ch@gmail.com \
    --cc=jassisinghbrar@gmail.com \
    --cc=kgene.kim@samsung.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=sbkim73@samsung.com \
    --cc=sw.youn@samsung.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.