Re: [PATCH v9] i2c: exynos5: add High Speed I2C controller driver

2013-05-23 Thread Naveen Krishna Ch
On 17 May 2013 15:40, Naveen Krishna Chatradhi ch.nav...@samsung.com wrote:
 Adds support for High Speed I2C driver found in Exynos5 and
 later SoCs from Samsung.

 Driver only supports Device Tree method.

 Changes since v1:
 1. Added FIFO functionality
 2. Added High speed mode functionality
 3. Remove SMBUS_QUICK
 4. Remove the debugfs functionality
 5. Use devm_* functions where ever possible
 6. Driver is free from GPIO configs (only supports pinctrl method)
 7. Use OF data string clock-frequency to get the bus operating frequencies
 8. Split the clock divisor calculation function
 9. Add resets for the failed transacton cases
 10. few other bug fixes and cosmetic changes

 Signed-off-by: Taekgyun Ko taeggyun...@samsung.com
 Signed-off-by: Naveen Krishna Chatradhi ch.nav...@samsung.com
 Reviewed-by: Simon Glass s...@google.com
 Tested-by: Andrew Bresticker abres...@google.com
 Signed-off-by: Yuvaraj Kumar C D yuvaraj...@samsung.com
 Signed-off-by: Andrew Bresticker abres...@google.com
 ---

 Changes since v8
 1. improved the device tree bindings description page for i2c-exynos5
 2. fixed the return value check for devm_ioremap_resource

  .../devicetree/bindings/i2c/i2c-exynos5.txt|   45 +
  drivers/i2c/busses/Kconfig |7 +
  drivers/i2c/busses/Makefile|1 +
  drivers/i2c/busses/i2c-exynos5.c   |  888 
 
  4 files changed, 941 insertions(+)
  create mode 100644 Documentation/devicetree/bindings/i2c/i2c-exynos5.txt
  create mode 100644 drivers/i2c/busses/i2c-exynos5.c

 diff --git a/Documentation/devicetree/bindings/i2c/i2c-exynos5.txt 
 b/Documentation/devicetree/bindings/i2c/i2c-exynos5.txt
 new file mode 100644
 index 000..29c01c0
 --- /dev/null
 +++ b/Documentation/devicetree/bindings/i2c/i2c-exynos5.txt
 @@ -0,0 +1,45 @@
 +* Samsung's High Speed I2C controller
 +
 +The Samsung's High Speed I2C controller is used to interface with I2C devices
 +at various speeds ranging from 100khz to 3.4Mhz.
 +
 +Required properties:
 +  - compatible: value should be.
 +  - samsung,exynos5-hsi2c, for i2c compatible with exynos5 hsi2c.
 +  - reg: physical base address of the controller and length of memory mapped
 +region.
 +  - interrupts: interrupt number to the cpu.
 +  - #address-cells: always 1 (for i2c addresses)
 +  - #size-cells: always 0
 +
 +  - Pinctrl:
 +- pinctrl-0: Pin control group to be used for this controller.
 +- pinctrl-names: Should contain only one value - default.
 +
 +Optional properties:
 +  - samsung,hs-mode: Mode of operation, High speed or Fast speed mode. If not
 +specified, default value is 0.
 +  - clock-frequency: Desired operating frequency in Hz of the bus.
 +If not specified, the default value in Hz is 10.
 +
 +Example:
 +
 +hsi2c@12ca {
 +   compatible = samsung,exynos5-hsi2c;
 +   reg = 0x12ca 0x100;
 +   interrupts = 56;
 +   clock-frequency = 10;
 +
 +   /* Pinctrl variant begins here */
 +   pinctrl-0 = i2c4_bus;
 +   pinctrl-names = default;
 +   /* Pinctrl variant ends here */
 +
 +   #address-cells = 1;
 +   #size-cells = 0;
 +
 +   s2mps11_pmic@66 {
 +   compatible = samsung,s2mps11-pmic;
 +   reg = 0x66;
 +   };
 +};
 diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
 index adfee98..49a665f 100644
 --- a/drivers/i2c/busses/Kconfig
 +++ b/drivers/i2c/busses/Kconfig
 @@ -434,6 +434,13 @@ config I2C_EG20T
   ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series.
   ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH.

 +config I2C_EXYNOS5
 +   tristate Exynos5 high-speed I2C driver
 +   depends on ARCH_EXYNOS5  OF
 +   help
 + Say Y here to include support for high-speed I2C controller in the
 + Exynos5 based Samsung SoCs.
 +
  config I2C_GPIO
 tristate GPIO-based bitbanging I2C
 depends on GENERIC_GPIO
 diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
 index 8f4fc23..b19366c 100644
 --- a/drivers/i2c/busses/Makefile
 +++ b/drivers/i2c/busses/Makefile
 @@ -42,6 +42,7 @@ i2c-designware-platform-objs := i2c-designware-platdrv.o
  obj-$(CONFIG_I2C_DESIGNWARE_PCI)   += i2c-designware-pci.o
  i2c-designware-pci-objs := i2c-designware-pcidrv.o
  obj-$(CONFIG_I2C_EG20T)+= i2c-eg20t.o
 +obj-$(CONFIG_I2C_EXYNOS5)  += i2c-exynos5.o
  obj-$(CONFIG_I2C_GPIO) += i2c-gpio.o
  obj-$(CONFIG_I2C_HIGHLANDER)   += i2c-highlander.o
  obj-$(CONFIG_I2C_IBM_IIC)  += i2c-ibm_iic.o
 diff --git a/drivers/i2c/busses/i2c-exynos5.c 
 b/drivers/i2c/busses/i2c-exynos5.c
 new file mode 100644
 index 000..33c481d
 --- /dev/null
 +++ b/drivers/i2c/busses/i2c-exynos5.c
 @@ -0,0 +1,888 @@
 +/**
 + * i2c-exynos5.c - Samsung Exynos5 I2C Controller Driver
 + *
 + * Copyright (C) 2013 Samsung Electronics Co., Ltd.
 + *
 + * This program 

Re: [PATCH] ARM: EXYNOS: Fix support of Exynos4210 rev0 SoC

2013-05-23 Thread Tomasz Figa
Hi Kukjin,

On Thursday 23 of May 2013 10:11:17 Kukjin Kim wrote:
 Kukjin Kim wrote:
  Tomasz Figa wrote:
   Hi Kukjin,
  
  Hi,
  
   On Wednesday 15 of May 2013 17:08:04 Tomasz Figa wrote:
This patch extends exynos_init_time() function to handle Exynos4210
  
  rev0
  
SoC, which differs in availability of system timers and needs
  
  different
  
clocksource initialization.

This makes it possible to use exynos_init_time() function as init_time
callback for all Exynos-based boards, including Universal_C210, which
originally had to use samsung_timer_init().

Signed-off-by: Tomasz Figa t.f...@samsung.com
Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com
---

 arch/arm/mach-exynos/Kconfig   |  3 ++-
 arch/arm/mach-exynos/common.c  | 30

+- arch/arm/mach-exynos/common.h

  |  2 ++
 
 arch/arm/mach-exynos/mach-universal_c210.c |  5 ++---
 4 files changed, 35 insertions(+), 5 deletions(-)
   
   Could you pick this patch to your fixes branch?
  
  Yeah, I will after looking at.
  
   This is a fix of a regression in handling Exynos4210 rev0 SoC (e.g.
   Universal C210 board) introduced by patches merged to 3.10.
  
  OK, I see but I didn't review yet and I  will within a couple of days ;-)
 
 OK, looks fine, this will be sent to upstream during -rc for v3.10.

Thanks.

 But, Tomasz, as you know, non-DT supporting files will be gone away in
 v3.11, just note.

Sure. This is a good thing.

In 3.11 Universal C210 will be supported only using device tree, but for 3.10 
we need this patch to make the old board file still work.

Best regards,
-- 
Tomasz Figa
Linux Kernel Developer
Samsung RD Institute Poland
Samsung Electronics
--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] clk: exynos5250: Added MUX, DIV and GATE clocks for Gscaler and MFC

2013-05-23 Thread Arun Kumar K
NAK

In testing we have seen that, when sysmmu of mfc/gscl is used,
the respective IP clock has to be ON, or else it was malfunctioning.
So for smmu_mfcl and smmu_mfcr, the parent should be mfc
so that we make sure the parent is turned on every time sysmmu is accessed.
Same thing applies to gscl also.

Regards
Arun Kumar

On Tue, Mar 26, 2013 at 9:56 AM, Prasanna Kumar prasanna...@samsung.com wrote:
 From: Prasanna Kumar prasanna...@samsung.com

 Gscaler :

   1. For aclk_300_gscl,following clocks are added
   Mux clocks
 mout_aclk_300_gscl_mid,
 mout_aclk_300_gscl_mid1,
 mout_aclk_300_gscl
   Divider clock
 div_aclk300_gscl
   Sub-Mux clock ( driven from output of divider clock)
 mout_sub_aclk300
   2. For aclk_266_gscl,
Sub-Mux clock mout_sub_aclk266 added
Divider clock has been modified to refer Sub-Mux clock

 MFC :
For aclk_333
 Sub-Mux clock mout_sub_aclk333 added
Divider clock has been modified to refer Sub-Mux clock
 Signed-off-by: Prasanna Kumar prasanna...@samsung.com
 ---
  drivers/clk/samsung/clk-exynos5250.c |   57 +
  1 files changed, 43 insertions(+), 14 deletions(-)

 diff --git a/drivers/clk/samsung/clk-exynos5250.c 
 b/drivers/clk/samsung/clk-exynos5250.c
 index e40d6af..40dff9d 100644
 --- a/drivers/clk/samsung/clk-exynos5250.c
 +++ b/drivers/clk/samsung/clk-exynos5250.c
 @@ -24,7 +24,9 @@
  #define DIV_CPU0   0x500
  #define SRC_CORE1  0x4204
  #define SRC_TOP0   0x10210
 +#define SRC_TOP1   0x10214
  #define SRC_TOP2   0x10218
 +#define SRC_TOP3   0x1021C
  #define SRC_GSCL   0x10220
  #define SRC_DISP1_00x1022c
  #define SRC_MAU0x10240
 @@ -112,7 +114,9 @@ static __initdata unsigned long exynos5250_clk_regs[] = {
 DIV_CPU0,
 SRC_CORE1,
 SRC_TOP0,
 +   SRC_TOP1,
 SRC_TOP2,
 +   SRC_TOP3,
 SRC_GSCL,
 SRC_DISP1_0,
 SRC_MAU,
 @@ -167,6 +171,13 @@ PNAME(mout_mpll_user_p)= { fin_pll, sclk_mpll };
  PNAME(mout_bpll_user_p)= { fin_pll, sclk_bpll };
  PNAME(mout_aclk166_p)  = { sclk_cpll, sclk_mpll_user };
  PNAME(mout_aclk200_p)  = { sclk_mpll_user, sclk_bpll_user };
 +PNAME(mout_sub_aclk266_p) = { fin_pll, div_aclk266 };
 +PNAME(mout_aclk_300_gscl_mid_p) = { sclk_mpll_user, sclk_bpll_user};
 +PNAME(mout_aclk_300_gscl_mid1_p) = { sclk_vpll, sclk_cpll};
 +PNAME(mout_aclk_300_gscl_p) = { mout_aclk_300_gscl_mid,
 +   mout_aclk_300_gscl_mid1 };
 +PNAME(mout_sub_aclk300_p) = { fin_pll, div_aclk300_gscl };
 +PNAME(mout_sub_aclk333_p) = { fin_pll, div_aclk333 };
  PNAME(mout_hdmi_p) = { div_hdmi_pixel, sclk_hdmiphy };
  PNAME(mout_usb3_p) = { sclk_mpll_user, sclk_cpll };
  PNAME(mout_group1_p)   = { fin_pll, fin_pll, sclk_hdmi27m,
 @@ -220,8 +231,20 @@ struct samsung_mux_clock exynos5250_mux_clks[] 
 __initdata = {
 MUX(none, sclk_mpll_user, mout_mpll_user_p, SRC_TOP2, 20, 1),
 MUX(none, sclk_bpll_user, mout_bpll_user_p, SRC_TOP2, 24, 1),
 MUX(none, mout_aclk166, mout_aclk166_p, SRC_TOP0, 8, 1),
 -   MUX(none, mout_aclk333, mout_aclk166_p, SRC_TOP0, 16, 1),
 MUX(none, mout_aclk200, mout_aclk200_p, SRC_TOP0, 12, 1),
 +   MUX_A(none, mout_sub_aclk266, mout_sub_aclk266_p,
 +   SRC_TOP3, 8, 1, m_sub_aclk266),
 +   MUX(none, mout_aclk_300_gscl, mout_aclk_300_gscl_p,
 +   SRC_TOP0, 25, 1),
 +   MUX(none, mout_aclk_300_gscl_mid, mout_aclk_300_gscl_mid_p,
 +   SRC_TOP0, 24, 1),
 +   MUX(none, mout_aclk_300_gscl_mid1, mout_aclk_300_gscl_mid1_p,
 +   SRC_TOP1, 12, 1),
 +   MUX_A(none, mout_sub_aclk300, mout_sub_aclk300_p,
 +   SRC_TOP3, 10, 1, m_sub_aclk300),
 +   MUX(none, mout_aclk333, mout_aclk166_p, SRC_TOP0, 16, 1),
 +   MUX_A(none, mout_sub_aclk333, mout_sub_aclk333_p,
 +   SRC_TOP3, 24, 1, m_sub_aclk333),
 MUX(none, mout_cam_bayer, mout_group1_p, SRC_GSCL, 12, 4),
 MUX(none, mout_cam0, mout_group1_p, SRC_GSCL, 16, 4),
 MUX(none, mout_cam1, mout_group1_p, SRC_GSCL, 20, 4),
 @@ -257,10 +280,12 @@ struct samsung_div_clock exynos5250_div_clks[] 
 __initdata = {
 DIV(none, sclk_apll, mout_apll, DIV_CPU0, 24, 3),
 DIV(none, aclk66_pre, sclk_mpll_user, DIV_TOP1, 24, 3),
 DIV(none, aclk66, aclk66_pre, DIV_TOP0, 0, 3),
 -   DIV(none, aclk266, sclk_mpll_user, DIV_TOP0, 16, 3),
 DIV(none, aclk166, mout_aclk166, DIV_TOP0, 8, 3),
 -   DIV(none, aclk333, mout_aclk333, DIV_TOP0, 20, 3),
 DIV(none, aclk200, mout_aclk200, DIV_TOP0, 

[PATCH] ARM: EXYNOS: fix software reset logic for EXYNOS5440 SOC

2013-05-23 Thread 이정석

This patch fixes software reset logic. Software reset applies only to
powered-on domains in SOC because software reset to all domains causes
reboot failure.

Signed-off-by: Jungseok Lee jays@samsung.com
---
 arch/arm/mach-exynos/common.c |6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index 7f431dd..a22615d 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -317,9 +317,13 @@ void exynos5_restart(char mode, const char *cmd)
val = 0x1;
addr = EXYNOS_SWRESET;
} else if (of_machine_is_compatible(samsung,exynos5440)) {
+   u32 status;
np = of_find_compatible_node(NULL, NULL,
samsung,exynos5440-clock);
+   addr = of_iomap(np, 0) + 0xbc;
+   status = __raw_readl(addr);
addr = of_iomap(np, 0) + 0xcc;
-   val = (0xfff  20) | (0x1  16);
+   val = __raw_readl(addr);
+   val = (val  0x) | (status  0x);
} else {
pr_err(%s: cannot support non-DT\n, __func__);
return;
-- 
1.7.10.4



--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Pulls and drive strengths in the pinctrl world

2013-05-23 Thread Stephen Warren
On 05/18/2013 10:30 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
 On 16:57 Sat 18 May , Tomasz Figa wrote:
...
 Personally I'd prefer a solution with separate property for each 
 parameter, because it's much more flexible and allows shorter lines, 
 making device tree sources more readable.

 we already discuss this on the ML the one property perline will endup with
 100s of node if not 1000s so we all do agree we do not want this in the DT

If you introduce s second level of nodes into the DT like the Tegra
bindings do, that's really not an issue.

For Tegra, each pinctrl state is a node.

Within this, there are a bunch of child nodes, each of which applies to
n pins, and sets up an arbitrary set of parameters; some nodes can set
up mux functions, some can set up e.g. pull-up, etc. The same pin can be
affected by multiple of these nodes.

This all allows you to group together common settings and avoid
duplication and having too many nodes.

Then, client drivers' pincrl-0 properties just reference a single
top-level state node, not each of the 10/100/... child nodes.

Take a look at something like nodes state_i2xmux_* in
arch/arm/boot/dts/tegra20-seaboard.dts.
--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Pulls and drive strengths in the pinctrl world

2013-05-23 Thread Stephen Warren
On 05/19/2013 03:17 AM, Jean-Christophe PLAGNIOL-VILLARD wrote:
...
 how a pin can not have mux?

Well, if that's the way HW is designed, that's just the way it is.

There are certainly pins on Tegra which don't have a mux in HW, but have
some configuration options such as drive strength that can be configured.

--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [rtc-linux] [PATCH] rtc: max8998: Check for pdata presence before dereferencing

2013-05-23 Thread Andrew Morton
On Wed, 15 May 2013 17:16:08 +0200 Tomasz Figa t.f...@samsung.com wrote:

 Currently the driver can crash with a NULL pointer dereference if no pdata
 is provided, despite of successful registration of MFD part. This patch
 fixes the problem by adding a NULL check before dereferencing the pdata
 pointer.
 
 ...

 --- a/drivers/rtc/rtc-max8998.c
 +++ b/drivers/rtc/rtc-max8998.c
 @@ -285,7 +285,7 @@ static int max8998_rtc_probe(struct platform_device *pdev)
   info-irq, ret);
  
   dev_info(pdev-dev, RTC CHIP NAME: %s\n, pdev-id_entry-name);
 - if (pdata-rtc_delay) {
 + if (pdata  pdata-rtc_delay) {
   info-lp3974_bug_workaround = true;
   dev_warn(pdev-dev, LP3974 with RTC REGERR option.
RTC updates will be extremely slow.\n);

Looking at your description I'm unable to determine which kernel
versions we should fix.  This is because the changelog didn't describe
the circumstances under which the bug triggers.

It's pretty simple: when fixing a bug, include a full description of
the bug!  As if you were sending a bug report, not a patch.
--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] clk: Exynos5250: Add clocks for G3D

2013-05-23 Thread Arun Kumar K
Hi Tomasz,

Thanks for your review.

 + DIV(aclk_400_g3d, aclk_400_g3d, mout_aclk400, DIV_TOP0, 24,
 3),

 Do you need to export this div clock? If it's a parent of a gate clock,
 then you can simply add CLK_SET_RATE_PARENT flag to the gate clock and
 calling set_rate on it will reconfigure the divider.


Yes this clock doesnt need to exported. But the current driver gets this clock
and will fail if its not exported. So that will need some changes from the
driver side also.


   DIV(none, div_cam_bayer, mout_cam_bayer, DIV_GSCL, 12, 4),
   DIV(none, div_cam0, mout_cam0, DIV_GSCL, 16, 4),
   DIV(none, div_cam1, mout_cam1, DIV_GSCL, 20, 4),
 @@ -462,6 +471,7 @@ struct samsung_gate_clock exynos5250_gate_clks[]
 __initdata = { GATE(dp, dp, aclk200, GATE_IP_DISP1, 4, 0, 0),
   GATE(mixer, mixer, aclk200, GATE_IP_DISP1, 5, 0, 0),
   GATE(hdmi, hdmi, aclk200, GATE_IP_DISP1, 6, 0, 0),
 + GATE(g3d, g3d, aclk_400_g3d, GATE_IP_G3D, 0, 0, 0),

 This would be then:

 GATE(g3d, g3d, aclk_400_g3d, GATE_IP_G3D, 0,
 CLK_SET_RATE_PARENT, 0),


Yes this would work. I will change it accordingly.

Thanks
Arun
--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: clk: Exynos5250: Add clocks for G3D

2013-05-23 Thread Arun Kumar K
Hi Doug,

Thanks for the review.
But as per Tomasz Figa's comment, I will remove the exporting of aclk_400_g3d
to the driver.

Regards
Arun

On Wed, May 22, 2013 at 4:13 AM, Doug Anderson diand...@chromium.org wrote:
 Arun,

 On Tue, May 21, 2013 at 5:36 AM, Arun Kumar K arun...@samsung.com wrote:
 @@ -262,6 +270,7 @@ struct samsung_div_clock exynos5250_div_clks[] 
 __initdata = {
 DIV(none, aclk166, mout_aclk166, DIV_TOP0, 8, 3),
 DIV(none, aclk333, mout_aclk333, DIV_TOP0, 20, 3),
 DIV(none, aclk200, mout_aclk200, DIV_TOP0, 12, 3),
 +   DIV(aclk_400_g3d, aclk_400_g3d, mout_aclk400, DIV_TOP0, 24, 3),

 Doh!  I looked at this more and it looks like I missed something.
 You've added this clock to the range assigned for [Peripheral Clock
 Gates].  This is not a gate clock but is a div clock.

 Perhaps it should be in a different range?  Could make IDs that start
 at 512 or something?

 -Doug
--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/5] Add generic set_rate clk_ops for PLL35XX and PLL36XX for samsung SoCs

2013-05-23 Thread Vikas Sajjan
This patch series does the following: 

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

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

 3) Adds set_rate() and round_rate() clk_ops for PLL35XX and PLL36XXX

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

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

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

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

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

-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/5] clk: samsung: Add set_rate() clk_ops for PLL35XX

2013-05-23 Thread Vikas Sajjan
From: Yadwinder Singh Brar yadi.b...@samsung.com

Adds set_rate() and round_rate() clk_ops for PLL35XX

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

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

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

[PATCH 4/5] clk: samsung: Add set_rate() clk_ops for PLL36XX

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

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

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 291cc9e..55ff5fd 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -224,6 +224,13 @@ struct clk * __init samsung_clk_register_pll35xx(const 
char *name,
 #define PLL36XX_MDIV_SHIFT (16)
 #define PLL36XX_PDIV_SHIFT (8)
 #define PLL36XX_SDIV_SHIFT (0)
+#define PLL36XX_KDIV_SHIFT (0)
+#define PLL36XX_LOCK_STAT_SHIFT (29)
+
+#define PLL36XX_MDIV(_tmp) ((_tmp)  (PLL36XX_MDIV_MASK  PLL36XX_MDIV_SHIFT))
+#define PLL36XX_PDIV(_tmp) ((_tmp)  (PLL36XX_PDIV_MASK  PLL36XX_PDIV_SHIFT))
+#define PLL36XX_SDIV(_tmp) ((_tmp)  (PLL36XX_SDIV_MASK  PLL36XX_SDIV_SHIFT))
+#define PLL36XX_KDIV(_tmp) ((_tmp)  (PLL36XX_KDIV_MASK  PLL36XX_KDIV_SHIFT))
 
 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
@@ -246,8 +253,65 @@ static unsigned long samsung_pll36xx_recalc_rate(struct 
clk_hw *hw,
return (unsigned long)fvco;
 }
 
+static long samsung_pll36xx_round_rate(struct clk_hw *hw, unsigned long drate,
+   unsigned long *prate)
+{
+   /* retruns the same 'drate' whichs comes as input */
+   return drate;
+}
+
+static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
+   unsigned long parent_rate)
+{
+   struct samsung_clk_pll *pll = to_clk_pll(hw);
+   u32 tmp, pll_con0, pll_con1, mdiv, pdiv, sdiv, kdiv;
+   struct samsung_pll_rate_table *rate;
+
+   rate = samsung_get_pll_settings(pll, drate);
+   if (!rate) {
+   pr_err(%s: Invalid rate : %lu for pll clk %s\n, __func__,
+   drate, __clk_get_name(hw-clk));
+   return -EINVAL;
+   }
+
+   mdiv = PLL36XX_MDIV(rate-pll_con0);
+   pdiv = PLL36XX_PDIV(rate-pll_con0);
+   sdiv = PLL36XX_SDIV(rate-pll_con0);
+   kdiv = PLL36XX_KDIV(rate-pll_con1);
+
+   pll_con0 = pll_readl(pll, PLL36XX_CON0_OFFSET);
+   pll_con1 = pll_readl(pll, PLL36XX_CON1_OFFSET);
+
+   pll_con1 = ~(PLL36XX_KDIV_MASK  PLL36XX_KDIV_SHIFT);
+
+   /* Set PLL lock time.
+  Maximum lock time can be 3000 * PDIV cycles */
+   pll_writel(pll, ((pdiv  PLL36XX_PDIV_SHIFT) * 3000),
+   PLL36XX_LOCK_OFFSET);
+
+/* Change PLL PMS values */
+   pll_con0 = ~((PLL36XX_MDIV_MASK  PLL36XX_MDIV_SHIFT) |
+   (PLL36XX_PDIV_MASK  PLL36XX_PDIV_SHIFT) |
+   (PLL36XX_SDIV_MASK  PLL36XX_SDIV_SHIFT));
+   pll_con0 |= mdiv | pdiv | sdiv;
+   pll_writel(pll, pll_con0, PLL36XX_CON0_OFFSET);
+
+   pll_con1 |= kdiv;
+   pll_writel(pll, pll_con1, PLL36XX_CON1_OFFSET);
+
+   /* wait_lock_time */
+   do {
+   cpu_relax();
+   tmp = pll_readl(pll, PLL36XX_CON0_OFFSET);
+   } while (!(tmp  (1  PLL36XX_LOCK_STAT_SHIFT)));
+
+   return 0;
+}
+
 static const struct clk_ops samsung_pll36xx_clk_ops = {
.recalc_rate = samsung_pll36xx_recalc_rate,
+   .set_rate = samsung_pll36xx_set_rate,
+   .round_rate = samsung_pll36xx_round_rate,
 };
 
 struct clk * __init samsung_clk_register_pll36xx(const char *name,
@@ -280,6 +344,9 @@ struct clk * __init samsung_clk_register_pll36xx(const char 
*name,
sort(pll-rate_table, pll-rate_count,
sizeof(struct samsung_pll_rate_table),
samsung_compare_rate, NULL);
+   } else {
+   samsung_pll35xx_clk_ops.round_rate = NULL;
+   samsung_pll35xx_clk_ops.set_rate = NULL;
}
 
clk = clk_register(NULL, pll-hw);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/5] clk: samsung: Add EPLL and VPLL freq table for exynos5250 SoC

2013-05-23 Thread Vikas Sajjan
Adds the EPLL and VPLL freq table for exynos5250 SoC.

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

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

--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RESEND PATCH 0/5] Add generic set_rate clk_ops for PLL35XX and PLL36XX for samsung SoCs

2013-05-23 Thread Vikas Sajjan
This patch series does the following: 

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

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

 3) Adds set_rate() and round_rate() clk_ops for PLL35XX and PLL36XXX

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

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

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

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

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

-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RESEND PATCH 2/5] clk: samsung: Add support to register rate_table for PLL3xxx

2013-05-23 Thread Vikas Sajjan
From: Yadwinder Singh Brar yadi.b...@samsung.com

This patch defines a common rate_table which will contain recommended p, m, s
and k values for supported rates that needs to be changed for changing
corresponding PLL's rate.
It also sorts the rate table while registering the PLL rate table.
So that this sorted table can be used for making the searching of required
rate efficient.

Signed-off-by: Yadwinder Singh Brar yadi.b...@samsung.com
---
 drivers/clk/samsung/clk-exynos4.c|8 
 drivers/clk/samsung/clk-exynos5250.c |   14 +++---
 drivers/clk/samsung/clk-pll.c|   35 --
 drivers/clk/samsung/clk-pll.h|   27 --
 4 files changed, 69 insertions(+), 15 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos4.c 
b/drivers/clk/samsung/clk-exynos4.c
index cf7d4e7..beff8a1 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -1021,13 +1021,13 @@ void __init exynos4_clk_init(struct device_node *np, 
enum exynos4_soc exynos4_so
reg_base + VPLL_CON0, pll_4650c);
} else {
apll = samsung_clk_register_pll35xx(fout_apll, fin_pll,
-   reg_base + APLL_LOCK);
+   reg_base + APLL_LOCK, NULL, 0);
mpll = samsung_clk_register_pll35xx(fout_mpll, fin_pll,
-   reg_base + E4X12_MPLL_LOCK);
+   reg_base + E4X12_MPLL_LOCK, NULL, 0);
epll = samsung_clk_register_pll36xx(fout_epll, fin_pll,
-   reg_base + EPLL_LOCK);
+   reg_base + EPLL_LOCK, NULL, 0);
vpll = samsung_clk_register_pll36xx(fout_vpll, fin_pll,
-   reg_base + VPLL_LOCK);
+   reg_base + VPLL_LOCK, NULL, 0);
}
 
samsung_clk_add_lookup(apll, fout_apll);
diff --git a/drivers/clk/samsung/clk-exynos5250.c 
b/drivers/clk/samsung/clk-exynos5250.c
index 687b580..ddf10ca 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -491,19 +491,19 @@ void __init exynos5250_clk_init(struct device_node *np)
ext_clk_match);
 
apll = samsung_clk_register_pll35xx(fout_apll, fin_pll,
-   reg_base);
+   reg_base, NULL, 0);
mpll = samsung_clk_register_pll35xx(fout_mpll, fin_pll,
-   reg_base + 0x4000);
+   reg_base + 0x4000, NULL, 0);
bpll = samsung_clk_register_pll35xx(fout_bpll, fin_pll,
-   reg_base + 0x20010);
+   reg_base + 0x20010, NULL, 0);
gpll = samsung_clk_register_pll35xx(fout_gpll, fin_pll,
-   reg_base + 0x10050);
+   reg_base + 0x10050, NULL, 0);
cpll = samsung_clk_register_pll35xx(fout_cpll, fin_pll,
-   reg_base + 0x10020);
+   reg_base + 0x10020, NULL, 0);
epll = samsung_clk_register_pll36xx(fout_epll, fin_pll,
-   reg_base + 0x10030);
+   reg_base + 0x10030, NULL, 0);
vpll = samsung_clk_register_pll36xx(fout_vpll, mout_vpllsrc,
-   reg_base + 0x10040);
+   reg_base + 0x10040, NULL, 0);
 
samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,
ARRAY_SIZE(exynos5250_fixed_rate_clks));
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 01f17cf..b8c0260 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -10,12 +10,15 @@
 */
 
 #include linux/errno.h
+#include linux/sort.h
 #include clk.h
 #include clk-pll.h
 
 struct samsung_clk_pll {
struct clk_hw   hw;
const void __iomem  *base;
+   struct samsung_pll_rate_table *rate_table;
+   unsigned int rate_count;
 };
 
 #define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
@@ -25,6 +28,14 @@ struct samsung_clk_pll {
 #define pll_writel(pll, val, offset)   \
__raw_writel(val, (void __iomem *)(pll-base + (offset)));
 
+static int samsung_compare_rate(const void *_a, const void *_b)
+{
+   const struct samsung_pll_rate_table *a = _a;
+   const struct samsung_pll_rate_table *b = _b;
+
+   return a-rate - b-rate;
+}
+
 /*
  * PLL35xx Clock Type
  */
@@ -62,7 +73,9 @@ static const struct clk_ops samsung_pll35xx_clk_ops = {
 };
 
 struct clk * __init samsung_clk_register_pll35xx(const char *name,
-   const char *pname, const void __iomem *base)
+   const char *pname, const void __iomem *base,
+   struct samsung_pll_rate_table *rate_table,
+  

[RESEND PATCH 3/5] clk: samsung: Add set_rate() clk_ops for PLL35xx

2013-05-23 Thread Vikas Sajjan
From: Yadwinder Singh Brar yadi.b...@samsung.com

Adds set_rate() and round_rate() clk_ops for PLL35xx

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

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

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

[RESEND PATCH 4/5] clk: samsung: Add set_rate() clk_ops for PLL36xx

2013-05-23 Thread Vikas Sajjan
This patch adds set_rate and round_rate clk_ops for PLL36xx
The round_rate() implementation as of now is dummy, it returns the same rate
which is passed as input.

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

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 291cc9e..55ff5fd 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -224,6 +224,13 @@ struct clk * __init samsung_clk_register_pll35xx(const 
char *name,
 #define PLL36XX_MDIV_SHIFT (16)
 #define PLL36XX_PDIV_SHIFT (8)
 #define PLL36XX_SDIV_SHIFT (0)
+#define PLL36XX_KDIV_SHIFT (0)
+#define PLL36XX_LOCK_STAT_SHIFT (29)
+
+#define PLL36XX_MDIV(_tmp) ((_tmp)  (PLL36XX_MDIV_MASK  PLL36XX_MDIV_SHIFT))
+#define PLL36XX_PDIV(_tmp) ((_tmp)  (PLL36XX_PDIV_MASK  PLL36XX_PDIV_SHIFT))
+#define PLL36XX_SDIV(_tmp) ((_tmp)  (PLL36XX_SDIV_MASK  PLL36XX_SDIV_SHIFT))
+#define PLL36XX_KDIV(_tmp) ((_tmp)  (PLL36XX_KDIV_MASK  PLL36XX_KDIV_SHIFT))
 
 static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
@@ -246,8 +253,65 @@ static unsigned long samsung_pll36xx_recalc_rate(struct 
clk_hw *hw,
return (unsigned long)fvco;
 }
 
+static long samsung_pll36xx_round_rate(struct clk_hw *hw, unsigned long drate,
+   unsigned long *prate)
+{
+   /* retruns the same 'drate' whichs comes as input */
+   return drate;
+}
+
+static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
+   unsigned long parent_rate)
+{
+   struct samsung_clk_pll *pll = to_clk_pll(hw);
+   u32 tmp, pll_con0, pll_con1, mdiv, pdiv, sdiv, kdiv;
+   struct samsung_pll_rate_table *rate;
+
+   rate = samsung_get_pll_settings(pll, drate);
+   if (!rate) {
+   pr_err(%s: Invalid rate : %lu for pll clk %s\n, __func__,
+   drate, __clk_get_name(hw-clk));
+   return -EINVAL;
+   }
+
+   mdiv = PLL36XX_MDIV(rate-pll_con0);
+   pdiv = PLL36XX_PDIV(rate-pll_con0);
+   sdiv = PLL36XX_SDIV(rate-pll_con0);
+   kdiv = PLL36XX_KDIV(rate-pll_con1);
+
+   pll_con0 = pll_readl(pll, PLL36XX_CON0_OFFSET);
+   pll_con1 = pll_readl(pll, PLL36XX_CON1_OFFSET);
+
+   pll_con1 = ~(PLL36XX_KDIV_MASK  PLL36XX_KDIV_SHIFT);
+
+   /* Set PLL lock time.
+  Maximum lock time can be 3000 * PDIV cycles */
+   pll_writel(pll, ((pdiv  PLL36XX_PDIV_SHIFT) * 3000),
+   PLL36XX_LOCK_OFFSET);
+
+/* Change PLL PMS values */
+   pll_con0 = ~((PLL36XX_MDIV_MASK  PLL36XX_MDIV_SHIFT) |
+   (PLL36XX_PDIV_MASK  PLL36XX_PDIV_SHIFT) |
+   (PLL36XX_SDIV_MASK  PLL36XX_SDIV_SHIFT));
+   pll_con0 |= mdiv | pdiv | sdiv;
+   pll_writel(pll, pll_con0, PLL36XX_CON0_OFFSET);
+
+   pll_con1 |= kdiv;
+   pll_writel(pll, pll_con1, PLL36XX_CON1_OFFSET);
+
+   /* wait_lock_time */
+   do {
+   cpu_relax();
+   tmp = pll_readl(pll, PLL36XX_CON0_OFFSET);
+   } while (!(tmp  (1  PLL36XX_LOCK_STAT_SHIFT)));
+
+   return 0;
+}
+
 static const struct clk_ops samsung_pll36xx_clk_ops = {
.recalc_rate = samsung_pll36xx_recalc_rate,
+   .set_rate = samsung_pll36xx_set_rate,
+   .round_rate = samsung_pll36xx_round_rate,
 };
 
 struct clk * __init samsung_clk_register_pll36xx(const char *name,
@@ -280,6 +344,9 @@ struct clk * __init samsung_clk_register_pll36xx(const char 
*name,
sort(pll-rate_table, pll-rate_count,
sizeof(struct samsung_pll_rate_table),
samsung_compare_rate, NULL);
+   } else {
+   samsung_pll35xx_clk_ops.round_rate = NULL;
+   samsung_pll35xx_clk_ops.set_rate = NULL;
}
 
clk = clk_register(NULL, pll-hw);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RESEND PATCH 5/5] clk: samsung: Add EPLL and VPLL freq table for exynos5250 SoC

2013-05-23 Thread Vikas Sajjan
Adds the EPLL and VPLL freq table for exynos5250 SoC.

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

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

--
To unsubscribe from this list: send the line unsubscribe linux-samsung-soc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RESEND PATCH 1/5] clk: samsung: Use clk-base instead of directly using clk-con0 for PLL3xxx

2013-05-23 Thread Vikas Sajjan
From: Yadwinder Singh Brar yadi.b...@samsung.com

To factor out possible common code, this patch unifies the clk strutures used
for PLL35xx  PLL36xx and usues clk-base instead of clk-con0.

Signed-off-by: Yadwinder Singh Brar yadi.b...@samsung.com
---
 drivers/clk/samsung/clk-exynos4.c|   10 ---
 drivers/clk/samsung/clk-exynos5250.c |   14 -
 drivers/clk/samsung/clk-pll.c|   54 ++
 drivers/clk/samsung/clk-pll.h|4 +--
 4 files changed, 44 insertions(+), 38 deletions(-)

diff --git a/drivers/clk/samsung/clk-exynos4.c 
b/drivers/clk/samsung/clk-exynos4.c
index d0940e6..cf7d4e7 100644
--- a/drivers/clk/samsung/clk-exynos4.c
+++ b/drivers/clk/samsung/clk-exynos4.c
@@ -97,12 +97,14 @@
 #define GATE_IP_PERIL  0xc950
 #define E4210_GATE_IP_PERIR0xc960
 #define GATE_BLOCK 0xc970
+#define E4X12_MPLL_LOCK0x10008
 #define E4X12_MPLL_CON00x10108
 #define SRC_DMC0x10200
 #define SRC_MASK_DMC   0x10300
 #define DIV_DMC0   0x10500
 #define DIV_DMC1   0x10504
 #define GATE_IP_DMC0x10900
+#define APLL_LOCK  0x14000
 #define APLL_CON0  0x14100
 #define E4210_MPLL_CON00x14108
 #define SRC_CPU0x14200
@@ -1019,13 +1021,13 @@ void __init exynos4_clk_init(struct device_node *np, 
enum exynos4_soc exynos4_so
reg_base + VPLL_CON0, pll_4650c);
} else {
apll = samsung_clk_register_pll35xx(fout_apll, fin_pll,
-   reg_base + APLL_CON0);
+   reg_base + APLL_LOCK);
mpll = samsung_clk_register_pll35xx(fout_mpll, fin_pll,
-   reg_base + E4X12_MPLL_CON0);
+   reg_base + E4X12_MPLL_LOCK);
epll = samsung_clk_register_pll36xx(fout_epll, fin_pll,
-   reg_base + EPLL_CON0);
+   reg_base + EPLL_LOCK);
vpll = samsung_clk_register_pll36xx(fout_vpll, fin_pll,
-   reg_base + VPLL_CON0);
+   reg_base + VPLL_LOCK);
}
 
samsung_clk_add_lookup(apll, fout_apll);
diff --git a/drivers/clk/samsung/clk-exynos5250.c 
b/drivers/clk/samsung/clk-exynos5250.c
index 5c97e75..687b580 100644
--- a/drivers/clk/samsung/clk-exynos5250.c
+++ b/drivers/clk/samsung/clk-exynos5250.c
@@ -491,19 +491,19 @@ void __init exynos5250_clk_init(struct device_node *np)
ext_clk_match);
 
apll = samsung_clk_register_pll35xx(fout_apll, fin_pll,
-   reg_base + 0x100);
+   reg_base);
mpll = samsung_clk_register_pll35xx(fout_mpll, fin_pll,
-   reg_base + 0x4100);
+   reg_base + 0x4000);
bpll = samsung_clk_register_pll35xx(fout_bpll, fin_pll,
-   reg_base + 0x20110);
+   reg_base + 0x20010);
gpll = samsung_clk_register_pll35xx(fout_gpll, fin_pll,
-   reg_base + 0x10150);
+   reg_base + 0x10050);
cpll = samsung_clk_register_pll35xx(fout_cpll, fin_pll,
-   reg_base + 0x10120);
+   reg_base + 0x10020);
epll = samsung_clk_register_pll36xx(fout_epll, fin_pll,
-   reg_base + 0x10130);
+   reg_base + 0x10030);
vpll = samsung_clk_register_pll36xx(fout_vpll, mout_vpllsrc,
-   reg_base + 0x10140);
+   reg_base + 0x10040);
 
samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks,
ARRAY_SIZE(exynos5250_fixed_rate_clks));
diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 89135f6..01f17cf 100644
--- a/drivers/clk/samsung/clk-pll.c
+++ b/drivers/clk/samsung/clk-pll.c
@@ -13,9 +13,24 @@
 #include clk.h
 #include clk-pll.h
 
+struct samsung_clk_pll {
+   struct clk_hw   hw;
+   const void __iomem  *base;
+};
+
+#define to_clk_pll(_hw) container_of(_hw, struct samsung_clk_pll, hw)
+
+#define pll_readl(pll, offset) \
+   __raw_readl((void __iomem *)(pll-base + (offset)));
+#define pll_writel(pll, val, offset)   \
+   __raw_writel(val, (void __iomem *)(pll-base + (offset)));
+
 /*
  * PLL35xx Clock Type
  */
+#define PLL35XX_LOCK_OFFSET 0x0
+#define PLL35XX_CON0_OFFSET 0x100
+#define PLL35XX_CON1_OFFSET 0x104
 
 #define PLL35XX_MDIV_MASK   (0x3FF)
 #define PLL35XX_PDIV_MASK   (0x3F)
@@ -24,21 +39,14 @@
 #define PLL35XX_PDIV_SHIFT  (8)
 #define PLL35XX_SDIV_SHIFT  (0)