All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] ARM: S3C24XX: convert s3c2410, s3c2440 s3c2442 to common clock framework
@ 2013-12-13 12:56 ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 12:56 UTC (permalink / raw)
  To: Kukjin Kim, t.figa; +Cc: mturquette, linux-arm-kernel, linux-samsung-soc

This series converts the earliest s3c socs to use a clock driver based on the
common clock framework instead of the old Samsung clock implementation.

The only obstacle I found was the configuration of the clkout outputs in
the different machines. As I lack hardware test and knowledge on what is
expected there, somebody with interest in these machines will have to
step up to implement the clkout configuration
This can for example be done in the machine_init function after
the platform-devices (and thus the dclk-device) are populated.

This leaves the s3c2412 soc to be converted, as it has yet another different
clock tree.

Tested on an Openmoko Neo Freerunner (S3C2442), but of course more tests
would be really helpful.

Heiko Stuebner (12):
  ARM: S3C24XX: cpufreq-utils: don't write raw values to MPLLCON when using ccf
  dt-bindings: document s3c24xx controller for external clock output
  clk: samsung: add clock driver for external clock outputs
  ARM: S3C24XX: enable usage of common dclk if common clock framework is enabled
  ARM: S3C24XX: only store clock registers when old clock code is active
  clk: samsung: add plls used by the early s3c24xx cpus
  dt-bindings: add documentation for s3c2410 clock controller
  clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442
  ARM: S3C24XX: add platform code for conversion to the common clock framework
  ARM: S3C24XX: convert s3c2440 and s3c2442 to common clock framework
  ARM: S3C24XX: convert s3c2410 to common clock framework
  ARM: S3C24XX: remove legacy clock code

 .../bindings/clock/samsung,s3c2410-clock.txt       |   50 ++
 .../bindings/clock/samsung,s3c2410-dclk.txt        |   53 ++
 arch/arm/mach-s3c24xx/Kconfig                      |   50 +-
 arch/arm/mach-s3c24xx/Makefile                     |    6 +-
 arch/arm/mach-s3c24xx/clock-dclk.c                 |  195 --------
 arch/arm/mach-s3c24xx/clock-s3c2410.c              |  285 -----------
 arch/arm/mach-s3c24xx/clock-s3c2440.c              |  217 --------
 arch/arm/mach-s3c24xx/clock-s3c244x.c              |  141 ------
 arch/arm/mach-s3c24xx/common.c                     |   45 +-
 arch/arm/mach-s3c24xx/common.h                     |   11 +-
 arch/arm/mach-s3c24xx/cpufreq-utils.c              |   13 +
 arch/arm/mach-s3c24xx/include/mach/regs-clock.h    |   18 -
 arch/arm/mach-s3c24xx/include/mach/regs-gpio.h     |    3 -
 arch/arm/mach-s3c24xx/mach-amlm5900.c              |    9 +-
 arch/arm/mach-s3c24xx/mach-anubis.c                |   15 +-
 arch/arm/mach-s3c24xx/mach-at2440evb.c             |   10 +-
 arch/arm/mach-s3c24xx/mach-bast.c                  |   15 +-
 arch/arm/mach-s3c24xx/mach-gta02.c                 |    8 +-
 arch/arm/mach-s3c24xx/mach-h1940.c                 |   10 +-
 arch/arm/mach-s3c24xx/mach-mini2440.c              |   10 +-
 arch/arm/mach-s3c24xx/mach-n30.c                   |   12 +-
 arch/arm/mach-s3c24xx/mach-nexcoder.c              |   10 +-
 arch/arm/mach-s3c24xx/mach-osiris.c                |   15 +-
 arch/arm/mach-s3c24xx/mach-otom.c                  |   10 +-
 arch/arm/mach-s3c24xx/mach-qt2410.c                |    9 +-
 arch/arm/mach-s3c24xx/mach-rx1950.c                |   15 +-
 arch/arm/mach-s3c24xx/mach-rx3715.c                |   10 +-
 arch/arm/mach-s3c24xx/mach-smdk2410.c              |    9 +-
 arch/arm/mach-s3c24xx/mach-smdk2440.c              |   10 +-
 arch/arm/mach-s3c24xx/mach-tct_hammer.c            |    9 +-
 arch/arm/mach-s3c24xx/mach-vr1000.c                |   15 +-
 arch/arm/mach-s3c24xx/pm.c                         |   13 +-
 arch/arm/mach-s3c24xx/s3c2410.c                    |   56 ---
 arch/arm/mach-s3c24xx/s3c2442.c                    |  111 -----
 arch/arm/mach-s3c24xx/s3c244x.c                    |   59 +--
 drivers/clk/samsung/Makefile                       |    2 +
 drivers/clk/samsung/clk-pll.c                      |  182 +++++++
 drivers/clk/samsung/clk-pll.h                      |    3 +
 drivers/clk/samsung/clk-s3c2410-dclk.c             |  517 ++++++++++++++++++++
 drivers/clk/samsung/clk-s3c2410.c                  |  428 ++++++++++++++++
 include/dt-bindings/clock/samsung,s3c2410-clock.h  |   64 +++
 include/dt-bindings/clock/samsung,s3c2410-dclk.h   |   28 ++
 42 files changed, 1575 insertions(+), 1176 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
 delete mode 100644 arch/arm/mach-s3c24xx/clock-dclk.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2410.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2440.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c244x.c
 create mode 100644 drivers/clk/samsung/clk-s3c2410-dclk.c
 create mode 100644 drivers/clk/samsung/clk-s3c2410.c
 create mode 100644 include/dt-bindings/clock/samsung,s3c2410-clock.h
 create mode 100644 include/dt-bindings/clock/samsung,s3c2410-dclk.h

-- 
1.7.10.4

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

* [PATCH 00/12] ARM: S3C24XX: convert s3c2410, s3c2440 s3c2442 to common clock framework
@ 2013-12-13 12:56 ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 12:56 UTC (permalink / raw)
  To: linux-arm-kernel

This series converts the earliest s3c socs to use a clock driver based on the
common clock framework instead of the old Samsung clock implementation.

The only obstacle I found was the configuration of the clkout outputs in
the different machines. As I lack hardware test and knowledge on what is
expected there, somebody with interest in these machines will have to
step up to implement the clkout configuration
This can for example be done in the machine_init function after
the platform-devices (and thus the dclk-device) are populated.

This leaves the s3c2412 soc to be converted, as it has yet another different
clock tree.

Tested on an Openmoko Neo Freerunner (S3C2442), but of course more tests
would be really helpful.

Heiko Stuebner (12):
  ARM: S3C24XX: cpufreq-utils: don't write raw values to MPLLCON when using ccf
  dt-bindings: document s3c24xx controller for external clock output
  clk: samsung: add clock driver for external clock outputs
  ARM: S3C24XX: enable usage of common dclk if common clock framework is enabled
  ARM: S3C24XX: only store clock registers when old clock code is active
  clk: samsung: add plls used by the early s3c24xx cpus
  dt-bindings: add documentation for s3c2410 clock controller
  clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442
  ARM: S3C24XX: add platform code for conversion to the common clock framework
  ARM: S3C24XX: convert s3c2440 and s3c2442 to common clock framework
  ARM: S3C24XX: convert s3c2410 to common clock framework
  ARM: S3C24XX: remove legacy clock code

 .../bindings/clock/samsung,s3c2410-clock.txt       |   50 ++
 .../bindings/clock/samsung,s3c2410-dclk.txt        |   53 ++
 arch/arm/mach-s3c24xx/Kconfig                      |   50 +-
 arch/arm/mach-s3c24xx/Makefile                     |    6 +-
 arch/arm/mach-s3c24xx/clock-dclk.c                 |  195 --------
 arch/arm/mach-s3c24xx/clock-s3c2410.c              |  285 -----------
 arch/arm/mach-s3c24xx/clock-s3c2440.c              |  217 --------
 arch/arm/mach-s3c24xx/clock-s3c244x.c              |  141 ------
 arch/arm/mach-s3c24xx/common.c                     |   45 +-
 arch/arm/mach-s3c24xx/common.h                     |   11 +-
 arch/arm/mach-s3c24xx/cpufreq-utils.c              |   13 +
 arch/arm/mach-s3c24xx/include/mach/regs-clock.h    |   18 -
 arch/arm/mach-s3c24xx/include/mach/regs-gpio.h     |    3 -
 arch/arm/mach-s3c24xx/mach-amlm5900.c              |    9 +-
 arch/arm/mach-s3c24xx/mach-anubis.c                |   15 +-
 arch/arm/mach-s3c24xx/mach-at2440evb.c             |   10 +-
 arch/arm/mach-s3c24xx/mach-bast.c                  |   15 +-
 arch/arm/mach-s3c24xx/mach-gta02.c                 |    8 +-
 arch/arm/mach-s3c24xx/mach-h1940.c                 |   10 +-
 arch/arm/mach-s3c24xx/mach-mini2440.c              |   10 +-
 arch/arm/mach-s3c24xx/mach-n30.c                   |   12 +-
 arch/arm/mach-s3c24xx/mach-nexcoder.c              |   10 +-
 arch/arm/mach-s3c24xx/mach-osiris.c                |   15 +-
 arch/arm/mach-s3c24xx/mach-otom.c                  |   10 +-
 arch/arm/mach-s3c24xx/mach-qt2410.c                |    9 +-
 arch/arm/mach-s3c24xx/mach-rx1950.c                |   15 +-
 arch/arm/mach-s3c24xx/mach-rx3715.c                |   10 +-
 arch/arm/mach-s3c24xx/mach-smdk2410.c              |    9 +-
 arch/arm/mach-s3c24xx/mach-smdk2440.c              |   10 +-
 arch/arm/mach-s3c24xx/mach-tct_hammer.c            |    9 +-
 arch/arm/mach-s3c24xx/mach-vr1000.c                |   15 +-
 arch/arm/mach-s3c24xx/pm.c                         |   13 +-
 arch/arm/mach-s3c24xx/s3c2410.c                    |   56 ---
 arch/arm/mach-s3c24xx/s3c2442.c                    |  111 -----
 arch/arm/mach-s3c24xx/s3c244x.c                    |   59 +--
 drivers/clk/samsung/Makefile                       |    2 +
 drivers/clk/samsung/clk-pll.c                      |  182 +++++++
 drivers/clk/samsung/clk-pll.h                      |    3 +
 drivers/clk/samsung/clk-s3c2410-dclk.c             |  517 ++++++++++++++++++++
 drivers/clk/samsung/clk-s3c2410.c                  |  428 ++++++++++++++++
 include/dt-bindings/clock/samsung,s3c2410-clock.h  |   64 +++
 include/dt-bindings/clock/samsung,s3c2410-dclk.h   |   28 ++
 42 files changed, 1575 insertions(+), 1176 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
 delete mode 100644 arch/arm/mach-s3c24xx/clock-dclk.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2410.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2440.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c244x.c
 create mode 100644 drivers/clk/samsung/clk-s3c2410-dclk.c
 create mode 100644 drivers/clk/samsung/clk-s3c2410.c
 create mode 100644 include/dt-bindings/clock/samsung,s3c2410-clock.h
 create mode 100644 include/dt-bindings/clock/samsung,s3c2410-dclk.h

-- 
1.7.10.4

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

* [PATCH 01/12] ARM: S3C24XX: cpufreq-utils: don't write raw values to MPLLCON when using ccf
  2013-12-13 12:56 ` Heiko Stübner
@ 2013-12-13 12:57   ` Heiko Stübner
  -1 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 12:57 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: t.figa, mturquette, linux-arm-kernel, linux-samsung-soc

The s3c24xx cpufreq driver needs to change the mpll speed and was doing
this by writing raw values from a translation table into the MPLLCON
register.

Change this to use a regular clk_set_rate call when using the common
clock framework and only write the raw value in the samsung_clock case.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/cpufreq-utils.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/mach-s3c24xx/cpufreq-utils.c b/arch/arm/mach-s3c24xx/cpufreq-utils.c
index 2a0aa56..680a031 100644
--- a/arch/arm/mach-s3c24xx/cpufreq-utils.c
+++ b/arch/arm/mach-s3c24xx/cpufreq-utils.c
@@ -14,6 +14,7 @@
 #include <linux/errno.h>
 #include <linux/cpufreq.h>
 #include <linux/io.h>
+#include <linux/clk.h>
 
 #include <mach/map.h>
 #include <mach/regs-clock.h>
@@ -60,5 +61,17 @@ void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
  */
 void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg)
 {
+#ifdef CONFIG_SAMSUNG_CLOCK
 	__raw_writel(cfg->pll.driver_data, S3C2410_MPLLCON);
+#endif
+
+#ifdef CONFIG_COMMON_CLK
+	struct clk *mpll = clk_get(NULL, "mpll");
+	if (IS_ERR(mpll))
+		return;
+
+	clk_set_rate(mpll, cfg->pll.frequency);
+
+	clk_put(mpll);
+#endif
 }
-- 
1.7.10.4

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

* [PATCH 01/12] ARM: S3C24XX: cpufreq-utils: don't write raw values to MPLLCON when using ccf
@ 2013-12-13 12:57   ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 12:57 UTC (permalink / raw)
  To: linux-arm-kernel

The s3c24xx cpufreq driver needs to change the mpll speed and was doing
this by writing raw values from a translation table into the MPLLCON
register.

Change this to use a regular clk_set_rate call when using the common
clock framework and only write the raw value in the samsung_clock case.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/cpufreq-utils.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/arch/arm/mach-s3c24xx/cpufreq-utils.c b/arch/arm/mach-s3c24xx/cpufreq-utils.c
index 2a0aa56..680a031 100644
--- a/arch/arm/mach-s3c24xx/cpufreq-utils.c
+++ b/arch/arm/mach-s3c24xx/cpufreq-utils.c
@@ -14,6 +14,7 @@
 #include <linux/errno.h>
 #include <linux/cpufreq.h>
 #include <linux/io.h>
+#include <linux/clk.h>
 
 #include <mach/map.h>
 #include <mach/regs-clock.h>
@@ -60,5 +61,17 @@ void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
  */
 void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg)
 {
+#ifdef CONFIG_SAMSUNG_CLOCK
 	__raw_writel(cfg->pll.driver_data, S3C2410_MPLLCON);
+#endif
+
+#ifdef CONFIG_COMMON_CLK
+	struct clk *mpll = clk_get(NULL, "mpll");
+	if (IS_ERR(mpll))
+		return;
+
+	clk_set_rate(mpll, cfg->pll.frequency);
+
+	clk_put(mpll);
+#endif
 }
-- 
1.7.10.4

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

* [PATCH 02/12] dt-bindings: document s3c24xx controller for external clock output
  2013-12-13 12:56 ` Heiko Stübner
@ 2013-12-13 12:59   ` Heiko Stübner
  -1 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 12:59 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: t.figa, mturquette, linux-arm-kernel, linux-samsung-soc,
	Rob Herring, Pawel Moll, Mark Rutland, Stephen Warren,
	Ian Campbell, devicetree

The clock settings are distributed over a regular register and parts
of the misccr register.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 .../bindings/clock/samsung,s3c2410-dclk.txt        |   53 ++++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt

diff --git a/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt b/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
new file mode 100644
index 0000000..0a1f7b1
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
@@ -0,0 +1,53 @@
+* Samsung S3C24XX External Clock Output Controller
+
+The S3C24XX series can generate clock signals on two clock output pads.
+The clock binding described here is applicable to all SoCs in
+the s3c24x family.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - "samsung,s3c2410-dclk" - controller in S3C2410 SoCs.
+  - "samsung,s3c2412-dclk" - controller in S3C2412 SoCs.
+  - "samsung,s3c2440-dclk" - controller in S3C2440 and S3C2442 SoCs.
+  - "samsung,s3c2443-dclk" - controller in S3C2443 and later SoCs.
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- #clock-cells: should be 1.
+- samsung,misccr: phandle to the syscon managing the misccr register, which
+  holds configuration settings for different soc-components (clocks, usb, ...).
+
+Each clock is assigned an identifier and client nodes can use this identifier
+to specify the clock which they consume.
+
+All available clocks are defined as preprocessor macros in
+dt-bindings/clock/samsung,s3c2410-dclk.h header and can be used in device
+tree sources.
+
+To enable the clock outputs it is necessary to configure the pins accordingly
+using the pinctrl framework.
+
+Example:
+
+&pinctrl_0 {
+	clkout0: clkout0 {
+		samsung,pins = "gph-9";
+		samsung,pin-function = <2>;
+	};
+	clkout1: clkout1 {
+		samsung,pins = "gph-10";
+		samsung,pin-function = <2>;
+	};
+};
+
+[...]
+
+	clocks: clock-controller@56000084 {
+		compatible = "samsung,s3c2410-dclk";
+		reg = <0x56000084 0x4>;
+		#clock-cells = <1>;
+		samsung,misccr = <&misccr>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&clkout0>, <&clkout1>;
+	};
-- 
1.7.10.4

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

* [PATCH 02/12] dt-bindings: document s3c24xx controller for external clock output
@ 2013-12-13 12:59   ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

The clock settings are distributed over a regular register and parts
of the misccr register.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 .../bindings/clock/samsung,s3c2410-dclk.txt        |   53 ++++++++++++++++++++
 1 file changed, 53 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt

diff --git a/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt b/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
new file mode 100644
index 0000000..0a1f7b1
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
@@ -0,0 +1,53 @@
+* Samsung S3C24XX External Clock Output Controller
+
+The S3C24XX series can generate clock signals on two clock output pads.
+The clock binding described here is applicable to all SoCs in
+the s3c24x family.
+
+Required Properties:
+
+- compatible: should be one of the following.
+  - "samsung,s3c2410-dclk" - controller in S3C2410 SoCs.
+  - "samsung,s3c2412-dclk" - controller in S3C2412 SoCs.
+  - "samsung,s3c2440-dclk" - controller in S3C2440 and S3C2442 SoCs.
+  - "samsung,s3c2443-dclk" - controller in S3C2443 and later SoCs.
+- reg: physical base address of the controller and length of memory mapped
+  region.
+- #clock-cells: should be 1.
+- samsung,misccr: phandle to the syscon managing the misccr register, which
+  holds configuration settings for different soc-components (clocks, usb, ...).
+
+Each clock is assigned an identifier and client nodes can use this identifier
+to specify the clock which they consume.
+
+All available clocks are defined as preprocessor macros in
+dt-bindings/clock/samsung,s3c2410-dclk.h header and can be used in device
+tree sources.
+
+To enable the clock outputs it is necessary to configure the pins accordingly
+using the pinctrl framework.
+
+Example:
+
+&pinctrl_0 {
+	clkout0: clkout0 {
+		samsung,pins = "gph-9";
+		samsung,pin-function = <2>;
+	};
+	clkout1: clkout1 {
+		samsung,pins = "gph-10";
+		samsung,pin-function = <2>;
+	};
+};
+
+[...]
+
+	clocks: clock-controller at 56000084 {
+		compatible = "samsung,s3c2410-dclk";
+		reg = <0x56000084 0x4>;
+		#clock-cells = <1>;
+		samsung,misccr = <&misccr>;
+
+		pinctrl-names = "default";
+		pinctrl-0 = <&clkout0>, <&clkout1>;
+	};
-- 
1.7.10.4

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

* [PATCH 03/12] clk: samsung: add clock driver for external clock outputs
  2013-12-13 12:56 ` Heiko Stübner
@ 2013-12-13 12:59   ` Heiko Stübner
  -1 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 12:59 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: t.figa, mturquette, linux-arm-kernel, linux-samsung-soc

This adds a driver for controlling the external clock outputs of
s3c24xx architectures including the dclk muxes and dividers.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 drivers/clk/samsung/Makefile                     |    1 +
 drivers/clk/samsung/clk-s3c2410-dclk.c           |  517 ++++++++++++++++++++++
 include/dt-bindings/clock/samsung,s3c2410-dclk.h |   28 ++
 3 files changed, 546 insertions(+)
 create mode 100644 drivers/clk/samsung/clk-s3c2410-dclk.c
 create mode 100644 include/dt-bindings/clock/samsung,s3c2410-dclk.h

diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 4c892c6..568683c 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -8,5 +8,6 @@ obj-$(CONFIG_SOC_EXYNOS5250)	+= clk-exynos5250.o
 obj-$(CONFIG_SOC_EXYNOS5420)	+= clk-exynos5420.o
 obj-$(CONFIG_SOC_EXYNOS5440)	+= clk-exynos5440.o
 obj-$(CONFIG_ARCH_EXYNOS)	+= clk-exynos-audss.o
+obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
 obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
 obj-$(CONFIG_ARCH_S3C64XX)	+= clk-s3c64xx.o
diff --git a/drivers/clk/samsung/clk-s3c2410-dclk.c b/drivers/clk/samsung/clk-s3c2410-dclk.c
new file mode 100644
index 0000000..de10e5c
--- /dev/null
+++ b/drivers/clk/samsung/clk-s3c2410-dclk.c
@@ -0,0 +1,517 @@
+/*
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Common Clock Framework support for s3c24xx external clock output.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/mfd/syscon.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/of.h>
+#include <dt-bindings/clock/samsung,s3c2410-dclk.h>
+#include "clk.h"
+
+/* legacy access to misccr, until dt conversion is finished */
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+enum supported_socs {
+	S3C2410,
+	S3C2412,
+	S3C2440,
+	S3C2443,
+};
+
+struct s3c24xx_dclk_drv_data {
+	int cpu_type;
+};
+
+/*
+ * Clock for output-parent selection in misccr
+ */
+
+struct s3c24xx_clkout {
+	struct clk_hw		hw;
+	struct regmap		*misccr;
+	u32			mask;
+	u8			shift;
+};
+
+#define to_s3c24xx_clkout(_hw) container_of(_hw, struct s3c24xx_clkout, hw)
+
+static u8 s3c24xx_clkout_get_parent(struct clk_hw *hw)
+{
+	struct s3c24xx_clkout *clkout = to_s3c24xx_clkout(hw);
+	int num_parents = __clk_get_num_parents(hw->clk);
+	u32 val;
+	int ret = 0;
+
+	if (clkout->misccr)
+		ret = regmap_read(clkout->misccr, 0, &val);
+	else
+		val = readl_relaxed(S3C24XX_MISCCR) >> clkout->shift;
+
+	if (ret)
+		return ret;
+
+	val >>= clkout->shift;
+	val &= clkout->mask;
+
+	if (val >= num_parents)
+		return -EINVAL;
+
+	return val;
+}
+
+static int s3c24xx_clkout_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct s3c24xx_clkout *clkout = to_s3c24xx_clkout(hw);
+	int ret = 0;
+
+	if (clkout->misccr)
+		ret = regmap_update_bits(clkout->misccr, 0,
+					 (clkout->mask << clkout->shift),
+					 (index << clkout->shift));
+	else
+		s3c2410_modify_misccr((clkout->mask << clkout->shift),
+				      (index << clkout->shift));
+
+	return ret;
+}
+
+const struct clk_ops s3c24xx_clkout_ops = {
+	.get_parent = s3c24xx_clkout_get_parent,
+	.set_parent = s3c24xx_clkout_set_parent,
+	.determine_rate = __clk_mux_determine_rate,
+};
+
+struct clk *s3c24xx_register_clkout(struct device *dev, const char *name,
+		const char **parent_names, u8 num_parents,
+		struct regmap *misccr, u8 shift, u32 mask)
+{
+	struct s3c24xx_clkout *clkout;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	/* allocate the clkout */
+	clkout = kzalloc(sizeof(*clkout), GFP_KERNEL);
+	if (!clkout)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &s3c24xx_clkout_ops;
+	init.flags = CLK_IS_BASIC;
+	init.parent_names = parent_names;
+	init.num_parents = num_parents;
+
+	clkout->misccr = misccr;
+	clkout->shift = shift;
+	clkout->mask = mask;
+	clkout->hw.init = &init;
+
+	clk = clk_register(dev, &clkout->hw);
+
+	return clk;
+}
+
+/*
+ * dclk and clkout init
+ */
+
+struct s3c24xx_dclk {
+	struct device *dev;
+	void __iomem *base;
+	struct clk_onecell_data clk_data;
+	struct notifier_block dclk0_div_change_nb;
+	struct notifier_block dclk1_div_change_nb;
+	spinlock_t dclk_lock;
+	unsigned long reg_save;
+};
+
+#define to_s3c24xx_dclk0(x) \
+		container_of(x, struct s3c24xx_dclk, dclk0_div_change_nb)
+
+#define to_s3c24xx_dclk1(x) \
+		container_of(x, struct s3c24xx_dclk, dclk1_div_change_nb)
+
+static const char dummy_nm[] __initconst = "dummy_name";
+
+PNAME(dclk_s3c2410_p) = { "pclk", "uclk" };
+PNAME(clkout0_s3c2410_p) = { "mpll", "upll", "fclk", "hclk", "pclk",
+			     "gate_dclk0" };
+PNAME(clkout1_s3c2410_p) = { "mpll", "upll", "fclk", "hclk", "pclk",
+			     "gate_dclk1" };
+
+PNAME(clkout0_s3c2412_p) = { "mpll", "upll", dummy_nm /* rtc clock output */,
+			     "hclk", "pclk", "gate_dclk0" };
+PNAME(clkout1_s3c2412_p) = { "xti", "upll", "fclk", "hclk", "pclk",
+			     "gate_dclk1" };
+
+PNAME(clkout0_s3c2440_p) = { "xti", "upll", "fclk", "hclk", "pclk",
+			     "gate_dclk0" };
+PNAME(clkout1_s3c2440_p) = { "mpll", "upll", dummy_nm /* rtc clock output */,
+			     "hclk", "pclk", "gate_dclk1" };
+
+PNAME(dclk_s3c2443_p) = { "pclk", "epll" };
+PNAME(clkout0_s3c2443_p) = { "xti", "epll", "armclk", "hclk", "pclk",
+			     "gate_dclk0" };
+PNAME(clkout1_s3c2443_p) = { dummy_nm, "epll", dummy_nm /* rtc clock output */,
+			     "hclk", "pclk", "gate_dclk1" };
+
+#define DCLKCON_DCLK_DIV_MASK		0xf
+#define DCLKCON_DCLK0_DIV_SHIFT		4
+#define DCLKCON_DCLK0_CMP_SHIFT		8
+#define DCLKCON_DCLK1_DIV_SHIFT		20
+#define DCLKCON_DCLK1_CMP_SHIFT		24
+
+static void s3c24xx_dclk_update_cmp(struct s3c24xx_dclk *s3c24xx_dclk,
+				    int div_shift, int cmp_shift)
+{
+	unsigned long flags = 0;
+	u32 dclk_con, div, cmp;
+
+	spin_lock_irqsave(&s3c24xx_dclk->dclk_lock, flags);
+
+	dclk_con = readl_relaxed(s3c24xx_dclk->base);
+
+	div = ((dclk_con >> div_shift) & DCLKCON_DCLK_DIV_MASK) + 1;
+	cmp = ((div + 1) / 2) - 1;
+
+	dclk_con &= ~(DCLKCON_DCLK_DIV_MASK << cmp_shift);
+	dclk_con |= (cmp << cmp_shift);
+
+	writel_relaxed(dclk_con, s3c24xx_dclk->base);
+
+	spin_unlock_irqrestore(&s3c24xx_dclk->dclk_lock, flags);
+}
+
+static int s3c24xx_dclk0_div_notify(struct notifier_block *nb,
+			       unsigned long event, void *data)
+{
+	struct s3c24xx_dclk *s3c24xx_dclk = to_s3c24xx_dclk0(nb);
+
+	if (event == POST_RATE_CHANGE) {
+		s3c24xx_dclk_update_cmp(s3c24xx_dclk,
+			DCLKCON_DCLK0_DIV_SHIFT, DCLKCON_DCLK0_CMP_SHIFT);
+	}
+
+	return NOTIFY_DONE;
+}
+
+static int s3c24xx_dclk1_div_notify(struct notifier_block *nb,
+			       unsigned long event, void *data)
+{
+	struct s3c24xx_dclk *s3c24xx_dclk = to_s3c24xx_dclk1(nb);
+
+	if (event == POST_RATE_CHANGE) {
+		s3c24xx_dclk_update_cmp(s3c24xx_dclk,
+			DCLKCON_DCLK1_DIV_SHIFT, DCLKCON_DCLK1_CMP_SHIFT);
+	}
+
+	return NOTIFY_DONE;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int s3c24xx_dclk_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct s3c24xx_dclk *s3c24xx_dclk = platform_get_drvdata(pdev);
+
+	s3c24xx_dclk->reg_save = readl_relaxed(s3c24xx_dclk->base);
+	return 0;
+}
+
+static int s3c24xx_dclk_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct s3c24xx_dclk *s3c24xx_dclk = platform_get_drvdata(pdev);
+
+	writel_relaxed(s3c24xx_dclk->reg_save, s3c24xx_dclk->base);
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(s3c24xx_dclk_pm_ops,
+			 s3c24xx_dclk_suspend, s3c24xx_dclk_resume);
+
+static const struct of_device_id s3c24xx_dclk_dt_match[];
+
+static inline int s3c24xx_dclk_get_driver_data(struct platform_device *pdev)
+{
+	struct s3c24xx_dclk_drv_data *data;
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+		const struct of_device_id *match;
+		match = of_match_node(s3c24xx_dclk_dt_match, pdev->dev.of_node);
+		data = (struct s3c24xx_dclk_drv_data *) match->data;
+		return data->cpu_type;
+	}
+
+	return platform_get_device_id(pdev)->driver_data;
+}
+
+static int s3c24xx_dclk_probe(struct platform_device *pdev)
+{
+	struct s3c24xx_dclk *s3c24xx_dclk;
+	struct device_node *np = pdev->dev.of_node;
+	struct regmap *misccr = NULL;
+	struct resource *mem;
+	struct clk **clk_table;
+	const char **clkout0_parent_names, **clkout1_parent_names;
+	u8 clkout0_num_parents, clkout1_num_parents;
+	int current_soc, ret, i;
+
+	s3c24xx_dclk = devm_kzalloc(&pdev->dev, sizeof(*s3c24xx_dclk),
+				    GFP_KERNEL);
+	if (!s3c24xx_dclk)
+		return -ENOMEM;
+
+	s3c24xx_dclk->dev = &pdev->dev;
+	platform_set_drvdata(pdev, s3c24xx_dclk);
+	spin_lock_init(&s3c24xx_dclk->dclk_lock);
+
+	clk_table = devm_kzalloc(&pdev->dev,
+				 sizeof(struct clk *) * DCLK_MAX_CLKS,
+				 GFP_KERNEL);
+	if (!clk_table)
+		return -ENOMEM;
+
+	s3c24xx_dclk->clk_data.clks = clk_table;
+	s3c24xx_dclk->clk_data.clk_num = DCLK_MAX_CLKS;
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	s3c24xx_dclk->base = devm_ioremap_resource(&pdev->dev, mem);
+	if (IS_ERR(s3c24xx_dclk->base))
+		return PTR_ERR(s3c24xx_dclk->base);
+
+	/* when run from devicetree, get the misccr through a syscon-regmap */
+	if (np) {
+		misccr = syscon_regmap_lookup_by_phandle(np, "samsung,misccr");
+		if (IS_ERR(misccr)) {
+			dev_err(&pdev->dev, "could not get misccr syscon, %ld\n",
+				PTR_ERR(misccr));
+			return PTR_ERR(misccr);
+		}
+	}
+
+	current_soc = s3c24xx_dclk_get_driver_data(pdev);
+
+	if (current_soc == S3C2443) {
+		clk_table[MUX_DCLK0] = clk_register_mux(&pdev->dev,
+					"mux_dclk0", dclk_s3c2443_p,
+					ARRAY_SIZE(dclk_s3c2443_p), 0,
+					s3c24xx_dclk->base, 1, 1, 0,
+					&s3c24xx_dclk->dclk_lock);
+		clk_table[MUX_DCLK1] = clk_register_mux(&pdev->dev,
+					"mux_dclk1", dclk_s3c2443_p,
+					ARRAY_SIZE(dclk_s3c2443_p), 0,
+					s3c24xx_dclk->base, 17, 1, 0,
+					&s3c24xx_dclk->dclk_lock);
+	} else {
+		clk_table[MUX_DCLK0] = clk_register_mux(&pdev->dev,
+					"mux_dclk0", dclk_s3c2410_p,
+					ARRAY_SIZE(dclk_s3c2410_p), 0,
+					s3c24xx_dclk->base, 1, 1, 0,
+					&s3c24xx_dclk->dclk_lock);
+		clk_table[MUX_DCLK1] = clk_register_mux(&pdev->dev,
+					"mux_dclk1", dclk_s3c2410_p,
+					ARRAY_SIZE(dclk_s3c2410_p), 0,
+					s3c24xx_dclk->base, 17, 1, 0,
+					&s3c24xx_dclk->dclk_lock);
+	}
+
+	clk_table[DIV_DCLK0] = clk_register_divider(&pdev->dev, "div_dclk0",
+					"mux_dclk0", 0, s3c24xx_dclk->base,
+					4, 4, 0, &s3c24xx_dclk->dclk_lock);
+	clk_table[DIV_DCLK1] = clk_register_divider(&pdev->dev, "div_dclk1",
+					"mux_dclk1", 0, s3c24xx_dclk->base,
+					20, 4, 0, &s3c24xx_dclk->dclk_lock);
+
+	clk_table[GATE_DCLK0] = clk_register_gate(&pdev->dev, "gate_dclk0",
+					"div_dclk0", CLK_SET_RATE_PARENT,
+					s3c24xx_dclk->base, 0, 0,
+					&s3c24xx_dclk->dclk_lock);
+	clk_table[GATE_DCLK1] = clk_register_gate(&pdev->dev, "gate_dclk1",
+					"div_dclk1", CLK_SET_RATE_PARENT,
+					s3c24xx_dclk->base, 16, 0,
+					&s3c24xx_dclk->dclk_lock);
+
+	switch (current_soc) {
+	case S3C2410:
+		clkout0_parent_names = clkout0_s3c2410_p;
+		clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2410_p);
+		clkout1_parent_names = clkout1_s3c2410_p;
+		clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2410_p);
+		break;
+	case S3C2412:
+		clkout0_parent_names = clkout0_s3c2412_p;
+		clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2412_p);
+		clkout1_parent_names = clkout1_s3c2412_p;
+		clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2412_p);
+		break;
+	case S3C2440:
+		clkout0_parent_names = clkout0_s3c2440_p;
+		clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2440_p);
+		clkout1_parent_names = clkout1_s3c2440_p;
+		clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2440_p);
+		break;
+	case S3C2443:
+		clkout0_parent_names = clkout0_s3c2443_p;
+		clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2443_p);
+		clkout1_parent_names = clkout1_s3c2443_p;
+		clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2443_p);
+		break;
+	default:
+		dev_err(&pdev->dev, "unsupported soc %d\n", current_soc);
+		ret = -EINVAL;
+		goto err_clk_register;
+	}
+
+	clk_table[MUX_CLKOUT0] = s3c24xx_register_clkout(&pdev->dev,
+				"clkout0", clkout0_parent_names,
+				clkout0_num_parents, misccr, 4, 7);
+	clk_table[MUX_CLKOUT1] = s3c24xx_register_clkout(&pdev->dev, "clkout1",
+				clkout1_parent_names,
+				clkout1_num_parents, misccr, 8, 7);
+
+	for (i = 0; i < DCLK_MAX_CLKS; i++)
+		if (IS_ERR(clk_table[i])) {
+			dev_err(&pdev->dev, "clock %d failed to register\n", i);
+			ret = PTR_ERR(clk_table[i]);
+			goto err_clk_register;
+		}
+
+	ret = clk_register_clkdev(clk_table[MUX_DCLK0], "dclk0", NULL);
+	ret |= clk_register_clkdev(clk_table[MUX_DCLK1], "dclk1", NULL);
+	ret |= clk_register_clkdev(clk_table[MUX_CLKOUT0], "clkout0", NULL);
+	ret |= clk_register_clkdev(clk_table[MUX_CLKOUT1], "clkout1", NULL);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register aliases\n");
+		goto err_clk_register;
+	}
+
+	s3c24xx_dclk->dclk0_div_change_nb.notifier_call =
+						s3c24xx_dclk0_div_notify;
+	s3c24xx_dclk->dclk0_div_change_nb.next = NULL;
+
+	s3c24xx_dclk->dclk1_div_change_nb.notifier_call =
+						s3c24xx_dclk1_div_notify;
+	s3c24xx_dclk->dclk1_div_change_nb.next = NULL;
+
+	ret = clk_notifier_register(clk_table[DIV_DCLK0],
+				    &s3c24xx_dclk->dclk0_div_change_nb);
+	if (ret)
+		goto err_clk_register;
+
+	ret = clk_notifier_register(clk_table[DIV_DCLK1],
+				    &s3c24xx_dclk->dclk1_div_change_nb);
+	if (ret)
+		goto err_dclk_notify;
+
+	if (np) {
+		ret = of_clk_add_provider(np,
+			      of_clk_src_onecell_get, &s3c24xx_dclk->clk_data);
+		if (ret)
+			goto err_of_clk_provider;
+	}
+
+	return 0;
+
+err_of_clk_provider:
+	clk_notifier_unregister(clk_table[DIV_DCLK1],
+				&s3c24xx_dclk->dclk1_div_change_nb);
+err_dclk_notify:
+	clk_notifier_unregister(clk_table[DIV_DCLK0],
+				&s3c24xx_dclk->dclk0_div_change_nb);
+err_clk_register:
+	for (i = 0; i < DCLK_MAX_CLKS; i++)
+		if (clk_table[i] && !IS_ERR(clk_table[i]))
+			clk_unregister(clk_table[i]);
+
+	return ret;
+}
+
+static int s3c24xx_dclk_remove(struct platform_device *pdev)
+{
+	struct s3c24xx_dclk *s3c24xx_dclk = platform_get_drvdata(pdev);
+	struct clk **clk_table = s3c24xx_dclk->clk_data.clks;
+	int i;
+
+	of_clk_del_provider(pdev->dev.of_node);
+
+	clk_notifier_unregister(clk_table[DIV_DCLK1],
+				&s3c24xx_dclk->dclk1_div_change_nb);
+	clk_notifier_unregister(clk_table[DIV_DCLK0],
+				&s3c24xx_dclk->dclk0_div_change_nb);
+
+	for (i = 0; i < DCLK_MAX_CLKS; i++)
+		clk_unregister(clk_table[i]);
+
+	return 0;
+}
+
+static struct s3c24xx_dclk_drv_data s3c24xx_dclk_drv_data_array[] = {
+	[S3C2410] = { S3C2410 },
+	[S3C2412] = { S3C2412 },
+	[S3C2440] = { S3C2440 },
+	[S3C2443] = { S3C2443 },
+};
+
+static const struct of_device_id s3c24xx_dclk_dt_match[] = {
+	{
+		.compatible = "samsung,s3c2410-dclk",
+		.data = &s3c24xx_dclk_drv_data_array[S3C2410],
+	}, {
+		.compatible = "samsung,s3c2412-dclk",
+		.data = &s3c24xx_dclk_drv_data_array[S3C2412],
+	}, {
+		.compatible = "samsung,s3c2440-dclk",
+		.data = &s3c24xx_dclk_drv_data_array[S3C2440],
+	}, {
+		.compatible = "samsung,s3c2443-dclk",
+		.data = &s3c24xx_dclk_drv_data_array[S3C2443],
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, s3c24xx_dclk_dt_match);
+
+static struct platform_device_id s3c24xx_dclk_driver_ids[] = {
+	{
+		.name		= "s3c2410-dclk",
+		.driver_data	= S3C2410,
+	}, {
+		.name		= "s3c2412-dclk",
+		.driver_data	= S3C2412,
+	}, {
+		.name		= "s3c2440-dclk",
+		.driver_data	= S3C2440,
+	}, {
+		.name		= "s3c2443-dclk",
+		.driver_data	= S3C2443,
+	},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(platform, s3c24xx_dclk_driver_ids);
+
+static struct platform_driver s3c24xx_dclk_driver = {
+	.driver = {
+		.name		= "s3c24xx-dclk",
+		.owner		= THIS_MODULE,
+		.pm		= &s3c24xx_dclk_pm_ops,
+		.of_match_table	= of_match_ptr(s3c24xx_dclk_dt_match),
+	},
+	.probe = s3c24xx_dclk_probe,
+	.remove = s3c24xx_dclk_remove,
+	.id_table = s3c24xx_dclk_driver_ids,
+};
+module_platform_driver(s3c24xx_dclk_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
+MODULE_DESCRIPTION("Driver for the S3C24XX external clock outputs");
diff --git a/include/dt-bindings/clock/samsung,s3c2410-dclk.h b/include/dt-bindings/clock/samsung,s3c2410-dclk.h
new file mode 100644
index 0000000..7394d46
--- /dev/null
+++ b/include/dt-bindings/clock/samsung,s3c2410-dclk.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
+ *
+ * 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.
+ *
+ * Device Tree binding constants clock controllers of Samsung S3C2410 and later.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C2410_CLOCK_H
+#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C2410_CLOCK_H
+
+#define MUX_DCLK0	0
+#define MUX_DCLK1	1
+
+#define DIV_DCLK0	2
+#define DIV_DCLK1	3
+
+#define GATE_DCLK0	4
+#define GATE_DCLK1	5
+
+#define MUX_CLKOUT0	6
+#define MUX_CLKOUT1	7
+
+#define DCLK_MAX_CLKS	(MUX_CLKOUT1 + 1)
+
+#endif
-- 
1.7.10.4

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

* [PATCH 03/12] clk: samsung: add clock driver for external clock outputs
@ 2013-12-13 12:59   ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 12:59 UTC (permalink / raw)
  To: linux-arm-kernel

This adds a driver for controlling the external clock outputs of
s3c24xx architectures including the dclk muxes and dividers.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 drivers/clk/samsung/Makefile                     |    1 +
 drivers/clk/samsung/clk-s3c2410-dclk.c           |  517 ++++++++++++++++++++++
 include/dt-bindings/clock/samsung,s3c2410-dclk.h |   28 ++
 3 files changed, 546 insertions(+)
 create mode 100644 drivers/clk/samsung/clk-s3c2410-dclk.c
 create mode 100644 include/dt-bindings/clock/samsung,s3c2410-dclk.h

diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 4c892c6..568683c 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -8,5 +8,6 @@ obj-$(CONFIG_SOC_EXYNOS5250)	+= clk-exynos5250.o
 obj-$(CONFIG_SOC_EXYNOS5420)	+= clk-exynos5420.o
 obj-$(CONFIG_SOC_EXYNOS5440)	+= clk-exynos5440.o
 obj-$(CONFIG_ARCH_EXYNOS)	+= clk-exynos-audss.o
+obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
 obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
 obj-$(CONFIG_ARCH_S3C64XX)	+= clk-s3c64xx.o
diff --git a/drivers/clk/samsung/clk-s3c2410-dclk.c b/drivers/clk/samsung/clk-s3c2410-dclk.c
new file mode 100644
index 0000000..de10e5c
--- /dev/null
+++ b/drivers/clk/samsung/clk-s3c2410-dclk.c
@@ -0,0 +1,517 @@
+/*
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Common Clock Framework support for s3c24xx external clock output.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/mfd/syscon.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/of.h>
+#include <dt-bindings/clock/samsung,s3c2410-dclk.h>
+#include "clk.h"
+
+/* legacy access to misccr, until dt conversion is finished */
+#include <mach/hardware.h>
+#include <mach/regs-gpio.h>
+
+enum supported_socs {
+	S3C2410,
+	S3C2412,
+	S3C2440,
+	S3C2443,
+};
+
+struct s3c24xx_dclk_drv_data {
+	int cpu_type;
+};
+
+/*
+ * Clock for output-parent selection in misccr
+ */
+
+struct s3c24xx_clkout {
+	struct clk_hw		hw;
+	struct regmap		*misccr;
+	u32			mask;
+	u8			shift;
+};
+
+#define to_s3c24xx_clkout(_hw) container_of(_hw, struct s3c24xx_clkout, hw)
+
+static u8 s3c24xx_clkout_get_parent(struct clk_hw *hw)
+{
+	struct s3c24xx_clkout *clkout = to_s3c24xx_clkout(hw);
+	int num_parents = __clk_get_num_parents(hw->clk);
+	u32 val;
+	int ret = 0;
+
+	if (clkout->misccr)
+		ret = regmap_read(clkout->misccr, 0, &val);
+	else
+		val = readl_relaxed(S3C24XX_MISCCR) >> clkout->shift;
+
+	if (ret)
+		return ret;
+
+	val >>= clkout->shift;
+	val &= clkout->mask;
+
+	if (val >= num_parents)
+		return -EINVAL;
+
+	return val;
+}
+
+static int s3c24xx_clkout_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct s3c24xx_clkout *clkout = to_s3c24xx_clkout(hw);
+	int ret = 0;
+
+	if (clkout->misccr)
+		ret = regmap_update_bits(clkout->misccr, 0,
+					 (clkout->mask << clkout->shift),
+					 (index << clkout->shift));
+	else
+		s3c2410_modify_misccr((clkout->mask << clkout->shift),
+				      (index << clkout->shift));
+
+	return ret;
+}
+
+const struct clk_ops s3c24xx_clkout_ops = {
+	.get_parent = s3c24xx_clkout_get_parent,
+	.set_parent = s3c24xx_clkout_set_parent,
+	.determine_rate = __clk_mux_determine_rate,
+};
+
+struct clk *s3c24xx_register_clkout(struct device *dev, const char *name,
+		const char **parent_names, u8 num_parents,
+		struct regmap *misccr, u8 shift, u32 mask)
+{
+	struct s3c24xx_clkout *clkout;
+	struct clk *clk;
+	struct clk_init_data init;
+
+	/* allocate the clkout */
+	clkout = kzalloc(sizeof(*clkout), GFP_KERNEL);
+	if (!clkout)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &s3c24xx_clkout_ops;
+	init.flags = CLK_IS_BASIC;
+	init.parent_names = parent_names;
+	init.num_parents = num_parents;
+
+	clkout->misccr = misccr;
+	clkout->shift = shift;
+	clkout->mask = mask;
+	clkout->hw.init = &init;
+
+	clk = clk_register(dev, &clkout->hw);
+
+	return clk;
+}
+
+/*
+ * dclk and clkout init
+ */
+
+struct s3c24xx_dclk {
+	struct device *dev;
+	void __iomem *base;
+	struct clk_onecell_data clk_data;
+	struct notifier_block dclk0_div_change_nb;
+	struct notifier_block dclk1_div_change_nb;
+	spinlock_t dclk_lock;
+	unsigned long reg_save;
+};
+
+#define to_s3c24xx_dclk0(x) \
+		container_of(x, struct s3c24xx_dclk, dclk0_div_change_nb)
+
+#define to_s3c24xx_dclk1(x) \
+		container_of(x, struct s3c24xx_dclk, dclk1_div_change_nb)
+
+static const char dummy_nm[] __initconst = "dummy_name";
+
+PNAME(dclk_s3c2410_p) = { "pclk", "uclk" };
+PNAME(clkout0_s3c2410_p) = { "mpll", "upll", "fclk", "hclk", "pclk",
+			     "gate_dclk0" };
+PNAME(clkout1_s3c2410_p) = { "mpll", "upll", "fclk", "hclk", "pclk",
+			     "gate_dclk1" };
+
+PNAME(clkout0_s3c2412_p) = { "mpll", "upll", dummy_nm /* rtc clock output */,
+			     "hclk", "pclk", "gate_dclk0" };
+PNAME(clkout1_s3c2412_p) = { "xti", "upll", "fclk", "hclk", "pclk",
+			     "gate_dclk1" };
+
+PNAME(clkout0_s3c2440_p) = { "xti", "upll", "fclk", "hclk", "pclk",
+			     "gate_dclk0" };
+PNAME(clkout1_s3c2440_p) = { "mpll", "upll", dummy_nm /* rtc clock output */,
+			     "hclk", "pclk", "gate_dclk1" };
+
+PNAME(dclk_s3c2443_p) = { "pclk", "epll" };
+PNAME(clkout0_s3c2443_p) = { "xti", "epll", "armclk", "hclk", "pclk",
+			     "gate_dclk0" };
+PNAME(clkout1_s3c2443_p) = { dummy_nm, "epll", dummy_nm /* rtc clock output */,
+			     "hclk", "pclk", "gate_dclk1" };
+
+#define DCLKCON_DCLK_DIV_MASK		0xf
+#define DCLKCON_DCLK0_DIV_SHIFT		4
+#define DCLKCON_DCLK0_CMP_SHIFT		8
+#define DCLKCON_DCLK1_DIV_SHIFT		20
+#define DCLKCON_DCLK1_CMP_SHIFT		24
+
+static void s3c24xx_dclk_update_cmp(struct s3c24xx_dclk *s3c24xx_dclk,
+				    int div_shift, int cmp_shift)
+{
+	unsigned long flags = 0;
+	u32 dclk_con, div, cmp;
+
+	spin_lock_irqsave(&s3c24xx_dclk->dclk_lock, flags);
+
+	dclk_con = readl_relaxed(s3c24xx_dclk->base);
+
+	div = ((dclk_con >> div_shift) & DCLKCON_DCLK_DIV_MASK) + 1;
+	cmp = ((div + 1) / 2) - 1;
+
+	dclk_con &= ~(DCLKCON_DCLK_DIV_MASK << cmp_shift);
+	dclk_con |= (cmp << cmp_shift);
+
+	writel_relaxed(dclk_con, s3c24xx_dclk->base);
+
+	spin_unlock_irqrestore(&s3c24xx_dclk->dclk_lock, flags);
+}
+
+static int s3c24xx_dclk0_div_notify(struct notifier_block *nb,
+			       unsigned long event, void *data)
+{
+	struct s3c24xx_dclk *s3c24xx_dclk = to_s3c24xx_dclk0(nb);
+
+	if (event == POST_RATE_CHANGE) {
+		s3c24xx_dclk_update_cmp(s3c24xx_dclk,
+			DCLKCON_DCLK0_DIV_SHIFT, DCLKCON_DCLK0_CMP_SHIFT);
+	}
+
+	return NOTIFY_DONE;
+}
+
+static int s3c24xx_dclk1_div_notify(struct notifier_block *nb,
+			       unsigned long event, void *data)
+{
+	struct s3c24xx_dclk *s3c24xx_dclk = to_s3c24xx_dclk1(nb);
+
+	if (event == POST_RATE_CHANGE) {
+		s3c24xx_dclk_update_cmp(s3c24xx_dclk,
+			DCLKCON_DCLK1_DIV_SHIFT, DCLKCON_DCLK1_CMP_SHIFT);
+	}
+
+	return NOTIFY_DONE;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int s3c24xx_dclk_suspend(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct s3c24xx_dclk *s3c24xx_dclk = platform_get_drvdata(pdev);
+
+	s3c24xx_dclk->reg_save = readl_relaxed(s3c24xx_dclk->base);
+	return 0;
+}
+
+static int s3c24xx_dclk_resume(struct device *dev)
+{
+	struct platform_device *pdev = to_platform_device(dev);
+	struct s3c24xx_dclk *s3c24xx_dclk = platform_get_drvdata(pdev);
+
+	writel_relaxed(s3c24xx_dclk->reg_save, s3c24xx_dclk->base);
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(s3c24xx_dclk_pm_ops,
+			 s3c24xx_dclk_suspend, s3c24xx_dclk_resume);
+
+static const struct of_device_id s3c24xx_dclk_dt_match[];
+
+static inline int s3c24xx_dclk_get_driver_data(struct platform_device *pdev)
+{
+	struct s3c24xx_dclk_drv_data *data;
+	if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
+		const struct of_device_id *match;
+		match = of_match_node(s3c24xx_dclk_dt_match, pdev->dev.of_node);
+		data = (struct s3c24xx_dclk_drv_data *) match->data;
+		return data->cpu_type;
+	}
+
+	return platform_get_device_id(pdev)->driver_data;
+}
+
+static int s3c24xx_dclk_probe(struct platform_device *pdev)
+{
+	struct s3c24xx_dclk *s3c24xx_dclk;
+	struct device_node *np = pdev->dev.of_node;
+	struct regmap *misccr = NULL;
+	struct resource *mem;
+	struct clk **clk_table;
+	const char **clkout0_parent_names, **clkout1_parent_names;
+	u8 clkout0_num_parents, clkout1_num_parents;
+	int current_soc, ret, i;
+
+	s3c24xx_dclk = devm_kzalloc(&pdev->dev, sizeof(*s3c24xx_dclk),
+				    GFP_KERNEL);
+	if (!s3c24xx_dclk)
+		return -ENOMEM;
+
+	s3c24xx_dclk->dev = &pdev->dev;
+	platform_set_drvdata(pdev, s3c24xx_dclk);
+	spin_lock_init(&s3c24xx_dclk->dclk_lock);
+
+	clk_table = devm_kzalloc(&pdev->dev,
+				 sizeof(struct clk *) * DCLK_MAX_CLKS,
+				 GFP_KERNEL);
+	if (!clk_table)
+		return -ENOMEM;
+
+	s3c24xx_dclk->clk_data.clks = clk_table;
+	s3c24xx_dclk->clk_data.clk_num = DCLK_MAX_CLKS;
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	s3c24xx_dclk->base = devm_ioremap_resource(&pdev->dev, mem);
+	if (IS_ERR(s3c24xx_dclk->base))
+		return PTR_ERR(s3c24xx_dclk->base);
+
+	/* when run from devicetree, get the misccr through a syscon-regmap */
+	if (np) {
+		misccr = syscon_regmap_lookup_by_phandle(np, "samsung,misccr");
+		if (IS_ERR(misccr)) {
+			dev_err(&pdev->dev, "could not get misccr syscon, %ld\n",
+				PTR_ERR(misccr));
+			return PTR_ERR(misccr);
+		}
+	}
+
+	current_soc = s3c24xx_dclk_get_driver_data(pdev);
+
+	if (current_soc == S3C2443) {
+		clk_table[MUX_DCLK0] = clk_register_mux(&pdev->dev,
+					"mux_dclk0", dclk_s3c2443_p,
+					ARRAY_SIZE(dclk_s3c2443_p), 0,
+					s3c24xx_dclk->base, 1, 1, 0,
+					&s3c24xx_dclk->dclk_lock);
+		clk_table[MUX_DCLK1] = clk_register_mux(&pdev->dev,
+					"mux_dclk1", dclk_s3c2443_p,
+					ARRAY_SIZE(dclk_s3c2443_p), 0,
+					s3c24xx_dclk->base, 17, 1, 0,
+					&s3c24xx_dclk->dclk_lock);
+	} else {
+		clk_table[MUX_DCLK0] = clk_register_mux(&pdev->dev,
+					"mux_dclk0", dclk_s3c2410_p,
+					ARRAY_SIZE(dclk_s3c2410_p), 0,
+					s3c24xx_dclk->base, 1, 1, 0,
+					&s3c24xx_dclk->dclk_lock);
+		clk_table[MUX_DCLK1] = clk_register_mux(&pdev->dev,
+					"mux_dclk1", dclk_s3c2410_p,
+					ARRAY_SIZE(dclk_s3c2410_p), 0,
+					s3c24xx_dclk->base, 17, 1, 0,
+					&s3c24xx_dclk->dclk_lock);
+	}
+
+	clk_table[DIV_DCLK0] = clk_register_divider(&pdev->dev, "div_dclk0",
+					"mux_dclk0", 0, s3c24xx_dclk->base,
+					4, 4, 0, &s3c24xx_dclk->dclk_lock);
+	clk_table[DIV_DCLK1] = clk_register_divider(&pdev->dev, "div_dclk1",
+					"mux_dclk1", 0, s3c24xx_dclk->base,
+					20, 4, 0, &s3c24xx_dclk->dclk_lock);
+
+	clk_table[GATE_DCLK0] = clk_register_gate(&pdev->dev, "gate_dclk0",
+					"div_dclk0", CLK_SET_RATE_PARENT,
+					s3c24xx_dclk->base, 0, 0,
+					&s3c24xx_dclk->dclk_lock);
+	clk_table[GATE_DCLK1] = clk_register_gate(&pdev->dev, "gate_dclk1",
+					"div_dclk1", CLK_SET_RATE_PARENT,
+					s3c24xx_dclk->base, 16, 0,
+					&s3c24xx_dclk->dclk_lock);
+
+	switch (current_soc) {
+	case S3C2410:
+		clkout0_parent_names = clkout0_s3c2410_p;
+		clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2410_p);
+		clkout1_parent_names = clkout1_s3c2410_p;
+		clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2410_p);
+		break;
+	case S3C2412:
+		clkout0_parent_names = clkout0_s3c2412_p;
+		clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2412_p);
+		clkout1_parent_names = clkout1_s3c2412_p;
+		clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2412_p);
+		break;
+	case S3C2440:
+		clkout0_parent_names = clkout0_s3c2440_p;
+		clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2440_p);
+		clkout1_parent_names = clkout1_s3c2440_p;
+		clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2440_p);
+		break;
+	case S3C2443:
+		clkout0_parent_names = clkout0_s3c2443_p;
+		clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2443_p);
+		clkout1_parent_names = clkout1_s3c2443_p;
+		clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2443_p);
+		break;
+	default:
+		dev_err(&pdev->dev, "unsupported soc %d\n", current_soc);
+		ret = -EINVAL;
+		goto err_clk_register;
+	}
+
+	clk_table[MUX_CLKOUT0] = s3c24xx_register_clkout(&pdev->dev,
+				"clkout0", clkout0_parent_names,
+				clkout0_num_parents, misccr, 4, 7);
+	clk_table[MUX_CLKOUT1] = s3c24xx_register_clkout(&pdev->dev, "clkout1",
+				clkout1_parent_names,
+				clkout1_num_parents, misccr, 8, 7);
+
+	for (i = 0; i < DCLK_MAX_CLKS; i++)
+		if (IS_ERR(clk_table[i])) {
+			dev_err(&pdev->dev, "clock %d failed to register\n", i);
+			ret = PTR_ERR(clk_table[i]);
+			goto err_clk_register;
+		}
+
+	ret = clk_register_clkdev(clk_table[MUX_DCLK0], "dclk0", NULL);
+	ret |= clk_register_clkdev(clk_table[MUX_DCLK1], "dclk1", NULL);
+	ret |= clk_register_clkdev(clk_table[MUX_CLKOUT0], "clkout0", NULL);
+	ret |= clk_register_clkdev(clk_table[MUX_CLKOUT1], "clkout1", NULL);
+	if (ret) {
+		dev_err(&pdev->dev, "failed to register aliases\n");
+		goto err_clk_register;
+	}
+
+	s3c24xx_dclk->dclk0_div_change_nb.notifier_call =
+						s3c24xx_dclk0_div_notify;
+	s3c24xx_dclk->dclk0_div_change_nb.next = NULL;
+
+	s3c24xx_dclk->dclk1_div_change_nb.notifier_call =
+						s3c24xx_dclk1_div_notify;
+	s3c24xx_dclk->dclk1_div_change_nb.next = NULL;
+
+	ret = clk_notifier_register(clk_table[DIV_DCLK0],
+				    &s3c24xx_dclk->dclk0_div_change_nb);
+	if (ret)
+		goto err_clk_register;
+
+	ret = clk_notifier_register(clk_table[DIV_DCLK1],
+				    &s3c24xx_dclk->dclk1_div_change_nb);
+	if (ret)
+		goto err_dclk_notify;
+
+	if (np) {
+		ret = of_clk_add_provider(np,
+			      of_clk_src_onecell_get, &s3c24xx_dclk->clk_data);
+		if (ret)
+			goto err_of_clk_provider;
+	}
+
+	return 0;
+
+err_of_clk_provider:
+	clk_notifier_unregister(clk_table[DIV_DCLK1],
+				&s3c24xx_dclk->dclk1_div_change_nb);
+err_dclk_notify:
+	clk_notifier_unregister(clk_table[DIV_DCLK0],
+				&s3c24xx_dclk->dclk0_div_change_nb);
+err_clk_register:
+	for (i = 0; i < DCLK_MAX_CLKS; i++)
+		if (clk_table[i] && !IS_ERR(clk_table[i]))
+			clk_unregister(clk_table[i]);
+
+	return ret;
+}
+
+static int s3c24xx_dclk_remove(struct platform_device *pdev)
+{
+	struct s3c24xx_dclk *s3c24xx_dclk = platform_get_drvdata(pdev);
+	struct clk **clk_table = s3c24xx_dclk->clk_data.clks;
+	int i;
+
+	of_clk_del_provider(pdev->dev.of_node);
+
+	clk_notifier_unregister(clk_table[DIV_DCLK1],
+				&s3c24xx_dclk->dclk1_div_change_nb);
+	clk_notifier_unregister(clk_table[DIV_DCLK0],
+				&s3c24xx_dclk->dclk0_div_change_nb);
+
+	for (i = 0; i < DCLK_MAX_CLKS; i++)
+		clk_unregister(clk_table[i]);
+
+	return 0;
+}
+
+static struct s3c24xx_dclk_drv_data s3c24xx_dclk_drv_data_array[] = {
+	[S3C2410] = { S3C2410 },
+	[S3C2412] = { S3C2412 },
+	[S3C2440] = { S3C2440 },
+	[S3C2443] = { S3C2443 },
+};
+
+static const struct of_device_id s3c24xx_dclk_dt_match[] = {
+	{
+		.compatible = "samsung,s3c2410-dclk",
+		.data = &s3c24xx_dclk_drv_data_array[S3C2410],
+	}, {
+		.compatible = "samsung,s3c2412-dclk",
+		.data = &s3c24xx_dclk_drv_data_array[S3C2412],
+	}, {
+		.compatible = "samsung,s3c2440-dclk",
+		.data = &s3c24xx_dclk_drv_data_array[S3C2440],
+	}, {
+		.compatible = "samsung,s3c2443-dclk",
+		.data = &s3c24xx_dclk_drv_data_array[S3C2443],
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(of, s3c24xx_dclk_dt_match);
+
+static struct platform_device_id s3c24xx_dclk_driver_ids[] = {
+	{
+		.name		= "s3c2410-dclk",
+		.driver_data	= S3C2410,
+	}, {
+		.name		= "s3c2412-dclk",
+		.driver_data	= S3C2412,
+	}, {
+		.name		= "s3c2440-dclk",
+		.driver_data	= S3C2440,
+	}, {
+		.name		= "s3c2443-dclk",
+		.driver_data	= S3C2443,
+	},
+	{ }
+};
+
+MODULE_DEVICE_TABLE(platform, s3c24xx_dclk_driver_ids);
+
+static struct platform_driver s3c24xx_dclk_driver = {
+	.driver = {
+		.name		= "s3c24xx-dclk",
+		.owner		= THIS_MODULE,
+		.pm		= &s3c24xx_dclk_pm_ops,
+		.of_match_table	= of_match_ptr(s3c24xx_dclk_dt_match),
+	},
+	.probe = s3c24xx_dclk_probe,
+	.remove = s3c24xx_dclk_remove,
+	.id_table = s3c24xx_dclk_driver_ids,
+};
+module_platform_driver(s3c24xx_dclk_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
+MODULE_DESCRIPTION("Driver for the S3C24XX external clock outputs");
diff --git a/include/dt-bindings/clock/samsung,s3c2410-dclk.h b/include/dt-bindings/clock/samsung,s3c2410-dclk.h
new file mode 100644
index 0000000..7394d46
--- /dev/null
+++ b/include/dt-bindings/clock/samsung,s3c2410-dclk.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
+ *
+ * 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.
+ *
+ * Device Tree binding constants clock controllers of Samsung S3C2410 and later.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C2410_CLOCK_H
+#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C2410_CLOCK_H
+
+#define MUX_DCLK0	0
+#define MUX_DCLK1	1
+
+#define DIV_DCLK0	2
+#define DIV_DCLK1	3
+
+#define GATE_DCLK0	4
+#define GATE_DCLK1	5
+
+#define MUX_CLKOUT0	6
+#define MUX_CLKOUT1	7
+
+#define DCLK_MAX_CLKS	(MUX_CLKOUT1 + 1)
+
+#endif
-- 
1.7.10.4

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

* [PATCH 04/12] ARM: S3C24XX: enable usage of common dclk if common clock framework is enabled
  2013-12-13 12:56 ` Heiko Stübner
@ 2013-12-13 13:00   ` Heiko Stübner
  -1 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 13:00 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: t.figa, mturquette, linux-arm-kernel, linux-samsung-soc

Add platform device and select the correct implementation automatically
depending on wether the old samsung_clock or the common clock framework
is enabled.

This is only done for machines already using the old dclk implementation,
as everybody else should move to use dt anyway.

The machine-specific settings for the external clocks will have to be set
by somebody with knowledge about the specific hardware.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/Kconfig       |   22 +++++++++++++++++-----
 arch/arm/mach-s3c24xx/common.c      |   14 ++++++++++++++
 arch/arm/mach-s3c24xx/common.h      |    2 ++
 arch/arm/mach-s3c24xx/mach-anubis.c |    5 +++++
 arch/arm/mach-s3c24xx/mach-bast.c   |    5 +++++
 arch/arm/mach-s3c24xx/mach-osiris.c |    5 +++++
 arch/arm/mach-s3c24xx/mach-rx1950.c |    5 +++++
 arch/arm/mach-s3c24xx/mach-vr1000.c |    5 +++++
 arch/arm/mach-s3c24xx/pm.c          |    6 ++++++
 arch/arm/mach-s3c24xx/s3c244x.c     |    2 ++
 10 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index 397c440..b06a7a3 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -18,6 +18,13 @@ config PLAT_S3C24XX
 	help
 	  Base platform code for any Samsung S3C24XX device
 
+config S3C2410_COMMON_DCLK
+	bool
+	select REGMAP_MMIO
+	help
+	  Temporary symbol to build the dclk driver based on the common clock
+	  framework.
+
 menu "SAMSUNG S3C24XX SoCs Support"
 
 comment "S3C24XX SoCs"
@@ -284,7 +291,8 @@ config ARCH_BAST
 	select ISA
 	select MACH_BAST_IDE
 	select S3C2410_IOTIMING if ARM_S3C2410_CPUFREQ
-	select S3C24XX_DCLK
+	select S3C24XX_DCLK if SAMSUNG_CLOCK
+	select S3C2410_COMMON_DCLK if COMMON_CLK
 	select S3C24XX_SIMTEC_NOR
 	select S3C24XX_SIMTEC_PM if PM
 	select S3C24XX_SIMTEC_USB
@@ -365,7 +373,8 @@ config MACH_TCT_HAMMER
 config MACH_VR1000
 	bool "Thorcom VR1000"
 	select MACH_BAST_IDE
-	select S3C24XX_DCLK
+	select S3C24XX_DCLK if SAMSUNG_CLOCK
+	select S3C2410_COMMON_DCLK if COMMON_CLK
 	select S3C24XX_SIMTEC_NOR
 	select S3C24XX_SIMTEC_PM if PM
 	select S3C24XX_SIMTEC_USB
@@ -545,7 +554,8 @@ config MACH_ANUBIS
 	bool "Simtec Electronics ANUBIS"
 	select HAVE_PATA_PLATFORM
 	select S3C2440_XTAL_12000000
-	select S3C24XX_DCLK
+	select S3C24XX_DCLK if SAMSUNG_CLOCK
+	select S3C2410_COMMON_DCLK if COMMON_CLK
 	select S3C24XX_GPIO_EXTRA64
 	select S3C24XX_SIMTEC_PM if PM
 	select S3C_DEV_USB_HOST
@@ -586,7 +596,8 @@ config MACH_OSIRIS
 	bool "Simtec IM2440D20 (OSIRIS) module"
 	select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
 	select S3C2440_XTAL_12000000
-	select S3C24XX_DCLK
+	select S3C24XX_DCLK if SAMSUNG_CLOCK
+	select S3C2410_COMMON_DCLK if COMMON_CLK
 	select S3C24XX_GPIO_EXTRA128
 	select S3C24XX_SIMTEC_PM if PM
 	select S3C_DEV_NAND
@@ -658,7 +669,8 @@ config MACH_RX1950
 	select PM_H1940 if PM
 	select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
 	select S3C2440_XTAL_16934400
-	select S3C24XX_DCLK
+	select S3C24XX_DCLK if SAMSUNG_CLOCK
+	select S3C24XX_COMMON_DCLK if COMMON_CLK
 	select S3C24XX_PWM
 	select S3C_DEV_NAND
 	help
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index 015e6c0..051ed5e 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -549,3 +549,17 @@ void __init s3c2443_init_clocks(int xtal)
 	s3c2443_common_clk_init(NULL, xtal, 1, S3C24XX_VA_CLKPWR);
 }
 #endif
+
+#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2440) || \
+	defined(CONFIG_CPU_S3C2442)
+static struct resource s3c2410_dclk_resource[] = {
+	[0] = DEFINE_RES_MEM(0x56000084, 0x4),
+};
+
+struct platform_device s3c2410_device_dclk = {
+	.name		= "s3c2410-dclk",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(s3c2410_dclk_resource),
+	.resource	= s3c2410_dclk_resource,
+};
+#endif
diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h
index d7323f1..e16b601 100644
--- a/arch/arm/mach-s3c24xx/common.h
+++ b/arch/arm/mach-s3c24xx/common.h
@@ -114,6 +114,8 @@ extern struct platform_device s3c2412_device_dma;
 extern struct platform_device s3c2440_device_dma;
 extern struct platform_device s3c2443_device_dma;
 
+extern struct platform_device s3c2410_device_dclk;
+
 #ifdef CONFIG_S3C2443_COMMON_CLK
 void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
 				    int current_soc,
diff --git a/arch/arm/mach-s3c24xx/mach-anubis.c b/arch/arm/mach-s3c24xx/mach-anubis.c
index c1fb6c3..a7d1721a 100644
--- a/arch/arm/mach-s3c24xx/mach-anubis.c
+++ b/arch/arm/mach-s3c24xx/mach-anubis.c
@@ -351,6 +351,7 @@ static struct platform_device anubis_device_sm501 = {
 /* Standard Anubis devices */
 
 static struct platform_device *anubis_devices[] __initdata = {
+	&s3c2410_device_dclk,
 	&s3c_device_ohci,
 	&s3c_device_wdt,
 	&s3c_device_adc,
@@ -363,6 +364,7 @@ static struct platform_device *anubis_devices[] __initdata = {
 	&anubis_device_sm501,
 };
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 static struct clk *anubis_clocks[] __initdata = {
 	&s3c24xx_dclk0,
 	&s3c24xx_dclk1,
@@ -370,6 +372,7 @@ static struct clk *anubis_clocks[] __initdata = {
 	&s3c24xx_clkout1,
 	&s3c24xx_uclk,
 };
+#endif
 
 /* I2C devices. */
 
@@ -393,6 +396,7 @@ static struct s3c24xx_audio_simtec_pdata __initdata anubis_audio = {
 
 static void __init anubis_map_io(void)
 {
+#ifdef CONFIG_SAMSUNG_CLOCK
 	/* initialise the clocks */
 
 	s3c24xx_dclk0.parent = &clk_upll;
@@ -407,6 +411,7 @@ static void __init anubis_map_io(void)
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
 	s3c24xx_register_clocks(anubis_clocks, ARRAY_SIZE(anubis_clocks));
+#endif
 
 	s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
 	s3c24xx_init_clocks(0);
diff --git a/arch/arm/mach-s3c24xx/mach-bast.c b/arch/arm/mach-s3c24xx/mach-bast.c
index 22d6ae9..d5d67c5 100644
--- a/arch/arm/mach-s3c24xx/mach-bast.c
+++ b/arch/arm/mach-s3c24xx/mach-bast.c
@@ -522,6 +522,7 @@ static struct s3c_hwmon_pdata bast_hwmon_info = {
 // cat /sys/devices/platform/s3c24xx-adc/s3c-hwmon/in_0
 
 static struct platform_device *bast_devices[] __initdata = {
+	&s3c2410_device_dclk,
 	&s3c_device_ohci,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
@@ -536,6 +537,7 @@ static struct platform_device *bast_devices[] __initdata = {
 	&bast_sio,
 };
 
+#ifdef CONFIG_SAMSUNG_CLK
 static struct clk *bast_clocks[] __initdata = {
 	&s3c24xx_dclk0,
 	&s3c24xx_dclk1,
@@ -543,6 +545,7 @@ static struct clk *bast_clocks[] __initdata = {
 	&s3c24xx_clkout1,
 	&s3c24xx_uclk,
 };
+#endif
 
 static struct s3c_cpufreq_board __initdata bast_cpufreq = {
 	.refresh	= 7800, /* 7.8usec */
@@ -557,6 +560,7 @@ static struct s3c24xx_audio_simtec_pdata __initdata bast_audio = {
 
 static void __init bast_map_io(void)
 {
+#ifdef CONFIG_SAMSUNG_CLOCK
 	/* initialise the clocks */
 
 	s3c24xx_dclk0.parent = &clk_upll;
@@ -571,6 +575,7 @@ static void __init bast_map_io(void)
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
 	s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks));
+#endif
 
 	s3c_hwmon_set_platdata(&bast_hwmon_info);
 
diff --git a/arch/arm/mach-s3c24xx/mach-osiris.c b/arch/arm/mach-s3c24xx/mach-osiris.c
index 58d6fbe..d55d88d 100644
--- a/arch/arm/mach-s3c24xx/mach-osiris.c
+++ b/arch/arm/mach-s3c24xx/mach-osiris.c
@@ -343,12 +343,14 @@ static struct i2c_board_info osiris_i2c_devs[] __initdata = {
 /* Standard Osiris devices */
 
 static struct platform_device *osiris_devices[] __initdata = {
+	&s3c2410_device_dclk,
 	&s3c_device_i2c0,
 	&s3c_device_wdt,
 	&s3c_device_nand,
 	&osiris_pcmcia,
 };
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 static struct clk *osiris_clocks[] __initdata = {
 	&s3c24xx_dclk0,
 	&s3c24xx_dclk1,
@@ -356,6 +358,7 @@ static struct clk *osiris_clocks[] __initdata = {
 	&s3c24xx_clkout1,
 	&s3c24xx_uclk,
 };
+#endif
 
 static struct s3c_cpufreq_board __initdata osiris_cpufreq = {
 	.refresh	= 7800, /* refresh period is 7.8usec */
@@ -367,6 +370,7 @@ static void __init osiris_map_io(void)
 {
 	unsigned long flags;
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 	/* initialise the clocks */
 
 	s3c24xx_dclk0.parent = &clk_upll;
@@ -381,6 +385,7 @@ static void __init osiris_map_io(void)
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
 	s3c24xx_register_clocks(osiris_clocks, ARRAY_SIZE(osiris_clocks));
+#endif
 
 	s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
 	s3c24xx_init_clocks(0);
diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c
index 034b7fe..a0f12d1 100644
--- a/arch/arm/mach-s3c24xx/mach-rx1950.c
+++ b/arch/arm/mach-s3c24xx/mach-rx1950.c
@@ -708,6 +708,7 @@ static struct i2c_board_info rx1950_i2c_devices[] = {
 };
 
 static struct platform_device *rx1950_devices[] __initdata = {
+	&s3c2410_device_dclk,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
@@ -726,17 +727,21 @@ static struct platform_device *rx1950_devices[] __initdata = {
 	&rx1950_leds,
 };
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 static struct clk *rx1950_clocks[] __initdata = {
 	&s3c24xx_clkout0,
 	&s3c24xx_clkout1,
 };
+#endif
 
 static void __init rx1950_map_io(void)
 {
+#ifdef CONFIG_SAMSUNG_CLOCK
 	s3c24xx_clkout0.parent  = &clk_h;
 	s3c24xx_clkout1.parent  = &clk_f;
 
 	s3c24xx_register_clocks(rx1950_clocks, ARRAY_SIZE(rx1950_clocks));
+#endif
 
 	s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc));
 	s3c24xx_init_clocks(16934000);
diff --git a/arch/arm/mach-s3c24xx/mach-vr1000.c b/arch/arm/mach-s3c24xx/mach-vr1000.c
index 42e7187..8221988 100644
--- a/arch/arm/mach-s3c24xx/mach-vr1000.c
+++ b/arch/arm/mach-s3c24xx/mach-vr1000.c
@@ -285,6 +285,7 @@ static struct i2c_board_info vr1000_i2c_devs[] __initdata = {
 /* devices for this board */
 
 static struct platform_device *vr1000_devices[] __initdata = {
+	&s3c2410_device_dclk,
 	&s3c_device_ohci,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
@@ -298,6 +299,7 @@ static struct platform_device *vr1000_devices[] __initdata = {
 	&vr1000_led3,
 };
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 static struct clk *vr1000_clocks[] __initdata = {
 	&s3c24xx_dclk0,
 	&s3c24xx_dclk1,
@@ -305,6 +307,7 @@ static struct clk *vr1000_clocks[] __initdata = {
 	&s3c24xx_clkout1,
 	&s3c24xx_uclk,
 };
+#endif
 
 static void vr1000_power_off(void)
 {
@@ -313,6 +316,7 @@ static void vr1000_power_off(void)
 
 static void __init vr1000_map_io(void)
 {
+#if CONFIG_SAMSUNG_CLOCK
 	/* initialise clock sources */
 
 	s3c24xx_dclk0.parent = &clk_upll;
@@ -327,6 +331,7 @@ static void __init vr1000_map_io(void)
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
 	s3c24xx_register_clocks(vr1000_clocks, ARRAY_SIZE(vr1000_clocks));
+#endif
 
 	pm_power_off = vr1000_power_off;
 
diff --git a/arch/arm/mach-s3c24xx/pm.c b/arch/arm/mach-s3c24xx/pm.c
index caa5b72..75181db 100644
--- a/arch/arm/mach-s3c24xx/pm.c
+++ b/arch/arm/mach-s3c24xx/pm.c
@@ -78,9 +78,11 @@ static struct sleep_save core_save[] = {
 	SAVE_ITEM(S3C2410_CLKSLOW),
 };
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 static struct sleep_save misc_save[] = {
 	SAVE_ITEM(S3C2410_DCLKCON),
 };
+#endif
 
 /* s3c_pm_check_resume_pin
  *
@@ -139,12 +141,16 @@ void s3c_pm_configure_extint(void)
 void s3c_pm_restore_core(void)
 {
 	s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
+#ifdef CONFIG_SAMSUNG_CLOCK
 	s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
+#endif
 }
 
 void s3c_pm_save_core(void)
 {
+#ifdef CONFIG_SAMSUNG_CLOCK
 	s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
+#endif
 	s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
 }
 
diff --git a/arch/arm/mach-s3c24xx/s3c244x.c b/arch/arm/mach-s3c24xx/s3c244x.c
index 911b555..0ce2538 100644
--- a/arch/arm/mach-s3c24xx/s3c244x.c
+++ b/arch/arm/mach-s3c24xx/s3c244x.c
@@ -46,6 +46,7 @@
 #include <plat/nand-core.h>
 #include <plat/watchdog-reset.h>
 
+#include "common.h"
 #include "regs-dsc.h"
 
 static struct map_desc s3c244x_iodesc[] __initdata = {
@@ -74,6 +75,7 @@ void __init s3c244x_map_io(void)
 	s3c_nand_setname("s3c2440-nand");
 	s3c_device_ts.name = "s3c2440-ts";
 	s3c_device_usbgadget.name = "s3c2440-usbgadget";
+	s3c2410_device_dclk.name = "s3c2440-dclk";
 }
 
 void __init_or_cpufreq s3c244x_setup_clocks(void)
-- 
1.7.10.4

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

* [PATCH 04/12] ARM: S3C24XX: enable usage of common dclk if common clock framework is enabled
@ 2013-12-13 13:00   ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 13:00 UTC (permalink / raw)
  To: linux-arm-kernel

Add platform device and select the correct implementation automatically
depending on wether the old samsung_clock or the common clock framework
is enabled.

This is only done for machines already using the old dclk implementation,
as everybody else should move to use dt anyway.

The machine-specific settings for the external clocks will have to be set
by somebody with knowledge about the specific hardware.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/Kconfig       |   22 +++++++++++++++++-----
 arch/arm/mach-s3c24xx/common.c      |   14 ++++++++++++++
 arch/arm/mach-s3c24xx/common.h      |    2 ++
 arch/arm/mach-s3c24xx/mach-anubis.c |    5 +++++
 arch/arm/mach-s3c24xx/mach-bast.c   |    5 +++++
 arch/arm/mach-s3c24xx/mach-osiris.c |    5 +++++
 arch/arm/mach-s3c24xx/mach-rx1950.c |    5 +++++
 arch/arm/mach-s3c24xx/mach-vr1000.c |    5 +++++
 arch/arm/mach-s3c24xx/pm.c          |    6 ++++++
 arch/arm/mach-s3c24xx/s3c244x.c     |    2 ++
 10 files changed, 66 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index 397c440..b06a7a3 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -18,6 +18,13 @@ config PLAT_S3C24XX
 	help
 	  Base platform code for any Samsung S3C24XX device
 
+config S3C2410_COMMON_DCLK
+	bool
+	select REGMAP_MMIO
+	help
+	  Temporary symbol to build the dclk driver based on the common clock
+	  framework.
+
 menu "SAMSUNG S3C24XX SoCs Support"
 
 comment "S3C24XX SoCs"
@@ -284,7 +291,8 @@ config ARCH_BAST
 	select ISA
 	select MACH_BAST_IDE
 	select S3C2410_IOTIMING if ARM_S3C2410_CPUFREQ
-	select S3C24XX_DCLK
+	select S3C24XX_DCLK if SAMSUNG_CLOCK
+	select S3C2410_COMMON_DCLK if COMMON_CLK
 	select S3C24XX_SIMTEC_NOR
 	select S3C24XX_SIMTEC_PM if PM
 	select S3C24XX_SIMTEC_USB
@@ -365,7 +373,8 @@ config MACH_TCT_HAMMER
 config MACH_VR1000
 	bool "Thorcom VR1000"
 	select MACH_BAST_IDE
-	select S3C24XX_DCLK
+	select S3C24XX_DCLK if SAMSUNG_CLOCK
+	select S3C2410_COMMON_DCLK if COMMON_CLK
 	select S3C24XX_SIMTEC_NOR
 	select S3C24XX_SIMTEC_PM if PM
 	select S3C24XX_SIMTEC_USB
@@ -545,7 +554,8 @@ config MACH_ANUBIS
 	bool "Simtec Electronics ANUBIS"
 	select HAVE_PATA_PLATFORM
 	select S3C2440_XTAL_12000000
-	select S3C24XX_DCLK
+	select S3C24XX_DCLK if SAMSUNG_CLOCK
+	select S3C2410_COMMON_DCLK if COMMON_CLK
 	select S3C24XX_GPIO_EXTRA64
 	select S3C24XX_SIMTEC_PM if PM
 	select S3C_DEV_USB_HOST
@@ -586,7 +596,8 @@ config MACH_OSIRIS
 	bool "Simtec IM2440D20 (OSIRIS) module"
 	select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
 	select S3C2440_XTAL_12000000
-	select S3C24XX_DCLK
+	select S3C24XX_DCLK if SAMSUNG_CLOCK
+	select S3C2410_COMMON_DCLK if COMMON_CLK
 	select S3C24XX_GPIO_EXTRA128
 	select S3C24XX_SIMTEC_PM if PM
 	select S3C_DEV_NAND
@@ -658,7 +669,8 @@ config MACH_RX1950
 	select PM_H1940 if PM
 	select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
 	select S3C2440_XTAL_16934400
-	select S3C24XX_DCLK
+	select S3C24XX_DCLK if SAMSUNG_CLOCK
+	select S3C24XX_COMMON_DCLK if COMMON_CLK
 	select S3C24XX_PWM
 	select S3C_DEV_NAND
 	help
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index 015e6c0..051ed5e 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -549,3 +549,17 @@ void __init s3c2443_init_clocks(int xtal)
 	s3c2443_common_clk_init(NULL, xtal, 1, S3C24XX_VA_CLKPWR);
 }
 #endif
+
+#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2440) || \
+	defined(CONFIG_CPU_S3C2442)
+static struct resource s3c2410_dclk_resource[] = {
+	[0] = DEFINE_RES_MEM(0x56000084, 0x4),
+};
+
+struct platform_device s3c2410_device_dclk = {
+	.name		= "s3c2410-dclk",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(s3c2410_dclk_resource),
+	.resource	= s3c2410_dclk_resource,
+};
+#endif
diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h
index d7323f1..e16b601 100644
--- a/arch/arm/mach-s3c24xx/common.h
+++ b/arch/arm/mach-s3c24xx/common.h
@@ -114,6 +114,8 @@ extern struct platform_device s3c2412_device_dma;
 extern struct platform_device s3c2440_device_dma;
 extern struct platform_device s3c2443_device_dma;
 
+extern struct platform_device s3c2410_device_dclk;
+
 #ifdef CONFIG_S3C2443_COMMON_CLK
 void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
 				    int current_soc,
diff --git a/arch/arm/mach-s3c24xx/mach-anubis.c b/arch/arm/mach-s3c24xx/mach-anubis.c
index c1fb6c3..a7d1721a 100644
--- a/arch/arm/mach-s3c24xx/mach-anubis.c
+++ b/arch/arm/mach-s3c24xx/mach-anubis.c
@@ -351,6 +351,7 @@ static struct platform_device anubis_device_sm501 = {
 /* Standard Anubis devices */
 
 static struct platform_device *anubis_devices[] __initdata = {
+	&s3c2410_device_dclk,
 	&s3c_device_ohci,
 	&s3c_device_wdt,
 	&s3c_device_adc,
@@ -363,6 +364,7 @@ static struct platform_device *anubis_devices[] __initdata = {
 	&anubis_device_sm501,
 };
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 static struct clk *anubis_clocks[] __initdata = {
 	&s3c24xx_dclk0,
 	&s3c24xx_dclk1,
@@ -370,6 +372,7 @@ static struct clk *anubis_clocks[] __initdata = {
 	&s3c24xx_clkout1,
 	&s3c24xx_uclk,
 };
+#endif
 
 /* I2C devices. */
 
@@ -393,6 +396,7 @@ static struct s3c24xx_audio_simtec_pdata __initdata anubis_audio = {
 
 static void __init anubis_map_io(void)
 {
+#ifdef CONFIG_SAMSUNG_CLOCK
 	/* initialise the clocks */
 
 	s3c24xx_dclk0.parent = &clk_upll;
@@ -407,6 +411,7 @@ static void __init anubis_map_io(void)
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
 	s3c24xx_register_clocks(anubis_clocks, ARRAY_SIZE(anubis_clocks));
+#endif
 
 	s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
 	s3c24xx_init_clocks(0);
diff --git a/arch/arm/mach-s3c24xx/mach-bast.c b/arch/arm/mach-s3c24xx/mach-bast.c
index 22d6ae9..d5d67c5 100644
--- a/arch/arm/mach-s3c24xx/mach-bast.c
+++ b/arch/arm/mach-s3c24xx/mach-bast.c
@@ -522,6 +522,7 @@ static struct s3c_hwmon_pdata bast_hwmon_info = {
 // cat /sys/devices/platform/s3c24xx-adc/s3c-hwmon/in_0
 
 static struct platform_device *bast_devices[] __initdata = {
+	&s3c2410_device_dclk,
 	&s3c_device_ohci,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
@@ -536,6 +537,7 @@ static struct platform_device *bast_devices[] __initdata = {
 	&bast_sio,
 };
 
+#ifdef CONFIG_SAMSUNG_CLK
 static struct clk *bast_clocks[] __initdata = {
 	&s3c24xx_dclk0,
 	&s3c24xx_dclk1,
@@ -543,6 +545,7 @@ static struct clk *bast_clocks[] __initdata = {
 	&s3c24xx_clkout1,
 	&s3c24xx_uclk,
 };
+#endif
 
 static struct s3c_cpufreq_board __initdata bast_cpufreq = {
 	.refresh	= 7800, /* 7.8usec */
@@ -557,6 +560,7 @@ static struct s3c24xx_audio_simtec_pdata __initdata bast_audio = {
 
 static void __init bast_map_io(void)
 {
+#ifdef CONFIG_SAMSUNG_CLOCK
 	/* initialise the clocks */
 
 	s3c24xx_dclk0.parent = &clk_upll;
@@ -571,6 +575,7 @@ static void __init bast_map_io(void)
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
 	s3c24xx_register_clocks(bast_clocks, ARRAY_SIZE(bast_clocks));
+#endif
 
 	s3c_hwmon_set_platdata(&bast_hwmon_info);
 
diff --git a/arch/arm/mach-s3c24xx/mach-osiris.c b/arch/arm/mach-s3c24xx/mach-osiris.c
index 58d6fbe..d55d88d 100644
--- a/arch/arm/mach-s3c24xx/mach-osiris.c
+++ b/arch/arm/mach-s3c24xx/mach-osiris.c
@@ -343,12 +343,14 @@ static struct i2c_board_info osiris_i2c_devs[] __initdata = {
 /* Standard Osiris devices */
 
 static struct platform_device *osiris_devices[] __initdata = {
+	&s3c2410_device_dclk,
 	&s3c_device_i2c0,
 	&s3c_device_wdt,
 	&s3c_device_nand,
 	&osiris_pcmcia,
 };
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 static struct clk *osiris_clocks[] __initdata = {
 	&s3c24xx_dclk0,
 	&s3c24xx_dclk1,
@@ -356,6 +358,7 @@ static struct clk *osiris_clocks[] __initdata = {
 	&s3c24xx_clkout1,
 	&s3c24xx_uclk,
 };
+#endif
 
 static struct s3c_cpufreq_board __initdata osiris_cpufreq = {
 	.refresh	= 7800, /* refresh period is 7.8usec */
@@ -367,6 +370,7 @@ static void __init osiris_map_io(void)
 {
 	unsigned long flags;
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 	/* initialise the clocks */
 
 	s3c24xx_dclk0.parent = &clk_upll;
@@ -381,6 +385,7 @@ static void __init osiris_map_io(void)
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
 	s3c24xx_register_clocks(osiris_clocks, ARRAY_SIZE(osiris_clocks));
+#endif
 
 	s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
 	s3c24xx_init_clocks(0);
diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c
index 034b7fe..a0f12d1 100644
--- a/arch/arm/mach-s3c24xx/mach-rx1950.c
+++ b/arch/arm/mach-s3c24xx/mach-rx1950.c
@@ -708,6 +708,7 @@ static struct i2c_board_info rx1950_i2c_devices[] = {
 };
 
 static struct platform_device *rx1950_devices[] __initdata = {
+	&s3c2410_device_dclk,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
 	&s3c_device_i2c0,
@@ -726,17 +727,21 @@ static struct platform_device *rx1950_devices[] __initdata = {
 	&rx1950_leds,
 };
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 static struct clk *rx1950_clocks[] __initdata = {
 	&s3c24xx_clkout0,
 	&s3c24xx_clkout1,
 };
+#endif
 
 static void __init rx1950_map_io(void)
 {
+#ifdef CONFIG_SAMSUNG_CLOCK
 	s3c24xx_clkout0.parent  = &clk_h;
 	s3c24xx_clkout1.parent  = &clk_f;
 
 	s3c24xx_register_clocks(rx1950_clocks, ARRAY_SIZE(rx1950_clocks));
+#endif
 
 	s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc));
 	s3c24xx_init_clocks(16934000);
diff --git a/arch/arm/mach-s3c24xx/mach-vr1000.c b/arch/arm/mach-s3c24xx/mach-vr1000.c
index 42e7187..8221988 100644
--- a/arch/arm/mach-s3c24xx/mach-vr1000.c
+++ b/arch/arm/mach-s3c24xx/mach-vr1000.c
@@ -285,6 +285,7 @@ static struct i2c_board_info vr1000_i2c_devs[] __initdata = {
 /* devices for this board */
 
 static struct platform_device *vr1000_devices[] __initdata = {
+	&s3c2410_device_dclk,
 	&s3c_device_ohci,
 	&s3c_device_lcd,
 	&s3c_device_wdt,
@@ -298,6 +299,7 @@ static struct platform_device *vr1000_devices[] __initdata = {
 	&vr1000_led3,
 };
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 static struct clk *vr1000_clocks[] __initdata = {
 	&s3c24xx_dclk0,
 	&s3c24xx_dclk1,
@@ -305,6 +307,7 @@ static struct clk *vr1000_clocks[] __initdata = {
 	&s3c24xx_clkout1,
 	&s3c24xx_uclk,
 };
+#endif
 
 static void vr1000_power_off(void)
 {
@@ -313,6 +316,7 @@ static void vr1000_power_off(void)
 
 static void __init vr1000_map_io(void)
 {
+#if CONFIG_SAMSUNG_CLOCK
 	/* initialise clock sources */
 
 	s3c24xx_dclk0.parent = &clk_upll;
@@ -327,6 +331,7 @@ static void __init vr1000_map_io(void)
 	s3c24xx_uclk.parent  = &s3c24xx_clkout1;
 
 	s3c24xx_register_clocks(vr1000_clocks, ARRAY_SIZE(vr1000_clocks));
+#endif
 
 	pm_power_off = vr1000_power_off;
 
diff --git a/arch/arm/mach-s3c24xx/pm.c b/arch/arm/mach-s3c24xx/pm.c
index caa5b72..75181db 100644
--- a/arch/arm/mach-s3c24xx/pm.c
+++ b/arch/arm/mach-s3c24xx/pm.c
@@ -78,9 +78,11 @@ static struct sleep_save core_save[] = {
 	SAVE_ITEM(S3C2410_CLKSLOW),
 };
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 static struct sleep_save misc_save[] = {
 	SAVE_ITEM(S3C2410_DCLKCON),
 };
+#endif
 
 /* s3c_pm_check_resume_pin
  *
@@ -139,12 +141,16 @@ void s3c_pm_configure_extint(void)
 void s3c_pm_restore_core(void)
 {
 	s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
+#ifdef CONFIG_SAMSUNG_CLOCK
 	s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
+#endif
 }
 
 void s3c_pm_save_core(void)
 {
+#ifdef CONFIG_SAMSUNG_CLOCK
 	s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
+#endif
 	s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
 }
 
diff --git a/arch/arm/mach-s3c24xx/s3c244x.c b/arch/arm/mach-s3c24xx/s3c244x.c
index 911b555..0ce2538 100644
--- a/arch/arm/mach-s3c24xx/s3c244x.c
+++ b/arch/arm/mach-s3c24xx/s3c244x.c
@@ -46,6 +46,7 @@
 #include <plat/nand-core.h>
 #include <plat/watchdog-reset.h>
 
+#include "common.h"
 #include "regs-dsc.h"
 
 static struct map_desc s3c244x_iodesc[] __initdata = {
@@ -74,6 +75,7 @@ void __init s3c244x_map_io(void)
 	s3c_nand_setname("s3c2440-nand");
 	s3c_device_ts.name = "s3c2440-ts";
 	s3c_device_usbgadget.name = "s3c2440-usbgadget";
+	s3c2410_device_dclk.name = "s3c2440-dclk";
 }
 
 void __init_or_cpufreq s3c244x_setup_clocks(void)
-- 
1.7.10.4

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

* [PATCH 05/12] ARM: S3C24XX: only store clock registers when old clock code is active
  2013-12-13 12:56 ` Heiko Stübner
@ 2013-12-13 13:00   ` Heiko Stübner
  -1 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 13:00 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: t.figa, mturquette, linux-arm-kernel, linux-samsung-soc

The Samsung ccf driver already handles the save and restore of the clock
registers on suspend and resume. The architecture code should not
duplicate this when the ccf is active.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/pm.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/pm.c b/arch/arm/mach-s3c24xx/pm.c
index 75181db..9cc6fc1 100644
--- a/arch/arm/mach-s3c24xx/pm.c
+++ b/arch/arm/mach-s3c24xx/pm.c
@@ -50,9 +50,6 @@
 #define PFX "s3c24xx-pm: "
 
 static struct sleep_save core_save[] = {
-	SAVE_ITEM(S3C2410_LOCKTIME),
-	SAVE_ITEM(S3C2410_CLKCON),
-
 	/* we restore the timings here, with the proviso that the board
 	 * brings the system up in an slower, or equal frequency setting
 	 * to the original system.
@@ -69,6 +66,9 @@ static struct sleep_save core_save[] = {
 	SAVE_ITEM(S3C2410_BANKCON4),
 	SAVE_ITEM(S3C2410_BANKCON5),
 
+#ifdef CONFIG_SAMSUNG_CLOCK
+	SAVE_ITEM(S3C2410_LOCKTIME),
+	SAVE_ITEM(S3C2410_CLKCON),
 #ifndef CONFIG_CPU_FREQ
 	SAVE_ITEM(S3C2410_CLKDIVN),
 	SAVE_ITEM(S3C2410_MPLLCON),
@@ -76,6 +76,7 @@ static struct sleep_save core_save[] = {
 #endif
 	SAVE_ITEM(S3C2410_UPLLCON),
 	SAVE_ITEM(S3C2410_CLKSLOW),
+#endif /* CONFIG_SAMSUNG_CLOCK */
 };
 
 #ifdef CONFIG_SAMSUNG_CLOCK
-- 
1.7.10.4

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

* [PATCH 05/12] ARM: S3C24XX: only store clock registers when old clock code is active
@ 2013-12-13 13:00   ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 13:00 UTC (permalink / raw)
  To: linux-arm-kernel

The Samsung ccf driver already handles the save and restore of the clock
registers on suspend and resume. The architecture code should not
duplicate this when the ccf is active.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/pm.c |    7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/pm.c b/arch/arm/mach-s3c24xx/pm.c
index 75181db..9cc6fc1 100644
--- a/arch/arm/mach-s3c24xx/pm.c
+++ b/arch/arm/mach-s3c24xx/pm.c
@@ -50,9 +50,6 @@
 #define PFX "s3c24xx-pm: "
 
 static struct sleep_save core_save[] = {
-	SAVE_ITEM(S3C2410_LOCKTIME),
-	SAVE_ITEM(S3C2410_CLKCON),
-
 	/* we restore the timings here, with the proviso that the board
 	 * brings the system up in an slower, or equal frequency setting
 	 * to the original system.
@@ -69,6 +66,9 @@ static struct sleep_save core_save[] = {
 	SAVE_ITEM(S3C2410_BANKCON4),
 	SAVE_ITEM(S3C2410_BANKCON5),
 
+#ifdef CONFIG_SAMSUNG_CLOCK
+	SAVE_ITEM(S3C2410_LOCKTIME),
+	SAVE_ITEM(S3C2410_CLKCON),
 #ifndef CONFIG_CPU_FREQ
 	SAVE_ITEM(S3C2410_CLKDIVN),
 	SAVE_ITEM(S3C2410_MPLLCON),
@@ -76,6 +76,7 @@ static struct sleep_save core_save[] = {
 #endif
 	SAVE_ITEM(S3C2410_UPLLCON),
 	SAVE_ITEM(S3C2410_CLKSLOW),
+#endif /* CONFIG_SAMSUNG_CLOCK */
 };
 
 #ifdef CONFIG_SAMSUNG_CLOCK
-- 
1.7.10.4

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

* [PATCH 06/12] clk: samsung: add plls used by the early s3c24xx cpus
  2013-12-13 12:56 ` Heiko Stübner
@ 2013-12-13 13:00   ` Heiko Stübner
  -1 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 13:00 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: t.figa, mturquette, linux-arm-kernel, linux-samsung-soc

The manuals do not give them explicit names like in later socs, so more
generic names with a s3c2410-prefix were used for them.

As it was common to do so in the previous implementation, functionality
to change the pll rate is already included.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 drivers/clk/samsung/clk-pll.c |  182 +++++++++++++++++++++++++++++++++++++++++
 drivers/clk/samsung/clk-pll.h |    3 +
 2 files changed, 185 insertions(+)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 461a6bf..39573bd 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/hrtimer.h>
+#include <linux/delay.h>
 #include "clk.h"
 #include "clk-pll.h"
 
@@ -701,6 +702,169 @@ static const struct clk_ops samsung_pll6553_clk_ops = {
 };
 
 /*
+ * PLL Clock Type of S3C24XX before S3C2443
+ */
+
+#define PLLS3C2410_MDIV_MASK		(0xff)
+#define PLLS3C2410_PDIV_MASK		(0x1f)
+#define PLLS3C2410_SDIV_MASK		(0x3)
+#define PLLS3C2410_MDIV_SHIFT		(12)
+#define PLLS3C2410_PDIV_SHIFT		(4)
+#define PLLS3C2410_SDIV_SHIFT		(0)
+
+#define PLLS3C2410_ENABLE_REG_OFFSET	0x10
+
+static unsigned long samsung_s3c2410_pll_recalc_rate(struct clk_hw *hw,
+					unsigned long parent_rate)
+{
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
+	u32 pll_con, mdiv, pdiv, sdiv;
+	u64 fvco = parent_rate;
+
+	pll_con = __raw_readl(pll->con_reg);
+	mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
+	pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
+	sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
+
+	fvco *= (mdiv + 8);
+	do_div(fvco, (pdiv + 2) << sdiv);
+
+	return (unsigned int)fvco;
+}
+
+static unsigned long samsung_s3c2440_mpll_recalc_rate(struct clk_hw *hw,
+					unsigned long parent_rate)
+{
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
+	u32 pll_con, mdiv, pdiv, sdiv;
+	u64 fvco = parent_rate;
+
+	pll_con = __raw_readl(pll->con_reg);
+	mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
+	pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
+	sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
+
+	fvco *= (2 * (mdiv + 8));
+	do_div(fvco, (pdiv + 2) << sdiv);
+
+	return (unsigned int)fvco;
+}
+
+static int samsung_s3c2410_pll_set_rate(struct clk_hw *hw, unsigned long drate,
+					unsigned long prate)
+{
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
+	const struct samsung_pll_rate_table *rate;
+	u32 tmp;
+
+	/* 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;
+	}
+
+	tmp = __raw_readl(pll->con_reg);
+
+	/* Change PLL PMS values */
+	tmp &= ~((PLLS3C2410_MDIV_MASK << PLLS3C2410_MDIV_SHIFT) |
+			(PLLS3C2410_PDIV_MASK << PLLS3C2410_PDIV_SHIFT) |
+			(PLLS3C2410_SDIV_MASK << PLLS3C2410_SDIV_SHIFT));
+	tmp |= (rate->mdiv << PLLS3C2410_MDIV_SHIFT) |
+			(rate->pdiv << PLLS3C2410_PDIV_SHIFT) |
+			(rate->sdiv << PLLS3C2410_SDIV_SHIFT);
+	__raw_writel(tmp, pll->con_reg);
+
+	/* Time to settle according to the manual */
+	udelay(300);
+
+	return 0;
+}
+
+static int samsung_s3c2410_pll_enable(struct clk_hw *hw, int bit, bool enable)
+{
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
+	u32 pll_en = __raw_readl(pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
+	u32 pll_en_orig = pll_en;
+
+	if (enable)
+		pll_en &= ~BIT(bit);
+	else
+		pll_en |= BIT(bit);
+
+	__raw_writel(pll_en, pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
+
+	/* if we started the UPLL, then allow to settle */
+	if (enable && (pll_en_orig & BIT(bit)))
+		udelay(300);
+
+	return 0;
+}
+
+static int samsung_s3c2410_mpll_enable(struct clk_hw *hw)
+{
+	return samsung_s3c2410_pll_enable(hw, 5, true);
+}
+
+static void samsung_s3c2410_mpll_disable(struct clk_hw *hw)
+{
+	samsung_s3c2410_pll_enable(hw, 5, false);
+}
+
+static int samsung_s3c2410_upll_enable(struct clk_hw *hw)
+{
+	return samsung_s3c2410_pll_enable(hw, 7, true);
+}
+
+static void samsung_s3c2410_upll_disable(struct clk_hw *hw)
+{
+	samsung_s3c2410_pll_enable(hw, 7, false);
+}
+
+static const struct clk_ops samsung_s3c2410_mpll_clk_min_ops = {
+	.recalc_rate = samsung_s3c2410_pll_recalc_rate,
+	.enable = samsung_s3c2410_mpll_enable,
+	.disable = samsung_s3c2410_mpll_disable,
+};
+
+static const struct clk_ops samsung_s3c2410_upll_clk_min_ops = {
+	.recalc_rate = samsung_s3c2410_pll_recalc_rate,
+	.enable = samsung_s3c2410_upll_enable,
+	.disable = samsung_s3c2410_upll_disable,
+};
+
+static const struct clk_ops samsung_s3c2440_mpll_clk_min_ops = {
+	.recalc_rate = samsung_s3c2440_mpll_recalc_rate,
+	.enable = samsung_s3c2410_mpll_enable,
+	.disable = samsung_s3c2410_mpll_disable,
+};
+
+static const struct clk_ops samsung_s3c2410_mpll_clk_ops = {
+	.recalc_rate = samsung_s3c2410_pll_recalc_rate,
+	.enable = samsung_s3c2410_mpll_enable,
+	.disable = samsung_s3c2410_mpll_disable,
+	.round_rate = samsung_pll_round_rate,
+	.set_rate = samsung_s3c2410_pll_set_rate,
+};
+
+static const struct clk_ops samsung_s3c2410_upll_clk_ops = {
+	.recalc_rate = samsung_s3c2410_pll_recalc_rate,
+	.enable = samsung_s3c2410_upll_enable,
+	.disable = samsung_s3c2410_upll_disable,
+	.round_rate = samsung_pll_round_rate,
+	.set_rate = samsung_s3c2410_pll_set_rate,
+};
+
+static const struct clk_ops samsung_s3c2440_mpll_clk_ops = {
+	.recalc_rate = samsung_s3c2440_mpll_recalc_rate,
+	.enable = samsung_s3c2410_mpll_enable,
+	.disable = samsung_s3c2410_mpll_disable,
+	.round_rate = samsung_pll_round_rate,
+	.set_rate = samsung_s3c2410_pll_set_rate,
+};
+
+/*
  * PLL2550x Clock Type
  */
 
@@ -866,6 +1030,24 @@ static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
 		else
 			init.ops = &samsung_pll46xx_clk_ops;
 		break;
+	case pll_s3c2410_mpll:
+		if (!pll->rate_table)
+			init.ops = &samsung_s3c2410_mpll_clk_min_ops;
+		else
+			init.ops = &samsung_s3c2410_mpll_clk_ops;
+		break;
+	case pll_s3c2410_upll:
+		if (!pll->rate_table)
+			init.ops = &samsung_s3c2410_upll_clk_min_ops;
+		else
+			init.ops = &samsung_s3c2410_upll_clk_ops;
+		break;
+	case pll_s3c2440_mpll:
+		if (!pll->rate_table)
+			init.ops = &samsung_s3c2440_mpll_clk_min_ops;
+		else
+			init.ops = &samsung_s3c2440_mpll_clk_ops;
+		break;
 	default:
 		pr_warn("%s: Unknown pll type for pll clk %s\n",
 			__func__, pll_clk->name);
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index 5b64bdb..6428bcc 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -28,6 +28,9 @@ enum samsung_pll_type {
 	pll_6552,
 	pll_6552_s3c2416,
 	pll_6553,
+	pll_s3c2410_mpll,
+	pll_s3c2410_upll,
+	pll_s3c2440_mpll,
 };
 
 #define PLL_35XX_RATE(_rate, _m, _p, _s)			\
-- 
1.7.10.4

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

* [PATCH 06/12] clk: samsung: add plls used by the early s3c24xx cpus
@ 2013-12-13 13:00   ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 13:00 UTC (permalink / raw)
  To: linux-arm-kernel

The manuals do not give them explicit names like in later socs, so more
generic names with a s3c2410-prefix were used for them.

As it was common to do so in the previous implementation, functionality
to change the pll rate is already included.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 drivers/clk/samsung/clk-pll.c |  182 +++++++++++++++++++++++++++++++++++++++++
 drivers/clk/samsung/clk-pll.h |    3 +
 2 files changed, 185 insertions(+)

diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
index 461a6bf..39573bd 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/hrtimer.h>
+#include <linux/delay.h>
 #include "clk.h"
 #include "clk-pll.h"
 
@@ -701,6 +702,169 @@ static const struct clk_ops samsung_pll6553_clk_ops = {
 };
 
 /*
+ * PLL Clock Type of S3C24XX before S3C2443
+ */
+
+#define PLLS3C2410_MDIV_MASK		(0xff)
+#define PLLS3C2410_PDIV_MASK		(0x1f)
+#define PLLS3C2410_SDIV_MASK		(0x3)
+#define PLLS3C2410_MDIV_SHIFT		(12)
+#define PLLS3C2410_PDIV_SHIFT		(4)
+#define PLLS3C2410_SDIV_SHIFT		(0)
+
+#define PLLS3C2410_ENABLE_REG_OFFSET	0x10
+
+static unsigned long samsung_s3c2410_pll_recalc_rate(struct clk_hw *hw,
+					unsigned long parent_rate)
+{
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
+	u32 pll_con, mdiv, pdiv, sdiv;
+	u64 fvco = parent_rate;
+
+	pll_con = __raw_readl(pll->con_reg);
+	mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
+	pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
+	sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
+
+	fvco *= (mdiv + 8);
+	do_div(fvco, (pdiv + 2) << sdiv);
+
+	return (unsigned int)fvco;
+}
+
+static unsigned long samsung_s3c2440_mpll_recalc_rate(struct clk_hw *hw,
+					unsigned long parent_rate)
+{
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
+	u32 pll_con, mdiv, pdiv, sdiv;
+	u64 fvco = parent_rate;
+
+	pll_con = __raw_readl(pll->con_reg);
+	mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
+	pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
+	sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
+
+	fvco *= (2 * (mdiv + 8));
+	do_div(fvco, (pdiv + 2) << sdiv);
+
+	return (unsigned int)fvco;
+}
+
+static int samsung_s3c2410_pll_set_rate(struct clk_hw *hw, unsigned long drate,
+					unsigned long prate)
+{
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
+	const struct samsung_pll_rate_table *rate;
+	u32 tmp;
+
+	/* 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;
+	}
+
+	tmp = __raw_readl(pll->con_reg);
+
+	/* Change PLL PMS values */
+	tmp &= ~((PLLS3C2410_MDIV_MASK << PLLS3C2410_MDIV_SHIFT) |
+			(PLLS3C2410_PDIV_MASK << PLLS3C2410_PDIV_SHIFT) |
+			(PLLS3C2410_SDIV_MASK << PLLS3C2410_SDIV_SHIFT));
+	tmp |= (rate->mdiv << PLLS3C2410_MDIV_SHIFT) |
+			(rate->pdiv << PLLS3C2410_PDIV_SHIFT) |
+			(rate->sdiv << PLLS3C2410_SDIV_SHIFT);
+	__raw_writel(tmp, pll->con_reg);
+
+	/* Time to settle according to the manual */
+	udelay(300);
+
+	return 0;
+}
+
+static int samsung_s3c2410_pll_enable(struct clk_hw *hw, int bit, bool enable)
+{
+	struct samsung_clk_pll *pll = to_clk_pll(hw);
+	u32 pll_en = __raw_readl(pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
+	u32 pll_en_orig = pll_en;
+
+	if (enable)
+		pll_en &= ~BIT(bit);
+	else
+		pll_en |= BIT(bit);
+
+	__raw_writel(pll_en, pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
+
+	/* if we started the UPLL, then allow to settle */
+	if (enable && (pll_en_orig & BIT(bit)))
+		udelay(300);
+
+	return 0;
+}
+
+static int samsung_s3c2410_mpll_enable(struct clk_hw *hw)
+{
+	return samsung_s3c2410_pll_enable(hw, 5, true);
+}
+
+static void samsung_s3c2410_mpll_disable(struct clk_hw *hw)
+{
+	samsung_s3c2410_pll_enable(hw, 5, false);
+}
+
+static int samsung_s3c2410_upll_enable(struct clk_hw *hw)
+{
+	return samsung_s3c2410_pll_enable(hw, 7, true);
+}
+
+static void samsung_s3c2410_upll_disable(struct clk_hw *hw)
+{
+	samsung_s3c2410_pll_enable(hw, 7, false);
+}
+
+static const struct clk_ops samsung_s3c2410_mpll_clk_min_ops = {
+	.recalc_rate = samsung_s3c2410_pll_recalc_rate,
+	.enable = samsung_s3c2410_mpll_enable,
+	.disable = samsung_s3c2410_mpll_disable,
+};
+
+static const struct clk_ops samsung_s3c2410_upll_clk_min_ops = {
+	.recalc_rate = samsung_s3c2410_pll_recalc_rate,
+	.enable = samsung_s3c2410_upll_enable,
+	.disable = samsung_s3c2410_upll_disable,
+};
+
+static const struct clk_ops samsung_s3c2440_mpll_clk_min_ops = {
+	.recalc_rate = samsung_s3c2440_mpll_recalc_rate,
+	.enable = samsung_s3c2410_mpll_enable,
+	.disable = samsung_s3c2410_mpll_disable,
+};
+
+static const struct clk_ops samsung_s3c2410_mpll_clk_ops = {
+	.recalc_rate = samsung_s3c2410_pll_recalc_rate,
+	.enable = samsung_s3c2410_mpll_enable,
+	.disable = samsung_s3c2410_mpll_disable,
+	.round_rate = samsung_pll_round_rate,
+	.set_rate = samsung_s3c2410_pll_set_rate,
+};
+
+static const struct clk_ops samsung_s3c2410_upll_clk_ops = {
+	.recalc_rate = samsung_s3c2410_pll_recalc_rate,
+	.enable = samsung_s3c2410_upll_enable,
+	.disable = samsung_s3c2410_upll_disable,
+	.round_rate = samsung_pll_round_rate,
+	.set_rate = samsung_s3c2410_pll_set_rate,
+};
+
+static const struct clk_ops samsung_s3c2440_mpll_clk_ops = {
+	.recalc_rate = samsung_s3c2440_mpll_recalc_rate,
+	.enable = samsung_s3c2410_mpll_enable,
+	.disable = samsung_s3c2410_mpll_disable,
+	.round_rate = samsung_pll_round_rate,
+	.set_rate = samsung_s3c2410_pll_set_rate,
+};
+
+/*
  * PLL2550x Clock Type
  */
 
@@ -866,6 +1030,24 @@ static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
 		else
 			init.ops = &samsung_pll46xx_clk_ops;
 		break;
+	case pll_s3c2410_mpll:
+		if (!pll->rate_table)
+			init.ops = &samsung_s3c2410_mpll_clk_min_ops;
+		else
+			init.ops = &samsung_s3c2410_mpll_clk_ops;
+		break;
+	case pll_s3c2410_upll:
+		if (!pll->rate_table)
+			init.ops = &samsung_s3c2410_upll_clk_min_ops;
+		else
+			init.ops = &samsung_s3c2410_upll_clk_ops;
+		break;
+	case pll_s3c2440_mpll:
+		if (!pll->rate_table)
+			init.ops = &samsung_s3c2440_mpll_clk_min_ops;
+		else
+			init.ops = &samsung_s3c2440_mpll_clk_ops;
+		break;
 	default:
 		pr_warn("%s: Unknown pll type for pll clk %s\n",
 			__func__, pll_clk->name);
diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
index 5b64bdb..6428bcc 100644
--- a/drivers/clk/samsung/clk-pll.h
+++ b/drivers/clk/samsung/clk-pll.h
@@ -28,6 +28,9 @@ enum samsung_pll_type {
 	pll_6552,
 	pll_6552_s3c2416,
 	pll_6553,
+	pll_s3c2410_mpll,
+	pll_s3c2410_upll,
+	pll_s3c2440_mpll,
 };
 
 #define PLL_35XX_RATE(_rate, _m, _p, _s)			\
-- 
1.7.10.4

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

* [PATCH 08/12] clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442
  2013-12-13 12:56 ` Heiko Stübner
@ 2013-12-13 13:01   ` Heiko Stübner
  -1 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 13:01 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: t.figa, mturquette, linux-arm-kernel, linux-samsung-soc

This driver can handle the clock controllers of the socs mentioned above,
as they share a common clock tree with only small differences.

The clock structure is built according to the manuals of the included
SoCs and might include changes in comparison to the previous clock
structure.

As pll-rate-tables only the 12mhz variants are currently included.
The original code was wrongly checking for 169mhz xti values [a 0 to much
at the end], so the original 16mhz pll table would have never been
included and its values are so obscure that I have no possibility to
at least check their sane-ness. When using the formula from the manual
the resulting frequency is near the table value but still slightly off.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 drivers/clk/samsung/Makefile                      |    1 +
 drivers/clk/samsung/clk-s3c2410.c                 |  428 +++++++++++++++++++++
 include/dt-bindings/clock/samsung,s3c2410-clock.h |   64 +++
 3 files changed, 493 insertions(+)
 create mode 100644 drivers/clk/samsung/clk-s3c2410.c
 create mode 100644 include/dt-bindings/clock/samsung,s3c2410-clock.h

diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 568683c..60748b2 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_SOC_EXYNOS5250)	+= clk-exynos5250.o
 obj-$(CONFIG_SOC_EXYNOS5420)	+= clk-exynos5420.o
 obj-$(CONFIG_SOC_EXYNOS5440)	+= clk-exynos5440.o
 obj-$(CONFIG_ARCH_EXYNOS)	+= clk-exynos-audss.o
+obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
 obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
 obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
 obj-$(CONFIG_ARCH_S3C64XX)	+= clk-s3c64xx.o
diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c
new file mode 100644
index 0000000..8358cad
--- /dev/null
+++ b/drivers/clk/samsung/clk-s3c2410.c
@@ -0,0 +1,428 @@
+/*
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Common Clock Framework support for S3C2410 and following SoCs.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <dt-bindings/clock/samsung,s3c2410-clock.h>
+
+#include "clk.h"
+#include "clk-pll.h"
+
+#define LOCKTIME	0x00
+#define MPLLCON		0x04
+#define UPLLCON		0x08
+#define CLKCON		0x0c
+#define CLKSLOW		0x10
+#define CLKDIVN		0x14
+#define CAMDIVN		0x18
+
+/* the soc types */
+enum supported_socs {
+	S3C2410,
+	S3C2440,
+	S3C2442,
+};
+
+/* list of PLLs to be registered */
+enum s3c2410_plls {
+	mpll, upll,
+};
+
+/*
+ * list of controller registers to be saved and restored during a
+ * suspend/resume cycle.
+ */
+static unsigned long s3c2410_clk_regs[] __initdata = {
+	LOCKTIME,
+	MPLLCON,
+	UPLLCON,
+	CLKCON,
+	CLKSLOW,
+	CLKDIVN,
+	CAMDIVN,
+};
+
+PNAME(fclk_p) = { "mpll", "div_slow" };
+
+struct samsung_mux_clock s3c2410_common_muxes[] __initdata = {
+	MUX(FCLK, "fclk", fclk_p, CLKSLOW, 4, 1),
+};
+
+static struct clk_div_table divslow_d[] = {
+	{ .val = 0, .div = 1 },
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 4 },
+	{ .val = 3, .div = 6 },
+	{ .val = 4, .div = 8 },
+	{ .val = 5, .div = 10 },
+	{ .val = 6, .div = 12 },
+	{ .val = 7, .div = 14 },
+	{ .div = 0 },
+};
+
+struct samsung_div_clock s3c2410_common_dividers[] __initdata = {
+	DIV_T(0, "div_slow", "xti", CLKSLOW, 0, 3, divslow_d),
+	DIV(PCLK, "pclk", "hclk", CLKDIVN, 0, 1),
+};
+
+struct samsung_gate_clock s3c2410_common_gates[] __initdata = {
+	GATE(PCLK_SPI, "spi", "pclk", CLKCON, 18, 0, 0),
+	GATE(PCLK_I2S, "i2s", "pclk", CLKCON, 17, 0, 0),
+	GATE(PCLK_I2C, "i2c", "pclk", CLKCON, 16, 0, 0),
+	GATE(PCLK_ADC, "adc", "pclk", CLKCON, 15, 0, 0),
+	GATE(PCLK_RTC, "rtc", "pclk", CLKCON, 14, 0, 0),
+	GATE(PCLK_GPIO, "gpio", "pclk", CLKCON, 13, CLK_IGNORE_UNUSED, 0),
+	GATE(PCLK_UART2, "uart2", "pclk", CLKCON, 12, 0, 0),
+	GATE(PCLK_UART1, "uart1", "pclk", CLKCON, 11, 0, 0),
+	GATE(PCLK_UART0, "uart0", "pclk", CLKCON, 10, 0, 0),
+	GATE(PCLK_SDI, "sdi", "pclk", CLKCON, 9, 0, 0),
+	GATE(PCLK_PWM, "pwm", "pclk", CLKCON, 8, 0, 0),
+	GATE(HCLK_USBD, "usb-device", "hclk", CLKCON, 7, 0, 0),
+	GATE(HCLK_USBH, "usb-host", "hclk", CLKCON, 6, 0, 0),
+	GATE(HCLK_LCD, "lcd", "hclk", CLKCON, 5, 0, 0),
+	GATE(HCLK_NAND, "nand", "hclk", CLKCON, 4, 0, 0),
+};
+
+/* should be added _after_ the soc-specific clocks are created */
+struct samsung_clock_alias s3c2410_common_aliases[] __initdata = {
+	ALIAS(PCLK_I2C, "s3c2410-i2c.0", "i2c"),
+	ALIAS(PCLK_ADC, NULL, "adc"),
+	ALIAS(PCLK_RTC, NULL, "rtc"),
+	ALIAS(PCLK_PWM, NULL, "timers"),
+	ALIAS(HCLK_LCD, NULL, "lcd"),
+	ALIAS(HCLK_USBD, NULL, "usb-device"),
+	ALIAS(HCLK_USBH, NULL, "usb-host"),
+	ALIAS(UCLK, NULL, "usb-bus-host"),
+	ALIAS(UCLK, NULL, "usb-bus-gadget"),
+	ALIAS(ARMCLK, NULL, "armclk"),
+	ALIAS(UCLK, NULL, "uclk"),
+	ALIAS(HCLK, NULL, "hclk"),
+	ALIAS(MPLL, NULL, "mpll"),
+	ALIAS(FCLK, NULL, "fclk"),
+};
+
+/* S3C2410 specific clocks */
+
+static struct samsung_pll_rate_table pll_s3c2410_12mhz_tbl[] __initdata = {
+	/* sorted in descending order */
+	/* 2410A extras */
+	PLL_35XX_RATE(270000000, 127, 1, 1),
+	PLL_35XX_RATE(268000000, 126, 1, 1),
+	PLL_35XX_RATE(266000000, 125, 1, 1),
+	PLL_35XX_RATE(226000000, 105, 1, 1),
+	PLL_35XX_RATE(210000000, 132, 2, 1),
+	/* 2410 common */
+	PLL_35XX_RATE(203000000, 161, 3, 1),
+	PLL_35XX_RATE(192000000, 88, 1, 1),
+	PLL_35XX_RATE(186000000, 85, 1, 1),
+	PLL_35XX_RATE(180000000, 82, 1, 1),
+	PLL_35XX_RATE(170000000, 77, 1, 1),
+	PLL_35XX_RATE(158000000, 71, 1, 1),
+	PLL_35XX_RATE(152000000, 68, 1, 1),
+	PLL_35XX_RATE(147000000, 90, 2, 1),
+	PLL_35XX_RATE(135000000, 82, 2, 1),
+	PLL_35XX_RATE(124000000, 116, 1, 2),
+	PLL_35XX_RATE(118000000, 150, 2, 2),
+	PLL_35XX_RATE(113000000, 105, 1, 2),
+	PLL_35XX_RATE(101000000, 127, 2, 2),
+	PLL_35XX_RATE(90000000, 112, 2, 2),
+	PLL_35XX_RATE(85000000, 105, 2, 2),
+	PLL_35XX_RATE(79000000, 71, 1, 2),
+	PLL_35XX_RATE(68000000, 82, 2, 2),
+	PLL_35XX_RATE(56000000, 142, 2, 3),
+	PLL_35XX_RATE(48000000, 120, 2, 3),
+	PLL_35XX_RATE(51000000, 161, 3, 3),
+	PLL_35XX_RATE(45000000, 82, 1, 3),
+	PLL_35XX_RATE(34000000, 82, 2, 3),
+	{ },
+};
+
+static struct samsung_pll_clock s3c2410_plls[] __initdata = {
+	[mpll] = PLL(pll_s3c2410_mpll, MPLL, "mpll", "xti",
+						LOCKTIME, MPLLCON, NULL),
+	[upll] = PLL(pll_s3c2410_upll, UPLL, "upll", "xti",
+						LOCKTIME, UPLLCON, NULL),
+};
+
+struct samsung_div_clock s3c2410_dividers[] __initdata = {
+	DIV(HCLK, "hclk", "mpll", CLKDIVN, 1, 1),
+};
+
+struct samsung_fixed_factor_clock s3c2410_ffactor[] __initdata = {
+	/*
+	 * armclk is directly supplied by the fclk, without
+	 * switching possibility like on the s3c244x below.
+	 */
+	FFACTOR(ARMCLK, "armclk", "fclk", 1, 1, 0),
+
+	/* uclk is fed from the unmodified upll */
+	FFACTOR(UCLK, "uclk", "upll", 1, 1, 0),
+};
+
+struct samsung_clock_alias s3c2410_aliases[] __initdata = {
+	ALIAS(PCLK_UART0, "s3c2410-uart.0", "uart"),
+	ALIAS(PCLK_UART1, "s3c2410-uart.1", "uart"),
+	ALIAS(PCLK_UART2, "s3c2410-uart.2", "uart"),
+	ALIAS(PCLK_UART0, "s3c2410-uart.0", "clk_uart_baud0"),
+	ALIAS(PCLK_UART1, "s3c2410-uart.1", "clk_uart_baud0"),
+	ALIAS(PCLK_UART2, "s3c2410-uart.2", "clk_uart_baud0"),
+	ALIAS(UCLK, NULL, "clk_uart_baud1"),
+};
+
+/* S3C244x specific clocks */
+
+static struct samsung_pll_rate_table pll_s3c244x_12mhz_tbl[] __initdata = {
+	/* sorted in descending order */
+	PLL_35XX_RATE(400000000, 0x5c, 1, 1),
+	PLL_35XX_RATE(390000000, 0x7a, 2, 1),
+	PLL_35XX_RATE(380000000, 0x57, 1, 1),
+	PLL_35XX_RATE(370000000, 0xb1, 4, 1),
+	PLL_35XX_RATE(360000000, 0x70, 2, 1),
+	PLL_35XX_RATE(350000000, 0xa7, 4, 1),
+	PLL_35XX_RATE(340000000, 0x4d, 1, 1),
+	PLL_35XX_RATE(330000000, 0x66, 2, 1),
+	PLL_35XX_RATE(320000000, 0x98, 4, 1),
+	PLL_35XX_RATE(310000000, 0x93, 4, 1),
+	PLL_35XX_RATE(300000000, 0x75, 3, 1),
+	PLL_35XX_RATE(240000000, 0x70, 1, 2),
+	PLL_35XX_RATE(230000000, 0x6b, 1, 2),
+	PLL_35XX_RATE(220000000, 0x66, 1, 2),
+	PLL_35XX_RATE(210000000, 0x84, 2, 2),
+	PLL_35XX_RATE(200000000, 0x5c, 1, 2),
+	PLL_35XX_RATE(190000000, 0x57, 1, 2),
+	PLL_35XX_RATE(180000000, 0x70, 2, 2),
+	PLL_35XX_RATE(170000000, 0x4d, 1, 2),
+	PLL_35XX_RATE(160000000, 0x98, 4, 2),
+	PLL_35XX_RATE(150000000, 0x75, 3, 2),
+	PLL_35XX_RATE(120000000, 0x70, 1, 3),
+	PLL_35XX_RATE(110000000, 0x66, 1, 3),
+	PLL_35XX_RATE(100000000, 0x5c, 1, 3),
+	PLL_35XX_RATE(90000000, 0x70, 2, 3),
+	PLL_35XX_RATE(80000000, 0x98, 4, 3),
+	PLL_35XX_RATE(75000000, 0x75, 3, 3),
+};
+
+static struct samsung_pll_clock s3c244x_common_plls[] __initdata = {
+	[mpll] = PLL(pll_s3c2440_mpll, MPLL, "mpll", "xti",
+						LOCKTIME, MPLLCON, NULL),
+	[upll] = PLL(pll_s3c2410_upll, UPLL, "upll", "xti",
+						LOCKTIME, UPLLCON, NULL),
+};
+
+PNAME(hclk_p) = { "fclk", "div_hclk_2", "div_hclk_4", "div_hclk_3" };
+PNAME(armclk_p) = { "fclk", "hclk" };
+
+struct samsung_mux_clock s3c244x_common_muxes[] __initdata = {
+	MUX(HCLK, "hclk", hclk_p, CLKDIVN, 1, 2),
+	MUX(ARMCLK, "armclk", armclk_p, CAMDIVN, 12, 1),
+};
+
+struct samsung_fixed_factor_clock s3c244x_common_ffactor[] __initdata = {
+	FFACTOR(0, "div_hclk_2", "fclk", 1, 2, 0),
+	FFACTOR(0, "ff_cam", "div_cam", 2, 1, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_div_table div_hclk_4_d[] = {
+	{ .val = 0, .div = 4 },
+	{ .val = 1, .div = 8 },
+};
+
+static struct clk_div_table div_hclk_3_d[] = {
+	{ .val = 0, .div = 3 },
+	{ .val = 1, .div = 6 },
+};
+
+struct samsung_div_clock s3c244x_common_dividers[] __initdata = {
+	DIV(UCLK, "uclk", "upll", CLKDIVN, 3, 1),
+	DIV(0, "div_hclk", "fclk", CLKDIVN, 1, 1),
+	DIV_T(0, "div_hclk_4", "fclk", CAMDIVN, 9, 1, div_hclk_4_d),
+	DIV_T(0, "div_hclk_3", "fclk", CAMDIVN, 8, 1, div_hclk_3_d),
+	DIV(0, "div_cam", "upll", CAMDIVN, 0, 3),
+};
+
+struct samsung_gate_clock s3c244x_common_gates[] __initdata = {
+	GATE(HCLK_CAM, "cam", "hclk", CLKCON, 19, 0, 0),
+};
+
+struct samsung_clock_alias s3c244x_common_aliases[] __initdata = {
+	ALIAS(PCLK_UART0, "s3c2440-uart.0", "uart"),
+	ALIAS(PCLK_UART1, "s3c2440-uart.1", "uart"),
+	ALIAS(PCLK_UART2, "s3c2440-uart.2", "uart"),
+	ALIAS(PCLK_UART0, "s3c2440-uart.0", "clk_uart_baud2"),
+	ALIAS(PCLK_UART1, "s3c2440-uart.1", "clk_uart_baud2"),
+	ALIAS(PCLK_UART2, "s3c2440-uart.2", "clk_uart_baud2"),
+	ALIAS(HCLK_CAM, NULL, "camif"),
+	ALIAS(CAMIF, NULL, "camif-upll"),
+};
+
+/* S3C2440 specific clocks */
+
+PNAME(s3c2440_camif_p) = { "upll", "ff_cam" };
+
+struct samsung_mux_clock s3c2440_muxes[] __initdata = {
+	MUX(CAMIF, "camif", s3c2440_camif_p, CAMDIVN, 4, 1),
+};
+
+struct samsung_gate_clock s3c2440_gates[] __initdata = {
+	GATE(PCLK_AC97, "ac97", "pclk", CLKCON, 20, 0, 0),
+};
+
+/* S3C2442 specific clocks */
+
+struct samsung_fixed_factor_clock s3c2442_ffactor[] __initdata = {
+	FFACTOR(0, "upll_3", "upll", 1, 3, 0),
+};
+
+PNAME(s3c2442_camif_p) = { "upll", "ff_cam", "upll", "upll_3" };
+
+struct samsung_mux_clock s3c2442_muxes[] __initdata = {
+	MUX(CAMIF, "camif", s3c2442_camif_p, CAMDIVN, 4, 2),
+};
+
+/*
+ * fixed rate clocks generated outside the soc
+ * Only necessary until the devicetree-move is complete
+ */
+struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata = {
+	FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0),
+};
+
+static void __init s3c2410_common_clk_register_fixed_ext(unsigned long xti_f)
+{
+	struct samsung_clock_alias xti_alias = ALIAS(XTI, NULL, "xtal");
+
+	s3c2410_common_frate_clks[0].fixed_rate = xti_f;
+	samsung_clk_register_fixed_rate(s3c2410_common_frate_clks,
+				ARRAY_SIZE(s3c2410_common_frate_clks));
+
+	samsung_clk_register_alias(&xti_alias, 1);
+}
+
+void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
+				    int current_soc,
+				    void __iomem *reg_base)
+{
+	if (np) {
+		reg_base = of_iomap(np, 0);
+		if (!reg_base)
+			panic("%s: failed to map registers\n", __func__);
+	}
+
+	samsung_clk_init(np, reg_base, NR_CLKS,
+		s3c2410_clk_regs, ARRAY_SIZE(s3c2410_clk_regs), NULL, 0);
+
+	/* Register external clocks only in non-dt cases */
+	if (!np)
+		s3c2410_common_clk_register_fixed_ext(xti_f);
+
+	if (current_soc == 2410) {
+		if (_get_rate("xti") == 12 * MHZ) {
+			s3c2410_plls[mpll].rate_table = pll_s3c2410_12mhz_tbl;
+			s3c2410_plls[upll].rate_table = pll_s3c2410_12mhz_tbl;
+		}
+
+		/* Register PLLs. */
+		samsung_clk_register_pll(s3c2410_plls,
+				ARRAY_SIZE(s3c2410_plls), reg_base);
+
+	} else { /* S3C2440, S3C2442 */
+		if (_get_rate("xti") == 12 * MHZ) {
+			/*
+			 * plls follow different calculation schemes, with the
+			 * upll following the same scheme as the s3c2410 plls
+			 */
+			s3c244x_common_plls[mpll].rate_table =
+							pll_s3c244x_12mhz_tbl;
+			s3c244x_common_plls[upll].rate_table =
+							pll_s3c2410_12mhz_tbl;
+		}
+
+		/* Register PLLs. */
+		samsung_clk_register_pll(s3c244x_common_plls,
+				ARRAY_SIZE(s3c244x_common_plls), reg_base);
+	}
+
+	/* Register common internal clocks. */
+	samsung_clk_register_mux(s3c2410_common_muxes,
+			ARRAY_SIZE(s3c2410_common_muxes));
+	samsung_clk_register_div(s3c2410_common_dividers,
+			ARRAY_SIZE(s3c2410_common_dividers));
+	samsung_clk_register_gate(s3c2410_common_gates,
+		ARRAY_SIZE(s3c2410_common_gates));
+
+	if (current_soc == S3C2440 || current_soc == S3C2442) {
+		samsung_clk_register_div(s3c244x_common_dividers,
+				ARRAY_SIZE(s3c244x_common_dividers));
+		samsung_clk_register_gate(s3c244x_common_gates,
+				ARRAY_SIZE(s3c244x_common_gates));
+		samsung_clk_register_mux(s3c244x_common_muxes,
+				ARRAY_SIZE(s3c244x_common_muxes));
+		samsung_clk_register_fixed_factor(s3c244x_common_ffactor,
+				ARRAY_SIZE(s3c244x_common_ffactor));
+	}
+
+	/* Register SoC-specific clocks. */
+	switch (current_soc) {
+	case S3C2410:
+		samsung_clk_register_div(s3c2410_dividers,
+				ARRAY_SIZE(s3c2410_dividers));
+		samsung_clk_register_fixed_factor(s3c2410_ffactor,
+				ARRAY_SIZE(s3c2410_ffactor));
+		samsung_clk_register_alias(s3c2410_aliases,
+			ARRAY_SIZE(s3c2410_common_aliases));
+		break;
+	case S3C2440:
+		samsung_clk_register_mux(s3c2440_muxes,
+				ARRAY_SIZE(s3c2440_muxes));
+		samsung_clk_register_gate(s3c2440_gates,
+				ARRAY_SIZE(s3c2440_gates));
+		break;
+	case S3C2442:
+		samsung_clk_register_mux(s3c2442_muxes,
+				ARRAY_SIZE(s3c2442_muxes));
+		samsung_clk_register_fixed_factor(s3c2442_ffactor,
+				ARRAY_SIZE(s3c2442_ffactor));
+		break;
+	}
+
+	/*
+	 * Register common aliases at the end, as some of the aliased clocks
+	 * are SoC specific.
+	 */
+	samsung_clk_register_alias(s3c2410_common_aliases,
+		ARRAY_SIZE(s3c2410_common_aliases));
+
+	if (current_soc == S3C2440 || current_soc == S3C2442) {
+		samsung_clk_register_alias(s3c244x_common_aliases,
+			ARRAY_SIZE(s3c244x_common_aliases));
+	}
+}
+
+static void __init s3c2410_clk_init(struct device_node *np)
+{
+	s3c2410_common_clk_init(np, 0, S3C2410, 0);
+}
+CLK_OF_DECLARE(s3c2410_clk, "samsung,s3c2410-clock", s3c2410_clk_init);
+
+static void __init s3c2440_clk_init(struct device_node *np)
+{
+	s3c2410_common_clk_init(np, 0, S3C2440, 0);
+}
+CLK_OF_DECLARE(s3c2440_clk, "samsung,s3c2440-clock", s3c2440_clk_init);
+
+static void __init s3c2442_clk_init(struct device_node *np)
+{
+	s3c2410_common_clk_init(np, 0, S3C2442, 0);
+}
+CLK_OF_DECLARE(s3c2442_clk, "samsung,s3c2442-clock", s3c2442_clk_init);
diff --git a/include/dt-bindings/clock/samsung,s3c2410-clock.h b/include/dt-bindings/clock/samsung,s3c2410-clock.h
new file mode 100644
index 0000000..66c278f
--- /dev/null
+++ b/include/dt-bindings/clock/samsung,s3c2410-clock.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
+ *
+ * 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.
+ *
+ * Device Tree binding constants clock controllers of Samsung S3C2410 and later.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C2410_CLOCK_H
+#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C2410_CLOCK_H
+
+/*
+ * Let each exported clock get a unique index, which is used on DT-enabled
+ * platforms to lookup the clock from a clock specifier. These indices are
+ * therefore considered an ABI and so must not be changed. This implies
+ * that new clocks should be added either in free spaces between clock groups
+ * or at the end.
+ */
+
+/* Core clocks. */
+
+
+#define MPLL			1
+#define UPLL			2
+#define FCLK			3
+#define HCLK			4
+#define PCLK			5
+#define UCLK			6
+#define ARMCLK			7
+
+#define XTI			8
+
+/* pclk-gates */
+#define PCLK_UART0		16
+#define PCLK_UART1		17
+#define PCLK_UART2		18
+#define PCLK_I2C		19
+#define PCLK_SDI		20
+#define PCLK_SPI		21
+#define PCLK_ADC		22
+#define PCLK_AC97		23
+#define PCLK_I2S		24
+#define PCLK_PWM		25
+#define PCLK_RTC		26
+#define PCLK_GPIO		27
+
+
+/* hclk-gates */
+#define HCLK_LCD		32
+#define HCLK_USBH		33
+#define HCLK_USBD		34
+#define HCLK_NAND		35
+#define HCLK_CAM		36
+
+
+#define CAMIF			40
+
+
+/* Total number of clocks. */
+#define NR_CLKS			(CAMIF + 1)
+
+#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_S3C2443_CLOCK_H */
-- 
1.7.10.4

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

* [PATCH 08/12] clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442
@ 2013-12-13 13:01   ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 13:01 UTC (permalink / raw)
  To: linux-arm-kernel

This driver can handle the clock controllers of the socs mentioned above,
as they share a common clock tree with only small differences.

The clock structure is built according to the manuals of the included
SoCs and might include changes in comparison to the previous clock
structure.

As pll-rate-tables only the 12mhz variants are currently included.
The original code was wrongly checking for 169mhz xti values [a 0 to much
at the end], so the original 16mhz pll table would have never been
included and its values are so obscure that I have no possibility to
at least check their sane-ness. When using the formula from the manual
the resulting frequency is near the table value but still slightly off.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 drivers/clk/samsung/Makefile                      |    1 +
 drivers/clk/samsung/clk-s3c2410.c                 |  428 +++++++++++++++++++++
 include/dt-bindings/clock/samsung,s3c2410-clock.h |   64 +++
 3 files changed, 493 insertions(+)
 create mode 100644 drivers/clk/samsung/clk-s3c2410.c
 create mode 100644 include/dt-bindings/clock/samsung,s3c2410-clock.h

diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
index 568683c..60748b2 100644
--- a/drivers/clk/samsung/Makefile
+++ b/drivers/clk/samsung/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_SOC_EXYNOS5250)	+= clk-exynos5250.o
 obj-$(CONFIG_SOC_EXYNOS5420)	+= clk-exynos5420.o
 obj-$(CONFIG_SOC_EXYNOS5440)	+= clk-exynos5440.o
 obj-$(CONFIG_ARCH_EXYNOS)	+= clk-exynos-audss.o
+obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
 obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
 obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
 obj-$(CONFIG_ARCH_S3C64XX)	+= clk-s3c64xx.o
diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c
new file mode 100644
index 0000000..8358cad
--- /dev/null
+++ b/drivers/clk/samsung/clk-s3c2410.c
@@ -0,0 +1,428 @@
+/*
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Common Clock Framework support for S3C2410 and following SoCs.
+ */
+
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+#include <dt-bindings/clock/samsung,s3c2410-clock.h>
+
+#include "clk.h"
+#include "clk-pll.h"
+
+#define LOCKTIME	0x00
+#define MPLLCON		0x04
+#define UPLLCON		0x08
+#define CLKCON		0x0c
+#define CLKSLOW		0x10
+#define CLKDIVN		0x14
+#define CAMDIVN		0x18
+
+/* the soc types */
+enum supported_socs {
+	S3C2410,
+	S3C2440,
+	S3C2442,
+};
+
+/* list of PLLs to be registered */
+enum s3c2410_plls {
+	mpll, upll,
+};
+
+/*
+ * list of controller registers to be saved and restored during a
+ * suspend/resume cycle.
+ */
+static unsigned long s3c2410_clk_regs[] __initdata = {
+	LOCKTIME,
+	MPLLCON,
+	UPLLCON,
+	CLKCON,
+	CLKSLOW,
+	CLKDIVN,
+	CAMDIVN,
+};
+
+PNAME(fclk_p) = { "mpll", "div_slow" };
+
+struct samsung_mux_clock s3c2410_common_muxes[] __initdata = {
+	MUX(FCLK, "fclk", fclk_p, CLKSLOW, 4, 1),
+};
+
+static struct clk_div_table divslow_d[] = {
+	{ .val = 0, .div = 1 },
+	{ .val = 1, .div = 2 },
+	{ .val = 2, .div = 4 },
+	{ .val = 3, .div = 6 },
+	{ .val = 4, .div = 8 },
+	{ .val = 5, .div = 10 },
+	{ .val = 6, .div = 12 },
+	{ .val = 7, .div = 14 },
+	{ .div = 0 },
+};
+
+struct samsung_div_clock s3c2410_common_dividers[] __initdata = {
+	DIV_T(0, "div_slow", "xti", CLKSLOW, 0, 3, divslow_d),
+	DIV(PCLK, "pclk", "hclk", CLKDIVN, 0, 1),
+};
+
+struct samsung_gate_clock s3c2410_common_gates[] __initdata = {
+	GATE(PCLK_SPI, "spi", "pclk", CLKCON, 18, 0, 0),
+	GATE(PCLK_I2S, "i2s", "pclk", CLKCON, 17, 0, 0),
+	GATE(PCLK_I2C, "i2c", "pclk", CLKCON, 16, 0, 0),
+	GATE(PCLK_ADC, "adc", "pclk", CLKCON, 15, 0, 0),
+	GATE(PCLK_RTC, "rtc", "pclk", CLKCON, 14, 0, 0),
+	GATE(PCLK_GPIO, "gpio", "pclk", CLKCON, 13, CLK_IGNORE_UNUSED, 0),
+	GATE(PCLK_UART2, "uart2", "pclk", CLKCON, 12, 0, 0),
+	GATE(PCLK_UART1, "uart1", "pclk", CLKCON, 11, 0, 0),
+	GATE(PCLK_UART0, "uart0", "pclk", CLKCON, 10, 0, 0),
+	GATE(PCLK_SDI, "sdi", "pclk", CLKCON, 9, 0, 0),
+	GATE(PCLK_PWM, "pwm", "pclk", CLKCON, 8, 0, 0),
+	GATE(HCLK_USBD, "usb-device", "hclk", CLKCON, 7, 0, 0),
+	GATE(HCLK_USBH, "usb-host", "hclk", CLKCON, 6, 0, 0),
+	GATE(HCLK_LCD, "lcd", "hclk", CLKCON, 5, 0, 0),
+	GATE(HCLK_NAND, "nand", "hclk", CLKCON, 4, 0, 0),
+};
+
+/* should be added _after_ the soc-specific clocks are created */
+struct samsung_clock_alias s3c2410_common_aliases[] __initdata = {
+	ALIAS(PCLK_I2C, "s3c2410-i2c.0", "i2c"),
+	ALIAS(PCLK_ADC, NULL, "adc"),
+	ALIAS(PCLK_RTC, NULL, "rtc"),
+	ALIAS(PCLK_PWM, NULL, "timers"),
+	ALIAS(HCLK_LCD, NULL, "lcd"),
+	ALIAS(HCLK_USBD, NULL, "usb-device"),
+	ALIAS(HCLK_USBH, NULL, "usb-host"),
+	ALIAS(UCLK, NULL, "usb-bus-host"),
+	ALIAS(UCLK, NULL, "usb-bus-gadget"),
+	ALIAS(ARMCLK, NULL, "armclk"),
+	ALIAS(UCLK, NULL, "uclk"),
+	ALIAS(HCLK, NULL, "hclk"),
+	ALIAS(MPLL, NULL, "mpll"),
+	ALIAS(FCLK, NULL, "fclk"),
+};
+
+/* S3C2410 specific clocks */
+
+static struct samsung_pll_rate_table pll_s3c2410_12mhz_tbl[] __initdata = {
+	/* sorted in descending order */
+	/* 2410A extras */
+	PLL_35XX_RATE(270000000, 127, 1, 1),
+	PLL_35XX_RATE(268000000, 126, 1, 1),
+	PLL_35XX_RATE(266000000, 125, 1, 1),
+	PLL_35XX_RATE(226000000, 105, 1, 1),
+	PLL_35XX_RATE(210000000, 132, 2, 1),
+	/* 2410 common */
+	PLL_35XX_RATE(203000000, 161, 3, 1),
+	PLL_35XX_RATE(192000000, 88, 1, 1),
+	PLL_35XX_RATE(186000000, 85, 1, 1),
+	PLL_35XX_RATE(180000000, 82, 1, 1),
+	PLL_35XX_RATE(170000000, 77, 1, 1),
+	PLL_35XX_RATE(158000000, 71, 1, 1),
+	PLL_35XX_RATE(152000000, 68, 1, 1),
+	PLL_35XX_RATE(147000000, 90, 2, 1),
+	PLL_35XX_RATE(135000000, 82, 2, 1),
+	PLL_35XX_RATE(124000000, 116, 1, 2),
+	PLL_35XX_RATE(118000000, 150, 2, 2),
+	PLL_35XX_RATE(113000000, 105, 1, 2),
+	PLL_35XX_RATE(101000000, 127, 2, 2),
+	PLL_35XX_RATE(90000000, 112, 2, 2),
+	PLL_35XX_RATE(85000000, 105, 2, 2),
+	PLL_35XX_RATE(79000000, 71, 1, 2),
+	PLL_35XX_RATE(68000000, 82, 2, 2),
+	PLL_35XX_RATE(56000000, 142, 2, 3),
+	PLL_35XX_RATE(48000000, 120, 2, 3),
+	PLL_35XX_RATE(51000000, 161, 3, 3),
+	PLL_35XX_RATE(45000000, 82, 1, 3),
+	PLL_35XX_RATE(34000000, 82, 2, 3),
+	{ },
+};
+
+static struct samsung_pll_clock s3c2410_plls[] __initdata = {
+	[mpll] = PLL(pll_s3c2410_mpll, MPLL, "mpll", "xti",
+						LOCKTIME, MPLLCON, NULL),
+	[upll] = PLL(pll_s3c2410_upll, UPLL, "upll", "xti",
+						LOCKTIME, UPLLCON, NULL),
+};
+
+struct samsung_div_clock s3c2410_dividers[] __initdata = {
+	DIV(HCLK, "hclk", "mpll", CLKDIVN, 1, 1),
+};
+
+struct samsung_fixed_factor_clock s3c2410_ffactor[] __initdata = {
+	/*
+	 * armclk is directly supplied by the fclk, without
+	 * switching possibility like on the s3c244x below.
+	 */
+	FFACTOR(ARMCLK, "armclk", "fclk", 1, 1, 0),
+
+	/* uclk is fed from the unmodified upll */
+	FFACTOR(UCLK, "uclk", "upll", 1, 1, 0),
+};
+
+struct samsung_clock_alias s3c2410_aliases[] __initdata = {
+	ALIAS(PCLK_UART0, "s3c2410-uart.0", "uart"),
+	ALIAS(PCLK_UART1, "s3c2410-uart.1", "uart"),
+	ALIAS(PCLK_UART2, "s3c2410-uart.2", "uart"),
+	ALIAS(PCLK_UART0, "s3c2410-uart.0", "clk_uart_baud0"),
+	ALIAS(PCLK_UART1, "s3c2410-uart.1", "clk_uart_baud0"),
+	ALIAS(PCLK_UART2, "s3c2410-uart.2", "clk_uart_baud0"),
+	ALIAS(UCLK, NULL, "clk_uart_baud1"),
+};
+
+/* S3C244x specific clocks */
+
+static struct samsung_pll_rate_table pll_s3c244x_12mhz_tbl[] __initdata = {
+	/* sorted in descending order */
+	PLL_35XX_RATE(400000000, 0x5c, 1, 1),
+	PLL_35XX_RATE(390000000, 0x7a, 2, 1),
+	PLL_35XX_RATE(380000000, 0x57, 1, 1),
+	PLL_35XX_RATE(370000000, 0xb1, 4, 1),
+	PLL_35XX_RATE(360000000, 0x70, 2, 1),
+	PLL_35XX_RATE(350000000, 0xa7, 4, 1),
+	PLL_35XX_RATE(340000000, 0x4d, 1, 1),
+	PLL_35XX_RATE(330000000, 0x66, 2, 1),
+	PLL_35XX_RATE(320000000, 0x98, 4, 1),
+	PLL_35XX_RATE(310000000, 0x93, 4, 1),
+	PLL_35XX_RATE(300000000, 0x75, 3, 1),
+	PLL_35XX_RATE(240000000, 0x70, 1, 2),
+	PLL_35XX_RATE(230000000, 0x6b, 1, 2),
+	PLL_35XX_RATE(220000000, 0x66, 1, 2),
+	PLL_35XX_RATE(210000000, 0x84, 2, 2),
+	PLL_35XX_RATE(200000000, 0x5c, 1, 2),
+	PLL_35XX_RATE(190000000, 0x57, 1, 2),
+	PLL_35XX_RATE(180000000, 0x70, 2, 2),
+	PLL_35XX_RATE(170000000, 0x4d, 1, 2),
+	PLL_35XX_RATE(160000000, 0x98, 4, 2),
+	PLL_35XX_RATE(150000000, 0x75, 3, 2),
+	PLL_35XX_RATE(120000000, 0x70, 1, 3),
+	PLL_35XX_RATE(110000000, 0x66, 1, 3),
+	PLL_35XX_RATE(100000000, 0x5c, 1, 3),
+	PLL_35XX_RATE(90000000, 0x70, 2, 3),
+	PLL_35XX_RATE(80000000, 0x98, 4, 3),
+	PLL_35XX_RATE(75000000, 0x75, 3, 3),
+};
+
+static struct samsung_pll_clock s3c244x_common_plls[] __initdata = {
+	[mpll] = PLL(pll_s3c2440_mpll, MPLL, "mpll", "xti",
+						LOCKTIME, MPLLCON, NULL),
+	[upll] = PLL(pll_s3c2410_upll, UPLL, "upll", "xti",
+						LOCKTIME, UPLLCON, NULL),
+};
+
+PNAME(hclk_p) = { "fclk", "div_hclk_2", "div_hclk_4", "div_hclk_3" };
+PNAME(armclk_p) = { "fclk", "hclk" };
+
+struct samsung_mux_clock s3c244x_common_muxes[] __initdata = {
+	MUX(HCLK, "hclk", hclk_p, CLKDIVN, 1, 2),
+	MUX(ARMCLK, "armclk", armclk_p, CAMDIVN, 12, 1),
+};
+
+struct samsung_fixed_factor_clock s3c244x_common_ffactor[] __initdata = {
+	FFACTOR(0, "div_hclk_2", "fclk", 1, 2, 0),
+	FFACTOR(0, "ff_cam", "div_cam", 2, 1, CLK_SET_RATE_PARENT),
+};
+
+static struct clk_div_table div_hclk_4_d[] = {
+	{ .val = 0, .div = 4 },
+	{ .val = 1, .div = 8 },
+};
+
+static struct clk_div_table div_hclk_3_d[] = {
+	{ .val = 0, .div = 3 },
+	{ .val = 1, .div = 6 },
+};
+
+struct samsung_div_clock s3c244x_common_dividers[] __initdata = {
+	DIV(UCLK, "uclk", "upll", CLKDIVN, 3, 1),
+	DIV(0, "div_hclk", "fclk", CLKDIVN, 1, 1),
+	DIV_T(0, "div_hclk_4", "fclk", CAMDIVN, 9, 1, div_hclk_4_d),
+	DIV_T(0, "div_hclk_3", "fclk", CAMDIVN, 8, 1, div_hclk_3_d),
+	DIV(0, "div_cam", "upll", CAMDIVN, 0, 3),
+};
+
+struct samsung_gate_clock s3c244x_common_gates[] __initdata = {
+	GATE(HCLK_CAM, "cam", "hclk", CLKCON, 19, 0, 0),
+};
+
+struct samsung_clock_alias s3c244x_common_aliases[] __initdata = {
+	ALIAS(PCLK_UART0, "s3c2440-uart.0", "uart"),
+	ALIAS(PCLK_UART1, "s3c2440-uart.1", "uart"),
+	ALIAS(PCLK_UART2, "s3c2440-uart.2", "uart"),
+	ALIAS(PCLK_UART0, "s3c2440-uart.0", "clk_uart_baud2"),
+	ALIAS(PCLK_UART1, "s3c2440-uart.1", "clk_uart_baud2"),
+	ALIAS(PCLK_UART2, "s3c2440-uart.2", "clk_uart_baud2"),
+	ALIAS(HCLK_CAM, NULL, "camif"),
+	ALIAS(CAMIF, NULL, "camif-upll"),
+};
+
+/* S3C2440 specific clocks */
+
+PNAME(s3c2440_camif_p) = { "upll", "ff_cam" };
+
+struct samsung_mux_clock s3c2440_muxes[] __initdata = {
+	MUX(CAMIF, "camif", s3c2440_camif_p, CAMDIVN, 4, 1),
+};
+
+struct samsung_gate_clock s3c2440_gates[] __initdata = {
+	GATE(PCLK_AC97, "ac97", "pclk", CLKCON, 20, 0, 0),
+};
+
+/* S3C2442 specific clocks */
+
+struct samsung_fixed_factor_clock s3c2442_ffactor[] __initdata = {
+	FFACTOR(0, "upll_3", "upll", 1, 3, 0),
+};
+
+PNAME(s3c2442_camif_p) = { "upll", "ff_cam", "upll", "upll_3" };
+
+struct samsung_mux_clock s3c2442_muxes[] __initdata = {
+	MUX(CAMIF, "camif", s3c2442_camif_p, CAMDIVN, 4, 2),
+};
+
+/*
+ * fixed rate clocks generated outside the soc
+ * Only necessary until the devicetree-move is complete
+ */
+struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata = {
+	FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0),
+};
+
+static void __init s3c2410_common_clk_register_fixed_ext(unsigned long xti_f)
+{
+	struct samsung_clock_alias xti_alias = ALIAS(XTI, NULL, "xtal");
+
+	s3c2410_common_frate_clks[0].fixed_rate = xti_f;
+	samsung_clk_register_fixed_rate(s3c2410_common_frate_clks,
+				ARRAY_SIZE(s3c2410_common_frate_clks));
+
+	samsung_clk_register_alias(&xti_alias, 1);
+}
+
+void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
+				    int current_soc,
+				    void __iomem *reg_base)
+{
+	if (np) {
+		reg_base = of_iomap(np, 0);
+		if (!reg_base)
+			panic("%s: failed to map registers\n", __func__);
+	}
+
+	samsung_clk_init(np, reg_base, NR_CLKS,
+		s3c2410_clk_regs, ARRAY_SIZE(s3c2410_clk_regs), NULL, 0);
+
+	/* Register external clocks only in non-dt cases */
+	if (!np)
+		s3c2410_common_clk_register_fixed_ext(xti_f);
+
+	if (current_soc == 2410) {
+		if (_get_rate("xti") == 12 * MHZ) {
+			s3c2410_plls[mpll].rate_table = pll_s3c2410_12mhz_tbl;
+			s3c2410_plls[upll].rate_table = pll_s3c2410_12mhz_tbl;
+		}
+
+		/* Register PLLs. */
+		samsung_clk_register_pll(s3c2410_plls,
+				ARRAY_SIZE(s3c2410_plls), reg_base);
+
+	} else { /* S3C2440, S3C2442 */
+		if (_get_rate("xti") == 12 * MHZ) {
+			/*
+			 * plls follow different calculation schemes, with the
+			 * upll following the same scheme as the s3c2410 plls
+			 */
+			s3c244x_common_plls[mpll].rate_table =
+							pll_s3c244x_12mhz_tbl;
+			s3c244x_common_plls[upll].rate_table =
+							pll_s3c2410_12mhz_tbl;
+		}
+
+		/* Register PLLs. */
+		samsung_clk_register_pll(s3c244x_common_plls,
+				ARRAY_SIZE(s3c244x_common_plls), reg_base);
+	}
+
+	/* Register common internal clocks. */
+	samsung_clk_register_mux(s3c2410_common_muxes,
+			ARRAY_SIZE(s3c2410_common_muxes));
+	samsung_clk_register_div(s3c2410_common_dividers,
+			ARRAY_SIZE(s3c2410_common_dividers));
+	samsung_clk_register_gate(s3c2410_common_gates,
+		ARRAY_SIZE(s3c2410_common_gates));
+
+	if (current_soc == S3C2440 || current_soc == S3C2442) {
+		samsung_clk_register_div(s3c244x_common_dividers,
+				ARRAY_SIZE(s3c244x_common_dividers));
+		samsung_clk_register_gate(s3c244x_common_gates,
+				ARRAY_SIZE(s3c244x_common_gates));
+		samsung_clk_register_mux(s3c244x_common_muxes,
+				ARRAY_SIZE(s3c244x_common_muxes));
+		samsung_clk_register_fixed_factor(s3c244x_common_ffactor,
+				ARRAY_SIZE(s3c244x_common_ffactor));
+	}
+
+	/* Register SoC-specific clocks. */
+	switch (current_soc) {
+	case S3C2410:
+		samsung_clk_register_div(s3c2410_dividers,
+				ARRAY_SIZE(s3c2410_dividers));
+		samsung_clk_register_fixed_factor(s3c2410_ffactor,
+				ARRAY_SIZE(s3c2410_ffactor));
+		samsung_clk_register_alias(s3c2410_aliases,
+			ARRAY_SIZE(s3c2410_common_aliases));
+		break;
+	case S3C2440:
+		samsung_clk_register_mux(s3c2440_muxes,
+				ARRAY_SIZE(s3c2440_muxes));
+		samsung_clk_register_gate(s3c2440_gates,
+				ARRAY_SIZE(s3c2440_gates));
+		break;
+	case S3C2442:
+		samsung_clk_register_mux(s3c2442_muxes,
+				ARRAY_SIZE(s3c2442_muxes));
+		samsung_clk_register_fixed_factor(s3c2442_ffactor,
+				ARRAY_SIZE(s3c2442_ffactor));
+		break;
+	}
+
+	/*
+	 * Register common aliases at the end, as some of the aliased clocks
+	 * are SoC specific.
+	 */
+	samsung_clk_register_alias(s3c2410_common_aliases,
+		ARRAY_SIZE(s3c2410_common_aliases));
+
+	if (current_soc == S3C2440 || current_soc == S3C2442) {
+		samsung_clk_register_alias(s3c244x_common_aliases,
+			ARRAY_SIZE(s3c244x_common_aliases));
+	}
+}
+
+static void __init s3c2410_clk_init(struct device_node *np)
+{
+	s3c2410_common_clk_init(np, 0, S3C2410, 0);
+}
+CLK_OF_DECLARE(s3c2410_clk, "samsung,s3c2410-clock", s3c2410_clk_init);
+
+static void __init s3c2440_clk_init(struct device_node *np)
+{
+	s3c2410_common_clk_init(np, 0, S3C2440, 0);
+}
+CLK_OF_DECLARE(s3c2440_clk, "samsung,s3c2440-clock", s3c2440_clk_init);
+
+static void __init s3c2442_clk_init(struct device_node *np)
+{
+	s3c2410_common_clk_init(np, 0, S3C2442, 0);
+}
+CLK_OF_DECLARE(s3c2442_clk, "samsung,s3c2442-clock", s3c2442_clk_init);
diff --git a/include/dt-bindings/clock/samsung,s3c2410-clock.h b/include/dt-bindings/clock/samsung,s3c2410-clock.h
new file mode 100644
index 0000000..66c278f
--- /dev/null
+++ b/include/dt-bindings/clock/samsung,s3c2410-clock.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
+ *
+ * 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.
+ *
+ * Device Tree binding constants clock controllers of Samsung S3C2410 and later.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C2410_CLOCK_H
+#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C2410_CLOCK_H
+
+/*
+ * Let each exported clock get a unique index, which is used on DT-enabled
+ * platforms to lookup the clock from a clock specifier. These indices are
+ * therefore considered an ABI and so must not be changed. This implies
+ * that new clocks should be added either in free spaces between clock groups
+ * or at the end.
+ */
+
+/* Core clocks. */
+
+
+#define MPLL			1
+#define UPLL			2
+#define FCLK			3
+#define HCLK			4
+#define PCLK			5
+#define UCLK			6
+#define ARMCLK			7
+
+#define XTI			8
+
+/* pclk-gates */
+#define PCLK_UART0		16
+#define PCLK_UART1		17
+#define PCLK_UART2		18
+#define PCLK_I2C		19
+#define PCLK_SDI		20
+#define PCLK_SPI		21
+#define PCLK_ADC		22
+#define PCLK_AC97		23
+#define PCLK_I2S		24
+#define PCLK_PWM		25
+#define PCLK_RTC		26
+#define PCLK_GPIO		27
+
+
+/* hclk-gates */
+#define HCLK_LCD		32
+#define HCLK_USBH		33
+#define HCLK_USBD		34
+#define HCLK_NAND		35
+#define HCLK_CAM		36
+
+
+#define CAMIF			40
+
+
+/* Total number of clocks. */
+#define NR_CLKS			(CAMIF + 1)
+
+#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_S3C2443_CLOCK_H */
-- 
1.7.10.4

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

* [PATCH 09/12] ARM: S3C24XX: add platform code for conversion to the common clock framework
  2013-12-13 12:56 ` Heiko Stübner
@ 2013-12-13 13:02   ` Heiko Stübner
  -1 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 13:02 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: t.figa, mturquette, linux-arm-kernel, linux-samsung-soc

This adds the necessary init functions to init the clocks from the common
clock framework and necessary CONFIG_SAMSUNG_CLOCK ifdefs around the legacy
clock code.

This also includes empty stubs for the *_setup_clocks functions that are
called from the cpufreq driver on resume.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/Kconfig   |    5 +++++
 arch/arm/mach-s3c24xx/common.c  |   25 +++++++++++++++++++++++++
 arch/arm/mach-s3c24xx/common.h  |    7 +++++++
 arch/arm/mach-s3c24xx/s3c2410.c |    6 ++++++
 arch/arm/mach-s3c24xx/s3c2442.c |    3 ++-
 arch/arm/mach-s3c24xx/s3c244x.c |    6 ++++++
 6 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index b06a7a3..2a9a18c 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -18,6 +18,11 @@ config PLAT_S3C24XX
 	help
 	  Base platform code for any Samsung S3C24XX device
 
+config S3C2410_COMMON_CLK
+	bool
+	help
+	  Build the s3c2410 clock driver based on the common clock framework.
+
 config S3C2410_COMMON_DCLK
 	bool
 	select REGMAP_MMIO
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index 051ed5e..66dcb0e 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -53,6 +53,7 @@
 #include <plat/cpu-freq.h>
 #include <plat/pll.h>
 #include <plat/pwm-core.h>
+#include <plat/watchdog-reset.h>
 
 #include "common.h"
 
@@ -536,6 +537,14 @@ struct platform_device s3c2443_device_dma = {
 };
 #endif
 
+#if defined(CONFIG_COMMON_CLK) && defined(CONFIG_CPU_S3C2410)
+void __init s3c2410_init_clocks(int xtal)
+{
+	s3c2410_common_clk_init(NULL, xtal, 0, S3C24XX_VA_CLKPWR);
+	samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
+}
+#endif
+
 #ifdef CONFIG_CPU_S3C2416
 void __init s3c2416_init_clocks(int xtal)
 {
@@ -543,6 +552,22 @@ void __init s3c2416_init_clocks(int xtal)
 }
 #endif
 
+#if defined(CONFIG_COMMON_CLK) && defined(CONFIG_CPU_S3C2440)
+void __init s3c2440_init_clocks(int xtal)
+{
+	s3c2410_common_clk_init(NULL, xtal, 1, S3C24XX_VA_CLKPWR);
+	samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
+}
+#endif
+
+#if defined(CONFIG_COMMON_CLK) && defined(CONFIG_CPU_S3C2442)
+void __init s3c2442_init_clocks(int xtal)
+{
+	s3c2410_common_clk_init(NULL, xtal, 2, S3C24XX_VA_CLKPWR);
+	samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
+}
+#endif
+
 #ifdef CONFIG_CPU_S3C2443
 void __init s3c2443_init_clocks(int xtal)
 {
diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h
index e16b601..4b3157e 100644
--- a/arch/arm/mach-s3c24xx/common.h
+++ b/arch/arm/mach-s3c24xx/common.h
@@ -77,6 +77,7 @@ extern void s3c244x_restart(enum reboot_mode mode, const char *cmd);
 #ifdef CONFIG_CPU_S3C2440
 extern  int s3c2440_init(void);
 extern void s3c2440_map_io(void);
+extern void s3c2440_init_clocks(int xtal);
 extern void s3c2440_init_irq(void);
 #else
 #define s3c2440_init NULL
@@ -86,6 +87,7 @@ extern void s3c2440_init_irq(void);
 #ifdef CONFIG_CPU_S3C2442
 extern  int s3c2442_init(void);
 extern void s3c2442_map_io(void);
+extern void s3c2442_init_clocks(int xtal);
 extern void s3c2442_init_irq(void);
 #else
 #define s3c2442_init NULL
@@ -116,6 +118,11 @@ extern struct platform_device s3c2443_device_dma;
 
 extern struct platform_device s3c2410_device_dclk;
 
+#ifdef CONFIG_S3C2410_COMMON_CLK
+void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
+				    int current_soc,
+				    void __iomem *reg_base);
+#endif
 #ifdef CONFIG_S3C2443_COMMON_CLK
 void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
 				    int current_soc,
diff --git a/arch/arm/mach-s3c24xx/s3c2410.c b/arch/arm/mach-s3c24xx/s3c2410.c
index 34676d1..04bed99 100644
--- a/arch/arm/mach-s3c24xx/s3c2410.c
+++ b/arch/arm/mach-s3c24xx/s3c2410.c
@@ -82,6 +82,7 @@ void __init s3c2410_map_io(void)
 	iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
 }
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 void __init_or_cpufreq s3c2410_setup_clocks(void)
 {
 	struct clk *xtal_clk;
@@ -141,6 +142,11 @@ void __init s3c2410_init_clocks(int xtal)
 	clkdev_add_table(s3c2410_clk_lookup, ARRAY_SIZE(s3c2410_clk_lookup));
 	samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
 }
+#else
+void __init_or_cpufreq s3c2410_setup_clocks(void)
+{
+}
+#endif
 
 struct bus_type s3c2410_subsys = {
 	.name = "s3c2410-core",
diff --git a/arch/arm/mach-s3c24xx/s3c2442.c b/arch/arm/mach-s3c24xx/s3c2442.c
index 6819961..a4c1519 100644
--- a/arch/arm/mach-s3c24xx/s3c2442.c
+++ b/arch/arm/mach-s3c24xx/s3c2442.c
@@ -52,6 +52,7 @@
 
 #include "common.h"
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 /* S3C2442 extended clock support */
 
 static unsigned long s3c2442_camif_upll_round(struct clk *clk,
@@ -161,7 +162,7 @@ static __init int s3c2442_clk_init(void)
 }
 
 arch_initcall(s3c2442_clk_init);
-
+#endif
 
 static struct device s3c2442_dev = {
 	.bus		= &s3c2442_subsys,
diff --git a/arch/arm/mach-s3c24xx/s3c244x.c b/arch/arm/mach-s3c24xx/s3c244x.c
index 0ce2538..aaaf90d2 100644
--- a/arch/arm/mach-s3c24xx/s3c244x.c
+++ b/arch/arm/mach-s3c24xx/s3c244x.c
@@ -78,6 +78,7 @@ void __init s3c244x_map_io(void)
 	s3c2410_device_dclk.name = "s3c2440-dclk";
 }
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 void __init_or_cpufreq s3c244x_setup_clocks(void)
 {
 	struct clk *xtal_clk;
@@ -138,6 +139,11 @@ void __init s3c244x_init_clocks(int xtal)
 	s3c2410_baseclk_add();
 	samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
 }
+#else
+void __init_or_cpufreq s3c244x_setup_clocks(void)
+{
+}
+#endif
 
 /* Since the S3C2442 and S3C2440 share items, put both subsystems here */
 
-- 
1.7.10.4

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

* [PATCH 09/12] ARM: S3C24XX: add platform code for conversion to the common clock framework
@ 2013-12-13 13:02   ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 13:02 UTC (permalink / raw)
  To: linux-arm-kernel

This adds the necessary init functions to init the clocks from the common
clock framework and necessary CONFIG_SAMSUNG_CLOCK ifdefs around the legacy
clock code.

This also includes empty stubs for the *_setup_clocks functions that are
called from the cpufreq driver on resume.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/Kconfig   |    5 +++++
 arch/arm/mach-s3c24xx/common.c  |   25 +++++++++++++++++++++++++
 arch/arm/mach-s3c24xx/common.h  |    7 +++++++
 arch/arm/mach-s3c24xx/s3c2410.c |    6 ++++++
 arch/arm/mach-s3c24xx/s3c2442.c |    3 ++-
 arch/arm/mach-s3c24xx/s3c244x.c |    6 ++++++
 6 files changed, 51 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index b06a7a3..2a9a18c 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -18,6 +18,11 @@ config PLAT_S3C24XX
 	help
 	  Base platform code for any Samsung S3C24XX device
 
+config S3C2410_COMMON_CLK
+	bool
+	help
+	  Build the s3c2410 clock driver based on the common clock framework.
+
 config S3C2410_COMMON_DCLK
 	bool
 	select REGMAP_MMIO
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index 051ed5e..66dcb0e 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -53,6 +53,7 @@
 #include <plat/cpu-freq.h>
 #include <plat/pll.h>
 #include <plat/pwm-core.h>
+#include <plat/watchdog-reset.h>
 
 #include "common.h"
 
@@ -536,6 +537,14 @@ struct platform_device s3c2443_device_dma = {
 };
 #endif
 
+#if defined(CONFIG_COMMON_CLK) && defined(CONFIG_CPU_S3C2410)
+void __init s3c2410_init_clocks(int xtal)
+{
+	s3c2410_common_clk_init(NULL, xtal, 0, S3C24XX_VA_CLKPWR);
+	samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
+}
+#endif
+
 #ifdef CONFIG_CPU_S3C2416
 void __init s3c2416_init_clocks(int xtal)
 {
@@ -543,6 +552,22 @@ void __init s3c2416_init_clocks(int xtal)
 }
 #endif
 
+#if defined(CONFIG_COMMON_CLK) && defined(CONFIG_CPU_S3C2440)
+void __init s3c2440_init_clocks(int xtal)
+{
+	s3c2410_common_clk_init(NULL, xtal, 1, S3C24XX_VA_CLKPWR);
+	samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
+}
+#endif
+
+#if defined(CONFIG_COMMON_CLK) && defined(CONFIG_CPU_S3C2442)
+void __init s3c2442_init_clocks(int xtal)
+{
+	s3c2410_common_clk_init(NULL, xtal, 2, S3C24XX_VA_CLKPWR);
+	samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
+}
+#endif
+
 #ifdef CONFIG_CPU_S3C2443
 void __init s3c2443_init_clocks(int xtal)
 {
diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h
index e16b601..4b3157e 100644
--- a/arch/arm/mach-s3c24xx/common.h
+++ b/arch/arm/mach-s3c24xx/common.h
@@ -77,6 +77,7 @@ extern void s3c244x_restart(enum reboot_mode mode, const char *cmd);
 #ifdef CONFIG_CPU_S3C2440
 extern  int s3c2440_init(void);
 extern void s3c2440_map_io(void);
+extern void s3c2440_init_clocks(int xtal);
 extern void s3c2440_init_irq(void);
 #else
 #define s3c2440_init NULL
@@ -86,6 +87,7 @@ extern void s3c2440_init_irq(void);
 #ifdef CONFIG_CPU_S3C2442
 extern  int s3c2442_init(void);
 extern void s3c2442_map_io(void);
+extern void s3c2442_init_clocks(int xtal);
 extern void s3c2442_init_irq(void);
 #else
 #define s3c2442_init NULL
@@ -116,6 +118,11 @@ extern struct platform_device s3c2443_device_dma;
 
 extern struct platform_device s3c2410_device_dclk;
 
+#ifdef CONFIG_S3C2410_COMMON_CLK
+void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
+				    int current_soc,
+				    void __iomem *reg_base);
+#endif
 #ifdef CONFIG_S3C2443_COMMON_CLK
 void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f,
 				    int current_soc,
diff --git a/arch/arm/mach-s3c24xx/s3c2410.c b/arch/arm/mach-s3c24xx/s3c2410.c
index 34676d1..04bed99 100644
--- a/arch/arm/mach-s3c24xx/s3c2410.c
+++ b/arch/arm/mach-s3c24xx/s3c2410.c
@@ -82,6 +82,7 @@ void __init s3c2410_map_io(void)
 	iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
 }
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 void __init_or_cpufreq s3c2410_setup_clocks(void)
 {
 	struct clk *xtal_clk;
@@ -141,6 +142,11 @@ void __init s3c2410_init_clocks(int xtal)
 	clkdev_add_table(s3c2410_clk_lookup, ARRAY_SIZE(s3c2410_clk_lookup));
 	samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
 }
+#else
+void __init_or_cpufreq s3c2410_setup_clocks(void)
+{
+}
+#endif
 
 struct bus_type s3c2410_subsys = {
 	.name = "s3c2410-core",
diff --git a/arch/arm/mach-s3c24xx/s3c2442.c b/arch/arm/mach-s3c24xx/s3c2442.c
index 6819961..a4c1519 100644
--- a/arch/arm/mach-s3c24xx/s3c2442.c
+++ b/arch/arm/mach-s3c24xx/s3c2442.c
@@ -52,6 +52,7 @@
 
 #include "common.h"
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 /* S3C2442 extended clock support */
 
 static unsigned long s3c2442_camif_upll_round(struct clk *clk,
@@ -161,7 +162,7 @@ static __init int s3c2442_clk_init(void)
 }
 
 arch_initcall(s3c2442_clk_init);
-
+#endif
 
 static struct device s3c2442_dev = {
 	.bus		= &s3c2442_subsys,
diff --git a/arch/arm/mach-s3c24xx/s3c244x.c b/arch/arm/mach-s3c24xx/s3c244x.c
index 0ce2538..aaaf90d2 100644
--- a/arch/arm/mach-s3c24xx/s3c244x.c
+++ b/arch/arm/mach-s3c24xx/s3c244x.c
@@ -78,6 +78,7 @@ void __init s3c244x_map_io(void)
 	s3c2410_device_dclk.name = "s3c2440-dclk";
 }
 
+#ifdef CONFIG_SAMSUNG_CLOCK
 void __init_or_cpufreq s3c244x_setup_clocks(void)
 {
 	struct clk *xtal_clk;
@@ -138,6 +139,11 @@ void __init s3c244x_init_clocks(int xtal)
 	s3c2410_baseclk_add();
 	samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
 }
+#else
+void __init_or_cpufreq s3c244x_setup_clocks(void)
+{
+}
+#endif
 
 /* Since the S3C2442 and S3C2440 share items, put both subsystems here */
 
-- 
1.7.10.4

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

* [PATCH 10/12] ARM: S3C24XX: convert s3c2440 and s3c2442 to common clock framework
  2013-12-13 12:56 ` Heiko Stübner
@ 2013-12-13 13:02   ` Heiko Stübner
  -1 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 13:02 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: t.figa, mturquette, linux-arm-kernel, linux-samsung-soc

Convert all machines using these cpus to use the ccf clock driver
instead of the legacy Samsung clock implementation.

Some of the more esotheric machines will probably need a fixup, as they
do strange things to the clkout outputs, that I did not really understand
nor have the hardware to check.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/Kconfig          |    8 ++++----
 arch/arm/mach-s3c24xx/Makefile         |    4 ++--
 arch/arm/mach-s3c24xx/common.c         |    4 ----
 arch/arm/mach-s3c24xx/mach-anubis.c    |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-at2440evb.c |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-gta02.c     |    8 ++++++--
 arch/arm/mach-s3c24xx/mach-mini2440.c  |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-nexcoder.c  |   15 ++++++++++++---
 arch/arm/mach-s3c24xx/mach-osiris.c    |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-rx1950.c    |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-rx3715.c    |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-smdk2440.c  |   10 +++++++---
 12 files changed, 73 insertions(+), 36 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index 2a9a18c..c06197f 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -72,10 +72,10 @@ config CPU_S3C2416
 
 config CPU_S3C2440
 	bool "SAMSUNG S3C2440"
-	depends on SAMSUNG_CLOCK
+	select COMMON_CLK
 	select CPU_ARM920T
 	select CPU_LLSERIAL_S3C2440
-	select S3C2410_CLOCK
+	select S3C2410_COMMON_CLK
 	select S3C2410_PM if PM
 	select S3C2440_DMA if S3C24XX_DMA
 	help
@@ -83,10 +83,10 @@ config CPU_S3C2440
 
 config CPU_S3C2442
 	bool "SAMSUNG S3C2442"
-	depends on SAMSUNG_CLOCK
+	select COMMON_CLK
 	select CPU_ARM920T
 	select CPU_LLSERIAL_S3C2440
-	select S3C2410_CLOCK
+	select S3C2410_COMMON_CLK
 	select S3C2410_DMA if S3C24XX_DMA
 	select S3C2410_PM if PM
 	help
diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index ba0e547..720bf7a 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -29,9 +29,9 @@ obj-$(CONFIG_S3C2412_PM_SLEEP)	+= sleep-s3c2412.o
 obj-$(CONFIG_CPU_S3C2416)	+= s3c2416.o
 obj-$(CONFIG_S3C2416_PM)	+= pm-s3c2416.o
 
-obj-$(CONFIG_CPU_S3C2440)	+= s3c2440.o clock-s3c2440.o
+obj-$(CONFIG_CPU_S3C2440)	+= s3c2440.o
 obj-$(CONFIG_CPU_S3C2442)	+= s3c2442.o
-obj-$(CONFIG_CPU_S3C244X)	+= s3c244x.o clock-s3c244x.o
+obj-$(CONFIG_CPU_S3C244X)	+= s3c244x.o
 obj-$(CONFIG_S3C2440_DMA)	+= dma-s3c2440.o
 obj-$(CONFIG_S3C2440_PLL_12000000) += pll-s3c2440-12000000.o
 obj-$(CONFIG_S3C2440_PLL_16934400) += pll-s3c2440-16934400.o
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index 66dcb0e..cf00c4a 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -92,7 +92,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idcode		= 0x32440000,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2440_map_io,
-		.init_clocks	= s3c244x_init_clocks,
 		.init_uarts	= s3c244x_init_uarts,
 		.init		= s3c2440_init,
 		.name		= name_s3c2440
@@ -101,7 +100,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idcode		= 0x32440001,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2440_map_io,
-		.init_clocks	= s3c244x_init_clocks,
 		.init_uarts	= s3c244x_init_uarts,
 		.init		= s3c2440_init,
 		.name		= name_s3c2440a
@@ -110,7 +108,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idcode		= 0x32440aaa,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2442_map_io,
-		.init_clocks	= s3c244x_init_clocks,
 		.init_uarts	= s3c244x_init_uarts,
 		.init		= s3c2442_init,
 		.name		= name_s3c2442
@@ -119,7 +116,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idcode		= 0x32440aab,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2442_map_io,
-		.init_clocks	= s3c244x_init_clocks,
 		.init_uarts	= s3c244x_init_uarts,
 		.init		= s3c2442_init,
 		.name		= name_s3c2442b
diff --git a/arch/arm/mach-s3c24xx/mach-anubis.c b/arch/arm/mach-s3c24xx/mach-anubis.c
index a7d1721a..e43f984 100644
--- a/arch/arm/mach-s3c24xx/mach-anubis.c
+++ b/arch/arm/mach-s3c24xx/mach-anubis.c
@@ -45,7 +45,6 @@
 
 #include <net/ax88796.h>
 
-#include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <linux/platform_data/asoc-s3c24xx_simtec.h>
@@ -414,7 +413,6 @@ static void __init anubis_map_io(void)
 #endif
 
 	s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
@@ -432,6 +430,12 @@ static void __init anubis_map_io(void)
 	}
 }
 
+static void __init anubis_init_time(void)
+{
+	s3c2440_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init anubis_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
@@ -451,6 +455,6 @@ MACHINE_START(ANUBIS, "Simtec-Anubis")
 	.map_io		= anubis_map_io,
 	.init_machine	= anubis_init,
 	.init_irq	= s3c2440_init_irq,
-	.init_time	= samsung_timer_init,
+	.init_time	= anubis_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-at2440evb.c b/arch/arm/mach-s3c24xx/mach-at2440evb.c
index 6dfeeb7..f3ac0af 100644
--- a/arch/arm/mach-s3c24xx/mach-at2440evb.c
+++ b/arch/arm/mach-s3c24xx/mach-at2440evb.c
@@ -44,7 +44,6 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
-#include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <linux/platform_data/mmc-s3cmci.h>
@@ -191,11 +190,16 @@ static struct platform_device *at2440evb_devices[] __initdata = {
 static void __init at2440evb_map_io(void)
 {
 	s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc));
-	s3c24xx_init_clocks(16934400);
 	s3c24xx_init_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init at2440evb_init_time(void)
+{
+	s3c2440_init_clocks(16934400);
+	samsung_timer_init();
+}
+
 static void __init at2440evb_init(void)
 {
 	s3c24xx_fb_set_platdata(&at2440evb_fb_info);
@@ -212,6 +216,6 @@ MACHINE_START(AT2440EVB, "AT2440EVB")
 	.map_io		= at2440evb_map_io,
 	.init_machine	= at2440evb_init,
 	.init_irq	= s3c2440_init_irq,
-	.init_time	= samsung_timer_init,
+	.init_time	= at2440evb_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c
index 13d8d07..d8cd88c 100644
--- a/arch/arm/mach-s3c24xx/mach-gta02.c
+++ b/arch/arm/mach-s3c24xx/mach-gta02.c
@@ -500,7 +500,6 @@ static struct platform_device gta02_buttons_device = {
 static void __init gta02_map_io(void)
 {
 	s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc));
-	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
@@ -584,6 +583,11 @@ static void __init gta02_machine_init(void)
 	regulator_has_full_constraints();
 }
 
+static void __init gta02_init_time(void)
+{
+	s3c2442_init_clocks(12000000);
+	samsung_timer_init();
+}
 
 MACHINE_START(NEO1973_GTA02, "GTA02")
 	/* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
@@ -591,6 +595,6 @@ MACHINE_START(NEO1973_GTA02, "GTA02")
 	.map_io		= gta02_map_io,
 	.init_irq	= s3c2442_init_irq,
 	.init_machine	= gta02_machine_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= gta02_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c
index 4a18d49..d2b38f0 100644
--- a/arch/arm/mach-s3c24xx/mach-mini2440.c
+++ b/arch/arm/mach-s3c24xx/mach-mini2440.c
@@ -53,7 +53,6 @@
 #include <linux/mtd/partitions.h>
 
 #include <plat/gpio-cfg.h>
-#include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/samsung-time.h>
@@ -524,11 +523,16 @@ static struct platform_device *mini2440_devices[] __initdata = {
 static void __init mini2440_map_io(void)
 {
 	s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc));
-	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init mini2440_init_time(void)
+{
+	s3c2440_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 /*
  * mini2440_features string
  *
@@ -689,6 +693,6 @@ MACHINE_START(MINI2440, "MINI2440")
 	.map_io		= mini2440_map_io,
 	.init_machine	= mini2440_init,
 	.init_irq	= s3c2440_init_irq,
-	.init_time	= samsung_timer_init,
+	.init_time	= mini2440_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-nexcoder.c b/arch/arm/mach-s3c24xx/mach-nexcoder.c
index 01f4354..9ece48a 100644
--- a/arch/arm/mach-s3c24xx/mach-nexcoder.c
+++ b/arch/arm/mach-s3c24xx/mach-nexcoder.c
@@ -41,7 +41,6 @@
 #include <linux/platform_data/i2c-s3c2410.h>
 
 #include <plat/gpio-cfg.h>
-#include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/samsung-time.h>
@@ -134,13 +133,23 @@ static void __init nexcoder_sensorboard_init(void)
 static void __init nexcoder_map_io(void)
 {
 	s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
 	nexcoder_sensorboard_init();
 }
 
+static void __init nexcoder_init_time(void)
+{
+	/*
+	 * for whatever reason the nexcoder called s3c24xx_init_clocks(0)
+	 * meaning a xti value of 0Hz, so this machine will most likely
+	 * not work out of the box and needs a fixup.
+	 */
+	s3c2440_init_clocks(0);
+	samsung_timer_init();
+}
+
 static void __init nexcoder_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
@@ -153,6 +162,6 @@ MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
 	.map_io		= nexcoder_map_io,
 	.init_machine	= nexcoder_init,
 	.init_irq	= s3c2440_init_irq,
-	.init_time	= samsung_timer_init,
+	.init_time	= nexcoder_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-osiris.c b/arch/arm/mach-s3c24xx/mach-osiris.c
index d55d88d..a0d290b 100644
--- a/arch/arm/mach-s3c24xx/mach-osiris.c
+++ b/arch/arm/mach-s3c24xx/mach-osiris.c
@@ -39,7 +39,6 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
-#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/cpu-freq.h>
 #include <plat/devs.h>
@@ -388,7 +387,6 @@ static void __init osiris_map_io(void)
 #endif
 
 	s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
@@ -412,6 +410,12 @@ static void __init osiris_map_io(void)
 	local_irq_restore(flags);
 }
 
+static void __init osiris_init_time(void)
+{
+	s3c2440_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init osiris_init(void)
 {
 	register_syscore_ops(&osiris_pm_syscore_ops);
@@ -433,6 +437,6 @@ MACHINE_START(OSIRIS, "Simtec-OSIRIS")
 	.map_io		= osiris_map_io,
 	.init_irq	= s3c2440_init_irq,
 	.init_machine	= osiris_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= osiris_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c
index a0f12d1..b46312a 100644
--- a/arch/arm/mach-s3c24xx/mach-rx1950.c
+++ b/arch/arm/mach-s3c24xx/mach-rx1950.c
@@ -52,7 +52,6 @@
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
-#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/pm.h>
@@ -744,7 +743,6 @@ static void __init rx1950_map_io(void)
 #endif
 
 	s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc));
-	s3c24xx_init_clocks(16934000);
 	s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
@@ -757,6 +755,12 @@ static void __init rx1950_map_io(void)
 	s3c_pm_init();
 }
 
+static void __init rx1950_init_time(void)
+{
+	s3c2442_init_clocks(16934000);
+	samsung_timer_init();
+}
+
 static void __init rx1950_init_machine(void)
 {
 	int i;
@@ -819,6 +823,6 @@ MACHINE_START(RX1950, "HP iPAQ RX1950")
 	.reserve	= rx1950_reserve,
 	.init_irq	= s3c2442_init_irq,
 	.init_machine = rx1950_init_machine,
-	.init_time	= samsung_timer_init,
+	.init_time	= rx1950_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-rx3715.c b/arch/arm/mach-s3c24xx/mach-rx3715.c
index 3bc6231..d842f45 100644
--- a/arch/arm/mach-s3c24xx/mach-rx3715.c
+++ b/arch/arm/mach-s3c24xx/mach-rx3715.c
@@ -44,7 +44,6 @@
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
-#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/pm.h>
@@ -178,11 +177,16 @@ static struct platform_device *rx3715_devices[] __initdata = {
 static void __init rx3715_map_io(void)
 {
 	s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
-	s3c24xx_init_clocks(16934000);
 	s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init rx3715_init_time(void)
+{
+	s3c2440_init_clocks(16934000);
+	samsung_timer_init();
+}
+
 /* H1940 and RX3715 need to reserve this for suspend */
 static void __init rx3715_reserve(void)
 {
@@ -209,6 +213,6 @@ MACHINE_START(RX3715, "IPAQ-RX3715")
 	.reserve	= rx3715_reserve,
 	.init_irq	= s3c2440_init_irq,
 	.init_machine	= rx3715_init_machine,
-	.init_time	= samsung_timer_init,
+	.init_time	= rx3715_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2440.c b/arch/arm/mach-s3c24xx/mach-smdk2440.c
index de2e5d3..335fe26 100644
--- a/arch/arm/mach-s3c24xx/mach-smdk2440.c
+++ b/arch/arm/mach-s3c24xx/mach-smdk2440.c
@@ -38,7 +38,6 @@
 #include <mach/fb.h>
 #include <linux/platform_data/i2c-s3c2410.h>
 
-#include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/samsung-time.h>
@@ -159,11 +158,16 @@ static struct platform_device *smdk2440_devices[] __initdata = {
 static void __init smdk2440_map_io(void)
 {
 	s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
-	s3c24xx_init_clocks(16934400);
 	s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init smdk2440_init_time(void)
+{
+	s3c2440_init_clocks(16934400);
+	samsung_timer_init();
+}
+
 static void __init smdk2440_machine_init(void)
 {
 	s3c24xx_fb_set_platdata(&smdk2440_fb_info);
@@ -180,6 +184,6 @@ MACHINE_START(S3C2440, "SMDK2440")
 	.init_irq	= s3c2440_init_irq,
 	.map_io		= smdk2440_map_io,
 	.init_machine	= smdk2440_machine_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= smdk2440_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
-- 
1.7.10.4

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

* [PATCH 10/12] ARM: S3C24XX: convert s3c2440 and s3c2442 to common clock framework
@ 2013-12-13 13:02   ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 13:02 UTC (permalink / raw)
  To: linux-arm-kernel

Convert all machines using these cpus to use the ccf clock driver
instead of the legacy Samsung clock implementation.

Some of the more esotheric machines will probably need a fixup, as they
do strange things to the clkout outputs, that I did not really understand
nor have the hardware to check.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/Kconfig          |    8 ++++----
 arch/arm/mach-s3c24xx/Makefile         |    4 ++--
 arch/arm/mach-s3c24xx/common.c         |    4 ----
 arch/arm/mach-s3c24xx/mach-anubis.c    |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-at2440evb.c |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-gta02.c     |    8 ++++++--
 arch/arm/mach-s3c24xx/mach-mini2440.c  |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-nexcoder.c  |   15 ++++++++++++---
 arch/arm/mach-s3c24xx/mach-osiris.c    |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-rx1950.c    |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-rx3715.c    |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-smdk2440.c  |   10 +++++++---
 12 files changed, 73 insertions(+), 36 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index 2a9a18c..c06197f 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -72,10 +72,10 @@ config CPU_S3C2416
 
 config CPU_S3C2440
 	bool "SAMSUNG S3C2440"
-	depends on SAMSUNG_CLOCK
+	select COMMON_CLK
 	select CPU_ARM920T
 	select CPU_LLSERIAL_S3C2440
-	select S3C2410_CLOCK
+	select S3C2410_COMMON_CLK
 	select S3C2410_PM if PM
 	select S3C2440_DMA if S3C24XX_DMA
 	help
@@ -83,10 +83,10 @@ config CPU_S3C2440
 
 config CPU_S3C2442
 	bool "SAMSUNG S3C2442"
-	depends on SAMSUNG_CLOCK
+	select COMMON_CLK
 	select CPU_ARM920T
 	select CPU_LLSERIAL_S3C2440
-	select S3C2410_CLOCK
+	select S3C2410_COMMON_CLK
 	select S3C2410_DMA if S3C24XX_DMA
 	select S3C2410_PM if PM
 	help
diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index ba0e547..720bf7a 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -29,9 +29,9 @@ obj-$(CONFIG_S3C2412_PM_SLEEP)	+= sleep-s3c2412.o
 obj-$(CONFIG_CPU_S3C2416)	+= s3c2416.o
 obj-$(CONFIG_S3C2416_PM)	+= pm-s3c2416.o
 
-obj-$(CONFIG_CPU_S3C2440)	+= s3c2440.o clock-s3c2440.o
+obj-$(CONFIG_CPU_S3C2440)	+= s3c2440.o
 obj-$(CONFIG_CPU_S3C2442)	+= s3c2442.o
-obj-$(CONFIG_CPU_S3C244X)	+= s3c244x.o clock-s3c244x.o
+obj-$(CONFIG_CPU_S3C244X)	+= s3c244x.o
 obj-$(CONFIG_S3C2440_DMA)	+= dma-s3c2440.o
 obj-$(CONFIG_S3C2440_PLL_12000000) += pll-s3c2440-12000000.o
 obj-$(CONFIG_S3C2440_PLL_16934400) += pll-s3c2440-16934400.o
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index 66dcb0e..cf00c4a 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -92,7 +92,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idcode		= 0x32440000,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2440_map_io,
-		.init_clocks	= s3c244x_init_clocks,
 		.init_uarts	= s3c244x_init_uarts,
 		.init		= s3c2440_init,
 		.name		= name_s3c2440
@@ -101,7 +100,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idcode		= 0x32440001,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2440_map_io,
-		.init_clocks	= s3c244x_init_clocks,
 		.init_uarts	= s3c244x_init_uarts,
 		.init		= s3c2440_init,
 		.name		= name_s3c2440a
@@ -110,7 +108,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idcode		= 0x32440aaa,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2442_map_io,
-		.init_clocks	= s3c244x_init_clocks,
 		.init_uarts	= s3c244x_init_uarts,
 		.init		= s3c2442_init,
 		.name		= name_s3c2442
@@ -119,7 +116,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idcode		= 0x32440aab,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2442_map_io,
-		.init_clocks	= s3c244x_init_clocks,
 		.init_uarts	= s3c244x_init_uarts,
 		.init		= s3c2442_init,
 		.name		= name_s3c2442b
diff --git a/arch/arm/mach-s3c24xx/mach-anubis.c b/arch/arm/mach-s3c24xx/mach-anubis.c
index a7d1721a..e43f984 100644
--- a/arch/arm/mach-s3c24xx/mach-anubis.c
+++ b/arch/arm/mach-s3c24xx/mach-anubis.c
@@ -45,7 +45,6 @@
 
 #include <net/ax88796.h>
 
-#include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <linux/platform_data/asoc-s3c24xx_simtec.h>
@@ -414,7 +413,6 @@ static void __init anubis_map_io(void)
 #endif
 
 	s3c24xx_init_io(anubis_iodesc, ARRAY_SIZE(anubis_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(anubis_uartcfgs, ARRAY_SIZE(anubis_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
@@ -432,6 +430,12 @@ static void __init anubis_map_io(void)
 	}
 }
 
+static void __init anubis_init_time(void)
+{
+	s3c2440_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init anubis_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
@@ -451,6 +455,6 @@ MACHINE_START(ANUBIS, "Simtec-Anubis")
 	.map_io		= anubis_map_io,
 	.init_machine	= anubis_init,
 	.init_irq	= s3c2440_init_irq,
-	.init_time	= samsung_timer_init,
+	.init_time	= anubis_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-at2440evb.c b/arch/arm/mach-s3c24xx/mach-at2440evb.c
index 6dfeeb7..f3ac0af 100644
--- a/arch/arm/mach-s3c24xx/mach-at2440evb.c
+++ b/arch/arm/mach-s3c24xx/mach-at2440evb.c
@@ -44,7 +44,6 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
-#include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <linux/platform_data/mmc-s3cmci.h>
@@ -191,11 +190,16 @@ static struct platform_device *at2440evb_devices[] __initdata = {
 static void __init at2440evb_map_io(void)
 {
 	s3c24xx_init_io(at2440evb_iodesc, ARRAY_SIZE(at2440evb_iodesc));
-	s3c24xx_init_clocks(16934400);
 	s3c24xx_init_uarts(at2440evb_uartcfgs, ARRAY_SIZE(at2440evb_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init at2440evb_init_time(void)
+{
+	s3c2440_init_clocks(16934400);
+	samsung_timer_init();
+}
+
 static void __init at2440evb_init(void)
 {
 	s3c24xx_fb_set_platdata(&at2440evb_fb_info);
@@ -212,6 +216,6 @@ MACHINE_START(AT2440EVB, "AT2440EVB")
 	.map_io		= at2440evb_map_io,
 	.init_machine	= at2440evb_init,
 	.init_irq	= s3c2440_init_irq,
-	.init_time	= samsung_timer_init,
+	.init_time	= at2440evb_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c
index 13d8d07..d8cd88c 100644
--- a/arch/arm/mach-s3c24xx/mach-gta02.c
+++ b/arch/arm/mach-s3c24xx/mach-gta02.c
@@ -500,7 +500,6 @@ static struct platform_device gta02_buttons_device = {
 static void __init gta02_map_io(void)
 {
 	s3c24xx_init_io(gta02_iodesc, ARRAY_SIZE(gta02_iodesc));
-	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_uarts(gta02_uartcfgs, ARRAY_SIZE(gta02_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
@@ -584,6 +583,11 @@ static void __init gta02_machine_init(void)
 	regulator_has_full_constraints();
 }
 
+static void __init gta02_init_time(void)
+{
+	s3c2442_init_clocks(12000000);
+	samsung_timer_init();
+}
 
 MACHINE_START(NEO1973_GTA02, "GTA02")
 	/* Maintainer: Nelson Castillo <arhuaco@freaks-unidos.net> */
@@ -591,6 +595,6 @@ MACHINE_START(NEO1973_GTA02, "GTA02")
 	.map_io		= gta02_map_io,
 	.init_irq	= s3c2442_init_irq,
 	.init_machine	= gta02_machine_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= gta02_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c
index 4a18d49..d2b38f0 100644
--- a/arch/arm/mach-s3c24xx/mach-mini2440.c
+++ b/arch/arm/mach-s3c24xx/mach-mini2440.c
@@ -53,7 +53,6 @@
 #include <linux/mtd/partitions.h>
 
 #include <plat/gpio-cfg.h>
-#include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/samsung-time.h>
@@ -524,11 +523,16 @@ static struct platform_device *mini2440_devices[] __initdata = {
 static void __init mini2440_map_io(void)
 {
 	s3c24xx_init_io(mini2440_iodesc, ARRAY_SIZE(mini2440_iodesc));
-	s3c24xx_init_clocks(12000000);
 	s3c24xx_init_uarts(mini2440_uartcfgs, ARRAY_SIZE(mini2440_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init mini2440_init_time(void)
+{
+	s3c2440_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 /*
  * mini2440_features string
  *
@@ -689,6 +693,6 @@ MACHINE_START(MINI2440, "MINI2440")
 	.map_io		= mini2440_map_io,
 	.init_machine	= mini2440_init,
 	.init_irq	= s3c2440_init_irq,
-	.init_time	= samsung_timer_init,
+	.init_time	= mini2440_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-nexcoder.c b/arch/arm/mach-s3c24xx/mach-nexcoder.c
index 01f4354..9ece48a 100644
--- a/arch/arm/mach-s3c24xx/mach-nexcoder.c
+++ b/arch/arm/mach-s3c24xx/mach-nexcoder.c
@@ -41,7 +41,6 @@
 #include <linux/platform_data/i2c-s3c2410.h>
 
 #include <plat/gpio-cfg.h>
-#include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/samsung-time.h>
@@ -134,13 +133,23 @@ static void __init nexcoder_sensorboard_init(void)
 static void __init nexcoder_map_io(void)
 {
 	s3c24xx_init_io(nexcoder_iodesc, ARRAY_SIZE(nexcoder_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(nexcoder_uartcfgs, ARRAY_SIZE(nexcoder_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
 	nexcoder_sensorboard_init();
 }
 
+static void __init nexcoder_init_time(void)
+{
+	/*
+	 * for whatever reason the nexcoder called s3c24xx_init_clocks(0)
+	 * meaning a xti value of 0Hz, so this machine will most likely
+	 * not work out of the box and needs a fixup.
+	 */
+	s3c2440_init_clocks(0);
+	samsung_timer_init();
+}
+
 static void __init nexcoder_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
@@ -153,6 +162,6 @@ MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440")
 	.map_io		= nexcoder_map_io,
 	.init_machine	= nexcoder_init,
 	.init_irq	= s3c2440_init_irq,
-	.init_time	= samsung_timer_init,
+	.init_time	= nexcoder_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-osiris.c b/arch/arm/mach-s3c24xx/mach-osiris.c
index d55d88d..a0d290b 100644
--- a/arch/arm/mach-s3c24xx/mach-osiris.c
+++ b/arch/arm/mach-s3c24xx/mach-osiris.c
@@ -39,7 +39,6 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/mtd/partitions.h>
 
-#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/cpu-freq.h>
 #include <plat/devs.h>
@@ -388,7 +387,6 @@ static void __init osiris_map_io(void)
 #endif
 
 	s3c24xx_init_io(osiris_iodesc, ARRAY_SIZE(osiris_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(osiris_uartcfgs, ARRAY_SIZE(osiris_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
@@ -412,6 +410,12 @@ static void __init osiris_map_io(void)
 	local_irq_restore(flags);
 }
 
+static void __init osiris_init_time(void)
+{
+	s3c2440_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init osiris_init(void)
 {
 	register_syscore_ops(&osiris_pm_syscore_ops);
@@ -433,6 +437,6 @@ MACHINE_START(OSIRIS, "Simtec-OSIRIS")
 	.map_io		= osiris_map_io,
 	.init_irq	= s3c2440_init_irq,
 	.init_machine	= osiris_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= osiris_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c
index a0f12d1..b46312a 100644
--- a/arch/arm/mach-s3c24xx/mach-rx1950.c
+++ b/arch/arm/mach-s3c24xx/mach-rx1950.c
@@ -52,7 +52,6 @@
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
-#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/pm.h>
@@ -744,7 +743,6 @@ static void __init rx1950_map_io(void)
 #endif
 
 	s3c24xx_init_io(rx1950_iodesc, ARRAY_SIZE(rx1950_iodesc));
-	s3c24xx_init_clocks(16934000);
 	s3c24xx_init_uarts(rx1950_uartcfgs, ARRAY_SIZE(rx1950_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
@@ -757,6 +755,12 @@ static void __init rx1950_map_io(void)
 	s3c_pm_init();
 }
 
+static void __init rx1950_init_time(void)
+{
+	s3c2442_init_clocks(16934000);
+	samsung_timer_init();
+}
+
 static void __init rx1950_init_machine(void)
 {
 	int i;
@@ -819,6 +823,6 @@ MACHINE_START(RX1950, "HP iPAQ RX1950")
 	.reserve	= rx1950_reserve,
 	.init_irq	= s3c2442_init_irq,
 	.init_machine = rx1950_init_machine,
-	.init_time	= samsung_timer_init,
+	.init_time	= rx1950_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-rx3715.c b/arch/arm/mach-s3c24xx/mach-rx3715.c
index 3bc6231..d842f45 100644
--- a/arch/arm/mach-s3c24xx/mach-rx3715.c
+++ b/arch/arm/mach-s3c24xx/mach-rx3715.c
@@ -44,7 +44,6 @@
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
-#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/pm.h>
@@ -178,11 +177,16 @@ static struct platform_device *rx3715_devices[] __initdata = {
 static void __init rx3715_map_io(void)
 {
 	s3c24xx_init_io(rx3715_iodesc, ARRAY_SIZE(rx3715_iodesc));
-	s3c24xx_init_clocks(16934000);
 	s3c24xx_init_uarts(rx3715_uartcfgs, ARRAY_SIZE(rx3715_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init rx3715_init_time(void)
+{
+	s3c2440_init_clocks(16934000);
+	samsung_timer_init();
+}
+
 /* H1940 and RX3715 need to reserve this for suspend */
 static void __init rx3715_reserve(void)
 {
@@ -209,6 +213,6 @@ MACHINE_START(RX3715, "IPAQ-RX3715")
 	.reserve	= rx3715_reserve,
 	.init_irq	= s3c2440_init_irq,
 	.init_machine	= rx3715_init_machine,
-	.init_time	= samsung_timer_init,
+	.init_time	= rx3715_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2440.c b/arch/arm/mach-s3c24xx/mach-smdk2440.c
index de2e5d3..335fe26 100644
--- a/arch/arm/mach-s3c24xx/mach-smdk2440.c
+++ b/arch/arm/mach-s3c24xx/mach-smdk2440.c
@@ -38,7 +38,6 @@
 #include <mach/fb.h>
 #include <linux/platform_data/i2c-s3c2410.h>
 
-#include <plat/clock.h>
 #include <plat/devs.h>
 #include <plat/cpu.h>
 #include <plat/samsung-time.h>
@@ -159,11 +158,16 @@ static struct platform_device *smdk2440_devices[] __initdata = {
 static void __init smdk2440_map_io(void)
 {
 	s3c24xx_init_io(smdk2440_iodesc, ARRAY_SIZE(smdk2440_iodesc));
-	s3c24xx_init_clocks(16934400);
 	s3c24xx_init_uarts(smdk2440_uartcfgs, ARRAY_SIZE(smdk2440_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init smdk2440_init_time(void)
+{
+	s3c2440_init_clocks(16934400);
+	samsung_timer_init();
+}
+
 static void __init smdk2440_machine_init(void)
 {
 	s3c24xx_fb_set_platdata(&smdk2440_fb_info);
@@ -180,6 +184,6 @@ MACHINE_START(S3C2440, "SMDK2440")
 	.init_irq	= s3c2440_init_irq,
 	.map_io		= smdk2440_map_io,
 	.init_machine	= smdk2440_machine_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= smdk2440_init_time,
 	.restart	= s3c244x_restart,
 MACHINE_END
-- 
1.7.10.4

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

* [PATCH 11/12] ARM: S3C24XX: convert s3c2410 to common clock framework
  2013-12-13 12:56 ` Heiko Stübner
@ 2013-12-13 13:03   ` Heiko Stübner
  -1 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 13:03 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: t.figa, mturquette, linux-arm-kernel, linux-samsung-soc

Convert the machines using the s3c2410 to use the new driver based
on the common clock framework instead of the legacy Samsung clock driver.

As with the s3c244x, machines using the clkout output will need a fixup
from someone with the hardware.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/Kconfig           |    4 ++--
 arch/arm/mach-s3c24xx/common.c          |    2 --
 arch/arm/mach-s3c24xx/mach-amlm5900.c   |    9 +++++++--
 arch/arm/mach-s3c24xx/mach-bast.c       |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-h1940.c      |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-n30.c        |   12 ++++++++----
 arch/arm/mach-s3c24xx/mach-nexcoder.c   |    7 +------
 arch/arm/mach-s3c24xx/mach-otom.c       |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-qt2410.c     |    9 +++++++--
 arch/arm/mach-s3c24xx/mach-smdk2410.c   |    9 +++++++--
 arch/arm/mach-s3c24xx/mach-tct_hammer.c |    9 +++++++--
 arch/arm/mach-s3c24xx/mach-vr1000.c     |   10 +++++++---
 12 files changed, 67 insertions(+), 34 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index c06197f..12a2f6d 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -37,10 +37,10 @@ comment "S3C24XX SoCs"
 config CPU_S3C2410
 	bool "SAMSUNG S3C2410"
 	default y
-	depends on SAMSUNG_CLOCK
+	select COMMON_CLK
 	select CPU_ARM920T
 	select CPU_LLSERIAL_S3C2410
-	select S3C2410_CLOCK
+	select S3C2410_COMMON_CLK
 	select S3C2410_DMA if S3C24XX_DMA
 	select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ
 	select S3C2410_PM if PM
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index cf00c4a..29f5812 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -74,7 +74,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idcode		= 0x32410000,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2410_map_io,
-		.init_clocks	= s3c2410_init_clocks,
 		.init_uarts	= s3c2410_init_uarts,
 		.init		= s3c2410_init,
 		.name		= name_s3c2410
@@ -83,7 +82,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idcode		= 0x32410002,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2410_map_io,
-		.init_clocks	= s3c2410_init_clocks,
 		.init_uarts	= s3c2410_init_uarts,
 		.init		= s3c2410a_init,
 		.name		= name_s3c2410a
diff --git a/arch/arm/mach-s3c24xx/mach-amlm5900.c b/arch/arm/mach-s3c24xx/mach-amlm5900.c
index e27b5c9..ebe06ad 100644
--- a/arch/arm/mach-s3c24xx/mach-amlm5900.c
+++ b/arch/arm/mach-s3c24xx/mach-amlm5900.c
@@ -160,11 +160,16 @@ static struct platform_device *amlm5900_devices[] __initdata = {
 static void __init amlm5900_map_io(void)
 {
 	s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init amlm5900_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 #ifdef CONFIG_FB_S3C2410
 static struct s3c2410fb_display __initdata amlm5900_lcd_info = {
 	.width		= 160,
@@ -240,6 +245,6 @@ MACHINE_START(AML_M5900, "AML_M5900")
 	.map_io		= amlm5900_map_io,
 	.init_irq	= s3c2410_init_irq,
 	.init_machine	= amlm5900_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= amlm5900_init_time,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-bast.c b/arch/arm/mach-s3c24xx/mach-bast.c
index d5d67c5..a1323bc 100644
--- a/arch/arm/mach-s3c24xx/mach-bast.c
+++ b/arch/arm/mach-s3c24xx/mach-bast.c
@@ -49,7 +49,6 @@
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
-#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/cpu-freq.h>
 #include <plat/devs.h>
@@ -580,11 +579,16 @@ static void __init bast_map_io(void)
 	s3c_hwmon_set_platdata(&bast_hwmon_info);
 
 	s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init bast_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init bast_init(void)
 {
 	register_syscore_ops(&bast_pm_syscore_ops);
@@ -612,6 +616,6 @@ MACHINE_START(BAST, "Simtec-BAST")
 	.map_io		= bast_map_io,
 	.init_irq	= s3c2410_init_irq,
 	.init_machine	= bast_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= bast_init_time,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c
index 952b6a0..873e452 100644
--- a/arch/arm/mach-s3c24xx/mach-h1940.c
+++ b/arch/arm/mach-s3c24xx/mach-h1940.c
@@ -55,7 +55,6 @@
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
-#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/gpio-cfg.h>
@@ -645,7 +644,6 @@ static struct platform_device *h1940_devices[] __initdata = {
 static void __init h1940_map_io(void)
 {
 	s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
@@ -661,6 +659,12 @@ static void __init h1940_map_io(void)
 	WARN_ON(gpiochip_add(&h1940_latch_gpiochip));
 }
 
+static void __init h1940_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 /* H1940 and RX3715 need to reserve this for suspend */
 static void __init h1940_reserve(void)
 {
@@ -738,6 +742,6 @@ MACHINE_START(H1940, "IPAQ-H1940")
 	.reserve	= h1940_reserve,
 	.init_irq	= s3c2410_init_irq,
 	.init_machine	= h1940_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= h1940_init_time,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-n30.c b/arch/arm/mach-s3c24xx/mach-n30.c
index 2cb46c3..8c9fa09 100644
--- a/arch/arm/mach-s3c24xx/mach-n30.c
+++ b/arch/arm/mach-s3c24xx/mach-n30.c
@@ -44,7 +44,6 @@
 #include <linux/platform_data/i2c-s3c2410.h>
 #include <plat/regs-serial.h>
 
-#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <linux/platform_data/mmc-s3cmci.h>
@@ -534,11 +533,16 @@ static void __init n30_map_io(void)
 {
 	s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
 	n30_hwinit();
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init n30_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 /* GPB3 is the line that controls the pull-up for the USB D+ line */
 
 static void __init n30_init(void)
@@ -590,7 +594,7 @@ MACHINE_START(N30, "Acer-N30")
 				Ben Dooks <ben-linux@fluff.org>
 	*/
 	.atag_offset	= 0x100,
-	.init_time	= samsung_timer_init,
+	.init_time	= n30_init_time,
 	.init_machine	= n30_init,
 	.init_irq	= s3c2410_init_irq,
 	.map_io		= n30_map_io,
@@ -601,7 +605,7 @@ MACHINE_START(N35, "Acer-N35")
 	/* Maintainer: Christer Weinigel <christer@weinigel.se>
 	*/
 	.atag_offset	= 0x100,
-	.init_time	= samsung_timer_init,
+	.init_time	= n30_init_time,
 	.init_machine	= n30_init,
 	.init_irq	= s3c2410_init_irq,
 	.map_io		= n30_map_io,
diff --git a/arch/arm/mach-s3c24xx/mach-nexcoder.c b/arch/arm/mach-s3c24xx/mach-nexcoder.c
index 9ece48a..c594071 100644
--- a/arch/arm/mach-s3c24xx/mach-nexcoder.c
+++ b/arch/arm/mach-s3c24xx/mach-nexcoder.c
@@ -141,12 +141,7 @@ static void __init nexcoder_map_io(void)
 
 static void __init nexcoder_init_time(void)
 {
-	/*
-	 * for whatever reason the nexcoder called s3c24xx_init_clocks(0)
-	 * meaning a xti value of 0Hz, so this machine will most likely
-	 * not work out of the box and needs a fixup.
-	 */
-	s3c2440_init_clocks(0);
+	s3c2440_init_clocks(12000000);
 	samsung_timer_init();
 }
 
diff --git a/arch/arm/mach-s3c24xx/mach-otom.c b/arch/arm/mach-s3c24xx/mach-otom.c
index 7e16b07..889f7d7 100644
--- a/arch/arm/mach-s3c24xx/mach-otom.c
+++ b/arch/arm/mach-s3c24xx/mach-otom.c
@@ -29,7 +29,6 @@
 #include <mach/hardware.h>
 #include <mach/regs-gpio.h>
 
-#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/regs-serial.h>
@@ -100,11 +99,16 @@ static struct platform_device *otom11_devices[] __initdata = {
 static void __init otom11_map_io(void)
 {
 	s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init otom11_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init otom11_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
@@ -117,6 +121,6 @@ MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
 	.map_io		= otom11_map_io,
 	.init_machine	= otom11_init,
 	.init_irq	= s3c2410_init_irq,
-	.init_time	= samsung_timer_init,
+	.init_time	= otom11_init_time,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-qt2410.c b/arch/arm/mach-s3c24xx/mach-qt2410.c
index f8feaea..96fcf08 100644
--- a/arch/arm/mach-s3c24xx/mach-qt2410.c
+++ b/arch/arm/mach-s3c24xx/mach-qt2410.c
@@ -303,11 +303,16 @@ __setup("tft=", qt2410_tft_setup);
 static void __init qt2410_map_io(void)
 {
 	s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
-	s3c24xx_init_clocks(12*1000*1000);
 	s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init qt2410_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init qt2410_machine_init(void)
 {
 	s3c_nand_set_platdata(&qt2410_nand_info);
@@ -345,6 +350,6 @@ MACHINE_START(QT2410, "QT2410")
 	.map_io		= qt2410_map_io,
 	.init_irq	= s3c2410_init_irq,
 	.init_machine	= qt2410_machine_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= qt2410_init_time,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2410.c b/arch/arm/mach-s3c24xx/mach-smdk2410.c
index a773789..c961e50 100644
--- a/arch/arm/mach-s3c24xx/mach-smdk2410.c
+++ b/arch/arm/mach-s3c24xx/mach-smdk2410.c
@@ -99,11 +99,16 @@ static struct platform_device *smdk2410_devices[] __initdata = {
 static void __init smdk2410_map_io(void)
 {
 	s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init smdk2410_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init smdk2410_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
@@ -118,6 +123,6 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc
 	.map_io		= smdk2410_map_io,
 	.init_irq	= s3c2410_init_irq,
 	.init_machine	= smdk2410_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= smdk2410_init_time,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-tct_hammer.c b/arch/arm/mach-s3c24xx/mach-tct_hammer.c
index 7fad8f0..3d6afe7 100644
--- a/arch/arm/mach-s3c24xx/mach-tct_hammer.c
+++ b/arch/arm/mach-s3c24xx/mach-tct_hammer.c
@@ -135,11 +135,16 @@ static struct platform_device *tct_hammer_devices[] __initdata = {
 static void __init tct_hammer_map_io(void)
 {
 	s3c24xx_init_io(tct_hammer_iodesc, ARRAY_SIZE(tct_hammer_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(tct_hammer_uartcfgs, ARRAY_SIZE(tct_hammer_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init tct_hammer_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init tct_hammer_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
@@ -151,6 +156,6 @@ MACHINE_START(TCT_HAMMER, "TCT_HAMMER")
 	.map_io		= tct_hammer_map_io,
 	.init_irq	= s3c2410_init_irq,
 	.init_machine	= tct_hammer_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= tct_hammer_init_time,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-vr1000.c b/arch/arm/mach-s3c24xx/mach-vr1000.c
index 8221988..443c74e 100644
--- a/arch/arm/mach-s3c24xx/mach-vr1000.c
+++ b/arch/arm/mach-s3c24xx/mach-vr1000.c
@@ -41,7 +41,6 @@
 #include <mach/hardware.h>
 #include <mach/regs-gpio.h>
 
-#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/regs-serial.h>
@@ -336,11 +335,16 @@ static void __init vr1000_map_io(void)
 	pm_power_off = vr1000_power_off;
 
 	s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init vr1000_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init vr1000_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
@@ -361,6 +365,6 @@ MACHINE_START(VR1000, "Thorcom-VR1000")
 	.map_io		= vr1000_map_io,
 	.init_machine	= vr1000_init,
 	.init_irq	= s3c2410_init_irq,
-	.init_time	= samsung_timer_init,
+	.init_time	= vr1000_init_time,
 	.restart	= s3c2410_restart,
 MACHINE_END
-- 
1.7.10.4

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

* [PATCH 11/12] ARM: S3C24XX: convert s3c2410 to common clock framework
@ 2013-12-13 13:03   ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 13:03 UTC (permalink / raw)
  To: linux-arm-kernel

Convert the machines using the s3c2410 to use the new driver based
on the common clock framework instead of the legacy Samsung clock driver.

As with the s3c244x, machines using the clkout output will need a fixup
from someone with the hardware.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/Kconfig           |    4 ++--
 arch/arm/mach-s3c24xx/common.c          |    2 --
 arch/arm/mach-s3c24xx/mach-amlm5900.c   |    9 +++++++--
 arch/arm/mach-s3c24xx/mach-bast.c       |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-h1940.c      |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-n30.c        |   12 ++++++++----
 arch/arm/mach-s3c24xx/mach-nexcoder.c   |    7 +------
 arch/arm/mach-s3c24xx/mach-otom.c       |   10 +++++++---
 arch/arm/mach-s3c24xx/mach-qt2410.c     |    9 +++++++--
 arch/arm/mach-s3c24xx/mach-smdk2410.c   |    9 +++++++--
 arch/arm/mach-s3c24xx/mach-tct_hammer.c |    9 +++++++--
 arch/arm/mach-s3c24xx/mach-vr1000.c     |   10 +++++++---
 12 files changed, 67 insertions(+), 34 deletions(-)

diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index c06197f..12a2f6d 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -37,10 +37,10 @@ comment "S3C24XX SoCs"
 config CPU_S3C2410
 	bool "SAMSUNG S3C2410"
 	default y
-	depends on SAMSUNG_CLOCK
+	select COMMON_CLK
 	select CPU_ARM920T
 	select CPU_LLSERIAL_S3C2410
-	select S3C2410_CLOCK
+	select S3C2410_COMMON_CLK
 	select S3C2410_DMA if S3C24XX_DMA
 	select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ
 	select S3C2410_PM if PM
diff --git a/arch/arm/mach-s3c24xx/common.c b/arch/arm/mach-s3c24xx/common.c
index cf00c4a..29f5812 100644
--- a/arch/arm/mach-s3c24xx/common.c
+++ b/arch/arm/mach-s3c24xx/common.c
@@ -74,7 +74,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idcode		= 0x32410000,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2410_map_io,
-		.init_clocks	= s3c2410_init_clocks,
 		.init_uarts	= s3c2410_init_uarts,
 		.init		= s3c2410_init,
 		.name		= name_s3c2410
@@ -83,7 +82,6 @@ static struct cpu_table cpu_ids[] __initdata = {
 		.idcode		= 0x32410002,
 		.idmask		= 0xffffffff,
 		.map_io		= s3c2410_map_io,
-		.init_clocks	= s3c2410_init_clocks,
 		.init_uarts	= s3c2410_init_uarts,
 		.init		= s3c2410a_init,
 		.name		= name_s3c2410a
diff --git a/arch/arm/mach-s3c24xx/mach-amlm5900.c b/arch/arm/mach-s3c24xx/mach-amlm5900.c
index e27b5c9..ebe06ad 100644
--- a/arch/arm/mach-s3c24xx/mach-amlm5900.c
+++ b/arch/arm/mach-s3c24xx/mach-amlm5900.c
@@ -160,11 +160,16 @@ static struct platform_device *amlm5900_devices[] __initdata = {
 static void __init amlm5900_map_io(void)
 {
 	s3c24xx_init_io(amlm5900_iodesc, ARRAY_SIZE(amlm5900_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(amlm5900_uartcfgs, ARRAY_SIZE(amlm5900_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init amlm5900_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 #ifdef CONFIG_FB_S3C2410
 static struct s3c2410fb_display __initdata amlm5900_lcd_info = {
 	.width		= 160,
@@ -240,6 +245,6 @@ MACHINE_START(AML_M5900, "AML_M5900")
 	.map_io		= amlm5900_map_io,
 	.init_irq	= s3c2410_init_irq,
 	.init_machine	= amlm5900_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= amlm5900_init_time,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-bast.c b/arch/arm/mach-s3c24xx/mach-bast.c
index d5d67c5..a1323bc 100644
--- a/arch/arm/mach-s3c24xx/mach-bast.c
+++ b/arch/arm/mach-s3c24xx/mach-bast.c
@@ -49,7 +49,6 @@
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
-#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/cpu-freq.h>
 #include <plat/devs.h>
@@ -580,11 +579,16 @@ static void __init bast_map_io(void)
 	s3c_hwmon_set_platdata(&bast_hwmon_info);
 
 	s3c24xx_init_io(bast_iodesc, ARRAY_SIZE(bast_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(bast_uartcfgs, ARRAY_SIZE(bast_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init bast_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init bast_init(void)
 {
 	register_syscore_ops(&bast_pm_syscore_ops);
@@ -612,6 +616,6 @@ MACHINE_START(BAST, "Simtec-BAST")
 	.map_io		= bast_map_io,
 	.init_irq	= s3c2410_init_irq,
 	.init_machine	= bast_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= bast_init_time,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-h1940.c b/arch/arm/mach-s3c24xx/mach-h1940.c
index 952b6a0..873e452 100644
--- a/arch/arm/mach-s3c24xx/mach-h1940.c
+++ b/arch/arm/mach-s3c24xx/mach-h1940.c
@@ -55,7 +55,6 @@
 #include <mach/regs-gpio.h>
 #include <mach/regs-lcd.h>
 
-#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/gpio-cfg.h>
@@ -645,7 +644,6 @@ static struct platform_device *h1940_devices[] __initdata = {
 static void __init h1940_map_io(void)
 {
 	s3c24xx_init_io(h1940_iodesc, ARRAY_SIZE(h1940_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(h1940_uartcfgs, ARRAY_SIZE(h1940_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 
@@ -661,6 +659,12 @@ static void __init h1940_map_io(void)
 	WARN_ON(gpiochip_add(&h1940_latch_gpiochip));
 }
 
+static void __init h1940_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 /* H1940 and RX3715 need to reserve this for suspend */
 static void __init h1940_reserve(void)
 {
@@ -738,6 +742,6 @@ MACHINE_START(H1940, "IPAQ-H1940")
 	.reserve	= h1940_reserve,
 	.init_irq	= s3c2410_init_irq,
 	.init_machine	= h1940_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= h1940_init_time,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-n30.c b/arch/arm/mach-s3c24xx/mach-n30.c
index 2cb46c3..8c9fa09 100644
--- a/arch/arm/mach-s3c24xx/mach-n30.c
+++ b/arch/arm/mach-s3c24xx/mach-n30.c
@@ -44,7 +44,6 @@
 #include <linux/platform_data/i2c-s3c2410.h>
 #include <plat/regs-serial.h>
 
-#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <linux/platform_data/mmc-s3cmci.h>
@@ -534,11 +533,16 @@ static void __init n30_map_io(void)
 {
 	s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));
 	n30_hwinit();
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(n30_uartcfgs, ARRAY_SIZE(n30_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init n30_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 /* GPB3 is the line that controls the pull-up for the USB D+ line */
 
 static void __init n30_init(void)
@@ -590,7 +594,7 @@ MACHINE_START(N30, "Acer-N30")
 				Ben Dooks <ben-linux@fluff.org>
 	*/
 	.atag_offset	= 0x100,
-	.init_time	= samsung_timer_init,
+	.init_time	= n30_init_time,
 	.init_machine	= n30_init,
 	.init_irq	= s3c2410_init_irq,
 	.map_io		= n30_map_io,
@@ -601,7 +605,7 @@ MACHINE_START(N35, "Acer-N35")
 	/* Maintainer: Christer Weinigel <christer@weinigel.se>
 	*/
 	.atag_offset	= 0x100,
-	.init_time	= samsung_timer_init,
+	.init_time	= n30_init_time,
 	.init_machine	= n30_init,
 	.init_irq	= s3c2410_init_irq,
 	.map_io		= n30_map_io,
diff --git a/arch/arm/mach-s3c24xx/mach-nexcoder.c b/arch/arm/mach-s3c24xx/mach-nexcoder.c
index 9ece48a..c594071 100644
--- a/arch/arm/mach-s3c24xx/mach-nexcoder.c
+++ b/arch/arm/mach-s3c24xx/mach-nexcoder.c
@@ -141,12 +141,7 @@ static void __init nexcoder_map_io(void)
 
 static void __init nexcoder_init_time(void)
 {
-	/*
-	 * for whatever reason the nexcoder called s3c24xx_init_clocks(0)
-	 * meaning a xti value of 0Hz, so this machine will most likely
-	 * not work out of the box and needs a fixup.
-	 */
-	s3c2440_init_clocks(0);
+	s3c2440_init_clocks(12000000);
 	samsung_timer_init();
 }
 
diff --git a/arch/arm/mach-s3c24xx/mach-otom.c b/arch/arm/mach-s3c24xx/mach-otom.c
index 7e16b07..889f7d7 100644
--- a/arch/arm/mach-s3c24xx/mach-otom.c
+++ b/arch/arm/mach-s3c24xx/mach-otom.c
@@ -29,7 +29,6 @@
 #include <mach/hardware.h>
 #include <mach/regs-gpio.h>
 
-#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/regs-serial.h>
@@ -100,11 +99,16 @@ static struct platform_device *otom11_devices[] __initdata = {
 static void __init otom11_map_io(void)
 {
 	s3c24xx_init_io(otom11_iodesc, ARRAY_SIZE(otom11_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(otom11_uartcfgs, ARRAY_SIZE(otom11_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init otom11_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init otom11_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
@@ -117,6 +121,6 @@ MACHINE_START(OTOM, "Nex Vision - Otom 1.1")
 	.map_io		= otom11_map_io,
 	.init_machine	= otom11_init,
 	.init_irq	= s3c2410_init_irq,
-	.init_time	= samsung_timer_init,
+	.init_time	= otom11_init_time,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-qt2410.c b/arch/arm/mach-s3c24xx/mach-qt2410.c
index f8feaea..96fcf08 100644
--- a/arch/arm/mach-s3c24xx/mach-qt2410.c
+++ b/arch/arm/mach-s3c24xx/mach-qt2410.c
@@ -303,11 +303,16 @@ __setup("tft=", qt2410_tft_setup);
 static void __init qt2410_map_io(void)
 {
 	s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
-	s3c24xx_init_clocks(12*1000*1000);
 	s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init qt2410_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init qt2410_machine_init(void)
 {
 	s3c_nand_set_platdata(&qt2410_nand_info);
@@ -345,6 +350,6 @@ MACHINE_START(QT2410, "QT2410")
 	.map_io		= qt2410_map_io,
 	.init_irq	= s3c2410_init_irq,
 	.init_machine	= qt2410_machine_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= qt2410_init_time,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-smdk2410.c b/arch/arm/mach-s3c24xx/mach-smdk2410.c
index a773789..c961e50 100644
--- a/arch/arm/mach-s3c24xx/mach-smdk2410.c
+++ b/arch/arm/mach-s3c24xx/mach-smdk2410.c
@@ -99,11 +99,16 @@ static struct platform_device *smdk2410_devices[] __initdata = {
 static void __init smdk2410_map_io(void)
 {
 	s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init smdk2410_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init smdk2410_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
@@ -118,6 +123,6 @@ MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switc
 	.map_io		= smdk2410_map_io,
 	.init_irq	= s3c2410_init_irq,
 	.init_machine	= smdk2410_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= smdk2410_init_time,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-tct_hammer.c b/arch/arm/mach-s3c24xx/mach-tct_hammer.c
index 7fad8f0..3d6afe7 100644
--- a/arch/arm/mach-s3c24xx/mach-tct_hammer.c
+++ b/arch/arm/mach-s3c24xx/mach-tct_hammer.c
@@ -135,11 +135,16 @@ static struct platform_device *tct_hammer_devices[] __initdata = {
 static void __init tct_hammer_map_io(void)
 {
 	s3c24xx_init_io(tct_hammer_iodesc, ARRAY_SIZE(tct_hammer_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(tct_hammer_uartcfgs, ARRAY_SIZE(tct_hammer_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init tct_hammer_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init tct_hammer_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
@@ -151,6 +156,6 @@ MACHINE_START(TCT_HAMMER, "TCT_HAMMER")
 	.map_io		= tct_hammer_map_io,
 	.init_irq	= s3c2410_init_irq,
 	.init_machine	= tct_hammer_init,
-	.init_time	= samsung_timer_init,
+	.init_time	= tct_hammer_init_time,
 	.restart	= s3c2410_restart,
 MACHINE_END
diff --git a/arch/arm/mach-s3c24xx/mach-vr1000.c b/arch/arm/mach-s3c24xx/mach-vr1000.c
index 8221988..443c74e 100644
--- a/arch/arm/mach-s3c24xx/mach-vr1000.c
+++ b/arch/arm/mach-s3c24xx/mach-vr1000.c
@@ -41,7 +41,6 @@
 #include <mach/hardware.h>
 #include <mach/regs-gpio.h>
 
-#include <plat/clock.h>
 #include <plat/cpu.h>
 #include <plat/devs.h>
 #include <plat/regs-serial.h>
@@ -336,11 +335,16 @@ static void __init vr1000_map_io(void)
 	pm_power_off = vr1000_power_off;
 
 	s3c24xx_init_io(vr1000_iodesc, ARRAY_SIZE(vr1000_iodesc));
-	s3c24xx_init_clocks(0);
 	s3c24xx_init_uarts(vr1000_uartcfgs, ARRAY_SIZE(vr1000_uartcfgs));
 	samsung_set_timer_source(SAMSUNG_PWM3, SAMSUNG_PWM4);
 }
 
+static void __init vr1000_init_time(void)
+{
+	s3c2410_init_clocks(12000000);
+	samsung_timer_init();
+}
+
 static void __init vr1000_init(void)
 {
 	s3c_i2c0_set_platdata(NULL);
@@ -361,6 +365,6 @@ MACHINE_START(VR1000, "Thorcom-VR1000")
 	.map_io		= vr1000_map_io,
 	.init_machine	= vr1000_init,
 	.init_irq	= s3c2410_init_irq,
-	.init_time	= samsung_timer_init,
+	.init_time	= vr1000_init_time,
 	.restart	= s3c2410_restart,
 MACHINE_END
-- 
1.7.10.4

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

* [PATCH 12/12] ARM: S3C24XX: remove legacy clock code
  2013-12-13 12:56 ` Heiko Stübner
@ 2013-12-13 13:03   ` Heiko Stübner
  -1 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 13:03 UTC (permalink / raw)
  To: Kukjin Kim; +Cc: t.figa, mturquette, linux-arm-kernel, linux-samsung-soc

With the move to the common clock framework completed for s3c2410, s3c2440
and s3c2442, the legacy clock code for these machines can go away too.

This also includes the legacy dclk code, as all legacy users are converted
and the remaining user of the Samsung clock code (s3c2412) does not use
them at all.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/Kconfig                   |   11 -
 arch/arm/mach-s3c24xx/Makefile                  |    2 -
 arch/arm/mach-s3c24xx/clock-dclk.c              |  195 ----------------
 arch/arm/mach-s3c24xx/clock-s3c2410.c           |  285 -----------------------
 arch/arm/mach-s3c24xx/clock-s3c2440.c           |  217 -----------------
 arch/arm/mach-s3c24xx/clock-s3c244x.c           |  141 -----------
 arch/arm/mach-s3c24xx/common.h                  |    2 -
 arch/arm/mach-s3c24xx/include/mach/regs-clock.h |   18 --
 arch/arm/mach-s3c24xx/include/mach/regs-gpio.h  |    3 -
 arch/arm/mach-s3c24xx/pm.c                      |   12 -
 arch/arm/mach-s3c24xx/s3c2410.c                 |   62 -----
 arch/arm/mach-s3c24xx/s3c2442.c                 |  112 ---------
 arch/arm/mach-s3c24xx/s3c244x.c                 |   63 -----
 13 files changed, 1123 deletions(-)
 delete mode 100644 arch/arm/mach-s3c24xx/clock-dclk.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2410.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2440.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c244x.c

diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index 12a2f6d..075780e 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -109,17 +109,6 @@ config CPU_S3C2443
 
 # common code
 
-config S3C2410_CLOCK
-	bool
-	help
-	  Clock code for the S3C2410, and similar processors which
-	  is currently includes the S3C2410, S3C2440, S3C2442.
-
-config S3C24XX_DCLK
-	bool
-	help
-	  Clock code for supporting DCLK/CLKOUT on S3C24XX architectures
-
 config S3C24XX_SMDK
 	bool
 	help
diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index 720bf7a..51d9578 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -44,10 +44,8 @@ obj-$(CONFIG_PM)		+= pm.o irq-pm.o sleep.o
 
 # common code
 
-obj-$(CONFIG_S3C24XX_DCLK)	+= clock-dclk.o
 obj-$(CONFIG_S3C24XX_DMA)	+= dma.o
 
-obj-$(CONFIG_S3C2410_CLOCK)	+= clock-s3c2410.o
 obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += cpufreq-utils.o
 
 obj-$(CONFIG_S3C2410_IOTIMING)	+= iotiming-s3c2410.o
diff --git a/arch/arm/mach-s3c24xx/clock-dclk.c b/arch/arm/mach-s3c24xx/clock-dclk.c
deleted file mode 100644
index 1edd9b2..0000000
--- a/arch/arm/mach-s3c24xx/clock-dclk.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * 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.
- *
- * S3C24XX - definitions for DCLK and CLKOUT registers
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <mach/regs-clock.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-/* clocks that could be registered by external code */
-
-static int s3c24xx_dclk_enable(struct clk *clk, int enable)
-{
-	unsigned long dclkcon = __raw_readl(S3C24XX_DCLKCON);
-
-	if (enable)
-		dclkcon |= clk->ctrlbit;
-	else
-		dclkcon &= ~clk->ctrlbit;
-
-	__raw_writel(dclkcon, S3C24XX_DCLKCON);
-
-	return 0;
-}
-
-static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
-{
-	unsigned long dclkcon;
-	unsigned int uclk;
-
-	if (parent == &clk_upll)
-		uclk = 1;
-	else if (parent == &clk_p)
-		uclk = 0;
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	dclkcon = __raw_readl(S3C24XX_DCLKCON);
-
-	if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
-		if (uclk)
-			dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK;
-		else
-			dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK;
-	} else {
-		if (uclk)
-			dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK;
-		else
-			dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
-	}
-
-	__raw_writel(dclkcon, S3C24XX_DCLKCON);
-
-	return 0;
-}
-static unsigned long s3c24xx_calc_div(struct clk *clk, unsigned long rate)
-{
-	unsigned long div;
-
-	if ((rate == 0) || !clk->parent)
-		return 0;
-
-	div = clk_get_rate(clk->parent) / rate;
-	if (div < 2)
-		div = 2;
-	else if (div > 16)
-		div = 16;
-
-	return div;
-}
-
-static unsigned long s3c24xx_round_dclk_rate(struct clk *clk,
-	unsigned long rate)
-{
-	unsigned long div = s3c24xx_calc_div(clk, rate);
-
-	if (div == 0)
-		return 0;
-
-	return clk_get_rate(clk->parent) / div;
-}
-
-static int s3c24xx_set_dclk_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned long mask, data, div = s3c24xx_calc_div(clk, rate);
-
-	if (div == 0)
-		return -EINVAL;
-
-	if (clk == &s3c24xx_dclk0) {
-		mask = S3C2410_DCLKCON_DCLK0_DIV_MASK |
-			S3C2410_DCLKCON_DCLK0_CMP_MASK;
-		data = S3C2410_DCLKCON_DCLK0_DIV(div) |
-			S3C2410_DCLKCON_DCLK0_CMP((div + 1) / 2);
-	} else if (clk == &s3c24xx_dclk1) {
-		mask = S3C2410_DCLKCON_DCLK1_DIV_MASK |
-			S3C2410_DCLKCON_DCLK1_CMP_MASK;
-		data = S3C2410_DCLKCON_DCLK1_DIV(div) |
-			S3C2410_DCLKCON_DCLK1_CMP((div + 1) / 2);
-	} else
-		return -EINVAL;
-
-	clk->rate = clk_get_rate(clk->parent) / div;
-	__raw_writel(((__raw_readl(S3C24XX_DCLKCON) & ~mask) | data),
-		S3C24XX_DCLKCON);
-	return clk->rate;
-}
-static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
-{
-	unsigned long mask;
-	unsigned long source;
-
-	/* calculate the MISCCR setting for the clock */
-
-	if (parent == &clk_mpll)
-		source = S3C2410_MISCCR_CLK0_MPLL;
-	else if (parent == &clk_upll)
-		source = S3C2410_MISCCR_CLK0_UPLL;
-	else if (parent == &clk_f)
-		source = S3C2410_MISCCR_CLK0_FCLK;
-	else if (parent == &clk_h)
-		source = S3C2410_MISCCR_CLK0_HCLK;
-	else if (parent == &clk_p)
-		source = S3C2410_MISCCR_CLK0_PCLK;
-	else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0)
-		source = S3C2410_MISCCR_CLK0_DCLK0;
-	else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1)
-		source = S3C2410_MISCCR_CLK0_DCLK0;
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	if (clk == &s3c24xx_clkout0)
-		mask = S3C2410_MISCCR_CLK0_MASK;
-	else {
-		source <<= 4;
-		mask = S3C2410_MISCCR_CLK1_MASK;
-	}
-
-	s3c2410_modify_misccr(mask, source);
-	return 0;
-}
-
-/* external clock definitions */
-
-static struct clk_ops dclk_ops = {
-	.set_parent	= s3c24xx_dclk_setparent,
-	.set_rate	= s3c24xx_set_dclk_rate,
-	.round_rate	= s3c24xx_round_dclk_rate,
-};
-
-struct clk s3c24xx_dclk0 = {
-	.name		= "dclk0",
-	.ctrlbit	= S3C2410_DCLKCON_DCLK0EN,
-	.enable	        = s3c24xx_dclk_enable,
-	.ops		= &dclk_ops,
-};
-
-struct clk s3c24xx_dclk1 = {
-	.name		= "dclk1",
-	.ctrlbit	= S3C2410_DCLKCON_DCLK1EN,
-	.enable		= s3c24xx_dclk_enable,
-	.ops		= &dclk_ops,
-};
-
-static struct clk_ops clkout_ops = {
-	.set_parent	= s3c24xx_clkout_setparent,
-};
-
-struct clk s3c24xx_clkout0 = {
-	.name		= "clkout0",
-	.ops		= &clkout_ops,
-};
-
-struct clk s3c24xx_clkout1 = {
-	.name		= "clkout1",
-	.ops		= &clkout_ops,
-};
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2410.c b/arch/arm/mach-s3c24xx/clock-s3c2410.c
deleted file mode 100644
index d39d3c7..0000000
--- a/arch/arm/mach-s3c24xx/clock-s3c2410.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 2006 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410,S3C2440,S3C2442 Clock control support
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/serial_core.h>
-#include <linux/io.h>
-
-#include <asm/mach/map.h>
-
-#include <mach/hardware.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-clock.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-int s3c2410_clkcon_enable(struct clk *clk, int enable)
-{
-	unsigned int clocks = clk->ctrlbit;
-	unsigned long clkcon;
-
-	clkcon = __raw_readl(S3C2410_CLKCON);
-
-	if (enable)
-		clkcon |= clocks;
-	else
-		clkcon &= ~clocks;
-
-	/* ensure none of the special function bits set */
-	clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
-
-	__raw_writel(clkcon, S3C2410_CLKCON);
-
-	return 0;
-}
-
-static int s3c2410_upll_enable(struct clk *clk, int enable)
-{
-	unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
-	unsigned long orig = clkslow;
-
-	if (enable)
-		clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF;
-	else
-		clkslow |= S3C2410_CLKSLOW_UCLK_OFF;
-
-	__raw_writel(clkslow, S3C2410_CLKSLOW);
-
-	/* if we started the UPLL, then allow to settle */
-
-	if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
-		udelay(200);
-
-	return 0;
-}
-
-/* standard clock definitions */
-
-static struct clk init_clocks_off[] = {
-	{
-		.name		= "nand",
-		.parent		= &clk_h,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_NAND,
-	}, {
-		.name		= "sdi",
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_SDI,
-	}, {
-		.name		= "adc",
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_ADC,
-	}, {
-		.name		= "i2c",
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_IIC,
-	}, {
-		.name		= "iis",
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_IIS,
-	}, {
-		.name		= "spi",
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_SPI,
-	}
-};
-
-static struct clk clk_lcd = {
-	.name		= "lcd",
-	.parent		= &clk_h,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_LCDC,
-};
-
-static struct clk clk_gpio = {
-	.name		= "gpio",
-	.parent		= &clk_p,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_GPIO,
-};
-
-static struct clk clk_usb_host = {
-	.name		= "usb-host",
-	.parent		= &clk_h,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_USBH,
-};
-
-static struct clk clk_usb_device = {
-	.name		= "usb-device",
-	.parent		= &clk_h,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_USBD,
-};
-
-static struct clk clk_timers = {
-	.name		= "timers",
-	.parent		= &clk_p,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_PWMT,
-};
-
-struct clk s3c24xx_clk_uart0 = {
-	.name		= "uart",
-	.devname	= "s3c2410-uart.0",
-	.parent		= &clk_p,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_UART0,
-};
-
-struct clk s3c24xx_clk_uart1 = {
-	.name		= "uart",
-	.devname	= "s3c2410-uart.1",
-	.parent		= &clk_p,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_UART1,
-};
-
-struct clk s3c24xx_clk_uart2 = {
-	.name		= "uart",
-	.devname	= "s3c2410-uart.2",
-	.parent		= &clk_p,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_UART2,
-};
-
-static struct clk clk_rtc = {
-	.name		= "rtc",
-	.parent		= &clk_p,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_RTC,
-};
-
-static struct clk clk_watchdog = {
-	.name		= "watchdog",
-	.parent		= &clk_p,
-	.ctrlbit	= 0,
-};
-
-static struct clk clk_usb_bus_host = {
-	.name		= "usb-bus-host",
-	.parent		= &clk_usb_bus,
-};
-
-static struct clk clk_usb_bus_gadget = {
-	.name		= "usb-bus-gadget",
-	.parent		= &clk_usb_bus,
-};
-
-static struct clk *init_clocks[] = {
-	&clk_lcd,
-	&clk_gpio,
-	&clk_usb_host,
-	&clk_usb_device,
-	&clk_timers,
-	&s3c24xx_clk_uart0,
-	&s3c24xx_clk_uart1,
-	&s3c24xx_clk_uart2,
-	&clk_rtc,
-	&clk_watchdog,
-	&clk_usb_bus_host,
-	&clk_usb_bus_gadget,
-};
-
-/* s3c2410_baseclk_add()
- *
- * Add all the clocks used by the s3c2410 or compatible CPUs
- * such as the S3C2440 and S3C2442.
- *
- * We cannot use a system device as we are needed before any
- * of the init-calls that initialise the devices are actually
- * done.
-*/
-
-int __init s3c2410_baseclk_add(void)
-{
-	unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
-	unsigned long clkcon  = __raw_readl(S3C2410_CLKCON);
-	struct clk *xtal;
-	int ret;
-	int ptr;
-
-	clk_upll.enable = s3c2410_upll_enable;
-
-	if (s3c24xx_register_clock(&clk_usb_bus) < 0)
-		printk(KERN_ERR "failed to register usb bus clock\n");
-
-	/* register clocks from clock array */
-
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++) {
-		struct clk *clkp = init_clocks[ptr];
-
-		/* ensure that we note the clock state */
-
-		clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
-
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-	}
-
-	/* We must be careful disabling the clocks we are not intending to
-	 * be using at boot time, as subsystems such as the LCD which do
-	 * their own DMA requests to the bus can cause the system to lockup
-	 * if they where in the middle of requesting bus access.
-	 *
-	 * Disabling the LCD clock if the LCD is active is very dangerous,
-	 * and therefore the bootloader should be careful to not enable
-	 * the LCD clock if it is not needed.
-	*/
-
-	/* install (and disable) the clocks we do not need immediately */
-
-	s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-	s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-
-	/* show the clock-slow value */
-
-	xtal = clk_get(NULL, "xtal");
-
-	printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
-	       print_mhz(clk_get_rate(xtal) /
-			 ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
-	       (clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
-	       (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
-	       (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
-
-	return 0;
-}
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2440.c b/arch/arm/mach-s3c24xx/clock-s3c2440.c
deleted file mode 100644
index aaf006d..0000000
--- a/arch/arm/mach-s3c24xx/clock-s3c2440.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/clock.c
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2440 Clock support
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/mutex.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/serial_core.h>
-
-#include <mach/hardware.h>
-#include <linux/atomic.h>
-#include <asm/irq.h>
-
-#include <mach/regs-clock.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/regs-serial.h>
-
-/* S3C2440 extended clock support */
-
-static unsigned long s3c2440_camif_upll_round(struct clk *clk,
-					      unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	int div;
-
-	if (rate > parent_rate)
-		return parent_rate;
-
-	/* note, we remove the +/- 1 calculations for the divisor */
-
-	div = (parent_rate / rate) / 2;
-
-	if (div < 1)
-		div = 1;
-	else if (div > 16)
-		div = 16;
-
-	return parent_rate / (div * 2);
-}
-
-static int s3c2440_camif_upll_setrate(struct clk *clk, unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
-
-	rate = s3c2440_camif_upll_round(clk, rate);
-
-	camdivn &= ~(S3C2440_CAMDIVN_CAMCLK_SEL | S3C2440_CAMDIVN_CAMCLK_MASK);
-
-	if (rate != parent_rate) {
-		camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
-		camdivn |= (((parent_rate / rate) / 2) - 1);
-	}
-
-	__raw_writel(camdivn, S3C2440_CAMDIVN);
-
-	return 0;
-}
-
-static unsigned long s3c2440_camif_upll_getrate(struct clk *clk)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
-
-	if (!(camdivn & S3C2440_CAMDIVN_CAMCLK_SEL))
-		return parent_rate;
-
-	camdivn &= S3C2440_CAMDIVN_CAMCLK_MASK;
-
-	return parent_rate / (camdivn + 1) / 2;
-}
-
-/* Extra S3C2440 clocks */
-
-static struct clk s3c2440_clk_cam = {
-	.name		= "camif",
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2440_CLKCON_CAMERA,
-};
-
-static struct clk s3c2440_clk_cam_upll = {
-	.name		= "camif-upll",
-	.ops		= &(struct clk_ops) {
-		.set_rate	= s3c2440_camif_upll_setrate,
-		.get_rate	= s3c2440_camif_upll_getrate,
-		.round_rate	= s3c2440_camif_upll_round,
-	},
-};
-
-static struct clk s3c2440_clk_ac97 = {
-	.name		= "ac97",
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2440_CLKCON_AC97,
-};
-
-#define S3C24XX_VA_UART0      (S3C_VA_UART)
-#define S3C24XX_VA_UART1      (S3C_VA_UART + 0x4000 )
-#define S3C24XX_VA_UART2      (S3C_VA_UART + 0x8000 )
-#define S3C24XX_VA_UART3      (S3C_VA_UART + 0xC000 )
-
-static unsigned long  s3c2440_fclk_n_getrate(struct clk *clk)
-{
-	unsigned long ucon0, ucon1, ucon2, divisor;
-
-	/* the fun of calculating the uart divisors on the s3c2440 */
-	ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
-	ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
-	ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
-
-	ucon0 &= S3C2440_UCON0_DIVMASK;
-	ucon1 &= S3C2440_UCON1_DIVMASK;
-	ucon2 &= S3C2440_UCON2_DIVMASK;
-
-	if (ucon0 != 0)
-		divisor = (ucon0 >> S3C2440_UCON_DIVSHIFT) + 6;
-	else if (ucon1 != 0)
-		divisor = (ucon1 >> S3C2440_UCON_DIVSHIFT) + 21;
-	else if (ucon2 != 0)
-		divisor = (ucon2 >> S3C2440_UCON_DIVSHIFT) + 36;
-	else
-		/* manual calims 44, seems to be 9 */
-		divisor = 9;
-
-	return clk_get_rate(clk->parent) / divisor;
-}
-
-static struct clk s3c2440_clk_fclk_n = {
-	.name		= "fclk_n",
-	.parent		= &clk_f,
-	.ops		= &(struct clk_ops) {
-		.get_rate	= s3c2440_fclk_n_getrate,
-	},
-};
-
-static struct clk_lookup s3c2440_clk_lookup[] = {
-	CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
-	CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
-	CLKDEV_INIT(NULL, "clk_uart_baud3", &s3c2440_clk_fclk_n),
-	CLKDEV_INIT("s3c2440-uart.0", "uart", &s3c24xx_clk_uart0),
-	CLKDEV_INIT("s3c2440-uart.1", "uart", &s3c24xx_clk_uart1),
-	CLKDEV_INIT("s3c2440-uart.2", "uart", &s3c24xx_clk_uart2),
-	CLKDEV_INIT("s3c2440-camif", "camera", &s3c2440_clk_cam_upll),
-};
-
-static int __init_refok s3c2440_clk_add(struct device *dev, struct subsys_interface *sif)
-{
-	struct clk *clock_upll;
-	struct clk *clock_h;
-	struct clk *clock_p;
-
-	clock_p = clk_get(NULL, "pclk");
-	clock_h = clk_get(NULL, "hclk");
-	clock_upll = clk_get(NULL, "upll");
-
-	if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
-		printk(KERN_ERR "S3C2440: Failed to get parent clocks\n");
-		return -EINVAL;
-	}
-
-	s3c2440_clk_cam.parent = clock_h;
-	s3c2440_clk_ac97.parent = clock_p;
-	s3c2440_clk_cam_upll.parent = clock_upll;
-	s3c24xx_register_clock(&s3c2440_clk_fclk_n);
-
-	s3c24xx_register_clock(&s3c2440_clk_ac97);
-	s3c24xx_register_clock(&s3c2440_clk_cam);
-	s3c24xx_register_clock(&s3c2440_clk_cam_upll);
-	clkdev_add_table(s3c2440_clk_lookup, ARRAY_SIZE(s3c2440_clk_lookup));
-
-	clk_disable(&s3c2440_clk_ac97);
-	clk_disable(&s3c2440_clk_cam);
-
-	return 0;
-}
-
-static struct subsys_interface s3c2440_clk_interface = {
-	.name		= "s3c2440_clk",
-	.subsys		= &s3c2440_subsys,
-	.add_dev	= s3c2440_clk_add,
-};
-
-static __init int s3c24xx_clk_init(void)
-{
-	return subsys_interface_register(&s3c2440_clk_interface);
-}
-
-arch_initcall(s3c24xx_clk_init);
diff --git a/arch/arm/mach-s3c24xx/clock-s3c244x.c b/arch/arm/mach-s3c24xx/clock-s3c244x.c
deleted file mode 100644
index 6d9b688..0000000
--- a/arch/arm/mach-s3c24xx/clock-s3c244x.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/s3c24xx-clock.c
- *
- * Copyright (c) 2004-2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2440/S3C2442 Common clock support
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <linux/atomic.h>
-#include <asm/irq.h>
-
-#include <mach/regs-clock.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent)
-{
-	unsigned long camdivn;
-	unsigned long dvs;
-
-	if (parent == &clk_f)
-		dvs = 0;
-	else if (parent == &clk_h)
-		dvs = S3C2440_CAMDIVN_DVSEN;
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	camdivn  = __raw_readl(S3C2440_CAMDIVN);
-	camdivn &= ~S3C2440_CAMDIVN_DVSEN;
-	camdivn |= dvs;
-	__raw_writel(camdivn, S3C2440_CAMDIVN);
-
-	return 0;
-}
-
-static struct clk clk_arm = {
-	.name		= "armclk",
-	.id		= -1,
-	.ops		= &(struct clk_ops) {
-		.set_parent	= s3c2440_setparent_armclk,
-	},
-};
-
-static int s3c244x_clk_add(struct device *dev, struct subsys_interface *sif)
-{
-	unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
-	unsigned long clkdivn;
-	struct clk *clock_upll;
-	int ret;
-
-	printk("S3C244X: Clock Support, DVS %s\n",
-	       (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
-
-	clk_arm.parent = (camdivn & S3C2440_CAMDIVN_DVSEN) ? &clk_h : &clk_f;
-
-	ret = s3c24xx_register_clock(&clk_arm);
-	if (ret < 0) {
-		printk(KERN_ERR "S3C24XX: Failed to add armclk (%d)\n", ret);
-		return ret;
-	}
-
-	clock_upll = clk_get(NULL, "upll");
-	if (IS_ERR(clock_upll)) {
-		printk(KERN_ERR "S3C244X: Failed to get upll clock\n");
-		return -ENOENT;
-	}
-
-	/* check rate of UPLL, and if it is near 96MHz, then change
-	 * to using half the UPLL rate for the system */
-
-	if (clk_get_rate(clock_upll) > (94 * MHZ)) {
-		clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
-
-		spin_lock(&clocks_lock);
-
-		clkdivn = __raw_readl(S3C2410_CLKDIVN);
-		clkdivn |= S3C2440_CLKDIVN_UCLK;
-		__raw_writel(clkdivn, S3C2410_CLKDIVN);
-
-		spin_unlock(&clocks_lock);
-	}
-
-	return 0;
-}
-
-static struct subsys_interface s3c2440_clk_interface = {
-	.name		= "s3c2440_clk",
-	.subsys		= &s3c2440_subsys,
-	.add_dev	= s3c244x_clk_add,
-};
-
-static int s3c2440_clk_init(void)
-{
-	return subsys_interface_register(&s3c2440_clk_interface);
-}
-
-arch_initcall(s3c2440_clk_init);
-
-static struct subsys_interface s3c2442_clk_interface = {
-	.name		= "s3c2442_clk",
-	.subsys		= &s3c2442_subsys,
-	.add_dev	= s3c244x_clk_add,
-};
-
-static int s3c2442_clk_init(void)
-{
-	return subsys_interface_register(&s3c2442_clk_interface);
-}
-
-arch_initcall(s3c2442_clk_init);
diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h
index 4b3157e..30124d1d 100644
--- a/arch/arm/mach-s3c24xx/common.h
+++ b/arch/arm/mach-s3c24xx/common.h
@@ -67,10 +67,8 @@ extern struct syscore_ops s3c2416_irq_syscore_ops;
 #if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
 extern void s3c244x_map_io(void);
 extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-extern void s3c244x_init_clocks(int xtal);
 extern void s3c244x_restart(enum reboot_mode mode, const char *cmd);
 #else
-#define s3c244x_init_clocks NULL
 #define s3c244x_init_uarts NULL
 #endif
 
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-clock.h b/arch/arm/mach-s3c24xx/include/mach/regs-clock.h
index 3415b60..3db6c10 100644
--- a/arch/arm/mach-s3c24xx/include/mach/regs-clock.h
+++ b/arch/arm/mach-s3c24xx/include/mach/regs-clock.h
@@ -42,24 +42,6 @@
 #define S3C2410_CLKCON_IIS	     (1<<17)
 #define S3C2410_CLKCON_SPI	     (1<<18)
 
-/* DCLKCON register addresses in gpio.h */
-
-#define S3C2410_DCLKCON_DCLK0EN	     (1<<0)
-#define S3C2410_DCLKCON_DCLK0_PCLK   (0<<1)
-#define S3C2410_DCLKCON_DCLK0_UCLK   (1<<1)
-#define S3C2410_DCLKCON_DCLK0_DIV(x) (((x) - 1 )<<4)
-#define S3C2410_DCLKCON_DCLK0_CMP(x) (((x) - 1 )<<8)
-#define S3C2410_DCLKCON_DCLK0_DIV_MASK ((0xf)<<4)
-#define S3C2410_DCLKCON_DCLK0_CMP_MASK ((0xf)<<8)
-
-#define S3C2410_DCLKCON_DCLK1EN	     (1<<16)
-#define S3C2410_DCLKCON_DCLK1_PCLK   (0<<17)
-#define S3C2410_DCLKCON_DCLK1_UCLK   (1<<17)
-#define S3C2410_DCLKCON_DCLK1_DIV(x) (((x) - 1) <<20)
-#define S3C2410_DCLKCON_DCLK1_CMP(x) (((x) - 1) <<24)
-#define S3C2410_DCLKCON_DCLK1_DIV_MASK ((0xf) <<20)
-#define S3C2410_DCLKCON_DCLK1_CMP_MASK ((0xf) <<24)
-
 #define S3C2410_CLKDIVN_PDIVN	     (1<<0)
 #define S3C2410_CLKDIVN_HDIVN	     (1<<1)
 
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h b/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h
index c2ef016..c6583cf 100644
--- a/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h
@@ -457,9 +457,6 @@
 
 /* miscellaneous control */
 #define S3C2410_MISCCR	   S3C2410_GPIOREG(0x80)
-#define S3C2410_DCLKCON	   S3C2410_GPIOREG(0x84)
-
-#define S3C24XX_DCLKCON	   S3C24XX_GPIOREG2(0x84)
 
 /* see clock.h for dclk definitions */
 
diff --git a/arch/arm/mach-s3c24xx/pm.c b/arch/arm/mach-s3c24xx/pm.c
index 9cc6fc1..f2dff6f 100644
--- a/arch/arm/mach-s3c24xx/pm.c
+++ b/arch/arm/mach-s3c24xx/pm.c
@@ -79,12 +79,6 @@ static struct sleep_save core_save[] = {
 #endif /* CONFIG_SAMSUNG_CLOCK */
 };
 
-#ifdef CONFIG_SAMSUNG_CLOCK
-static struct sleep_save misc_save[] = {
-	SAVE_ITEM(S3C2410_DCLKCON),
-};
-#endif
-
 /* s3c_pm_check_resume_pin
  *
  * check to see if the pin is configured correctly for sleep mode, and
@@ -142,16 +136,10 @@ void s3c_pm_configure_extint(void)
 void s3c_pm_restore_core(void)
 {
 	s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
-#ifdef CONFIG_SAMSUNG_CLOCK
-	s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
-#endif
 }
 
 void s3c_pm_save_core(void)
 {
-#ifdef CONFIG_SAMSUNG_CLOCK
-	s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
-#endif
 	s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
 }
 
diff --git a/arch/arm/mach-s3c24xx/s3c2410.c b/arch/arm/mach-s3c24xx/s3c2410.c
index 04bed99..fef99fe 100644
--- a/arch/arm/mach-s3c24xx/s3c2410.c
+++ b/arch/arm/mach-s3c24xx/s3c2410.c
@@ -82,71 +82,9 @@ void __init s3c2410_map_io(void)
 	iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
 }
 
-#ifdef CONFIG_SAMSUNG_CLOCK
 void __init_or_cpufreq s3c2410_setup_clocks(void)
 {
-	struct clk *xtal_clk;
-	unsigned long tmp;
-	unsigned long xtal;
-	unsigned long fclk;
-	unsigned long hclk;
-	unsigned long pclk;
-
-	xtal_clk = clk_get(NULL, "xtal");
-	xtal = clk_get_rate(xtal_clk);
-	clk_put(xtal_clk);
-
-	/* now we've got our machine bits initialised, work out what
-	 * clocks we've got */
-
-	fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal);
-
-	tmp = __raw_readl(S3C2410_CLKDIVN);
-
-	/* work out clock scalings */
-
-	hclk = fclk / ((tmp & S3C2410_CLKDIVN_HDIVN) ? 2 : 1);
-	pclk = hclk / ((tmp & S3C2410_CLKDIVN_PDIVN) ? 2 : 1);
-
-	/* print brieft summary of clocks, etc */
-
-	printk("S3C2410: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
-	       print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
-
-	/* initialise the clocks here, to allow other things like the
-	 * console to use them
-	 */
-
-	s3c24xx_setup_clocks(fclk, hclk, pclk);
-}
-
-/* fake ARMCLK for use with cpufreq, etc. */
-
-static struct clk s3c2410_armclk = {
-	.name	= "armclk",
-	.parent	= &clk_f,
-	.id	= -1,
-};
-
-static struct clk_lookup s3c2410_clk_lookup[] = {
-	CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p),
-	CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
-};
-
-void __init s3c2410_init_clocks(int xtal)
-{
-	s3c24xx_register_baseclocks(xtal);
-	s3c2410_setup_clocks();
-	s3c2410_baseclk_add();
-	s3c24xx_register_clock(&s3c2410_armclk);
-	clkdev_add_table(s3c2410_clk_lookup, ARRAY_SIZE(s3c2410_clk_lookup));
-	samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
 }
-#else
-void __init_or_cpufreq s3c2410_setup_clocks(void)
-{
-}
-#endif
 
 struct bus_type s3c2410_subsys = {
 	.name = "s3c2410-core",
diff --git a/arch/arm/mach-s3c24xx/s3c2442.c b/arch/arm/mach-s3c24xx/s3c2442.c
index a4c1519..3fca198 100644
--- a/arch/arm/mach-s3c24xx/s3c2442.c
+++ b/arch/arm/mach-s3c24xx/s3c2442.c
@@ -52,118 +52,6 @@
 
 #include "common.h"
 
-#ifdef CONFIG_SAMSUNG_CLOCK
-/* S3C2442 extended clock support */
-
-static unsigned long s3c2442_camif_upll_round(struct clk *clk,
-					      unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	int div;
-
-	if (rate > parent_rate)
-		return parent_rate;
-
-	div = parent_rate / rate;
-
-	if (div == 3)
-		return parent_rate / 3;
-
-	/* note, we remove the +/- 1 calculations for the divisor */
-
-	div /= 2;
-
-	if (div < 1)
-		div = 1;
-	else if (div > 16)
-		div = 16;
-
-	return parent_rate / (div * 2);
-}
-
-static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
-
-	rate = s3c2442_camif_upll_round(clk, rate);
-
-	camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3;
-
-	if (rate == parent_rate) {
-		camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL;
-	} else if ((parent_rate / rate) == 3) {
-		camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
-		camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3;
-	} else {
-		camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK;
-		camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
-		camdivn |= (((parent_rate / rate) / 2) - 1);
-	}
-
-	__raw_writel(camdivn, S3C2440_CAMDIVN);
-
-	return 0;
-}
-
-/* Extra S3C2442 clocks */
-
-static struct clk s3c2442_clk_cam = {
-	.name		= "camif",
-	.id		= -1,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2440_CLKCON_CAMERA,
-};
-
-static struct clk s3c2442_clk_cam_upll = {
-	.name		= "camif-upll",
-	.id		= -1,
-	.ops		= &(struct clk_ops) {
-		.set_rate	= s3c2442_camif_upll_setrate,
-		.round_rate	= s3c2442_camif_upll_round,
-	},
-};
-
-static int s3c2442_clk_add(struct device *dev, struct subsys_interface *sif)
-{
-	struct clk *clock_upll;
-	struct clk *clock_h;
-	struct clk *clock_p;
-
-	clock_p = clk_get(NULL, "pclk");
-	clock_h = clk_get(NULL, "hclk");
-	clock_upll = clk_get(NULL, "upll");
-
-	if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
-		printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
-		return -EINVAL;
-	}
-
-	s3c2442_clk_cam.parent = clock_h;
-	s3c2442_clk_cam_upll.parent = clock_upll;
-
-	s3c24xx_register_clock(&s3c2442_clk_cam);
-	s3c24xx_register_clock(&s3c2442_clk_cam_upll);
-
-	clk_disable(&s3c2442_clk_cam);
-
-	return 0;
-}
-
-static struct subsys_interface s3c2442_clk_interface = {
-	.name		= "s3c2442_clk",
-	.subsys		= &s3c2442_subsys,
-	.add_dev	= s3c2442_clk_add,
-};
-
-static __init int s3c2442_clk_init(void)
-{
-	return subsys_interface_register(&s3c2442_clk_interface);
-}
-
-arch_initcall(s3c2442_clk_init);
-#endif
-
 static struct device s3c2442_dev = {
 	.bus		= &s3c2442_subsys,
 };
diff --git a/arch/arm/mach-s3c24xx/s3c244x.c b/arch/arm/mach-s3c24xx/s3c244x.c
index aaaf90d2..c15a1b7 100644
--- a/arch/arm/mach-s3c24xx/s3c244x.c
+++ b/arch/arm/mach-s3c24xx/s3c244x.c
@@ -78,72 +78,9 @@ void __init s3c244x_map_io(void)
 	s3c2410_device_dclk.name = "s3c2440-dclk";
 }
 
-#ifdef CONFIG_SAMSUNG_CLOCK
 void __init_or_cpufreq s3c244x_setup_clocks(void)
 {
-	struct clk *xtal_clk;
-	unsigned long clkdiv;
-	unsigned long camdiv;
-	unsigned long xtal;
-	unsigned long hclk, fclk, pclk;
-	int hdiv = 1;
-
-	xtal_clk = clk_get(NULL, "xtal");
-	xtal = clk_get_rate(xtal_clk);
-	clk_put(xtal_clk);
-
-	fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
-
-	clkdiv = __raw_readl(S3C2410_CLKDIVN);
-	camdiv = __raw_readl(S3C2440_CAMDIVN);
-
-	/* work out clock scalings */
-
-	switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
-	case S3C2440_CLKDIVN_HDIVN_1:
-		hdiv = 1;
-		break;
-
-	case S3C2440_CLKDIVN_HDIVN_2:
-		hdiv = 2;
-		break;
-
-	case S3C2440_CLKDIVN_HDIVN_4_8:
-		hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
-		break;
-
-	case S3C2440_CLKDIVN_HDIVN_3_6:
-		hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
-		break;
-	}
-
-	hclk = fclk / hdiv;
-	pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN) ? 2 : 1);
-
-	/* print brief summary of clocks, etc */
-
-	printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
-	       print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
-
-	s3c24xx_setup_clocks(fclk, hclk, pclk);
-}
-
-void __init s3c244x_init_clocks(int xtal)
-{
-	/* initialise the clocks here, to allow other things like the
-	 * console to use them, and to add new ones after the initialisation
-	 */
-
-	s3c24xx_register_baseclocks(xtal);
-	s3c244x_setup_clocks();
-	s3c2410_baseclk_add();
-	samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
 }
-#else
-void __init_or_cpufreq s3c244x_setup_clocks(void)
-{
-}
-#endif
 
 /* Since the S3C2442 and S3C2440 share items, put both subsystems here */
 
-- 
1.7.10.4

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

* [PATCH 12/12] ARM: S3C24XX: remove legacy clock code
@ 2013-12-13 13:03   ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2013-12-13 13:03 UTC (permalink / raw)
  To: linux-arm-kernel

With the move to the common clock framework completed for s3c2410, s3c2440
and s3c2442, the legacy clock code for these machines can go away too.

This also includes the legacy dclk code, as all legacy users are converted
and the remaining user of the Samsung clock code (s3c2412) does not use
them at all.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
---
 arch/arm/mach-s3c24xx/Kconfig                   |   11 -
 arch/arm/mach-s3c24xx/Makefile                  |    2 -
 arch/arm/mach-s3c24xx/clock-dclk.c              |  195 ----------------
 arch/arm/mach-s3c24xx/clock-s3c2410.c           |  285 -----------------------
 arch/arm/mach-s3c24xx/clock-s3c2440.c           |  217 -----------------
 arch/arm/mach-s3c24xx/clock-s3c244x.c           |  141 -----------
 arch/arm/mach-s3c24xx/common.h                  |    2 -
 arch/arm/mach-s3c24xx/include/mach/regs-clock.h |   18 --
 arch/arm/mach-s3c24xx/include/mach/regs-gpio.h  |    3 -
 arch/arm/mach-s3c24xx/pm.c                      |   12 -
 arch/arm/mach-s3c24xx/s3c2410.c                 |   62 -----
 arch/arm/mach-s3c24xx/s3c2442.c                 |  112 ---------
 arch/arm/mach-s3c24xx/s3c244x.c                 |   63 -----
 13 files changed, 1123 deletions(-)
 delete mode 100644 arch/arm/mach-s3c24xx/clock-dclk.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2410.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2440.c
 delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c244x.c

diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index 12a2f6d..075780e 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -109,17 +109,6 @@ config CPU_S3C2443
 
 # common code
 
-config S3C2410_CLOCK
-	bool
-	help
-	  Clock code for the S3C2410, and similar processors which
-	  is currently includes the S3C2410, S3C2440, S3C2442.
-
-config S3C24XX_DCLK
-	bool
-	help
-	  Clock code for supporting DCLK/CLKOUT on S3C24XX architectures
-
 config S3C24XX_SMDK
 	bool
 	help
diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index 720bf7a..51d9578 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -44,10 +44,8 @@ obj-$(CONFIG_PM)		+= pm.o irq-pm.o sleep.o
 
 # common code
 
-obj-$(CONFIG_S3C24XX_DCLK)	+= clock-dclk.o
 obj-$(CONFIG_S3C24XX_DMA)	+= dma.o
 
-obj-$(CONFIG_S3C2410_CLOCK)	+= clock-s3c2410.o
 obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += cpufreq-utils.o
 
 obj-$(CONFIG_S3C2410_IOTIMING)	+= iotiming-s3c2410.o
diff --git a/arch/arm/mach-s3c24xx/clock-dclk.c b/arch/arm/mach-s3c24xx/clock-dclk.c
deleted file mode 100644
index 1edd9b2..0000000
--- a/arch/arm/mach-s3c24xx/clock-dclk.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2004-2008 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *	http://armlinux.simtec.co.uk/
- *
- * 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.
- *
- * S3C24XX - definitions for DCLK and CLKOUT registers
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <mach/regs-clock.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-/* clocks that could be registered by external code */
-
-static int s3c24xx_dclk_enable(struct clk *clk, int enable)
-{
-	unsigned long dclkcon = __raw_readl(S3C24XX_DCLKCON);
-
-	if (enable)
-		dclkcon |= clk->ctrlbit;
-	else
-		dclkcon &= ~clk->ctrlbit;
-
-	__raw_writel(dclkcon, S3C24XX_DCLKCON);
-
-	return 0;
-}
-
-static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
-{
-	unsigned long dclkcon;
-	unsigned int uclk;
-
-	if (parent == &clk_upll)
-		uclk = 1;
-	else if (parent == &clk_p)
-		uclk = 0;
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	dclkcon = __raw_readl(S3C24XX_DCLKCON);
-
-	if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
-		if (uclk)
-			dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK;
-		else
-			dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK;
-	} else {
-		if (uclk)
-			dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK;
-		else
-			dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
-	}
-
-	__raw_writel(dclkcon, S3C24XX_DCLKCON);
-
-	return 0;
-}
-static unsigned long s3c24xx_calc_div(struct clk *clk, unsigned long rate)
-{
-	unsigned long div;
-
-	if ((rate == 0) || !clk->parent)
-		return 0;
-
-	div = clk_get_rate(clk->parent) / rate;
-	if (div < 2)
-		div = 2;
-	else if (div > 16)
-		div = 16;
-
-	return div;
-}
-
-static unsigned long s3c24xx_round_dclk_rate(struct clk *clk,
-	unsigned long rate)
-{
-	unsigned long div = s3c24xx_calc_div(clk, rate);
-
-	if (div == 0)
-		return 0;
-
-	return clk_get_rate(clk->parent) / div;
-}
-
-static int s3c24xx_set_dclk_rate(struct clk *clk, unsigned long rate)
-{
-	unsigned long mask, data, div = s3c24xx_calc_div(clk, rate);
-
-	if (div == 0)
-		return -EINVAL;
-
-	if (clk == &s3c24xx_dclk0) {
-		mask = S3C2410_DCLKCON_DCLK0_DIV_MASK |
-			S3C2410_DCLKCON_DCLK0_CMP_MASK;
-		data = S3C2410_DCLKCON_DCLK0_DIV(div) |
-			S3C2410_DCLKCON_DCLK0_CMP((div + 1) / 2);
-	} else if (clk == &s3c24xx_dclk1) {
-		mask = S3C2410_DCLKCON_DCLK1_DIV_MASK |
-			S3C2410_DCLKCON_DCLK1_CMP_MASK;
-		data = S3C2410_DCLKCON_DCLK1_DIV(div) |
-			S3C2410_DCLKCON_DCLK1_CMP((div + 1) / 2);
-	} else
-		return -EINVAL;
-
-	clk->rate = clk_get_rate(clk->parent) / div;
-	__raw_writel(((__raw_readl(S3C24XX_DCLKCON) & ~mask) | data),
-		S3C24XX_DCLKCON);
-	return clk->rate;
-}
-static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
-{
-	unsigned long mask;
-	unsigned long source;
-
-	/* calculate the MISCCR setting for the clock */
-
-	if (parent == &clk_mpll)
-		source = S3C2410_MISCCR_CLK0_MPLL;
-	else if (parent == &clk_upll)
-		source = S3C2410_MISCCR_CLK0_UPLL;
-	else if (parent == &clk_f)
-		source = S3C2410_MISCCR_CLK0_FCLK;
-	else if (parent == &clk_h)
-		source = S3C2410_MISCCR_CLK0_HCLK;
-	else if (parent == &clk_p)
-		source = S3C2410_MISCCR_CLK0_PCLK;
-	else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0)
-		source = S3C2410_MISCCR_CLK0_DCLK0;
-	else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1)
-		source = S3C2410_MISCCR_CLK0_DCLK0;
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	if (clk == &s3c24xx_clkout0)
-		mask = S3C2410_MISCCR_CLK0_MASK;
-	else {
-		source <<= 4;
-		mask = S3C2410_MISCCR_CLK1_MASK;
-	}
-
-	s3c2410_modify_misccr(mask, source);
-	return 0;
-}
-
-/* external clock definitions */
-
-static struct clk_ops dclk_ops = {
-	.set_parent	= s3c24xx_dclk_setparent,
-	.set_rate	= s3c24xx_set_dclk_rate,
-	.round_rate	= s3c24xx_round_dclk_rate,
-};
-
-struct clk s3c24xx_dclk0 = {
-	.name		= "dclk0",
-	.ctrlbit	= S3C2410_DCLKCON_DCLK0EN,
-	.enable	        = s3c24xx_dclk_enable,
-	.ops		= &dclk_ops,
-};
-
-struct clk s3c24xx_dclk1 = {
-	.name		= "dclk1",
-	.ctrlbit	= S3C2410_DCLKCON_DCLK1EN,
-	.enable		= s3c24xx_dclk_enable,
-	.ops		= &dclk_ops,
-};
-
-static struct clk_ops clkout_ops = {
-	.set_parent	= s3c24xx_clkout_setparent,
-};
-
-struct clk s3c24xx_clkout0 = {
-	.name		= "clkout0",
-	.ops		= &clkout_ops,
-};
-
-struct clk s3c24xx_clkout1 = {
-	.name		= "clkout1",
-	.ops		= &clkout_ops,
-};
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2410.c b/arch/arm/mach-s3c24xx/clock-s3c2410.c
deleted file mode 100644
index d39d3c7..0000000
--- a/arch/arm/mach-s3c24xx/clock-s3c2410.c
+++ /dev/null
@@ -1,285 +0,0 @@
-/*
- * Copyright (c) 2006 Simtec Electronics
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410,S3C2440,S3C2442 Clock control support
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/clk.h>
-#include <linux/mutex.h>
-#include <linux/delay.h>
-#include <linux/serial_core.h>
-#include <linux/io.h>
-
-#include <asm/mach/map.h>
-
-#include <mach/hardware.h>
-
-#include <plat/regs-serial.h>
-#include <mach/regs-clock.h>
-#include <mach/regs-gpio.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-int s3c2410_clkcon_enable(struct clk *clk, int enable)
-{
-	unsigned int clocks = clk->ctrlbit;
-	unsigned long clkcon;
-
-	clkcon = __raw_readl(S3C2410_CLKCON);
-
-	if (enable)
-		clkcon |= clocks;
-	else
-		clkcon &= ~clocks;
-
-	/* ensure none of the special function bits set */
-	clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
-
-	__raw_writel(clkcon, S3C2410_CLKCON);
-
-	return 0;
-}
-
-static int s3c2410_upll_enable(struct clk *clk, int enable)
-{
-	unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
-	unsigned long orig = clkslow;
-
-	if (enable)
-		clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF;
-	else
-		clkslow |= S3C2410_CLKSLOW_UCLK_OFF;
-
-	__raw_writel(clkslow, S3C2410_CLKSLOW);
-
-	/* if we started the UPLL, then allow to settle */
-
-	if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
-		udelay(200);
-
-	return 0;
-}
-
-/* standard clock definitions */
-
-static struct clk init_clocks_off[] = {
-	{
-		.name		= "nand",
-		.parent		= &clk_h,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_NAND,
-	}, {
-		.name		= "sdi",
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_SDI,
-	}, {
-		.name		= "adc",
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_ADC,
-	}, {
-		.name		= "i2c",
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_IIC,
-	}, {
-		.name		= "iis",
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_IIS,
-	}, {
-		.name		= "spi",
-		.parent		= &clk_p,
-		.enable		= s3c2410_clkcon_enable,
-		.ctrlbit	= S3C2410_CLKCON_SPI,
-	}
-};
-
-static struct clk clk_lcd = {
-	.name		= "lcd",
-	.parent		= &clk_h,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_LCDC,
-};
-
-static struct clk clk_gpio = {
-	.name		= "gpio",
-	.parent		= &clk_p,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_GPIO,
-};
-
-static struct clk clk_usb_host = {
-	.name		= "usb-host",
-	.parent		= &clk_h,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_USBH,
-};
-
-static struct clk clk_usb_device = {
-	.name		= "usb-device",
-	.parent		= &clk_h,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_USBD,
-};
-
-static struct clk clk_timers = {
-	.name		= "timers",
-	.parent		= &clk_p,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_PWMT,
-};
-
-struct clk s3c24xx_clk_uart0 = {
-	.name		= "uart",
-	.devname	= "s3c2410-uart.0",
-	.parent		= &clk_p,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_UART0,
-};
-
-struct clk s3c24xx_clk_uart1 = {
-	.name		= "uart",
-	.devname	= "s3c2410-uart.1",
-	.parent		= &clk_p,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_UART1,
-};
-
-struct clk s3c24xx_clk_uart2 = {
-	.name		= "uart",
-	.devname	= "s3c2410-uart.2",
-	.parent		= &clk_p,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_UART2,
-};
-
-static struct clk clk_rtc = {
-	.name		= "rtc",
-	.parent		= &clk_p,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2410_CLKCON_RTC,
-};
-
-static struct clk clk_watchdog = {
-	.name		= "watchdog",
-	.parent		= &clk_p,
-	.ctrlbit	= 0,
-};
-
-static struct clk clk_usb_bus_host = {
-	.name		= "usb-bus-host",
-	.parent		= &clk_usb_bus,
-};
-
-static struct clk clk_usb_bus_gadget = {
-	.name		= "usb-bus-gadget",
-	.parent		= &clk_usb_bus,
-};
-
-static struct clk *init_clocks[] = {
-	&clk_lcd,
-	&clk_gpio,
-	&clk_usb_host,
-	&clk_usb_device,
-	&clk_timers,
-	&s3c24xx_clk_uart0,
-	&s3c24xx_clk_uart1,
-	&s3c24xx_clk_uart2,
-	&clk_rtc,
-	&clk_watchdog,
-	&clk_usb_bus_host,
-	&clk_usb_bus_gadget,
-};
-
-/* s3c2410_baseclk_add()
- *
- * Add all the clocks used by the s3c2410 or compatible CPUs
- * such as the S3C2440 and S3C2442.
- *
- * We cannot use a system device as we are needed before any
- * of the init-calls that initialise the devices are actually
- * done.
-*/
-
-int __init s3c2410_baseclk_add(void)
-{
-	unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
-	unsigned long clkcon  = __raw_readl(S3C2410_CLKCON);
-	struct clk *xtal;
-	int ret;
-	int ptr;
-
-	clk_upll.enable = s3c2410_upll_enable;
-
-	if (s3c24xx_register_clock(&clk_usb_bus) < 0)
-		printk(KERN_ERR "failed to register usb bus clock\n");
-
-	/* register clocks from clock array */
-
-	for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++) {
-		struct clk *clkp = init_clocks[ptr];
-
-		/* ensure that we note the clock state */
-
-		clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
-
-		ret = s3c24xx_register_clock(clkp);
-		if (ret < 0) {
-			printk(KERN_ERR "Failed to register clock %s (%d)\n",
-			       clkp->name, ret);
-		}
-	}
-
-	/* We must be careful disabling the clocks we are not intending to
-	 * be using at boot time, as subsystems such as the LCD which do
-	 * their own DMA requests to the bus can cause the system to lockup
-	 * if they where in the middle of requesting bus access.
-	 *
-	 * Disabling the LCD clock if the LCD is active is very dangerous,
-	 * and therefore the bootloader should be careful to not enable
-	 * the LCD clock if it is not needed.
-	*/
-
-	/* install (and disable) the clocks we do not need immediately */
-
-	s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-	s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off));
-
-	/* show the clock-slow value */
-
-	xtal = clk_get(NULL, "xtal");
-
-	printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
-	       print_mhz(clk_get_rate(xtal) /
-			 ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
-	       (clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
-	       (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
-	       (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
-
-	return 0;
-}
diff --git a/arch/arm/mach-s3c24xx/clock-s3c2440.c b/arch/arm/mach-s3c24xx/clock-s3c2440.c
deleted file mode 100644
index aaf006d..0000000
--- a/arch/arm/mach-s3c24xx/clock-s3c2440.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/clock.c
- *
- * Copyright (c) 2004-2005 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2440 Clock support
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/mutex.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/serial_core.h>
-
-#include <mach/hardware.h>
-#include <linux/atomic.h>
-#include <asm/irq.h>
-
-#include <mach/regs-clock.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-#include <plat/regs-serial.h>
-
-/* S3C2440 extended clock support */
-
-static unsigned long s3c2440_camif_upll_round(struct clk *clk,
-					      unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	int div;
-
-	if (rate > parent_rate)
-		return parent_rate;
-
-	/* note, we remove the +/- 1 calculations for the divisor */
-
-	div = (parent_rate / rate) / 2;
-
-	if (div < 1)
-		div = 1;
-	else if (div > 16)
-		div = 16;
-
-	return parent_rate / (div * 2);
-}
-
-static int s3c2440_camif_upll_setrate(struct clk *clk, unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
-
-	rate = s3c2440_camif_upll_round(clk, rate);
-
-	camdivn &= ~(S3C2440_CAMDIVN_CAMCLK_SEL | S3C2440_CAMDIVN_CAMCLK_MASK);
-
-	if (rate != parent_rate) {
-		camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
-		camdivn |= (((parent_rate / rate) / 2) - 1);
-	}
-
-	__raw_writel(camdivn, S3C2440_CAMDIVN);
-
-	return 0;
-}
-
-static unsigned long s3c2440_camif_upll_getrate(struct clk *clk)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
-
-	if (!(camdivn & S3C2440_CAMDIVN_CAMCLK_SEL))
-		return parent_rate;
-
-	camdivn &= S3C2440_CAMDIVN_CAMCLK_MASK;
-
-	return parent_rate / (camdivn + 1) / 2;
-}
-
-/* Extra S3C2440 clocks */
-
-static struct clk s3c2440_clk_cam = {
-	.name		= "camif",
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2440_CLKCON_CAMERA,
-};
-
-static struct clk s3c2440_clk_cam_upll = {
-	.name		= "camif-upll",
-	.ops		= &(struct clk_ops) {
-		.set_rate	= s3c2440_camif_upll_setrate,
-		.get_rate	= s3c2440_camif_upll_getrate,
-		.round_rate	= s3c2440_camif_upll_round,
-	},
-};
-
-static struct clk s3c2440_clk_ac97 = {
-	.name		= "ac97",
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2440_CLKCON_AC97,
-};
-
-#define S3C24XX_VA_UART0      (S3C_VA_UART)
-#define S3C24XX_VA_UART1      (S3C_VA_UART + 0x4000 )
-#define S3C24XX_VA_UART2      (S3C_VA_UART + 0x8000 )
-#define S3C24XX_VA_UART3      (S3C_VA_UART + 0xC000 )
-
-static unsigned long  s3c2440_fclk_n_getrate(struct clk *clk)
-{
-	unsigned long ucon0, ucon1, ucon2, divisor;
-
-	/* the fun of calculating the uart divisors on the s3c2440 */
-	ucon0 = __raw_readl(S3C24XX_VA_UART0 + S3C2410_UCON);
-	ucon1 = __raw_readl(S3C24XX_VA_UART1 + S3C2410_UCON);
-	ucon2 = __raw_readl(S3C24XX_VA_UART2 + S3C2410_UCON);
-
-	ucon0 &= S3C2440_UCON0_DIVMASK;
-	ucon1 &= S3C2440_UCON1_DIVMASK;
-	ucon2 &= S3C2440_UCON2_DIVMASK;
-
-	if (ucon0 != 0)
-		divisor = (ucon0 >> S3C2440_UCON_DIVSHIFT) + 6;
-	else if (ucon1 != 0)
-		divisor = (ucon1 >> S3C2440_UCON_DIVSHIFT) + 21;
-	else if (ucon2 != 0)
-		divisor = (ucon2 >> S3C2440_UCON_DIVSHIFT) + 36;
-	else
-		/* manual calims 44, seems to be 9 */
-		divisor = 9;
-
-	return clk_get_rate(clk->parent) / divisor;
-}
-
-static struct clk s3c2440_clk_fclk_n = {
-	.name		= "fclk_n",
-	.parent		= &clk_f,
-	.ops		= &(struct clk_ops) {
-		.get_rate	= s3c2440_fclk_n_getrate,
-	},
-};
-
-static struct clk_lookup s3c2440_clk_lookup[] = {
-	CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
-	CLKDEV_INIT(NULL, "clk_uart_baud2", &clk_p),
-	CLKDEV_INIT(NULL, "clk_uart_baud3", &s3c2440_clk_fclk_n),
-	CLKDEV_INIT("s3c2440-uart.0", "uart", &s3c24xx_clk_uart0),
-	CLKDEV_INIT("s3c2440-uart.1", "uart", &s3c24xx_clk_uart1),
-	CLKDEV_INIT("s3c2440-uart.2", "uart", &s3c24xx_clk_uart2),
-	CLKDEV_INIT("s3c2440-camif", "camera", &s3c2440_clk_cam_upll),
-};
-
-static int __init_refok s3c2440_clk_add(struct device *dev, struct subsys_interface *sif)
-{
-	struct clk *clock_upll;
-	struct clk *clock_h;
-	struct clk *clock_p;
-
-	clock_p = clk_get(NULL, "pclk");
-	clock_h = clk_get(NULL, "hclk");
-	clock_upll = clk_get(NULL, "upll");
-
-	if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
-		printk(KERN_ERR "S3C2440: Failed to get parent clocks\n");
-		return -EINVAL;
-	}
-
-	s3c2440_clk_cam.parent = clock_h;
-	s3c2440_clk_ac97.parent = clock_p;
-	s3c2440_clk_cam_upll.parent = clock_upll;
-	s3c24xx_register_clock(&s3c2440_clk_fclk_n);
-
-	s3c24xx_register_clock(&s3c2440_clk_ac97);
-	s3c24xx_register_clock(&s3c2440_clk_cam);
-	s3c24xx_register_clock(&s3c2440_clk_cam_upll);
-	clkdev_add_table(s3c2440_clk_lookup, ARRAY_SIZE(s3c2440_clk_lookup));
-
-	clk_disable(&s3c2440_clk_ac97);
-	clk_disable(&s3c2440_clk_cam);
-
-	return 0;
-}
-
-static struct subsys_interface s3c2440_clk_interface = {
-	.name		= "s3c2440_clk",
-	.subsys		= &s3c2440_subsys,
-	.add_dev	= s3c2440_clk_add,
-};
-
-static __init int s3c24xx_clk_init(void)
-{
-	return subsys_interface_register(&s3c2440_clk_interface);
-}
-
-arch_initcall(s3c24xx_clk_init);
diff --git a/arch/arm/mach-s3c24xx/clock-s3c244x.c b/arch/arm/mach-s3c24xx/clock-s3c244x.c
deleted file mode 100644
index 6d9b688..0000000
--- a/arch/arm/mach-s3c24xx/clock-s3c244x.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/* linux/arch/arm/plat-s3c24xx/s3c24xx-clock.c
- *
- * Copyright (c) 2004-2008 Simtec Electronics
- *	http://armlinux.simtec.co.uk/
- *	Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2440/S3C2442 Common clock support
- *
- * 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.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/device.h>
-#include <linux/interrupt.h>
-#include <linux/ioport.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-#include <mach/hardware.h>
-#include <linux/atomic.h>
-#include <asm/irq.h>
-
-#include <mach/regs-clock.h>
-
-#include <plat/clock.h>
-#include <plat/cpu.h>
-
-static int s3c2440_setparent_armclk(struct clk *clk, struct clk *parent)
-{
-	unsigned long camdivn;
-	unsigned long dvs;
-
-	if (parent == &clk_f)
-		dvs = 0;
-	else if (parent == &clk_h)
-		dvs = S3C2440_CAMDIVN_DVSEN;
-	else
-		return -EINVAL;
-
-	clk->parent = parent;
-
-	camdivn  = __raw_readl(S3C2440_CAMDIVN);
-	camdivn &= ~S3C2440_CAMDIVN_DVSEN;
-	camdivn |= dvs;
-	__raw_writel(camdivn, S3C2440_CAMDIVN);
-
-	return 0;
-}
-
-static struct clk clk_arm = {
-	.name		= "armclk",
-	.id		= -1,
-	.ops		= &(struct clk_ops) {
-		.set_parent	= s3c2440_setparent_armclk,
-	},
-};
-
-static int s3c244x_clk_add(struct device *dev, struct subsys_interface *sif)
-{
-	unsigned long camdivn = __raw_readl(S3C2440_CAMDIVN);
-	unsigned long clkdivn;
-	struct clk *clock_upll;
-	int ret;
-
-	printk("S3C244X: Clock Support, DVS %s\n",
-	       (camdivn & S3C2440_CAMDIVN_DVSEN) ? "on" : "off");
-
-	clk_arm.parent = (camdivn & S3C2440_CAMDIVN_DVSEN) ? &clk_h : &clk_f;
-
-	ret = s3c24xx_register_clock(&clk_arm);
-	if (ret < 0) {
-		printk(KERN_ERR "S3C24XX: Failed to add armclk (%d)\n", ret);
-		return ret;
-	}
-
-	clock_upll = clk_get(NULL, "upll");
-	if (IS_ERR(clock_upll)) {
-		printk(KERN_ERR "S3C244X: Failed to get upll clock\n");
-		return -ENOENT;
-	}
-
-	/* check rate of UPLL, and if it is near 96MHz, then change
-	 * to using half the UPLL rate for the system */
-
-	if (clk_get_rate(clock_upll) > (94 * MHZ)) {
-		clk_usb_bus.rate = clk_get_rate(clock_upll) / 2;
-
-		spin_lock(&clocks_lock);
-
-		clkdivn = __raw_readl(S3C2410_CLKDIVN);
-		clkdivn |= S3C2440_CLKDIVN_UCLK;
-		__raw_writel(clkdivn, S3C2410_CLKDIVN);
-
-		spin_unlock(&clocks_lock);
-	}
-
-	return 0;
-}
-
-static struct subsys_interface s3c2440_clk_interface = {
-	.name		= "s3c2440_clk",
-	.subsys		= &s3c2440_subsys,
-	.add_dev	= s3c244x_clk_add,
-};
-
-static int s3c2440_clk_init(void)
-{
-	return subsys_interface_register(&s3c2440_clk_interface);
-}
-
-arch_initcall(s3c2440_clk_init);
-
-static struct subsys_interface s3c2442_clk_interface = {
-	.name		= "s3c2442_clk",
-	.subsys		= &s3c2442_subsys,
-	.add_dev	= s3c244x_clk_add,
-};
-
-static int s3c2442_clk_init(void)
-{
-	return subsys_interface_register(&s3c2442_clk_interface);
-}
-
-arch_initcall(s3c2442_clk_init);
diff --git a/arch/arm/mach-s3c24xx/common.h b/arch/arm/mach-s3c24xx/common.h
index 4b3157e..30124d1d 100644
--- a/arch/arm/mach-s3c24xx/common.h
+++ b/arch/arm/mach-s3c24xx/common.h
@@ -67,10 +67,8 @@ extern struct syscore_ops s3c2416_irq_syscore_ops;
 #if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
 extern void s3c244x_map_io(void);
 extern void s3c244x_init_uarts(struct s3c2410_uartcfg *cfg, int no);
-extern void s3c244x_init_clocks(int xtal);
 extern void s3c244x_restart(enum reboot_mode mode, const char *cmd);
 #else
-#define s3c244x_init_clocks NULL
 #define s3c244x_init_uarts NULL
 #endif
 
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-clock.h b/arch/arm/mach-s3c24xx/include/mach/regs-clock.h
index 3415b60..3db6c10 100644
--- a/arch/arm/mach-s3c24xx/include/mach/regs-clock.h
+++ b/arch/arm/mach-s3c24xx/include/mach/regs-clock.h
@@ -42,24 +42,6 @@
 #define S3C2410_CLKCON_IIS	     (1<<17)
 #define S3C2410_CLKCON_SPI	     (1<<18)
 
-/* DCLKCON register addresses in gpio.h */
-
-#define S3C2410_DCLKCON_DCLK0EN	     (1<<0)
-#define S3C2410_DCLKCON_DCLK0_PCLK   (0<<1)
-#define S3C2410_DCLKCON_DCLK0_UCLK   (1<<1)
-#define S3C2410_DCLKCON_DCLK0_DIV(x) (((x) - 1 )<<4)
-#define S3C2410_DCLKCON_DCLK0_CMP(x) (((x) - 1 )<<8)
-#define S3C2410_DCLKCON_DCLK0_DIV_MASK ((0xf)<<4)
-#define S3C2410_DCLKCON_DCLK0_CMP_MASK ((0xf)<<8)
-
-#define S3C2410_DCLKCON_DCLK1EN	     (1<<16)
-#define S3C2410_DCLKCON_DCLK1_PCLK   (0<<17)
-#define S3C2410_DCLKCON_DCLK1_UCLK   (1<<17)
-#define S3C2410_DCLKCON_DCLK1_DIV(x) (((x) - 1) <<20)
-#define S3C2410_DCLKCON_DCLK1_CMP(x) (((x) - 1) <<24)
-#define S3C2410_DCLKCON_DCLK1_DIV_MASK ((0xf) <<20)
-#define S3C2410_DCLKCON_DCLK1_CMP_MASK ((0xf) <<24)
-
 #define S3C2410_CLKDIVN_PDIVN	     (1<<0)
 #define S3C2410_CLKDIVN_HDIVN	     (1<<1)
 
diff --git a/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h b/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h
index c2ef016..c6583cf 100644
--- a/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h
+++ b/arch/arm/mach-s3c24xx/include/mach/regs-gpio.h
@@ -457,9 +457,6 @@
 
 /* miscellaneous control */
 #define S3C2410_MISCCR	   S3C2410_GPIOREG(0x80)
-#define S3C2410_DCLKCON	   S3C2410_GPIOREG(0x84)
-
-#define S3C24XX_DCLKCON	   S3C24XX_GPIOREG2(0x84)
 
 /* see clock.h for dclk definitions */
 
diff --git a/arch/arm/mach-s3c24xx/pm.c b/arch/arm/mach-s3c24xx/pm.c
index 9cc6fc1..f2dff6f 100644
--- a/arch/arm/mach-s3c24xx/pm.c
+++ b/arch/arm/mach-s3c24xx/pm.c
@@ -79,12 +79,6 @@ static struct sleep_save core_save[] = {
 #endif /* CONFIG_SAMSUNG_CLOCK */
 };
 
-#ifdef CONFIG_SAMSUNG_CLOCK
-static struct sleep_save misc_save[] = {
-	SAVE_ITEM(S3C2410_DCLKCON),
-};
-#endif
-
 /* s3c_pm_check_resume_pin
  *
  * check to see if the pin is configured correctly for sleep mode, and
@@ -142,16 +136,10 @@ void s3c_pm_configure_extint(void)
 void s3c_pm_restore_core(void)
 {
 	s3c_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
-#ifdef CONFIG_SAMSUNG_CLOCK
-	s3c_pm_do_restore(misc_save, ARRAY_SIZE(misc_save));
-#endif
 }
 
 void s3c_pm_save_core(void)
 {
-#ifdef CONFIG_SAMSUNG_CLOCK
-	s3c_pm_do_save(misc_save, ARRAY_SIZE(misc_save));
-#endif
 	s3c_pm_do_save(core_save, ARRAY_SIZE(core_save));
 }
 
diff --git a/arch/arm/mach-s3c24xx/s3c2410.c b/arch/arm/mach-s3c24xx/s3c2410.c
index 04bed99..fef99fe 100644
--- a/arch/arm/mach-s3c24xx/s3c2410.c
+++ b/arch/arm/mach-s3c24xx/s3c2410.c
@@ -82,71 +82,9 @@ void __init s3c2410_map_io(void)
 	iotable_init(s3c2410_iodesc, ARRAY_SIZE(s3c2410_iodesc));
 }
 
-#ifdef CONFIG_SAMSUNG_CLOCK
 void __init_or_cpufreq s3c2410_setup_clocks(void)
 {
-	struct clk *xtal_clk;
-	unsigned long tmp;
-	unsigned long xtal;
-	unsigned long fclk;
-	unsigned long hclk;
-	unsigned long pclk;
-
-	xtal_clk = clk_get(NULL, "xtal");
-	xtal = clk_get_rate(xtal_clk);
-	clk_put(xtal_clk);
-
-	/* now we've got our machine bits initialised, work out what
-	 * clocks we've got */
-
-	fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal);
-
-	tmp = __raw_readl(S3C2410_CLKDIVN);
-
-	/* work out clock scalings */
-
-	hclk = fclk / ((tmp & S3C2410_CLKDIVN_HDIVN) ? 2 : 1);
-	pclk = hclk / ((tmp & S3C2410_CLKDIVN_PDIVN) ? 2 : 1);
-
-	/* print brieft summary of clocks, etc */
-
-	printk("S3C2410: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
-	       print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
-
-	/* initialise the clocks here, to allow other things like the
-	 * console to use them
-	 */
-
-	s3c24xx_setup_clocks(fclk, hclk, pclk);
-}
-
-/* fake ARMCLK for use with cpufreq, etc. */
-
-static struct clk s3c2410_armclk = {
-	.name	= "armclk",
-	.parent	= &clk_f,
-	.id	= -1,
-};
-
-static struct clk_lookup s3c2410_clk_lookup[] = {
-	CLKDEV_INIT(NULL, "clk_uart_baud0", &clk_p),
-	CLKDEV_INIT(NULL, "clk_uart_baud1", &s3c24xx_uclk),
-};
-
-void __init s3c2410_init_clocks(int xtal)
-{
-	s3c24xx_register_baseclocks(xtal);
-	s3c2410_setup_clocks();
-	s3c2410_baseclk_add();
-	s3c24xx_register_clock(&s3c2410_armclk);
-	clkdev_add_table(s3c2410_clk_lookup, ARRAY_SIZE(s3c2410_clk_lookup));
-	samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
 }
-#else
-void __init_or_cpufreq s3c2410_setup_clocks(void)
-{
-}
-#endif
 
 struct bus_type s3c2410_subsys = {
 	.name = "s3c2410-core",
diff --git a/arch/arm/mach-s3c24xx/s3c2442.c b/arch/arm/mach-s3c24xx/s3c2442.c
index a4c1519..3fca198 100644
--- a/arch/arm/mach-s3c24xx/s3c2442.c
+++ b/arch/arm/mach-s3c24xx/s3c2442.c
@@ -52,118 +52,6 @@
 
 #include "common.h"
 
-#ifdef CONFIG_SAMSUNG_CLOCK
-/* S3C2442 extended clock support */
-
-static unsigned long s3c2442_camif_upll_round(struct clk *clk,
-					      unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	int div;
-
-	if (rate > parent_rate)
-		return parent_rate;
-
-	div = parent_rate / rate;
-
-	if (div == 3)
-		return parent_rate / 3;
-
-	/* note, we remove the +/- 1 calculations for the divisor */
-
-	div /= 2;
-
-	if (div < 1)
-		div = 1;
-	else if (div > 16)
-		div = 16;
-
-	return parent_rate / (div * 2);
-}
-
-static int s3c2442_camif_upll_setrate(struct clk *clk, unsigned long rate)
-{
-	unsigned long parent_rate = clk_get_rate(clk->parent);
-	unsigned long camdivn =  __raw_readl(S3C2440_CAMDIVN);
-
-	rate = s3c2442_camif_upll_round(clk, rate);
-
-	camdivn &= ~S3C2442_CAMDIVN_CAMCLK_DIV3;
-
-	if (rate == parent_rate) {
-		camdivn &= ~S3C2440_CAMDIVN_CAMCLK_SEL;
-	} else if ((parent_rate / rate) == 3) {
-		camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
-		camdivn |= S3C2442_CAMDIVN_CAMCLK_DIV3;
-	} else {
-		camdivn &= ~S3C2440_CAMDIVN_CAMCLK_MASK;
-		camdivn |= S3C2440_CAMDIVN_CAMCLK_SEL;
-		camdivn |= (((parent_rate / rate) / 2) - 1);
-	}
-
-	__raw_writel(camdivn, S3C2440_CAMDIVN);
-
-	return 0;
-}
-
-/* Extra S3C2442 clocks */
-
-static struct clk s3c2442_clk_cam = {
-	.name		= "camif",
-	.id		= -1,
-	.enable		= s3c2410_clkcon_enable,
-	.ctrlbit	= S3C2440_CLKCON_CAMERA,
-};
-
-static struct clk s3c2442_clk_cam_upll = {
-	.name		= "camif-upll",
-	.id		= -1,
-	.ops		= &(struct clk_ops) {
-		.set_rate	= s3c2442_camif_upll_setrate,
-		.round_rate	= s3c2442_camif_upll_round,
-	},
-};
-
-static int s3c2442_clk_add(struct device *dev, struct subsys_interface *sif)
-{
-	struct clk *clock_upll;
-	struct clk *clock_h;
-	struct clk *clock_p;
-
-	clock_p = clk_get(NULL, "pclk");
-	clock_h = clk_get(NULL, "hclk");
-	clock_upll = clk_get(NULL, "upll");
-
-	if (IS_ERR(clock_p) || IS_ERR(clock_h) || IS_ERR(clock_upll)) {
-		printk(KERN_ERR "S3C2442: Failed to get parent clocks\n");
-		return -EINVAL;
-	}
-
-	s3c2442_clk_cam.parent = clock_h;
-	s3c2442_clk_cam_upll.parent = clock_upll;
-
-	s3c24xx_register_clock(&s3c2442_clk_cam);
-	s3c24xx_register_clock(&s3c2442_clk_cam_upll);
-
-	clk_disable(&s3c2442_clk_cam);
-
-	return 0;
-}
-
-static struct subsys_interface s3c2442_clk_interface = {
-	.name		= "s3c2442_clk",
-	.subsys		= &s3c2442_subsys,
-	.add_dev	= s3c2442_clk_add,
-};
-
-static __init int s3c2442_clk_init(void)
-{
-	return subsys_interface_register(&s3c2442_clk_interface);
-}
-
-arch_initcall(s3c2442_clk_init);
-#endif
-
 static struct device s3c2442_dev = {
 	.bus		= &s3c2442_subsys,
 };
diff --git a/arch/arm/mach-s3c24xx/s3c244x.c b/arch/arm/mach-s3c24xx/s3c244x.c
index aaaf90d2..c15a1b7 100644
--- a/arch/arm/mach-s3c24xx/s3c244x.c
+++ b/arch/arm/mach-s3c24xx/s3c244x.c
@@ -78,72 +78,9 @@ void __init s3c244x_map_io(void)
 	s3c2410_device_dclk.name = "s3c2440-dclk";
 }
 
-#ifdef CONFIG_SAMSUNG_CLOCK
 void __init_or_cpufreq s3c244x_setup_clocks(void)
 {
-	struct clk *xtal_clk;
-	unsigned long clkdiv;
-	unsigned long camdiv;
-	unsigned long xtal;
-	unsigned long hclk, fclk, pclk;
-	int hdiv = 1;
-
-	xtal_clk = clk_get(NULL, "xtal");
-	xtal = clk_get_rate(xtal_clk);
-	clk_put(xtal_clk);
-
-	fclk = s3c24xx_get_pll(__raw_readl(S3C2410_MPLLCON), xtal) * 2;
-
-	clkdiv = __raw_readl(S3C2410_CLKDIVN);
-	camdiv = __raw_readl(S3C2440_CAMDIVN);
-
-	/* work out clock scalings */
-
-	switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
-	case S3C2440_CLKDIVN_HDIVN_1:
-		hdiv = 1;
-		break;
-
-	case S3C2440_CLKDIVN_HDIVN_2:
-		hdiv = 2;
-		break;
-
-	case S3C2440_CLKDIVN_HDIVN_4_8:
-		hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
-		break;
-
-	case S3C2440_CLKDIVN_HDIVN_3_6:
-		hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
-		break;
-	}
-
-	hclk = fclk / hdiv;
-	pclk = hclk / ((clkdiv & S3C2440_CLKDIVN_PDIVN) ? 2 : 1);
-
-	/* print brief summary of clocks, etc */
-
-	printk("S3C244X: core %ld.%03ld MHz, memory %ld.%03ld MHz, peripheral %ld.%03ld MHz\n",
-	       print_mhz(fclk), print_mhz(hclk), print_mhz(pclk));
-
-	s3c24xx_setup_clocks(fclk, hclk, pclk);
-}
-
-void __init s3c244x_init_clocks(int xtal)
-{
-	/* initialise the clocks here, to allow other things like the
-	 * console to use them, and to add new ones after the initialisation
-	 */
-
-	s3c24xx_register_baseclocks(xtal);
-	s3c244x_setup_clocks();
-	s3c2410_baseclk_add();
-	samsung_wdt_reset_init(S3C24XX_VA_WATCHDOG);
 }
-#else
-void __init_or_cpufreq s3c244x_setup_clocks(void)
-{
-}
-#endif
 
 /* Since the S3C2442 and S3C2440 share items, put both subsystems here */
 
-- 
1.7.10.4

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

* Re: [PATCH 06/12] clk: samsung: add plls used by the early s3c24xx cpus
  2013-12-13 13:00   ` Heiko Stübner
@ 2013-12-31 19:45     ` Mike Turquette
  -1 siblings, 0 replies; 54+ messages in thread
From: Mike Turquette @ 2013-12-31 19:45 UTC (permalink / raw)
  To: Heiko Stübner, Kukjin Kim
  Cc: t.figa, linux-arm-kernel, linux-samsung-soc

Quoting Heiko Stübner (2013-12-13 05:00:54)
> The manuals do not give them explicit names like in later socs, so more
> generic names with a s3c2410-prefix were used for them.
> 
> As it was common to do so in the previous implementation, functionality
> to change the pll rate is already included.
> 
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>

Acked-by: Mike Turquette <mturquette@linaro.org>

> ---
>  drivers/clk/samsung/clk-pll.c |  182 +++++++++++++++++++++++++++++++++++++++++
>  drivers/clk/samsung/clk-pll.h |    3 +
>  2 files changed, 185 insertions(+)
> 
> diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
> index 461a6bf..39573bd 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/hrtimer.h>
> +#include <linux/delay.h>
>  #include "clk.h"
>  #include "clk-pll.h"
>  
> @@ -701,6 +702,169 @@ static const struct clk_ops samsung_pll6553_clk_ops = {
>  };
>  
>  /*
> + * PLL Clock Type of S3C24XX before S3C2443
> + */
> +
> +#define PLLS3C2410_MDIV_MASK           (0xff)
> +#define PLLS3C2410_PDIV_MASK           (0x1f)
> +#define PLLS3C2410_SDIV_MASK           (0x3)
> +#define PLLS3C2410_MDIV_SHIFT          (12)
> +#define PLLS3C2410_PDIV_SHIFT          (4)
> +#define PLLS3C2410_SDIV_SHIFT          (0)
> +
> +#define PLLS3C2410_ENABLE_REG_OFFSET   0x10
> +
> +static unsigned long samsung_s3c2410_pll_recalc_rate(struct clk_hw *hw,
> +                                       unsigned long parent_rate)
> +{
> +       struct samsung_clk_pll *pll = to_clk_pll(hw);
> +       u32 pll_con, mdiv, pdiv, sdiv;
> +       u64 fvco = parent_rate;
> +
> +       pll_con = __raw_readl(pll->con_reg);
> +       mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
> +       pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
> +       sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
> +
> +       fvco *= (mdiv + 8);
> +       do_div(fvco, (pdiv + 2) << sdiv);
> +
> +       return (unsigned int)fvco;
> +}
> +
> +static unsigned long samsung_s3c2440_mpll_recalc_rate(struct clk_hw *hw,
> +                                       unsigned long parent_rate)
> +{
> +       struct samsung_clk_pll *pll = to_clk_pll(hw);
> +       u32 pll_con, mdiv, pdiv, sdiv;
> +       u64 fvco = parent_rate;
> +
> +       pll_con = __raw_readl(pll->con_reg);
> +       mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
> +       pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
> +       sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
> +
> +       fvco *= (2 * (mdiv + 8));
> +       do_div(fvco, (pdiv + 2) << sdiv);
> +
> +       return (unsigned int)fvco;
> +}
> +
> +static int samsung_s3c2410_pll_set_rate(struct clk_hw *hw, unsigned long drate,
> +                                       unsigned long prate)
> +{
> +       struct samsung_clk_pll *pll = to_clk_pll(hw);
> +       const struct samsung_pll_rate_table *rate;
> +       u32 tmp;
> +
> +       /* 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;
> +       }
> +
> +       tmp = __raw_readl(pll->con_reg);
> +
> +       /* Change PLL PMS values */
> +       tmp &= ~((PLLS3C2410_MDIV_MASK << PLLS3C2410_MDIV_SHIFT) |
> +                       (PLLS3C2410_PDIV_MASK << PLLS3C2410_PDIV_SHIFT) |
> +                       (PLLS3C2410_SDIV_MASK << PLLS3C2410_SDIV_SHIFT));
> +       tmp |= (rate->mdiv << PLLS3C2410_MDIV_SHIFT) |
> +                       (rate->pdiv << PLLS3C2410_PDIV_SHIFT) |
> +                       (rate->sdiv << PLLS3C2410_SDIV_SHIFT);
> +       __raw_writel(tmp, pll->con_reg);
> +
> +       /* Time to settle according to the manual */
> +       udelay(300);
> +
> +       return 0;
> +}
> +
> +static int samsung_s3c2410_pll_enable(struct clk_hw *hw, int bit, bool enable)
> +{
> +       struct samsung_clk_pll *pll = to_clk_pll(hw);
> +       u32 pll_en = __raw_readl(pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
> +       u32 pll_en_orig = pll_en;
> +
> +       if (enable)
> +               pll_en &= ~BIT(bit);
> +       else
> +               pll_en |= BIT(bit);
> +
> +       __raw_writel(pll_en, pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
> +
> +       /* if we started the UPLL, then allow to settle */
> +       if (enable && (pll_en_orig & BIT(bit)))
> +               udelay(300);
> +
> +       return 0;
> +}
> +
> +static int samsung_s3c2410_mpll_enable(struct clk_hw *hw)
> +{
> +       return samsung_s3c2410_pll_enable(hw, 5, true);
> +}
> +
> +static void samsung_s3c2410_mpll_disable(struct clk_hw *hw)
> +{
> +       samsung_s3c2410_pll_enable(hw, 5, false);
> +}
> +
> +static int samsung_s3c2410_upll_enable(struct clk_hw *hw)
> +{
> +       return samsung_s3c2410_pll_enable(hw, 7, true);
> +}
> +
> +static void samsung_s3c2410_upll_disable(struct clk_hw *hw)
> +{
> +       samsung_s3c2410_pll_enable(hw, 7, false);
> +}
> +
> +static const struct clk_ops samsung_s3c2410_mpll_clk_min_ops = {
> +       .recalc_rate = samsung_s3c2410_pll_recalc_rate,
> +       .enable = samsung_s3c2410_mpll_enable,
> +       .disable = samsung_s3c2410_mpll_disable,
> +};
> +
> +static const struct clk_ops samsung_s3c2410_upll_clk_min_ops = {
> +       .recalc_rate = samsung_s3c2410_pll_recalc_rate,
> +       .enable = samsung_s3c2410_upll_enable,
> +       .disable = samsung_s3c2410_upll_disable,
> +};
> +
> +static const struct clk_ops samsung_s3c2440_mpll_clk_min_ops = {
> +       .recalc_rate = samsung_s3c2440_mpll_recalc_rate,
> +       .enable = samsung_s3c2410_mpll_enable,
> +       .disable = samsung_s3c2410_mpll_disable,
> +};
> +
> +static const struct clk_ops samsung_s3c2410_mpll_clk_ops = {
> +       .recalc_rate = samsung_s3c2410_pll_recalc_rate,
> +       .enable = samsung_s3c2410_mpll_enable,
> +       .disable = samsung_s3c2410_mpll_disable,
> +       .round_rate = samsung_pll_round_rate,
> +       .set_rate = samsung_s3c2410_pll_set_rate,
> +};
> +
> +static const struct clk_ops samsung_s3c2410_upll_clk_ops = {
> +       .recalc_rate = samsung_s3c2410_pll_recalc_rate,
> +       .enable = samsung_s3c2410_upll_enable,
> +       .disable = samsung_s3c2410_upll_disable,
> +       .round_rate = samsung_pll_round_rate,
> +       .set_rate = samsung_s3c2410_pll_set_rate,
> +};
> +
> +static const struct clk_ops samsung_s3c2440_mpll_clk_ops = {
> +       .recalc_rate = samsung_s3c2440_mpll_recalc_rate,
> +       .enable = samsung_s3c2410_mpll_enable,
> +       .disable = samsung_s3c2410_mpll_disable,
> +       .round_rate = samsung_pll_round_rate,
> +       .set_rate = samsung_s3c2410_pll_set_rate,
> +};
> +
> +/*
>   * PLL2550x Clock Type
>   */
>  
> @@ -866,6 +1030,24 @@ static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
>                 else
>                         init.ops = &samsung_pll46xx_clk_ops;
>                 break;
> +       case pll_s3c2410_mpll:
> +               if (!pll->rate_table)
> +                       init.ops = &samsung_s3c2410_mpll_clk_min_ops;
> +               else
> +                       init.ops = &samsung_s3c2410_mpll_clk_ops;
> +               break;
> +       case pll_s3c2410_upll:
> +               if (!pll->rate_table)
> +                       init.ops = &samsung_s3c2410_upll_clk_min_ops;
> +               else
> +                       init.ops = &samsung_s3c2410_upll_clk_ops;
> +               break;
> +       case pll_s3c2440_mpll:
> +               if (!pll->rate_table)
> +                       init.ops = &samsung_s3c2440_mpll_clk_min_ops;
> +               else
> +                       init.ops = &samsung_s3c2440_mpll_clk_ops;
> +               break;
>         default:
>                 pr_warn("%s: Unknown pll type for pll clk %s\n",
>                         __func__, pll_clk->name);
> diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
> index 5b64bdb..6428bcc 100644
> --- a/drivers/clk/samsung/clk-pll.h
> +++ b/drivers/clk/samsung/clk-pll.h
> @@ -28,6 +28,9 @@ enum samsung_pll_type {
>         pll_6552,
>         pll_6552_s3c2416,
>         pll_6553,
> +       pll_s3c2410_mpll,
> +       pll_s3c2410_upll,
> +       pll_s3c2440_mpll,
>  };
>  
>  #define PLL_35XX_RATE(_rate, _m, _p, _s)                       \
> -- 
> 1.7.10.4
> 

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

* [PATCH 06/12] clk: samsung: add plls used by the early s3c24xx cpus
@ 2013-12-31 19:45     ` Mike Turquette
  0 siblings, 0 replies; 54+ messages in thread
From: Mike Turquette @ 2013-12-31 19:45 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Heiko St?bner (2013-12-13 05:00:54)
> The manuals do not give them explicit names like in later socs, so more
> generic names with a s3c2410-prefix were used for them.
> 
> As it was common to do so in the previous implementation, functionality
> to change the pll rate is already included.
> 
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>

Acked-by: Mike Turquette <mturquette@linaro.org>

> ---
>  drivers/clk/samsung/clk-pll.c |  182 +++++++++++++++++++++++++++++++++++++++++
>  drivers/clk/samsung/clk-pll.h |    3 +
>  2 files changed, 185 insertions(+)
> 
> diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c
> index 461a6bf..39573bd 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/hrtimer.h>
> +#include <linux/delay.h>
>  #include "clk.h"
>  #include "clk-pll.h"
>  
> @@ -701,6 +702,169 @@ static const struct clk_ops samsung_pll6553_clk_ops = {
>  };
>  
>  /*
> + * PLL Clock Type of S3C24XX before S3C2443
> + */
> +
> +#define PLLS3C2410_MDIV_MASK           (0xff)
> +#define PLLS3C2410_PDIV_MASK           (0x1f)
> +#define PLLS3C2410_SDIV_MASK           (0x3)
> +#define PLLS3C2410_MDIV_SHIFT          (12)
> +#define PLLS3C2410_PDIV_SHIFT          (4)
> +#define PLLS3C2410_SDIV_SHIFT          (0)
> +
> +#define PLLS3C2410_ENABLE_REG_OFFSET   0x10
> +
> +static unsigned long samsung_s3c2410_pll_recalc_rate(struct clk_hw *hw,
> +                                       unsigned long parent_rate)
> +{
> +       struct samsung_clk_pll *pll = to_clk_pll(hw);
> +       u32 pll_con, mdiv, pdiv, sdiv;
> +       u64 fvco = parent_rate;
> +
> +       pll_con = __raw_readl(pll->con_reg);
> +       mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
> +       pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
> +       sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
> +
> +       fvco *= (mdiv + 8);
> +       do_div(fvco, (pdiv + 2) << sdiv);
> +
> +       return (unsigned int)fvco;
> +}
> +
> +static unsigned long samsung_s3c2440_mpll_recalc_rate(struct clk_hw *hw,
> +                                       unsigned long parent_rate)
> +{
> +       struct samsung_clk_pll *pll = to_clk_pll(hw);
> +       u32 pll_con, mdiv, pdiv, sdiv;
> +       u64 fvco = parent_rate;
> +
> +       pll_con = __raw_readl(pll->con_reg);
> +       mdiv = (pll_con >> PLLS3C2410_MDIV_SHIFT) & PLLS3C2410_MDIV_MASK;
> +       pdiv = (pll_con >> PLLS3C2410_PDIV_SHIFT) & PLLS3C2410_PDIV_MASK;
> +       sdiv = (pll_con >> PLLS3C2410_SDIV_SHIFT) & PLLS3C2410_SDIV_MASK;
> +
> +       fvco *= (2 * (mdiv + 8));
> +       do_div(fvco, (pdiv + 2) << sdiv);
> +
> +       return (unsigned int)fvco;
> +}
> +
> +static int samsung_s3c2410_pll_set_rate(struct clk_hw *hw, unsigned long drate,
> +                                       unsigned long prate)
> +{
> +       struct samsung_clk_pll *pll = to_clk_pll(hw);
> +       const struct samsung_pll_rate_table *rate;
> +       u32 tmp;
> +
> +       /* 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;
> +       }
> +
> +       tmp = __raw_readl(pll->con_reg);
> +
> +       /* Change PLL PMS values */
> +       tmp &= ~((PLLS3C2410_MDIV_MASK << PLLS3C2410_MDIV_SHIFT) |
> +                       (PLLS3C2410_PDIV_MASK << PLLS3C2410_PDIV_SHIFT) |
> +                       (PLLS3C2410_SDIV_MASK << PLLS3C2410_SDIV_SHIFT));
> +       tmp |= (rate->mdiv << PLLS3C2410_MDIV_SHIFT) |
> +                       (rate->pdiv << PLLS3C2410_PDIV_SHIFT) |
> +                       (rate->sdiv << PLLS3C2410_SDIV_SHIFT);
> +       __raw_writel(tmp, pll->con_reg);
> +
> +       /* Time to settle according to the manual */
> +       udelay(300);
> +
> +       return 0;
> +}
> +
> +static int samsung_s3c2410_pll_enable(struct clk_hw *hw, int bit, bool enable)
> +{
> +       struct samsung_clk_pll *pll = to_clk_pll(hw);
> +       u32 pll_en = __raw_readl(pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
> +       u32 pll_en_orig = pll_en;
> +
> +       if (enable)
> +               pll_en &= ~BIT(bit);
> +       else
> +               pll_en |= BIT(bit);
> +
> +       __raw_writel(pll_en, pll->lock_reg + PLLS3C2410_ENABLE_REG_OFFSET);
> +
> +       /* if we started the UPLL, then allow to settle */
> +       if (enable && (pll_en_orig & BIT(bit)))
> +               udelay(300);
> +
> +       return 0;
> +}
> +
> +static int samsung_s3c2410_mpll_enable(struct clk_hw *hw)
> +{
> +       return samsung_s3c2410_pll_enable(hw, 5, true);
> +}
> +
> +static void samsung_s3c2410_mpll_disable(struct clk_hw *hw)
> +{
> +       samsung_s3c2410_pll_enable(hw, 5, false);
> +}
> +
> +static int samsung_s3c2410_upll_enable(struct clk_hw *hw)
> +{
> +       return samsung_s3c2410_pll_enable(hw, 7, true);
> +}
> +
> +static void samsung_s3c2410_upll_disable(struct clk_hw *hw)
> +{
> +       samsung_s3c2410_pll_enable(hw, 7, false);
> +}
> +
> +static const struct clk_ops samsung_s3c2410_mpll_clk_min_ops = {
> +       .recalc_rate = samsung_s3c2410_pll_recalc_rate,
> +       .enable = samsung_s3c2410_mpll_enable,
> +       .disable = samsung_s3c2410_mpll_disable,
> +};
> +
> +static const struct clk_ops samsung_s3c2410_upll_clk_min_ops = {
> +       .recalc_rate = samsung_s3c2410_pll_recalc_rate,
> +       .enable = samsung_s3c2410_upll_enable,
> +       .disable = samsung_s3c2410_upll_disable,
> +};
> +
> +static const struct clk_ops samsung_s3c2440_mpll_clk_min_ops = {
> +       .recalc_rate = samsung_s3c2440_mpll_recalc_rate,
> +       .enable = samsung_s3c2410_mpll_enable,
> +       .disable = samsung_s3c2410_mpll_disable,
> +};
> +
> +static const struct clk_ops samsung_s3c2410_mpll_clk_ops = {
> +       .recalc_rate = samsung_s3c2410_pll_recalc_rate,
> +       .enable = samsung_s3c2410_mpll_enable,
> +       .disable = samsung_s3c2410_mpll_disable,
> +       .round_rate = samsung_pll_round_rate,
> +       .set_rate = samsung_s3c2410_pll_set_rate,
> +};
> +
> +static const struct clk_ops samsung_s3c2410_upll_clk_ops = {
> +       .recalc_rate = samsung_s3c2410_pll_recalc_rate,
> +       .enable = samsung_s3c2410_upll_enable,
> +       .disable = samsung_s3c2410_upll_disable,
> +       .round_rate = samsung_pll_round_rate,
> +       .set_rate = samsung_s3c2410_pll_set_rate,
> +};
> +
> +static const struct clk_ops samsung_s3c2440_mpll_clk_ops = {
> +       .recalc_rate = samsung_s3c2440_mpll_recalc_rate,
> +       .enable = samsung_s3c2410_mpll_enable,
> +       .disable = samsung_s3c2410_mpll_disable,
> +       .round_rate = samsung_pll_round_rate,
> +       .set_rate = samsung_s3c2410_pll_set_rate,
> +};
> +
> +/*
>   * PLL2550x Clock Type
>   */
>  
> @@ -866,6 +1030,24 @@ static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
>                 else
>                         init.ops = &samsung_pll46xx_clk_ops;
>                 break;
> +       case pll_s3c2410_mpll:
> +               if (!pll->rate_table)
> +                       init.ops = &samsung_s3c2410_mpll_clk_min_ops;
> +               else
> +                       init.ops = &samsung_s3c2410_mpll_clk_ops;
> +               break;
> +       case pll_s3c2410_upll:
> +               if (!pll->rate_table)
> +                       init.ops = &samsung_s3c2410_upll_clk_min_ops;
> +               else
> +                       init.ops = &samsung_s3c2410_upll_clk_ops;
> +               break;
> +       case pll_s3c2440_mpll:
> +               if (!pll->rate_table)
> +                       init.ops = &samsung_s3c2440_mpll_clk_min_ops;
> +               else
> +                       init.ops = &samsung_s3c2440_mpll_clk_ops;
> +               break;
>         default:
>                 pr_warn("%s: Unknown pll type for pll clk %s\n",
>                         __func__, pll_clk->name);
> diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h
> index 5b64bdb..6428bcc 100644
> --- a/drivers/clk/samsung/clk-pll.h
> +++ b/drivers/clk/samsung/clk-pll.h
> @@ -28,6 +28,9 @@ enum samsung_pll_type {
>         pll_6552,
>         pll_6552_s3c2416,
>         pll_6553,
> +       pll_s3c2410_mpll,
> +       pll_s3c2410_upll,
> +       pll_s3c2440_mpll,
>  };
>  
>  #define PLL_35XX_RATE(_rate, _m, _p, _s)                       \
> -- 
> 1.7.10.4
> 

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

* Re: [PATCH 03/12] clk: samsung: add clock driver for external clock outputs
  2013-12-13 12:59   ` Heiko Stübner
@ 2013-12-31 19:46     ` Mike Turquette
  -1 siblings, 0 replies; 54+ messages in thread
From: Mike Turquette @ 2013-12-31 19:46 UTC (permalink / raw)
  To: Heiko Stübner, Kukjin Kim
  Cc: t.figa, linux-arm-kernel, linux-samsung-soc

Quoting Heiko Stübner (2013-12-13 04:59:36)
> This adds a driver for controlling the external clock outputs of
> s3c24xx architectures including the dclk muxes and dividers.
> 
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>

Acked-by: Mike Turquette <mturquette@linaro.org>

> ---
>  drivers/clk/samsung/Makefile                     |    1 +
>  drivers/clk/samsung/clk-s3c2410-dclk.c           |  517 ++++++++++++++++++++++
>  include/dt-bindings/clock/samsung,s3c2410-dclk.h |   28 ++
>  3 files changed, 546 insertions(+)
>  create mode 100644 drivers/clk/samsung/clk-s3c2410-dclk.c
>  create mode 100644 include/dt-bindings/clock/samsung,s3c2410-dclk.h
> 
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> index 4c892c6..568683c 100644
> --- a/drivers/clk/samsung/Makefile
> +++ b/drivers/clk/samsung/Makefile
> @@ -8,5 +8,6 @@ obj-$(CONFIG_SOC_EXYNOS5250)    += clk-exynos5250.o
>  obj-$(CONFIG_SOC_EXYNOS5420)   += clk-exynos5420.o
>  obj-$(CONFIG_SOC_EXYNOS5440)   += clk-exynos5440.o
>  obj-$(CONFIG_ARCH_EXYNOS)      += clk-exynos-audss.o
> +obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
>  obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
>  obj-$(CONFIG_ARCH_S3C64XX)     += clk-s3c64xx.o
> diff --git a/drivers/clk/samsung/clk-s3c2410-dclk.c b/drivers/clk/samsung/clk-s3c2410-dclk.c
> new file mode 100644
> index 0000000..de10e5c
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-s3c2410-dclk.c
> @@ -0,0 +1,517 @@
> +/*
> + * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * Common Clock Framework support for s3c24xx external clock output.
> + */
> +
> +#include <linux/platform_device.h>
> +#include <linux/module.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/clk-provider.h>
> +#include <linux/regmap.h>
> +#include <linux/of.h>
> +#include <dt-bindings/clock/samsung,s3c2410-dclk.h>
> +#include "clk.h"
> +
> +/* legacy access to misccr, until dt conversion is finished */
> +#include <mach/hardware.h>
> +#include <mach/regs-gpio.h>
> +
> +enum supported_socs {
> +       S3C2410,
> +       S3C2412,
> +       S3C2440,
> +       S3C2443,
> +};
> +
> +struct s3c24xx_dclk_drv_data {
> +       int cpu_type;
> +};
> +
> +/*
> + * Clock for output-parent selection in misccr
> + */
> +
> +struct s3c24xx_clkout {
> +       struct clk_hw           hw;
> +       struct regmap           *misccr;
> +       u32                     mask;
> +       u8                      shift;
> +};
> +
> +#define to_s3c24xx_clkout(_hw) container_of(_hw, struct s3c24xx_clkout, hw)
> +
> +static u8 s3c24xx_clkout_get_parent(struct clk_hw *hw)
> +{
> +       struct s3c24xx_clkout *clkout = to_s3c24xx_clkout(hw);
> +       int num_parents = __clk_get_num_parents(hw->clk);
> +       u32 val;
> +       int ret = 0;
> +
> +       if (clkout->misccr)
> +               ret = regmap_read(clkout->misccr, 0, &val);
> +       else
> +               val = readl_relaxed(S3C24XX_MISCCR) >> clkout->shift;
> +
> +       if (ret)
> +               return ret;
> +
> +       val >>= clkout->shift;
> +       val &= clkout->mask;
> +
> +       if (val >= num_parents)
> +               return -EINVAL;
> +
> +       return val;
> +}
> +
> +static int s3c24xx_clkout_set_parent(struct clk_hw *hw, u8 index)
> +{
> +       struct s3c24xx_clkout *clkout = to_s3c24xx_clkout(hw);
> +       int ret = 0;
> +
> +       if (clkout->misccr)
> +               ret = regmap_update_bits(clkout->misccr, 0,
> +                                        (clkout->mask << clkout->shift),
> +                                        (index << clkout->shift));
> +       else
> +               s3c2410_modify_misccr((clkout->mask << clkout->shift),
> +                                     (index << clkout->shift));
> +
> +       return ret;
> +}
> +
> +const struct clk_ops s3c24xx_clkout_ops = {
> +       .get_parent = s3c24xx_clkout_get_parent,
> +       .set_parent = s3c24xx_clkout_set_parent,
> +       .determine_rate = __clk_mux_determine_rate,
> +};
> +
> +struct clk *s3c24xx_register_clkout(struct device *dev, const char *name,
> +               const char **parent_names, u8 num_parents,
> +               struct regmap *misccr, u8 shift, u32 mask)
> +{
> +       struct s3c24xx_clkout *clkout;
> +       struct clk *clk;
> +       struct clk_init_data init;
> +
> +       /* allocate the clkout */
> +       clkout = kzalloc(sizeof(*clkout), GFP_KERNEL);
> +       if (!clkout)
> +               return ERR_PTR(-ENOMEM);
> +
> +       init.name = name;
> +       init.ops = &s3c24xx_clkout_ops;
> +       init.flags = CLK_IS_BASIC;
> +       init.parent_names = parent_names;
> +       init.num_parents = num_parents;
> +
> +       clkout->misccr = misccr;
> +       clkout->shift = shift;
> +       clkout->mask = mask;
> +       clkout->hw.init = &init;
> +
> +       clk = clk_register(dev, &clkout->hw);
> +
> +       return clk;
> +}
> +
> +/*
> + * dclk and clkout init
> + */
> +
> +struct s3c24xx_dclk {
> +       struct device *dev;
> +       void __iomem *base;
> +       struct clk_onecell_data clk_data;
> +       struct notifier_block dclk0_div_change_nb;
> +       struct notifier_block dclk1_div_change_nb;
> +       spinlock_t dclk_lock;
> +       unsigned long reg_save;
> +};
> +
> +#define to_s3c24xx_dclk0(x) \
> +               container_of(x, struct s3c24xx_dclk, dclk0_div_change_nb)
> +
> +#define to_s3c24xx_dclk1(x) \
> +               container_of(x, struct s3c24xx_dclk, dclk1_div_change_nb)
> +
> +static const char dummy_nm[] __initconst = "dummy_name";
> +
> +PNAME(dclk_s3c2410_p) = { "pclk", "uclk" };
> +PNAME(clkout0_s3c2410_p) = { "mpll", "upll", "fclk", "hclk", "pclk",
> +                            "gate_dclk0" };
> +PNAME(clkout1_s3c2410_p) = { "mpll", "upll", "fclk", "hclk", "pclk",
> +                            "gate_dclk1" };
> +
> +PNAME(clkout0_s3c2412_p) = { "mpll", "upll", dummy_nm /* rtc clock output */,
> +                            "hclk", "pclk", "gate_dclk0" };
> +PNAME(clkout1_s3c2412_p) = { "xti", "upll", "fclk", "hclk", "pclk",
> +                            "gate_dclk1" };
> +
> +PNAME(clkout0_s3c2440_p) = { "xti", "upll", "fclk", "hclk", "pclk",
> +                            "gate_dclk0" };
> +PNAME(clkout1_s3c2440_p) = { "mpll", "upll", dummy_nm /* rtc clock output */,
> +                            "hclk", "pclk", "gate_dclk1" };
> +
> +PNAME(dclk_s3c2443_p) = { "pclk", "epll" };
> +PNAME(clkout0_s3c2443_p) = { "xti", "epll", "armclk", "hclk", "pclk",
> +                            "gate_dclk0" };
> +PNAME(clkout1_s3c2443_p) = { dummy_nm, "epll", dummy_nm /* rtc clock output */,
> +                            "hclk", "pclk", "gate_dclk1" };
> +
> +#define DCLKCON_DCLK_DIV_MASK          0xf
> +#define DCLKCON_DCLK0_DIV_SHIFT                4
> +#define DCLKCON_DCLK0_CMP_SHIFT                8
> +#define DCLKCON_DCLK1_DIV_SHIFT                20
> +#define DCLKCON_DCLK1_CMP_SHIFT                24
> +
> +static void s3c24xx_dclk_update_cmp(struct s3c24xx_dclk *s3c24xx_dclk,
> +                                   int div_shift, int cmp_shift)
> +{
> +       unsigned long flags = 0;
> +       u32 dclk_con, div, cmp;
> +
> +       spin_lock_irqsave(&s3c24xx_dclk->dclk_lock, flags);
> +
> +       dclk_con = readl_relaxed(s3c24xx_dclk->base);
> +
> +       div = ((dclk_con >> div_shift) & DCLKCON_DCLK_DIV_MASK) + 1;
> +       cmp = ((div + 1) / 2) - 1;
> +
> +       dclk_con &= ~(DCLKCON_DCLK_DIV_MASK << cmp_shift);
> +       dclk_con |= (cmp << cmp_shift);
> +
> +       writel_relaxed(dclk_con, s3c24xx_dclk->base);
> +
> +       spin_unlock_irqrestore(&s3c24xx_dclk->dclk_lock, flags);
> +}
> +
> +static int s3c24xx_dclk0_div_notify(struct notifier_block *nb,
> +                              unsigned long event, void *data)
> +{
> +       struct s3c24xx_dclk *s3c24xx_dclk = to_s3c24xx_dclk0(nb);
> +
> +       if (event == POST_RATE_CHANGE) {
> +               s3c24xx_dclk_update_cmp(s3c24xx_dclk,
> +                       DCLKCON_DCLK0_DIV_SHIFT, DCLKCON_DCLK0_CMP_SHIFT);
> +       }
> +
> +       return NOTIFY_DONE;
> +}
> +
> +static int s3c24xx_dclk1_div_notify(struct notifier_block *nb,
> +                              unsigned long event, void *data)
> +{
> +       struct s3c24xx_dclk *s3c24xx_dclk = to_s3c24xx_dclk1(nb);
> +
> +       if (event == POST_RATE_CHANGE) {
> +               s3c24xx_dclk_update_cmp(s3c24xx_dclk,
> +                       DCLKCON_DCLK1_DIV_SHIFT, DCLKCON_DCLK1_CMP_SHIFT);
> +       }
> +
> +       return NOTIFY_DONE;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int s3c24xx_dclk_suspend(struct device *dev)
> +{
> +       struct platform_device *pdev = to_platform_device(dev);
> +       struct s3c24xx_dclk *s3c24xx_dclk = platform_get_drvdata(pdev);
> +
> +       s3c24xx_dclk->reg_save = readl_relaxed(s3c24xx_dclk->base);
> +       return 0;
> +}
> +
> +static int s3c24xx_dclk_resume(struct device *dev)
> +{
> +       struct platform_device *pdev = to_platform_device(dev);
> +       struct s3c24xx_dclk *s3c24xx_dclk = platform_get_drvdata(pdev);
> +
> +       writel_relaxed(s3c24xx_dclk->reg_save, s3c24xx_dclk->base);
> +       return 0;
> +}
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(s3c24xx_dclk_pm_ops,
> +                        s3c24xx_dclk_suspend, s3c24xx_dclk_resume);
> +
> +static const struct of_device_id s3c24xx_dclk_dt_match[];
> +
> +static inline int s3c24xx_dclk_get_driver_data(struct platform_device *pdev)
> +{
> +       struct s3c24xx_dclk_drv_data *data;
> +       if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
> +               const struct of_device_id *match;
> +               match = of_match_node(s3c24xx_dclk_dt_match, pdev->dev.of_node);
> +               data = (struct s3c24xx_dclk_drv_data *) match->data;
> +               return data->cpu_type;
> +       }
> +
> +       return platform_get_device_id(pdev)->driver_data;
> +}
> +
> +static int s3c24xx_dclk_probe(struct platform_device *pdev)
> +{
> +       struct s3c24xx_dclk *s3c24xx_dclk;
> +       struct device_node *np = pdev->dev.of_node;
> +       struct regmap *misccr = NULL;
> +       struct resource *mem;
> +       struct clk **clk_table;
> +       const char **clkout0_parent_names, **clkout1_parent_names;
> +       u8 clkout0_num_parents, clkout1_num_parents;
> +       int current_soc, ret, i;
> +
> +       s3c24xx_dclk = devm_kzalloc(&pdev->dev, sizeof(*s3c24xx_dclk),
> +                                   GFP_KERNEL);
> +       if (!s3c24xx_dclk)
> +               return -ENOMEM;
> +
> +       s3c24xx_dclk->dev = &pdev->dev;
> +       platform_set_drvdata(pdev, s3c24xx_dclk);
> +       spin_lock_init(&s3c24xx_dclk->dclk_lock);
> +
> +       clk_table = devm_kzalloc(&pdev->dev,
> +                                sizeof(struct clk *) * DCLK_MAX_CLKS,
> +                                GFP_KERNEL);
> +       if (!clk_table)
> +               return -ENOMEM;
> +
> +       s3c24xx_dclk->clk_data.clks = clk_table;
> +       s3c24xx_dclk->clk_data.clk_num = DCLK_MAX_CLKS;
> +
> +       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       s3c24xx_dclk->base = devm_ioremap_resource(&pdev->dev, mem);
> +       if (IS_ERR(s3c24xx_dclk->base))
> +               return PTR_ERR(s3c24xx_dclk->base);
> +
> +       /* when run from devicetree, get the misccr through a syscon-regmap */
> +       if (np) {
> +               misccr = syscon_regmap_lookup_by_phandle(np, "samsung,misccr");
> +               if (IS_ERR(misccr)) {
> +                       dev_err(&pdev->dev, "could not get misccr syscon, %ld\n",
> +                               PTR_ERR(misccr));
> +                       return PTR_ERR(misccr);
> +               }
> +       }
> +
> +       current_soc = s3c24xx_dclk_get_driver_data(pdev);
> +
> +       if (current_soc == S3C2443) {
> +               clk_table[MUX_DCLK0] = clk_register_mux(&pdev->dev,
> +                                       "mux_dclk0", dclk_s3c2443_p,
> +                                       ARRAY_SIZE(dclk_s3c2443_p), 0,
> +                                       s3c24xx_dclk->base, 1, 1, 0,
> +                                       &s3c24xx_dclk->dclk_lock);
> +               clk_table[MUX_DCLK1] = clk_register_mux(&pdev->dev,
> +                                       "mux_dclk1", dclk_s3c2443_p,
> +                                       ARRAY_SIZE(dclk_s3c2443_p), 0,
> +                                       s3c24xx_dclk->base, 17, 1, 0,
> +                                       &s3c24xx_dclk->dclk_lock);
> +       } else {
> +               clk_table[MUX_DCLK0] = clk_register_mux(&pdev->dev,
> +                                       "mux_dclk0", dclk_s3c2410_p,
> +                                       ARRAY_SIZE(dclk_s3c2410_p), 0,
> +                                       s3c24xx_dclk->base, 1, 1, 0,
> +                                       &s3c24xx_dclk->dclk_lock);
> +               clk_table[MUX_DCLK1] = clk_register_mux(&pdev->dev,
> +                                       "mux_dclk1", dclk_s3c2410_p,
> +                                       ARRAY_SIZE(dclk_s3c2410_p), 0,
> +                                       s3c24xx_dclk->base, 17, 1, 0,
> +                                       &s3c24xx_dclk->dclk_lock);
> +       }
> +
> +       clk_table[DIV_DCLK0] = clk_register_divider(&pdev->dev, "div_dclk0",
> +                                       "mux_dclk0", 0, s3c24xx_dclk->base,
> +                                       4, 4, 0, &s3c24xx_dclk->dclk_lock);
> +       clk_table[DIV_DCLK1] = clk_register_divider(&pdev->dev, "div_dclk1",
> +                                       "mux_dclk1", 0, s3c24xx_dclk->base,
> +                                       20, 4, 0, &s3c24xx_dclk->dclk_lock);
> +
> +       clk_table[GATE_DCLK0] = clk_register_gate(&pdev->dev, "gate_dclk0",
> +                                       "div_dclk0", CLK_SET_RATE_PARENT,
> +                                       s3c24xx_dclk->base, 0, 0,
> +                                       &s3c24xx_dclk->dclk_lock);
> +       clk_table[GATE_DCLK1] = clk_register_gate(&pdev->dev, "gate_dclk1",
> +                                       "div_dclk1", CLK_SET_RATE_PARENT,
> +                                       s3c24xx_dclk->base, 16, 0,
> +                                       &s3c24xx_dclk->dclk_lock);
> +
> +       switch (current_soc) {
> +       case S3C2410:
> +               clkout0_parent_names = clkout0_s3c2410_p;
> +               clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2410_p);
> +               clkout1_parent_names = clkout1_s3c2410_p;
> +               clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2410_p);
> +               break;
> +       case S3C2412:
> +               clkout0_parent_names = clkout0_s3c2412_p;
> +               clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2412_p);
> +               clkout1_parent_names = clkout1_s3c2412_p;
> +               clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2412_p);
> +               break;
> +       case S3C2440:
> +               clkout0_parent_names = clkout0_s3c2440_p;
> +               clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2440_p);
> +               clkout1_parent_names = clkout1_s3c2440_p;
> +               clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2440_p);
> +               break;
> +       case S3C2443:
> +               clkout0_parent_names = clkout0_s3c2443_p;
> +               clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2443_p);
> +               clkout1_parent_names = clkout1_s3c2443_p;
> +               clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2443_p);
> +               break;
> +       default:
> +               dev_err(&pdev->dev, "unsupported soc %d\n", current_soc);
> +               ret = -EINVAL;
> +               goto err_clk_register;
> +       }
> +
> +       clk_table[MUX_CLKOUT0] = s3c24xx_register_clkout(&pdev->dev,
> +                               "clkout0", clkout0_parent_names,
> +                               clkout0_num_parents, misccr, 4, 7);
> +       clk_table[MUX_CLKOUT1] = s3c24xx_register_clkout(&pdev->dev, "clkout1",
> +                               clkout1_parent_names,
> +                               clkout1_num_parents, misccr, 8, 7);
> +
> +       for (i = 0; i < DCLK_MAX_CLKS; i++)
> +               if (IS_ERR(clk_table[i])) {
> +                       dev_err(&pdev->dev, "clock %d failed to register\n", i);
> +                       ret = PTR_ERR(clk_table[i]);
> +                       goto err_clk_register;
> +               }
> +
> +       ret = clk_register_clkdev(clk_table[MUX_DCLK0], "dclk0", NULL);
> +       ret |= clk_register_clkdev(clk_table[MUX_DCLK1], "dclk1", NULL);
> +       ret |= clk_register_clkdev(clk_table[MUX_CLKOUT0], "clkout0", NULL);
> +       ret |= clk_register_clkdev(clk_table[MUX_CLKOUT1], "clkout1", NULL);
> +       if (ret) {
> +               dev_err(&pdev->dev, "failed to register aliases\n");
> +               goto err_clk_register;
> +       }
> +
> +       s3c24xx_dclk->dclk0_div_change_nb.notifier_call =
> +                                               s3c24xx_dclk0_div_notify;
> +       s3c24xx_dclk->dclk0_div_change_nb.next = NULL;
> +
> +       s3c24xx_dclk->dclk1_div_change_nb.notifier_call =
> +                                               s3c24xx_dclk1_div_notify;
> +       s3c24xx_dclk->dclk1_div_change_nb.next = NULL;
> +
> +       ret = clk_notifier_register(clk_table[DIV_DCLK0],
> +                                   &s3c24xx_dclk->dclk0_div_change_nb);
> +       if (ret)
> +               goto err_clk_register;
> +
> +       ret = clk_notifier_register(clk_table[DIV_DCLK1],
> +                                   &s3c24xx_dclk->dclk1_div_change_nb);
> +       if (ret)
> +               goto err_dclk_notify;
> +
> +       if (np) {
> +               ret = of_clk_add_provider(np,
> +                             of_clk_src_onecell_get, &s3c24xx_dclk->clk_data);
> +               if (ret)
> +                       goto err_of_clk_provider;
> +       }
> +
> +       return 0;
> +
> +err_of_clk_provider:
> +       clk_notifier_unregister(clk_table[DIV_DCLK1],
> +                               &s3c24xx_dclk->dclk1_div_change_nb);
> +err_dclk_notify:
> +       clk_notifier_unregister(clk_table[DIV_DCLK0],
> +                               &s3c24xx_dclk->dclk0_div_change_nb);
> +err_clk_register:
> +       for (i = 0; i < DCLK_MAX_CLKS; i++)
> +               if (clk_table[i] && !IS_ERR(clk_table[i]))
> +                       clk_unregister(clk_table[i]);
> +
> +       return ret;
> +}
> +
> +static int s3c24xx_dclk_remove(struct platform_device *pdev)
> +{
> +       struct s3c24xx_dclk *s3c24xx_dclk = platform_get_drvdata(pdev);
> +       struct clk **clk_table = s3c24xx_dclk->clk_data.clks;
> +       int i;
> +
> +       of_clk_del_provider(pdev->dev.of_node);
> +
> +       clk_notifier_unregister(clk_table[DIV_DCLK1],
> +                               &s3c24xx_dclk->dclk1_div_change_nb);
> +       clk_notifier_unregister(clk_table[DIV_DCLK0],
> +                               &s3c24xx_dclk->dclk0_div_change_nb);
> +
> +       for (i = 0; i < DCLK_MAX_CLKS; i++)
> +               clk_unregister(clk_table[i]);
> +
> +       return 0;
> +}
> +
> +static struct s3c24xx_dclk_drv_data s3c24xx_dclk_drv_data_array[] = {
> +       [S3C2410] = { S3C2410 },
> +       [S3C2412] = { S3C2412 },
> +       [S3C2440] = { S3C2440 },
> +       [S3C2443] = { S3C2443 },
> +};
> +
> +static const struct of_device_id s3c24xx_dclk_dt_match[] = {
> +       {
> +               .compatible = "samsung,s3c2410-dclk",
> +               .data = &s3c24xx_dclk_drv_data_array[S3C2410],
> +       }, {
> +               .compatible = "samsung,s3c2412-dclk",
> +               .data = &s3c24xx_dclk_drv_data_array[S3C2412],
> +       }, {
> +               .compatible = "samsung,s3c2440-dclk",
> +               .data = &s3c24xx_dclk_drv_data_array[S3C2440],
> +       }, {
> +               .compatible = "samsung,s3c2443-dclk",
> +               .data = &s3c24xx_dclk_drv_data_array[S3C2443],
> +       },
> +       { },
> +};
> +MODULE_DEVICE_TABLE(of, s3c24xx_dclk_dt_match);
> +
> +static struct platform_device_id s3c24xx_dclk_driver_ids[] = {
> +       {
> +               .name           = "s3c2410-dclk",
> +               .driver_data    = S3C2410,
> +       }, {
> +               .name           = "s3c2412-dclk",
> +               .driver_data    = S3C2412,
> +       }, {
> +               .name           = "s3c2440-dclk",
> +               .driver_data    = S3C2440,
> +       }, {
> +               .name           = "s3c2443-dclk",
> +               .driver_data    = S3C2443,
> +       },
> +       { }
> +};
> +
> +MODULE_DEVICE_TABLE(platform, s3c24xx_dclk_driver_ids);
> +
> +static struct platform_driver s3c24xx_dclk_driver = {
> +       .driver = {
> +               .name           = "s3c24xx-dclk",
> +               .owner          = THIS_MODULE,
> +               .pm             = &s3c24xx_dclk_pm_ops,
> +               .of_match_table = of_match_ptr(s3c24xx_dclk_dt_match),
> +       },
> +       .probe = s3c24xx_dclk_probe,
> +       .remove = s3c24xx_dclk_remove,
> +       .id_table = s3c24xx_dclk_driver_ids,
> +};
> +module_platform_driver(s3c24xx_dclk_driver);
> +
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
> +MODULE_DESCRIPTION("Driver for the S3C24XX external clock outputs");
> diff --git a/include/dt-bindings/clock/samsung,s3c2410-dclk.h b/include/dt-bindings/clock/samsung,s3c2410-dclk.h
> new file mode 100644
> index 0000000..7394d46
> --- /dev/null
> +++ b/include/dt-bindings/clock/samsung,s3c2410-dclk.h
> @@ -0,0 +1,28 @@
> +/*
> + * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
> + *
> + * 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.
> + *
> + * Device Tree binding constants clock controllers of Samsung S3C2410 and later.
> + */
> +
> +#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C2410_CLOCK_H
> +#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C2410_CLOCK_H
> +
> +#define MUX_DCLK0      0
> +#define MUX_DCLK1      1
> +
> +#define DIV_DCLK0      2
> +#define DIV_DCLK1      3
> +
> +#define GATE_DCLK0     4
> +#define GATE_DCLK1     5
> +
> +#define MUX_CLKOUT0    6
> +#define MUX_CLKOUT1    7
> +
> +#define DCLK_MAX_CLKS  (MUX_CLKOUT1 + 1)
> +
> +#endif
> -- 
> 1.7.10.4
> 

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

* [PATCH 03/12] clk: samsung: add clock driver for external clock outputs
@ 2013-12-31 19:46     ` Mike Turquette
  0 siblings, 0 replies; 54+ messages in thread
From: Mike Turquette @ 2013-12-31 19:46 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Heiko St?bner (2013-12-13 04:59:36)
> This adds a driver for controlling the external clock outputs of
> s3c24xx architectures including the dclk muxes and dividers.
> 
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>

Acked-by: Mike Turquette <mturquette@linaro.org>

> ---
>  drivers/clk/samsung/Makefile                     |    1 +
>  drivers/clk/samsung/clk-s3c2410-dclk.c           |  517 ++++++++++++++++++++++
>  include/dt-bindings/clock/samsung,s3c2410-dclk.h |   28 ++
>  3 files changed, 546 insertions(+)
>  create mode 100644 drivers/clk/samsung/clk-s3c2410-dclk.c
>  create mode 100644 include/dt-bindings/clock/samsung,s3c2410-dclk.h
> 
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> index 4c892c6..568683c 100644
> --- a/drivers/clk/samsung/Makefile
> +++ b/drivers/clk/samsung/Makefile
> @@ -8,5 +8,6 @@ obj-$(CONFIG_SOC_EXYNOS5250)    += clk-exynos5250.o
>  obj-$(CONFIG_SOC_EXYNOS5420)   += clk-exynos5420.o
>  obj-$(CONFIG_SOC_EXYNOS5440)   += clk-exynos5440.o
>  obj-$(CONFIG_ARCH_EXYNOS)      += clk-exynos-audss.o
> +obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
>  obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
>  obj-$(CONFIG_ARCH_S3C64XX)     += clk-s3c64xx.o
> diff --git a/drivers/clk/samsung/clk-s3c2410-dclk.c b/drivers/clk/samsung/clk-s3c2410-dclk.c
> new file mode 100644
> index 0000000..de10e5c
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-s3c2410-dclk.c
> @@ -0,0 +1,517 @@
> +/*
> + * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * Common Clock Framework support for s3c24xx external clock output.
> + */
> +
> +#include <linux/platform_device.h>
> +#include <linux/module.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/clk-provider.h>
> +#include <linux/regmap.h>
> +#include <linux/of.h>
> +#include <dt-bindings/clock/samsung,s3c2410-dclk.h>
> +#include "clk.h"
> +
> +/* legacy access to misccr, until dt conversion is finished */
> +#include <mach/hardware.h>
> +#include <mach/regs-gpio.h>
> +
> +enum supported_socs {
> +       S3C2410,
> +       S3C2412,
> +       S3C2440,
> +       S3C2443,
> +};
> +
> +struct s3c24xx_dclk_drv_data {
> +       int cpu_type;
> +};
> +
> +/*
> + * Clock for output-parent selection in misccr
> + */
> +
> +struct s3c24xx_clkout {
> +       struct clk_hw           hw;
> +       struct regmap           *misccr;
> +       u32                     mask;
> +       u8                      shift;
> +};
> +
> +#define to_s3c24xx_clkout(_hw) container_of(_hw, struct s3c24xx_clkout, hw)
> +
> +static u8 s3c24xx_clkout_get_parent(struct clk_hw *hw)
> +{
> +       struct s3c24xx_clkout *clkout = to_s3c24xx_clkout(hw);
> +       int num_parents = __clk_get_num_parents(hw->clk);
> +       u32 val;
> +       int ret = 0;
> +
> +       if (clkout->misccr)
> +               ret = regmap_read(clkout->misccr, 0, &val);
> +       else
> +               val = readl_relaxed(S3C24XX_MISCCR) >> clkout->shift;
> +
> +       if (ret)
> +               return ret;
> +
> +       val >>= clkout->shift;
> +       val &= clkout->mask;
> +
> +       if (val >= num_parents)
> +               return -EINVAL;
> +
> +       return val;
> +}
> +
> +static int s3c24xx_clkout_set_parent(struct clk_hw *hw, u8 index)
> +{
> +       struct s3c24xx_clkout *clkout = to_s3c24xx_clkout(hw);
> +       int ret = 0;
> +
> +       if (clkout->misccr)
> +               ret = regmap_update_bits(clkout->misccr, 0,
> +                                        (clkout->mask << clkout->shift),
> +                                        (index << clkout->shift));
> +       else
> +               s3c2410_modify_misccr((clkout->mask << clkout->shift),
> +                                     (index << clkout->shift));
> +
> +       return ret;
> +}
> +
> +const struct clk_ops s3c24xx_clkout_ops = {
> +       .get_parent = s3c24xx_clkout_get_parent,
> +       .set_parent = s3c24xx_clkout_set_parent,
> +       .determine_rate = __clk_mux_determine_rate,
> +};
> +
> +struct clk *s3c24xx_register_clkout(struct device *dev, const char *name,
> +               const char **parent_names, u8 num_parents,
> +               struct regmap *misccr, u8 shift, u32 mask)
> +{
> +       struct s3c24xx_clkout *clkout;
> +       struct clk *clk;
> +       struct clk_init_data init;
> +
> +       /* allocate the clkout */
> +       clkout = kzalloc(sizeof(*clkout), GFP_KERNEL);
> +       if (!clkout)
> +               return ERR_PTR(-ENOMEM);
> +
> +       init.name = name;
> +       init.ops = &s3c24xx_clkout_ops;
> +       init.flags = CLK_IS_BASIC;
> +       init.parent_names = parent_names;
> +       init.num_parents = num_parents;
> +
> +       clkout->misccr = misccr;
> +       clkout->shift = shift;
> +       clkout->mask = mask;
> +       clkout->hw.init = &init;
> +
> +       clk = clk_register(dev, &clkout->hw);
> +
> +       return clk;
> +}
> +
> +/*
> + * dclk and clkout init
> + */
> +
> +struct s3c24xx_dclk {
> +       struct device *dev;
> +       void __iomem *base;
> +       struct clk_onecell_data clk_data;
> +       struct notifier_block dclk0_div_change_nb;
> +       struct notifier_block dclk1_div_change_nb;
> +       spinlock_t dclk_lock;
> +       unsigned long reg_save;
> +};
> +
> +#define to_s3c24xx_dclk0(x) \
> +               container_of(x, struct s3c24xx_dclk, dclk0_div_change_nb)
> +
> +#define to_s3c24xx_dclk1(x) \
> +               container_of(x, struct s3c24xx_dclk, dclk1_div_change_nb)
> +
> +static const char dummy_nm[] __initconst = "dummy_name";
> +
> +PNAME(dclk_s3c2410_p) = { "pclk", "uclk" };
> +PNAME(clkout0_s3c2410_p) = { "mpll", "upll", "fclk", "hclk", "pclk",
> +                            "gate_dclk0" };
> +PNAME(clkout1_s3c2410_p) = { "mpll", "upll", "fclk", "hclk", "pclk",
> +                            "gate_dclk1" };
> +
> +PNAME(clkout0_s3c2412_p) = { "mpll", "upll", dummy_nm /* rtc clock output */,
> +                            "hclk", "pclk", "gate_dclk0" };
> +PNAME(clkout1_s3c2412_p) = { "xti", "upll", "fclk", "hclk", "pclk",
> +                            "gate_dclk1" };
> +
> +PNAME(clkout0_s3c2440_p) = { "xti", "upll", "fclk", "hclk", "pclk",
> +                            "gate_dclk0" };
> +PNAME(clkout1_s3c2440_p) = { "mpll", "upll", dummy_nm /* rtc clock output */,
> +                            "hclk", "pclk", "gate_dclk1" };
> +
> +PNAME(dclk_s3c2443_p) = { "pclk", "epll" };
> +PNAME(clkout0_s3c2443_p) = { "xti", "epll", "armclk", "hclk", "pclk",
> +                            "gate_dclk0" };
> +PNAME(clkout1_s3c2443_p) = { dummy_nm, "epll", dummy_nm /* rtc clock output */,
> +                            "hclk", "pclk", "gate_dclk1" };
> +
> +#define DCLKCON_DCLK_DIV_MASK          0xf
> +#define DCLKCON_DCLK0_DIV_SHIFT                4
> +#define DCLKCON_DCLK0_CMP_SHIFT                8
> +#define DCLKCON_DCLK1_DIV_SHIFT                20
> +#define DCLKCON_DCLK1_CMP_SHIFT                24
> +
> +static void s3c24xx_dclk_update_cmp(struct s3c24xx_dclk *s3c24xx_dclk,
> +                                   int div_shift, int cmp_shift)
> +{
> +       unsigned long flags = 0;
> +       u32 dclk_con, div, cmp;
> +
> +       spin_lock_irqsave(&s3c24xx_dclk->dclk_lock, flags);
> +
> +       dclk_con = readl_relaxed(s3c24xx_dclk->base);
> +
> +       div = ((dclk_con >> div_shift) & DCLKCON_DCLK_DIV_MASK) + 1;
> +       cmp = ((div + 1) / 2) - 1;
> +
> +       dclk_con &= ~(DCLKCON_DCLK_DIV_MASK << cmp_shift);
> +       dclk_con |= (cmp << cmp_shift);
> +
> +       writel_relaxed(dclk_con, s3c24xx_dclk->base);
> +
> +       spin_unlock_irqrestore(&s3c24xx_dclk->dclk_lock, flags);
> +}
> +
> +static int s3c24xx_dclk0_div_notify(struct notifier_block *nb,
> +                              unsigned long event, void *data)
> +{
> +       struct s3c24xx_dclk *s3c24xx_dclk = to_s3c24xx_dclk0(nb);
> +
> +       if (event == POST_RATE_CHANGE) {
> +               s3c24xx_dclk_update_cmp(s3c24xx_dclk,
> +                       DCLKCON_DCLK0_DIV_SHIFT, DCLKCON_DCLK0_CMP_SHIFT);
> +       }
> +
> +       return NOTIFY_DONE;
> +}
> +
> +static int s3c24xx_dclk1_div_notify(struct notifier_block *nb,
> +                              unsigned long event, void *data)
> +{
> +       struct s3c24xx_dclk *s3c24xx_dclk = to_s3c24xx_dclk1(nb);
> +
> +       if (event == POST_RATE_CHANGE) {
> +               s3c24xx_dclk_update_cmp(s3c24xx_dclk,
> +                       DCLKCON_DCLK1_DIV_SHIFT, DCLKCON_DCLK1_CMP_SHIFT);
> +       }
> +
> +       return NOTIFY_DONE;
> +}
> +
> +#ifdef CONFIG_PM_SLEEP
> +static int s3c24xx_dclk_suspend(struct device *dev)
> +{
> +       struct platform_device *pdev = to_platform_device(dev);
> +       struct s3c24xx_dclk *s3c24xx_dclk = platform_get_drvdata(pdev);
> +
> +       s3c24xx_dclk->reg_save = readl_relaxed(s3c24xx_dclk->base);
> +       return 0;
> +}
> +
> +static int s3c24xx_dclk_resume(struct device *dev)
> +{
> +       struct platform_device *pdev = to_platform_device(dev);
> +       struct s3c24xx_dclk *s3c24xx_dclk = platform_get_drvdata(pdev);
> +
> +       writel_relaxed(s3c24xx_dclk->reg_save, s3c24xx_dclk->base);
> +       return 0;
> +}
> +#endif
> +
> +static SIMPLE_DEV_PM_OPS(s3c24xx_dclk_pm_ops,
> +                        s3c24xx_dclk_suspend, s3c24xx_dclk_resume);
> +
> +static const struct of_device_id s3c24xx_dclk_dt_match[];
> +
> +static inline int s3c24xx_dclk_get_driver_data(struct platform_device *pdev)
> +{
> +       struct s3c24xx_dclk_drv_data *data;
> +       if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) {
> +               const struct of_device_id *match;
> +               match = of_match_node(s3c24xx_dclk_dt_match, pdev->dev.of_node);
> +               data = (struct s3c24xx_dclk_drv_data *) match->data;
> +               return data->cpu_type;
> +       }
> +
> +       return platform_get_device_id(pdev)->driver_data;
> +}
> +
> +static int s3c24xx_dclk_probe(struct platform_device *pdev)
> +{
> +       struct s3c24xx_dclk *s3c24xx_dclk;
> +       struct device_node *np = pdev->dev.of_node;
> +       struct regmap *misccr = NULL;
> +       struct resource *mem;
> +       struct clk **clk_table;
> +       const char **clkout0_parent_names, **clkout1_parent_names;
> +       u8 clkout0_num_parents, clkout1_num_parents;
> +       int current_soc, ret, i;
> +
> +       s3c24xx_dclk = devm_kzalloc(&pdev->dev, sizeof(*s3c24xx_dclk),
> +                                   GFP_KERNEL);
> +       if (!s3c24xx_dclk)
> +               return -ENOMEM;
> +
> +       s3c24xx_dclk->dev = &pdev->dev;
> +       platform_set_drvdata(pdev, s3c24xx_dclk);
> +       spin_lock_init(&s3c24xx_dclk->dclk_lock);
> +
> +       clk_table = devm_kzalloc(&pdev->dev,
> +                                sizeof(struct clk *) * DCLK_MAX_CLKS,
> +                                GFP_KERNEL);
> +       if (!clk_table)
> +               return -ENOMEM;
> +
> +       s3c24xx_dclk->clk_data.clks = clk_table;
> +       s3c24xx_dclk->clk_data.clk_num = DCLK_MAX_CLKS;
> +
> +       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       s3c24xx_dclk->base = devm_ioremap_resource(&pdev->dev, mem);
> +       if (IS_ERR(s3c24xx_dclk->base))
> +               return PTR_ERR(s3c24xx_dclk->base);
> +
> +       /* when run from devicetree, get the misccr through a syscon-regmap */
> +       if (np) {
> +               misccr = syscon_regmap_lookup_by_phandle(np, "samsung,misccr");
> +               if (IS_ERR(misccr)) {
> +                       dev_err(&pdev->dev, "could not get misccr syscon, %ld\n",
> +                               PTR_ERR(misccr));
> +                       return PTR_ERR(misccr);
> +               }
> +       }
> +
> +       current_soc = s3c24xx_dclk_get_driver_data(pdev);
> +
> +       if (current_soc == S3C2443) {
> +               clk_table[MUX_DCLK0] = clk_register_mux(&pdev->dev,
> +                                       "mux_dclk0", dclk_s3c2443_p,
> +                                       ARRAY_SIZE(dclk_s3c2443_p), 0,
> +                                       s3c24xx_dclk->base, 1, 1, 0,
> +                                       &s3c24xx_dclk->dclk_lock);
> +               clk_table[MUX_DCLK1] = clk_register_mux(&pdev->dev,
> +                                       "mux_dclk1", dclk_s3c2443_p,
> +                                       ARRAY_SIZE(dclk_s3c2443_p), 0,
> +                                       s3c24xx_dclk->base, 17, 1, 0,
> +                                       &s3c24xx_dclk->dclk_lock);
> +       } else {
> +               clk_table[MUX_DCLK0] = clk_register_mux(&pdev->dev,
> +                                       "mux_dclk0", dclk_s3c2410_p,
> +                                       ARRAY_SIZE(dclk_s3c2410_p), 0,
> +                                       s3c24xx_dclk->base, 1, 1, 0,
> +                                       &s3c24xx_dclk->dclk_lock);
> +               clk_table[MUX_DCLK1] = clk_register_mux(&pdev->dev,
> +                                       "mux_dclk1", dclk_s3c2410_p,
> +                                       ARRAY_SIZE(dclk_s3c2410_p), 0,
> +                                       s3c24xx_dclk->base, 17, 1, 0,
> +                                       &s3c24xx_dclk->dclk_lock);
> +       }
> +
> +       clk_table[DIV_DCLK0] = clk_register_divider(&pdev->dev, "div_dclk0",
> +                                       "mux_dclk0", 0, s3c24xx_dclk->base,
> +                                       4, 4, 0, &s3c24xx_dclk->dclk_lock);
> +       clk_table[DIV_DCLK1] = clk_register_divider(&pdev->dev, "div_dclk1",
> +                                       "mux_dclk1", 0, s3c24xx_dclk->base,
> +                                       20, 4, 0, &s3c24xx_dclk->dclk_lock);
> +
> +       clk_table[GATE_DCLK0] = clk_register_gate(&pdev->dev, "gate_dclk0",
> +                                       "div_dclk0", CLK_SET_RATE_PARENT,
> +                                       s3c24xx_dclk->base, 0, 0,
> +                                       &s3c24xx_dclk->dclk_lock);
> +       clk_table[GATE_DCLK1] = clk_register_gate(&pdev->dev, "gate_dclk1",
> +                                       "div_dclk1", CLK_SET_RATE_PARENT,
> +                                       s3c24xx_dclk->base, 16, 0,
> +                                       &s3c24xx_dclk->dclk_lock);
> +
> +       switch (current_soc) {
> +       case S3C2410:
> +               clkout0_parent_names = clkout0_s3c2410_p;
> +               clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2410_p);
> +               clkout1_parent_names = clkout1_s3c2410_p;
> +               clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2410_p);
> +               break;
> +       case S3C2412:
> +               clkout0_parent_names = clkout0_s3c2412_p;
> +               clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2412_p);
> +               clkout1_parent_names = clkout1_s3c2412_p;
> +               clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2412_p);
> +               break;
> +       case S3C2440:
> +               clkout0_parent_names = clkout0_s3c2440_p;
> +               clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2440_p);
> +               clkout1_parent_names = clkout1_s3c2440_p;
> +               clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2440_p);
> +               break;
> +       case S3C2443:
> +               clkout0_parent_names = clkout0_s3c2443_p;
> +               clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2443_p);
> +               clkout1_parent_names = clkout1_s3c2443_p;
> +               clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2443_p);
> +               break;
> +       default:
> +               dev_err(&pdev->dev, "unsupported soc %d\n", current_soc);
> +               ret = -EINVAL;
> +               goto err_clk_register;
> +       }
> +
> +       clk_table[MUX_CLKOUT0] = s3c24xx_register_clkout(&pdev->dev,
> +                               "clkout0", clkout0_parent_names,
> +                               clkout0_num_parents, misccr, 4, 7);
> +       clk_table[MUX_CLKOUT1] = s3c24xx_register_clkout(&pdev->dev, "clkout1",
> +                               clkout1_parent_names,
> +                               clkout1_num_parents, misccr, 8, 7);
> +
> +       for (i = 0; i < DCLK_MAX_CLKS; i++)
> +               if (IS_ERR(clk_table[i])) {
> +                       dev_err(&pdev->dev, "clock %d failed to register\n", i);
> +                       ret = PTR_ERR(clk_table[i]);
> +                       goto err_clk_register;
> +               }
> +
> +       ret = clk_register_clkdev(clk_table[MUX_DCLK0], "dclk0", NULL);
> +       ret |= clk_register_clkdev(clk_table[MUX_DCLK1], "dclk1", NULL);
> +       ret |= clk_register_clkdev(clk_table[MUX_CLKOUT0], "clkout0", NULL);
> +       ret |= clk_register_clkdev(clk_table[MUX_CLKOUT1], "clkout1", NULL);
> +       if (ret) {
> +               dev_err(&pdev->dev, "failed to register aliases\n");
> +               goto err_clk_register;
> +       }
> +
> +       s3c24xx_dclk->dclk0_div_change_nb.notifier_call =
> +                                               s3c24xx_dclk0_div_notify;
> +       s3c24xx_dclk->dclk0_div_change_nb.next = NULL;
> +
> +       s3c24xx_dclk->dclk1_div_change_nb.notifier_call =
> +                                               s3c24xx_dclk1_div_notify;
> +       s3c24xx_dclk->dclk1_div_change_nb.next = NULL;
> +
> +       ret = clk_notifier_register(clk_table[DIV_DCLK0],
> +                                   &s3c24xx_dclk->dclk0_div_change_nb);
> +       if (ret)
> +               goto err_clk_register;
> +
> +       ret = clk_notifier_register(clk_table[DIV_DCLK1],
> +                                   &s3c24xx_dclk->dclk1_div_change_nb);
> +       if (ret)
> +               goto err_dclk_notify;
> +
> +       if (np) {
> +               ret = of_clk_add_provider(np,
> +                             of_clk_src_onecell_get, &s3c24xx_dclk->clk_data);
> +               if (ret)
> +                       goto err_of_clk_provider;
> +       }
> +
> +       return 0;
> +
> +err_of_clk_provider:
> +       clk_notifier_unregister(clk_table[DIV_DCLK1],
> +                               &s3c24xx_dclk->dclk1_div_change_nb);
> +err_dclk_notify:
> +       clk_notifier_unregister(clk_table[DIV_DCLK0],
> +                               &s3c24xx_dclk->dclk0_div_change_nb);
> +err_clk_register:
> +       for (i = 0; i < DCLK_MAX_CLKS; i++)
> +               if (clk_table[i] && !IS_ERR(clk_table[i]))
> +                       clk_unregister(clk_table[i]);
> +
> +       return ret;
> +}
> +
> +static int s3c24xx_dclk_remove(struct platform_device *pdev)
> +{
> +       struct s3c24xx_dclk *s3c24xx_dclk = platform_get_drvdata(pdev);
> +       struct clk **clk_table = s3c24xx_dclk->clk_data.clks;
> +       int i;
> +
> +       of_clk_del_provider(pdev->dev.of_node);
> +
> +       clk_notifier_unregister(clk_table[DIV_DCLK1],
> +                               &s3c24xx_dclk->dclk1_div_change_nb);
> +       clk_notifier_unregister(clk_table[DIV_DCLK0],
> +                               &s3c24xx_dclk->dclk0_div_change_nb);
> +
> +       for (i = 0; i < DCLK_MAX_CLKS; i++)
> +               clk_unregister(clk_table[i]);
> +
> +       return 0;
> +}
> +
> +static struct s3c24xx_dclk_drv_data s3c24xx_dclk_drv_data_array[] = {
> +       [S3C2410] = { S3C2410 },
> +       [S3C2412] = { S3C2412 },
> +       [S3C2440] = { S3C2440 },
> +       [S3C2443] = { S3C2443 },
> +};
> +
> +static const struct of_device_id s3c24xx_dclk_dt_match[] = {
> +       {
> +               .compatible = "samsung,s3c2410-dclk",
> +               .data = &s3c24xx_dclk_drv_data_array[S3C2410],
> +       }, {
> +               .compatible = "samsung,s3c2412-dclk",
> +               .data = &s3c24xx_dclk_drv_data_array[S3C2412],
> +       }, {
> +               .compatible = "samsung,s3c2440-dclk",
> +               .data = &s3c24xx_dclk_drv_data_array[S3C2440],
> +       }, {
> +               .compatible = "samsung,s3c2443-dclk",
> +               .data = &s3c24xx_dclk_drv_data_array[S3C2443],
> +       },
> +       { },
> +};
> +MODULE_DEVICE_TABLE(of, s3c24xx_dclk_dt_match);
> +
> +static struct platform_device_id s3c24xx_dclk_driver_ids[] = {
> +       {
> +               .name           = "s3c2410-dclk",
> +               .driver_data    = S3C2410,
> +       }, {
> +               .name           = "s3c2412-dclk",
> +               .driver_data    = S3C2412,
> +       }, {
> +               .name           = "s3c2440-dclk",
> +               .driver_data    = S3C2440,
> +       }, {
> +               .name           = "s3c2443-dclk",
> +               .driver_data    = S3C2443,
> +       },
> +       { }
> +};
> +
> +MODULE_DEVICE_TABLE(platform, s3c24xx_dclk_driver_ids);
> +
> +static struct platform_driver s3c24xx_dclk_driver = {
> +       .driver = {
> +               .name           = "s3c24xx-dclk",
> +               .owner          = THIS_MODULE,
> +               .pm             = &s3c24xx_dclk_pm_ops,
> +               .of_match_table = of_match_ptr(s3c24xx_dclk_dt_match),
> +       },
> +       .probe = s3c24xx_dclk_probe,
> +       .remove = s3c24xx_dclk_remove,
> +       .id_table = s3c24xx_dclk_driver_ids,
> +};
> +module_platform_driver(s3c24xx_dclk_driver);
> +
> +MODULE_LICENSE("GPL v2");
> +MODULE_AUTHOR("Heiko Stuebner <heiko@sntech.de>");
> +MODULE_DESCRIPTION("Driver for the S3C24XX external clock outputs");
> diff --git a/include/dt-bindings/clock/samsung,s3c2410-dclk.h b/include/dt-bindings/clock/samsung,s3c2410-dclk.h
> new file mode 100644
> index 0000000..7394d46
> --- /dev/null
> +++ b/include/dt-bindings/clock/samsung,s3c2410-dclk.h
> @@ -0,0 +1,28 @@
> +/*
> + * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
> + *
> + * 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.
> + *
> + * Device Tree binding constants clock controllers of Samsung S3C2410 and later.
> + */
> +
> +#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C2410_CLOCK_H
> +#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C2410_CLOCK_H
> +
> +#define MUX_DCLK0      0
> +#define MUX_DCLK1      1
> +
> +#define DIV_DCLK0      2
> +#define DIV_DCLK1      3
> +
> +#define GATE_DCLK0     4
> +#define GATE_DCLK1     5
> +
> +#define MUX_CLKOUT0    6
> +#define MUX_CLKOUT1    7
> +
> +#define DCLK_MAX_CLKS  (MUX_CLKOUT1 + 1)
> +
> +#endif
> -- 
> 1.7.10.4
> 

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

* Re: [PATCH 08/12] clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442
  2013-12-13 13:01   ` Heiko Stübner
@ 2014-02-06 14:12     ` Mike Turquette
  -1 siblings, 0 replies; 54+ messages in thread
From: Mike Turquette @ 2014-02-06 14:12 UTC (permalink / raw)
  To: Heiko Stübner, Kukjin Kim
  Cc: t.figa, linux-arm-kernel, linux-samsung-soc

Quoting Heiko Stübner (2013-12-13 05:01:51)
> This driver can handle the clock controllers of the socs mentioned above,
> as they share a common clock tree with only small differences.
> 
> The clock structure is built according to the manuals of the included
> SoCs and might include changes in comparison to the previous clock
> structure.
> 
> As pll-rate-tables only the 12mhz variants are currently included.
> The original code was wrongly checking for 169mhz xti values [a 0 to much
> at the end], so the original 16mhz pll table would have never been
> included and its values are so obscure that I have no possibility to
> at least check their sane-ness. When using the formula from the manual
> the resulting frequency is near the table value but still slightly off.
> 
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>

Acked-by: Mike Turquette <mturquette@linaro.org>

> ---
>  drivers/clk/samsung/Makefile                      |    1 +
>  drivers/clk/samsung/clk-s3c2410.c                 |  428 +++++++++++++++++++++
>  include/dt-bindings/clock/samsung,s3c2410-clock.h |   64 +++
>  3 files changed, 493 insertions(+)
>  create mode 100644 drivers/clk/samsung/clk-s3c2410.c
>  create mode 100644 include/dt-bindings/clock/samsung,s3c2410-clock.h
> 
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> index 568683c..60748b2 100644
> --- a/drivers/clk/samsung/Makefile
> +++ b/drivers/clk/samsung/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_SOC_EXYNOS5250)    += clk-exynos5250.o
>  obj-$(CONFIG_SOC_EXYNOS5420)   += clk-exynos5420.o
>  obj-$(CONFIG_SOC_EXYNOS5440)   += clk-exynos5440.o
>  obj-$(CONFIG_ARCH_EXYNOS)      += clk-exynos-audss.o
> +obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
>  obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
>  obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
>  obj-$(CONFIG_ARCH_S3C64XX)     += clk-s3c64xx.o
> diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c
> new file mode 100644
> index 0000000..8358cad
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-s3c2410.c
> @@ -0,0 +1,428 @@
> +/*
> + * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * Common Clock Framework support for S3C2410 and following SoCs.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +
> +#include <dt-bindings/clock/samsung,s3c2410-clock.h>
> +
> +#include "clk.h"
> +#include "clk-pll.h"
> +
> +#define LOCKTIME       0x00
> +#define MPLLCON                0x04
> +#define UPLLCON                0x08
> +#define CLKCON         0x0c
> +#define CLKSLOW                0x10
> +#define CLKDIVN                0x14
> +#define CAMDIVN                0x18
> +
> +/* the soc types */
> +enum supported_socs {
> +       S3C2410,
> +       S3C2440,
> +       S3C2442,
> +};
> +
> +/* list of PLLs to be registered */
> +enum s3c2410_plls {
> +       mpll, upll,
> +};
> +
> +/*
> + * list of controller registers to be saved and restored during a
> + * suspend/resume cycle.
> + */
> +static unsigned long s3c2410_clk_regs[] __initdata = {
> +       LOCKTIME,
> +       MPLLCON,
> +       UPLLCON,
> +       CLKCON,
> +       CLKSLOW,
> +       CLKDIVN,
> +       CAMDIVN,
> +};
> +
> +PNAME(fclk_p) = { "mpll", "div_slow" };
> +
> +struct samsung_mux_clock s3c2410_common_muxes[] __initdata = {
> +       MUX(FCLK, "fclk", fclk_p, CLKSLOW, 4, 1),
> +};
> +
> +static struct clk_div_table divslow_d[] = {
> +       { .val = 0, .div = 1 },
> +       { .val = 1, .div = 2 },
> +       { .val = 2, .div = 4 },
> +       { .val = 3, .div = 6 },
> +       { .val = 4, .div = 8 },
> +       { .val = 5, .div = 10 },
> +       { .val = 6, .div = 12 },
> +       { .val = 7, .div = 14 },
> +       { .div = 0 },
> +};
> +
> +struct samsung_div_clock s3c2410_common_dividers[] __initdata = {
> +       DIV_T(0, "div_slow", "xti", CLKSLOW, 0, 3, divslow_d),
> +       DIV(PCLK, "pclk", "hclk", CLKDIVN, 0, 1),
> +};
> +
> +struct samsung_gate_clock s3c2410_common_gates[] __initdata = {
> +       GATE(PCLK_SPI, "spi", "pclk", CLKCON, 18, 0, 0),
> +       GATE(PCLK_I2S, "i2s", "pclk", CLKCON, 17, 0, 0),
> +       GATE(PCLK_I2C, "i2c", "pclk", CLKCON, 16, 0, 0),
> +       GATE(PCLK_ADC, "adc", "pclk", CLKCON, 15, 0, 0),
> +       GATE(PCLK_RTC, "rtc", "pclk", CLKCON, 14, 0, 0),
> +       GATE(PCLK_GPIO, "gpio", "pclk", CLKCON, 13, CLK_IGNORE_UNUSED, 0),
> +       GATE(PCLK_UART2, "uart2", "pclk", CLKCON, 12, 0, 0),
> +       GATE(PCLK_UART1, "uart1", "pclk", CLKCON, 11, 0, 0),
> +       GATE(PCLK_UART0, "uart0", "pclk", CLKCON, 10, 0, 0),
> +       GATE(PCLK_SDI, "sdi", "pclk", CLKCON, 9, 0, 0),
> +       GATE(PCLK_PWM, "pwm", "pclk", CLKCON, 8, 0, 0),
> +       GATE(HCLK_USBD, "usb-device", "hclk", CLKCON, 7, 0, 0),
> +       GATE(HCLK_USBH, "usb-host", "hclk", CLKCON, 6, 0, 0),
> +       GATE(HCLK_LCD, "lcd", "hclk", CLKCON, 5, 0, 0),
> +       GATE(HCLK_NAND, "nand", "hclk", CLKCON, 4, 0, 0),
> +};
> +
> +/* should be added _after_ the soc-specific clocks are created */
> +struct samsung_clock_alias s3c2410_common_aliases[] __initdata = {
> +       ALIAS(PCLK_I2C, "s3c2410-i2c.0", "i2c"),
> +       ALIAS(PCLK_ADC, NULL, "adc"),
> +       ALIAS(PCLK_RTC, NULL, "rtc"),
> +       ALIAS(PCLK_PWM, NULL, "timers"),
> +       ALIAS(HCLK_LCD, NULL, "lcd"),
> +       ALIAS(HCLK_USBD, NULL, "usb-device"),
> +       ALIAS(HCLK_USBH, NULL, "usb-host"),
> +       ALIAS(UCLK, NULL, "usb-bus-host"),
> +       ALIAS(UCLK, NULL, "usb-bus-gadget"),
> +       ALIAS(ARMCLK, NULL, "armclk"),
> +       ALIAS(UCLK, NULL, "uclk"),
> +       ALIAS(HCLK, NULL, "hclk"),
> +       ALIAS(MPLL, NULL, "mpll"),
> +       ALIAS(FCLK, NULL, "fclk"),
> +};
> +
> +/* S3C2410 specific clocks */
> +
> +static struct samsung_pll_rate_table pll_s3c2410_12mhz_tbl[] __initdata = {
> +       /* sorted in descending order */
> +       /* 2410A extras */
> +       PLL_35XX_RATE(270000000, 127, 1, 1),
> +       PLL_35XX_RATE(268000000, 126, 1, 1),
> +       PLL_35XX_RATE(266000000, 125, 1, 1),
> +       PLL_35XX_RATE(226000000, 105, 1, 1),
> +       PLL_35XX_RATE(210000000, 132, 2, 1),
> +       /* 2410 common */
> +       PLL_35XX_RATE(203000000, 161, 3, 1),
> +       PLL_35XX_RATE(192000000, 88, 1, 1),
> +       PLL_35XX_RATE(186000000, 85, 1, 1),
> +       PLL_35XX_RATE(180000000, 82, 1, 1),
> +       PLL_35XX_RATE(170000000, 77, 1, 1),
> +       PLL_35XX_RATE(158000000, 71, 1, 1),
> +       PLL_35XX_RATE(152000000, 68, 1, 1),
> +       PLL_35XX_RATE(147000000, 90, 2, 1),
> +       PLL_35XX_RATE(135000000, 82, 2, 1),
> +       PLL_35XX_RATE(124000000, 116, 1, 2),
> +       PLL_35XX_RATE(118000000, 150, 2, 2),
> +       PLL_35XX_RATE(113000000, 105, 1, 2),
> +       PLL_35XX_RATE(101000000, 127, 2, 2),
> +       PLL_35XX_RATE(90000000, 112, 2, 2),
> +       PLL_35XX_RATE(85000000, 105, 2, 2),
> +       PLL_35XX_RATE(79000000, 71, 1, 2),
> +       PLL_35XX_RATE(68000000, 82, 2, 2),
> +       PLL_35XX_RATE(56000000, 142, 2, 3),
> +       PLL_35XX_RATE(48000000, 120, 2, 3),
> +       PLL_35XX_RATE(51000000, 161, 3, 3),
> +       PLL_35XX_RATE(45000000, 82, 1, 3),
> +       PLL_35XX_RATE(34000000, 82, 2, 3),
> +       { },
> +};
> +
> +static struct samsung_pll_clock s3c2410_plls[] __initdata = {
> +       [mpll] = PLL(pll_s3c2410_mpll, MPLL, "mpll", "xti",
> +                                               LOCKTIME, MPLLCON, NULL),
> +       [upll] = PLL(pll_s3c2410_upll, UPLL, "upll", "xti",
> +                                               LOCKTIME, UPLLCON, NULL),
> +};
> +
> +struct samsung_div_clock s3c2410_dividers[] __initdata = {
> +       DIV(HCLK, "hclk", "mpll", CLKDIVN, 1, 1),
> +};
> +
> +struct samsung_fixed_factor_clock s3c2410_ffactor[] __initdata = {
> +       /*
> +        * armclk is directly supplied by the fclk, without
> +        * switching possibility like on the s3c244x below.
> +        */
> +       FFACTOR(ARMCLK, "armclk", "fclk", 1, 1, 0),
> +
> +       /* uclk is fed from the unmodified upll */
> +       FFACTOR(UCLK, "uclk", "upll", 1, 1, 0),
> +};
> +
> +struct samsung_clock_alias s3c2410_aliases[] __initdata = {
> +       ALIAS(PCLK_UART0, "s3c2410-uart.0", "uart"),
> +       ALIAS(PCLK_UART1, "s3c2410-uart.1", "uart"),
> +       ALIAS(PCLK_UART2, "s3c2410-uart.2", "uart"),
> +       ALIAS(PCLK_UART0, "s3c2410-uart.0", "clk_uart_baud0"),
> +       ALIAS(PCLK_UART1, "s3c2410-uart.1", "clk_uart_baud0"),
> +       ALIAS(PCLK_UART2, "s3c2410-uart.2", "clk_uart_baud0"),
> +       ALIAS(UCLK, NULL, "clk_uart_baud1"),
> +};
> +
> +/* S3C244x specific clocks */
> +
> +static struct samsung_pll_rate_table pll_s3c244x_12mhz_tbl[] __initdata = {
> +       /* sorted in descending order */
> +       PLL_35XX_RATE(400000000, 0x5c, 1, 1),
> +       PLL_35XX_RATE(390000000, 0x7a, 2, 1),
> +       PLL_35XX_RATE(380000000, 0x57, 1, 1),
> +       PLL_35XX_RATE(370000000, 0xb1, 4, 1),
> +       PLL_35XX_RATE(360000000, 0x70, 2, 1),
> +       PLL_35XX_RATE(350000000, 0xa7, 4, 1),
> +       PLL_35XX_RATE(340000000, 0x4d, 1, 1),
> +       PLL_35XX_RATE(330000000, 0x66, 2, 1),
> +       PLL_35XX_RATE(320000000, 0x98, 4, 1),
> +       PLL_35XX_RATE(310000000, 0x93, 4, 1),
> +       PLL_35XX_RATE(300000000, 0x75, 3, 1),
> +       PLL_35XX_RATE(240000000, 0x70, 1, 2),
> +       PLL_35XX_RATE(230000000, 0x6b, 1, 2),
> +       PLL_35XX_RATE(220000000, 0x66, 1, 2),
> +       PLL_35XX_RATE(210000000, 0x84, 2, 2),
> +       PLL_35XX_RATE(200000000, 0x5c, 1, 2),
> +       PLL_35XX_RATE(190000000, 0x57, 1, 2),
> +       PLL_35XX_RATE(180000000, 0x70, 2, 2),
> +       PLL_35XX_RATE(170000000, 0x4d, 1, 2),
> +       PLL_35XX_RATE(160000000, 0x98, 4, 2),
> +       PLL_35XX_RATE(150000000, 0x75, 3, 2),
> +       PLL_35XX_RATE(120000000, 0x70, 1, 3),
> +       PLL_35XX_RATE(110000000, 0x66, 1, 3),
> +       PLL_35XX_RATE(100000000, 0x5c, 1, 3),
> +       PLL_35XX_RATE(90000000, 0x70, 2, 3),
> +       PLL_35XX_RATE(80000000, 0x98, 4, 3),
> +       PLL_35XX_RATE(75000000, 0x75, 3, 3),
> +};
> +
> +static struct samsung_pll_clock s3c244x_common_plls[] __initdata = {
> +       [mpll] = PLL(pll_s3c2440_mpll, MPLL, "mpll", "xti",
> +                                               LOCKTIME, MPLLCON, NULL),
> +       [upll] = PLL(pll_s3c2410_upll, UPLL, "upll", "xti",
> +                                               LOCKTIME, UPLLCON, NULL),
> +};
> +
> +PNAME(hclk_p) = { "fclk", "div_hclk_2", "div_hclk_4", "div_hclk_3" };
> +PNAME(armclk_p) = { "fclk", "hclk" };
> +
> +struct samsung_mux_clock s3c244x_common_muxes[] __initdata = {
> +       MUX(HCLK, "hclk", hclk_p, CLKDIVN, 1, 2),
> +       MUX(ARMCLK, "armclk", armclk_p, CAMDIVN, 12, 1),
> +};
> +
> +struct samsung_fixed_factor_clock s3c244x_common_ffactor[] __initdata = {
> +       FFACTOR(0, "div_hclk_2", "fclk", 1, 2, 0),
> +       FFACTOR(0, "ff_cam", "div_cam", 2, 1, CLK_SET_RATE_PARENT),
> +};
> +
> +static struct clk_div_table div_hclk_4_d[] = {
> +       { .val = 0, .div = 4 },
> +       { .val = 1, .div = 8 },
> +};
> +
> +static struct clk_div_table div_hclk_3_d[] = {
> +       { .val = 0, .div = 3 },
> +       { .val = 1, .div = 6 },
> +};
> +
> +struct samsung_div_clock s3c244x_common_dividers[] __initdata = {
> +       DIV(UCLK, "uclk", "upll", CLKDIVN, 3, 1),
> +       DIV(0, "div_hclk", "fclk", CLKDIVN, 1, 1),
> +       DIV_T(0, "div_hclk_4", "fclk", CAMDIVN, 9, 1, div_hclk_4_d),
> +       DIV_T(0, "div_hclk_3", "fclk", CAMDIVN, 8, 1, div_hclk_3_d),
> +       DIV(0, "div_cam", "upll", CAMDIVN, 0, 3),
> +};
> +
> +struct samsung_gate_clock s3c244x_common_gates[] __initdata = {
> +       GATE(HCLK_CAM, "cam", "hclk", CLKCON, 19, 0, 0),
> +};
> +
> +struct samsung_clock_alias s3c244x_common_aliases[] __initdata = {
> +       ALIAS(PCLK_UART0, "s3c2440-uart.0", "uart"),
> +       ALIAS(PCLK_UART1, "s3c2440-uart.1", "uart"),
> +       ALIAS(PCLK_UART2, "s3c2440-uart.2", "uart"),
> +       ALIAS(PCLK_UART0, "s3c2440-uart.0", "clk_uart_baud2"),
> +       ALIAS(PCLK_UART1, "s3c2440-uart.1", "clk_uart_baud2"),
> +       ALIAS(PCLK_UART2, "s3c2440-uart.2", "clk_uart_baud2"),
> +       ALIAS(HCLK_CAM, NULL, "camif"),
> +       ALIAS(CAMIF, NULL, "camif-upll"),
> +};
> +
> +/* S3C2440 specific clocks */
> +
> +PNAME(s3c2440_camif_p) = { "upll", "ff_cam" };
> +
> +struct samsung_mux_clock s3c2440_muxes[] __initdata = {
> +       MUX(CAMIF, "camif", s3c2440_camif_p, CAMDIVN, 4, 1),
> +};
> +
> +struct samsung_gate_clock s3c2440_gates[] __initdata = {
> +       GATE(PCLK_AC97, "ac97", "pclk", CLKCON, 20, 0, 0),
> +};
> +
> +/* S3C2442 specific clocks */
> +
> +struct samsung_fixed_factor_clock s3c2442_ffactor[] __initdata = {
> +       FFACTOR(0, "upll_3", "upll", 1, 3, 0),
> +};
> +
> +PNAME(s3c2442_camif_p) = { "upll", "ff_cam", "upll", "upll_3" };
> +
> +struct samsung_mux_clock s3c2442_muxes[] __initdata = {
> +       MUX(CAMIF, "camif", s3c2442_camif_p, CAMDIVN, 4, 2),
> +};
> +
> +/*
> + * fixed rate clocks generated outside the soc
> + * Only necessary until the devicetree-move is complete
> + */
> +struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata = {
> +       FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0),
> +};
> +
> +static void __init s3c2410_common_clk_register_fixed_ext(unsigned long xti_f)
> +{
> +       struct samsung_clock_alias xti_alias = ALIAS(XTI, NULL, "xtal");
> +
> +       s3c2410_common_frate_clks[0].fixed_rate = xti_f;
> +       samsung_clk_register_fixed_rate(s3c2410_common_frate_clks,
> +                               ARRAY_SIZE(s3c2410_common_frate_clks));
> +
> +       samsung_clk_register_alias(&xti_alias, 1);
> +}
> +
> +void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
> +                                   int current_soc,
> +                                   void __iomem *reg_base)
> +{
> +       if (np) {
> +               reg_base = of_iomap(np, 0);
> +               if (!reg_base)
> +                       panic("%s: failed to map registers\n", __func__);
> +       }
> +
> +       samsung_clk_init(np, reg_base, NR_CLKS,
> +               s3c2410_clk_regs, ARRAY_SIZE(s3c2410_clk_regs), NULL, 0);
> +
> +       /* Register external clocks only in non-dt cases */
> +       if (!np)
> +               s3c2410_common_clk_register_fixed_ext(xti_f);
> +
> +       if (current_soc == 2410) {
> +               if (_get_rate("xti") == 12 * MHZ) {
> +                       s3c2410_plls[mpll].rate_table = pll_s3c2410_12mhz_tbl;
> +                       s3c2410_plls[upll].rate_table = pll_s3c2410_12mhz_tbl;
> +               }
> +
> +               /* Register PLLs. */
> +               samsung_clk_register_pll(s3c2410_plls,
> +                               ARRAY_SIZE(s3c2410_plls), reg_base);
> +
> +       } else { /* S3C2440, S3C2442 */
> +               if (_get_rate("xti") == 12 * MHZ) {
> +                       /*
> +                        * plls follow different calculation schemes, with the
> +                        * upll following the same scheme as the s3c2410 plls
> +                        */
> +                       s3c244x_common_plls[mpll].rate_table =
> +                                                       pll_s3c244x_12mhz_tbl;
> +                       s3c244x_common_plls[upll].rate_table =
> +                                                       pll_s3c2410_12mhz_tbl;
> +               }
> +
> +               /* Register PLLs. */
> +               samsung_clk_register_pll(s3c244x_common_plls,
> +                               ARRAY_SIZE(s3c244x_common_plls), reg_base);
> +       }
> +
> +       /* Register common internal clocks. */
> +       samsung_clk_register_mux(s3c2410_common_muxes,
> +                       ARRAY_SIZE(s3c2410_common_muxes));
> +       samsung_clk_register_div(s3c2410_common_dividers,
> +                       ARRAY_SIZE(s3c2410_common_dividers));
> +       samsung_clk_register_gate(s3c2410_common_gates,
> +               ARRAY_SIZE(s3c2410_common_gates));
> +
> +       if (current_soc == S3C2440 || current_soc == S3C2442) {
> +               samsung_clk_register_div(s3c244x_common_dividers,
> +                               ARRAY_SIZE(s3c244x_common_dividers));
> +               samsung_clk_register_gate(s3c244x_common_gates,
> +                               ARRAY_SIZE(s3c244x_common_gates));
> +               samsung_clk_register_mux(s3c244x_common_muxes,
> +                               ARRAY_SIZE(s3c244x_common_muxes));
> +               samsung_clk_register_fixed_factor(s3c244x_common_ffactor,
> +                               ARRAY_SIZE(s3c244x_common_ffactor));
> +       }
> +
> +       /* Register SoC-specific clocks. */
> +       switch (current_soc) {
> +       case S3C2410:
> +               samsung_clk_register_div(s3c2410_dividers,
> +                               ARRAY_SIZE(s3c2410_dividers));
> +               samsung_clk_register_fixed_factor(s3c2410_ffactor,
> +                               ARRAY_SIZE(s3c2410_ffactor));
> +               samsung_clk_register_alias(s3c2410_aliases,
> +                       ARRAY_SIZE(s3c2410_common_aliases));
> +               break;
> +       case S3C2440:
> +               samsung_clk_register_mux(s3c2440_muxes,
> +                               ARRAY_SIZE(s3c2440_muxes));
> +               samsung_clk_register_gate(s3c2440_gates,
> +                               ARRAY_SIZE(s3c2440_gates));
> +               break;
> +       case S3C2442:
> +               samsung_clk_register_mux(s3c2442_muxes,
> +                               ARRAY_SIZE(s3c2442_muxes));
> +               samsung_clk_register_fixed_factor(s3c2442_ffactor,
> +                               ARRAY_SIZE(s3c2442_ffactor));
> +               break;
> +       }
> +
> +       /*
> +        * Register common aliases at the end, as some of the aliased clocks
> +        * are SoC specific.
> +        */
> +       samsung_clk_register_alias(s3c2410_common_aliases,
> +               ARRAY_SIZE(s3c2410_common_aliases));
> +
> +       if (current_soc == S3C2440 || current_soc == S3C2442) {
> +               samsung_clk_register_alias(s3c244x_common_aliases,
> +                       ARRAY_SIZE(s3c244x_common_aliases));
> +       }
> +}
> +
> +static void __init s3c2410_clk_init(struct device_node *np)
> +{
> +       s3c2410_common_clk_init(np, 0, S3C2410, 0);
> +}
> +CLK_OF_DECLARE(s3c2410_clk, "samsung,s3c2410-clock", s3c2410_clk_init);
> +
> +static void __init s3c2440_clk_init(struct device_node *np)
> +{
> +       s3c2410_common_clk_init(np, 0, S3C2440, 0);
> +}
> +CLK_OF_DECLARE(s3c2440_clk, "samsung,s3c2440-clock", s3c2440_clk_init);
> +
> +static void __init s3c2442_clk_init(struct device_node *np)
> +{
> +       s3c2410_common_clk_init(np, 0, S3C2442, 0);
> +}
> +CLK_OF_DECLARE(s3c2442_clk, "samsung,s3c2442-clock", s3c2442_clk_init);
> diff --git a/include/dt-bindings/clock/samsung,s3c2410-clock.h b/include/dt-bindings/clock/samsung,s3c2410-clock.h
> new file mode 100644
> index 0000000..66c278f
> --- /dev/null
> +++ b/include/dt-bindings/clock/samsung,s3c2410-clock.h
> @@ -0,0 +1,64 @@
> +/*
> + * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
> + *
> + * 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.
> + *
> + * Device Tree binding constants clock controllers of Samsung S3C2410 and later.
> + */
> +
> +#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C2410_CLOCK_H
> +#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C2410_CLOCK_H
> +
> +/*
> + * Let each exported clock get a unique index, which is used on DT-enabled
> + * platforms to lookup the clock from a clock specifier. These indices are
> + * therefore considered an ABI and so must not be changed. This implies
> + * that new clocks should be added either in free spaces between clock groups
> + * or at the end.
> + */
> +
> +/* Core clocks. */
> +
> +
> +#define MPLL                   1
> +#define UPLL                   2
> +#define FCLK                   3
> +#define HCLK                   4
> +#define PCLK                   5
> +#define UCLK                   6
> +#define ARMCLK                 7
> +
> +#define XTI                    8
> +
> +/* pclk-gates */
> +#define PCLK_UART0             16
> +#define PCLK_UART1             17
> +#define PCLK_UART2             18
> +#define PCLK_I2C               19
> +#define PCLK_SDI               20
> +#define PCLK_SPI               21
> +#define PCLK_ADC               22
> +#define PCLK_AC97              23
> +#define PCLK_I2S               24
> +#define PCLK_PWM               25
> +#define PCLK_RTC               26
> +#define PCLK_GPIO              27
> +
> +
> +/* hclk-gates */
> +#define HCLK_LCD               32
> +#define HCLK_USBH              33
> +#define HCLK_USBD              34
> +#define HCLK_NAND              35
> +#define HCLK_CAM               36
> +
> +
> +#define CAMIF                  40
> +
> +
> +/* Total number of clocks. */
> +#define NR_CLKS                        (CAMIF + 1)
> +
> +#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_S3C2443_CLOCK_H */
> -- 
> 1.7.10.4
> 

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

* [PATCH 08/12] clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442
@ 2014-02-06 14:12     ` Mike Turquette
  0 siblings, 0 replies; 54+ messages in thread
From: Mike Turquette @ 2014-02-06 14:12 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Heiko St?bner (2013-12-13 05:01:51)
> This driver can handle the clock controllers of the socs mentioned above,
> as they share a common clock tree with only small differences.
> 
> The clock structure is built according to the manuals of the included
> SoCs and might include changes in comparison to the previous clock
> structure.
> 
> As pll-rate-tables only the 12mhz variants are currently included.
> The original code was wrongly checking for 169mhz xti values [a 0 to much
> at the end], so the original 16mhz pll table would have never been
> included and its values are so obscure that I have no possibility to
> at least check their sane-ness. When using the formula from the manual
> the resulting frequency is near the table value but still slightly off.
> 
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>

Acked-by: Mike Turquette <mturquette@linaro.org>

> ---
>  drivers/clk/samsung/Makefile                      |    1 +
>  drivers/clk/samsung/clk-s3c2410.c                 |  428 +++++++++++++++++++++
>  include/dt-bindings/clock/samsung,s3c2410-clock.h |   64 +++
>  3 files changed, 493 insertions(+)
>  create mode 100644 drivers/clk/samsung/clk-s3c2410.c
>  create mode 100644 include/dt-bindings/clock/samsung,s3c2410-clock.h
> 
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> index 568683c..60748b2 100644
> --- a/drivers/clk/samsung/Makefile
> +++ b/drivers/clk/samsung/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_SOC_EXYNOS5250)    += clk-exynos5250.o
>  obj-$(CONFIG_SOC_EXYNOS5420)   += clk-exynos5420.o
>  obj-$(CONFIG_SOC_EXYNOS5440)   += clk-exynos5440.o
>  obj-$(CONFIG_ARCH_EXYNOS)      += clk-exynos-audss.o
> +obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
>  obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
>  obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
>  obj-$(CONFIG_ARCH_S3C64XX)     += clk-s3c64xx.o
> diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c
> new file mode 100644
> index 0000000..8358cad
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-s3c2410.c
> @@ -0,0 +1,428 @@
> +/*
> + * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * Common Clock Framework support for S3C2410 and following SoCs.
> + */
> +
> +#include <linux/clk.h>
> +#include <linux/clkdev.h>
> +#include <linux/clk-provider.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +
> +#include <dt-bindings/clock/samsung,s3c2410-clock.h>
> +
> +#include "clk.h"
> +#include "clk-pll.h"
> +
> +#define LOCKTIME       0x00
> +#define MPLLCON                0x04
> +#define UPLLCON                0x08
> +#define CLKCON         0x0c
> +#define CLKSLOW                0x10
> +#define CLKDIVN                0x14
> +#define CAMDIVN                0x18
> +
> +/* the soc types */
> +enum supported_socs {
> +       S3C2410,
> +       S3C2440,
> +       S3C2442,
> +};
> +
> +/* list of PLLs to be registered */
> +enum s3c2410_plls {
> +       mpll, upll,
> +};
> +
> +/*
> + * list of controller registers to be saved and restored during a
> + * suspend/resume cycle.
> + */
> +static unsigned long s3c2410_clk_regs[] __initdata = {
> +       LOCKTIME,
> +       MPLLCON,
> +       UPLLCON,
> +       CLKCON,
> +       CLKSLOW,
> +       CLKDIVN,
> +       CAMDIVN,
> +};
> +
> +PNAME(fclk_p) = { "mpll", "div_slow" };
> +
> +struct samsung_mux_clock s3c2410_common_muxes[] __initdata = {
> +       MUX(FCLK, "fclk", fclk_p, CLKSLOW, 4, 1),
> +};
> +
> +static struct clk_div_table divslow_d[] = {
> +       { .val = 0, .div = 1 },
> +       { .val = 1, .div = 2 },
> +       { .val = 2, .div = 4 },
> +       { .val = 3, .div = 6 },
> +       { .val = 4, .div = 8 },
> +       { .val = 5, .div = 10 },
> +       { .val = 6, .div = 12 },
> +       { .val = 7, .div = 14 },
> +       { .div = 0 },
> +};
> +
> +struct samsung_div_clock s3c2410_common_dividers[] __initdata = {
> +       DIV_T(0, "div_slow", "xti", CLKSLOW, 0, 3, divslow_d),
> +       DIV(PCLK, "pclk", "hclk", CLKDIVN, 0, 1),
> +};
> +
> +struct samsung_gate_clock s3c2410_common_gates[] __initdata = {
> +       GATE(PCLK_SPI, "spi", "pclk", CLKCON, 18, 0, 0),
> +       GATE(PCLK_I2S, "i2s", "pclk", CLKCON, 17, 0, 0),
> +       GATE(PCLK_I2C, "i2c", "pclk", CLKCON, 16, 0, 0),
> +       GATE(PCLK_ADC, "adc", "pclk", CLKCON, 15, 0, 0),
> +       GATE(PCLK_RTC, "rtc", "pclk", CLKCON, 14, 0, 0),
> +       GATE(PCLK_GPIO, "gpio", "pclk", CLKCON, 13, CLK_IGNORE_UNUSED, 0),
> +       GATE(PCLK_UART2, "uart2", "pclk", CLKCON, 12, 0, 0),
> +       GATE(PCLK_UART1, "uart1", "pclk", CLKCON, 11, 0, 0),
> +       GATE(PCLK_UART0, "uart0", "pclk", CLKCON, 10, 0, 0),
> +       GATE(PCLK_SDI, "sdi", "pclk", CLKCON, 9, 0, 0),
> +       GATE(PCLK_PWM, "pwm", "pclk", CLKCON, 8, 0, 0),
> +       GATE(HCLK_USBD, "usb-device", "hclk", CLKCON, 7, 0, 0),
> +       GATE(HCLK_USBH, "usb-host", "hclk", CLKCON, 6, 0, 0),
> +       GATE(HCLK_LCD, "lcd", "hclk", CLKCON, 5, 0, 0),
> +       GATE(HCLK_NAND, "nand", "hclk", CLKCON, 4, 0, 0),
> +};
> +
> +/* should be added _after_ the soc-specific clocks are created */
> +struct samsung_clock_alias s3c2410_common_aliases[] __initdata = {
> +       ALIAS(PCLK_I2C, "s3c2410-i2c.0", "i2c"),
> +       ALIAS(PCLK_ADC, NULL, "adc"),
> +       ALIAS(PCLK_RTC, NULL, "rtc"),
> +       ALIAS(PCLK_PWM, NULL, "timers"),
> +       ALIAS(HCLK_LCD, NULL, "lcd"),
> +       ALIAS(HCLK_USBD, NULL, "usb-device"),
> +       ALIAS(HCLK_USBH, NULL, "usb-host"),
> +       ALIAS(UCLK, NULL, "usb-bus-host"),
> +       ALIAS(UCLK, NULL, "usb-bus-gadget"),
> +       ALIAS(ARMCLK, NULL, "armclk"),
> +       ALIAS(UCLK, NULL, "uclk"),
> +       ALIAS(HCLK, NULL, "hclk"),
> +       ALIAS(MPLL, NULL, "mpll"),
> +       ALIAS(FCLK, NULL, "fclk"),
> +};
> +
> +/* S3C2410 specific clocks */
> +
> +static struct samsung_pll_rate_table pll_s3c2410_12mhz_tbl[] __initdata = {
> +       /* sorted in descending order */
> +       /* 2410A extras */
> +       PLL_35XX_RATE(270000000, 127, 1, 1),
> +       PLL_35XX_RATE(268000000, 126, 1, 1),
> +       PLL_35XX_RATE(266000000, 125, 1, 1),
> +       PLL_35XX_RATE(226000000, 105, 1, 1),
> +       PLL_35XX_RATE(210000000, 132, 2, 1),
> +       /* 2410 common */
> +       PLL_35XX_RATE(203000000, 161, 3, 1),
> +       PLL_35XX_RATE(192000000, 88, 1, 1),
> +       PLL_35XX_RATE(186000000, 85, 1, 1),
> +       PLL_35XX_RATE(180000000, 82, 1, 1),
> +       PLL_35XX_RATE(170000000, 77, 1, 1),
> +       PLL_35XX_RATE(158000000, 71, 1, 1),
> +       PLL_35XX_RATE(152000000, 68, 1, 1),
> +       PLL_35XX_RATE(147000000, 90, 2, 1),
> +       PLL_35XX_RATE(135000000, 82, 2, 1),
> +       PLL_35XX_RATE(124000000, 116, 1, 2),
> +       PLL_35XX_RATE(118000000, 150, 2, 2),
> +       PLL_35XX_RATE(113000000, 105, 1, 2),
> +       PLL_35XX_RATE(101000000, 127, 2, 2),
> +       PLL_35XX_RATE(90000000, 112, 2, 2),
> +       PLL_35XX_RATE(85000000, 105, 2, 2),
> +       PLL_35XX_RATE(79000000, 71, 1, 2),
> +       PLL_35XX_RATE(68000000, 82, 2, 2),
> +       PLL_35XX_RATE(56000000, 142, 2, 3),
> +       PLL_35XX_RATE(48000000, 120, 2, 3),
> +       PLL_35XX_RATE(51000000, 161, 3, 3),
> +       PLL_35XX_RATE(45000000, 82, 1, 3),
> +       PLL_35XX_RATE(34000000, 82, 2, 3),
> +       { },
> +};
> +
> +static struct samsung_pll_clock s3c2410_plls[] __initdata = {
> +       [mpll] = PLL(pll_s3c2410_mpll, MPLL, "mpll", "xti",
> +                                               LOCKTIME, MPLLCON, NULL),
> +       [upll] = PLL(pll_s3c2410_upll, UPLL, "upll", "xti",
> +                                               LOCKTIME, UPLLCON, NULL),
> +};
> +
> +struct samsung_div_clock s3c2410_dividers[] __initdata = {
> +       DIV(HCLK, "hclk", "mpll", CLKDIVN, 1, 1),
> +};
> +
> +struct samsung_fixed_factor_clock s3c2410_ffactor[] __initdata = {
> +       /*
> +        * armclk is directly supplied by the fclk, without
> +        * switching possibility like on the s3c244x below.
> +        */
> +       FFACTOR(ARMCLK, "armclk", "fclk", 1, 1, 0),
> +
> +       /* uclk is fed from the unmodified upll */
> +       FFACTOR(UCLK, "uclk", "upll", 1, 1, 0),
> +};
> +
> +struct samsung_clock_alias s3c2410_aliases[] __initdata = {
> +       ALIAS(PCLK_UART0, "s3c2410-uart.0", "uart"),
> +       ALIAS(PCLK_UART1, "s3c2410-uart.1", "uart"),
> +       ALIAS(PCLK_UART2, "s3c2410-uart.2", "uart"),
> +       ALIAS(PCLK_UART0, "s3c2410-uart.0", "clk_uart_baud0"),
> +       ALIAS(PCLK_UART1, "s3c2410-uart.1", "clk_uart_baud0"),
> +       ALIAS(PCLK_UART2, "s3c2410-uart.2", "clk_uart_baud0"),
> +       ALIAS(UCLK, NULL, "clk_uart_baud1"),
> +};
> +
> +/* S3C244x specific clocks */
> +
> +static struct samsung_pll_rate_table pll_s3c244x_12mhz_tbl[] __initdata = {
> +       /* sorted in descending order */
> +       PLL_35XX_RATE(400000000, 0x5c, 1, 1),
> +       PLL_35XX_RATE(390000000, 0x7a, 2, 1),
> +       PLL_35XX_RATE(380000000, 0x57, 1, 1),
> +       PLL_35XX_RATE(370000000, 0xb1, 4, 1),
> +       PLL_35XX_RATE(360000000, 0x70, 2, 1),
> +       PLL_35XX_RATE(350000000, 0xa7, 4, 1),
> +       PLL_35XX_RATE(340000000, 0x4d, 1, 1),
> +       PLL_35XX_RATE(330000000, 0x66, 2, 1),
> +       PLL_35XX_RATE(320000000, 0x98, 4, 1),
> +       PLL_35XX_RATE(310000000, 0x93, 4, 1),
> +       PLL_35XX_RATE(300000000, 0x75, 3, 1),
> +       PLL_35XX_RATE(240000000, 0x70, 1, 2),
> +       PLL_35XX_RATE(230000000, 0x6b, 1, 2),
> +       PLL_35XX_RATE(220000000, 0x66, 1, 2),
> +       PLL_35XX_RATE(210000000, 0x84, 2, 2),
> +       PLL_35XX_RATE(200000000, 0x5c, 1, 2),
> +       PLL_35XX_RATE(190000000, 0x57, 1, 2),
> +       PLL_35XX_RATE(180000000, 0x70, 2, 2),
> +       PLL_35XX_RATE(170000000, 0x4d, 1, 2),
> +       PLL_35XX_RATE(160000000, 0x98, 4, 2),
> +       PLL_35XX_RATE(150000000, 0x75, 3, 2),
> +       PLL_35XX_RATE(120000000, 0x70, 1, 3),
> +       PLL_35XX_RATE(110000000, 0x66, 1, 3),
> +       PLL_35XX_RATE(100000000, 0x5c, 1, 3),
> +       PLL_35XX_RATE(90000000, 0x70, 2, 3),
> +       PLL_35XX_RATE(80000000, 0x98, 4, 3),
> +       PLL_35XX_RATE(75000000, 0x75, 3, 3),
> +};
> +
> +static struct samsung_pll_clock s3c244x_common_plls[] __initdata = {
> +       [mpll] = PLL(pll_s3c2440_mpll, MPLL, "mpll", "xti",
> +                                               LOCKTIME, MPLLCON, NULL),
> +       [upll] = PLL(pll_s3c2410_upll, UPLL, "upll", "xti",
> +                                               LOCKTIME, UPLLCON, NULL),
> +};
> +
> +PNAME(hclk_p) = { "fclk", "div_hclk_2", "div_hclk_4", "div_hclk_3" };
> +PNAME(armclk_p) = { "fclk", "hclk" };
> +
> +struct samsung_mux_clock s3c244x_common_muxes[] __initdata = {
> +       MUX(HCLK, "hclk", hclk_p, CLKDIVN, 1, 2),
> +       MUX(ARMCLK, "armclk", armclk_p, CAMDIVN, 12, 1),
> +};
> +
> +struct samsung_fixed_factor_clock s3c244x_common_ffactor[] __initdata = {
> +       FFACTOR(0, "div_hclk_2", "fclk", 1, 2, 0),
> +       FFACTOR(0, "ff_cam", "div_cam", 2, 1, CLK_SET_RATE_PARENT),
> +};
> +
> +static struct clk_div_table div_hclk_4_d[] = {
> +       { .val = 0, .div = 4 },
> +       { .val = 1, .div = 8 },
> +};
> +
> +static struct clk_div_table div_hclk_3_d[] = {
> +       { .val = 0, .div = 3 },
> +       { .val = 1, .div = 6 },
> +};
> +
> +struct samsung_div_clock s3c244x_common_dividers[] __initdata = {
> +       DIV(UCLK, "uclk", "upll", CLKDIVN, 3, 1),
> +       DIV(0, "div_hclk", "fclk", CLKDIVN, 1, 1),
> +       DIV_T(0, "div_hclk_4", "fclk", CAMDIVN, 9, 1, div_hclk_4_d),
> +       DIV_T(0, "div_hclk_3", "fclk", CAMDIVN, 8, 1, div_hclk_3_d),
> +       DIV(0, "div_cam", "upll", CAMDIVN, 0, 3),
> +};
> +
> +struct samsung_gate_clock s3c244x_common_gates[] __initdata = {
> +       GATE(HCLK_CAM, "cam", "hclk", CLKCON, 19, 0, 0),
> +};
> +
> +struct samsung_clock_alias s3c244x_common_aliases[] __initdata = {
> +       ALIAS(PCLK_UART0, "s3c2440-uart.0", "uart"),
> +       ALIAS(PCLK_UART1, "s3c2440-uart.1", "uart"),
> +       ALIAS(PCLK_UART2, "s3c2440-uart.2", "uart"),
> +       ALIAS(PCLK_UART0, "s3c2440-uart.0", "clk_uart_baud2"),
> +       ALIAS(PCLK_UART1, "s3c2440-uart.1", "clk_uart_baud2"),
> +       ALIAS(PCLK_UART2, "s3c2440-uart.2", "clk_uart_baud2"),
> +       ALIAS(HCLK_CAM, NULL, "camif"),
> +       ALIAS(CAMIF, NULL, "camif-upll"),
> +};
> +
> +/* S3C2440 specific clocks */
> +
> +PNAME(s3c2440_camif_p) = { "upll", "ff_cam" };
> +
> +struct samsung_mux_clock s3c2440_muxes[] __initdata = {
> +       MUX(CAMIF, "camif", s3c2440_camif_p, CAMDIVN, 4, 1),
> +};
> +
> +struct samsung_gate_clock s3c2440_gates[] __initdata = {
> +       GATE(PCLK_AC97, "ac97", "pclk", CLKCON, 20, 0, 0),
> +};
> +
> +/* S3C2442 specific clocks */
> +
> +struct samsung_fixed_factor_clock s3c2442_ffactor[] __initdata = {
> +       FFACTOR(0, "upll_3", "upll", 1, 3, 0),
> +};
> +
> +PNAME(s3c2442_camif_p) = { "upll", "ff_cam", "upll", "upll_3" };
> +
> +struct samsung_mux_clock s3c2442_muxes[] __initdata = {
> +       MUX(CAMIF, "camif", s3c2442_camif_p, CAMDIVN, 4, 2),
> +};
> +
> +/*
> + * fixed rate clocks generated outside the soc
> + * Only necessary until the devicetree-move is complete
> + */
> +struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata = {
> +       FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0),
> +};
> +
> +static void __init s3c2410_common_clk_register_fixed_ext(unsigned long xti_f)
> +{
> +       struct samsung_clock_alias xti_alias = ALIAS(XTI, NULL, "xtal");
> +
> +       s3c2410_common_frate_clks[0].fixed_rate = xti_f;
> +       samsung_clk_register_fixed_rate(s3c2410_common_frate_clks,
> +                               ARRAY_SIZE(s3c2410_common_frate_clks));
> +
> +       samsung_clk_register_alias(&xti_alias, 1);
> +}
> +
> +void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
> +                                   int current_soc,
> +                                   void __iomem *reg_base)
> +{
> +       if (np) {
> +               reg_base = of_iomap(np, 0);
> +               if (!reg_base)
> +                       panic("%s: failed to map registers\n", __func__);
> +       }
> +
> +       samsung_clk_init(np, reg_base, NR_CLKS,
> +               s3c2410_clk_regs, ARRAY_SIZE(s3c2410_clk_regs), NULL, 0);
> +
> +       /* Register external clocks only in non-dt cases */
> +       if (!np)
> +               s3c2410_common_clk_register_fixed_ext(xti_f);
> +
> +       if (current_soc == 2410) {
> +               if (_get_rate("xti") == 12 * MHZ) {
> +                       s3c2410_plls[mpll].rate_table = pll_s3c2410_12mhz_tbl;
> +                       s3c2410_plls[upll].rate_table = pll_s3c2410_12mhz_tbl;
> +               }
> +
> +               /* Register PLLs. */
> +               samsung_clk_register_pll(s3c2410_plls,
> +                               ARRAY_SIZE(s3c2410_plls), reg_base);
> +
> +       } else { /* S3C2440, S3C2442 */
> +               if (_get_rate("xti") == 12 * MHZ) {
> +                       /*
> +                        * plls follow different calculation schemes, with the
> +                        * upll following the same scheme as the s3c2410 plls
> +                        */
> +                       s3c244x_common_plls[mpll].rate_table =
> +                                                       pll_s3c244x_12mhz_tbl;
> +                       s3c244x_common_plls[upll].rate_table =
> +                                                       pll_s3c2410_12mhz_tbl;
> +               }
> +
> +               /* Register PLLs. */
> +               samsung_clk_register_pll(s3c244x_common_plls,
> +                               ARRAY_SIZE(s3c244x_common_plls), reg_base);
> +       }
> +
> +       /* Register common internal clocks. */
> +       samsung_clk_register_mux(s3c2410_common_muxes,
> +                       ARRAY_SIZE(s3c2410_common_muxes));
> +       samsung_clk_register_div(s3c2410_common_dividers,
> +                       ARRAY_SIZE(s3c2410_common_dividers));
> +       samsung_clk_register_gate(s3c2410_common_gates,
> +               ARRAY_SIZE(s3c2410_common_gates));
> +
> +       if (current_soc == S3C2440 || current_soc == S3C2442) {
> +               samsung_clk_register_div(s3c244x_common_dividers,
> +                               ARRAY_SIZE(s3c244x_common_dividers));
> +               samsung_clk_register_gate(s3c244x_common_gates,
> +                               ARRAY_SIZE(s3c244x_common_gates));
> +               samsung_clk_register_mux(s3c244x_common_muxes,
> +                               ARRAY_SIZE(s3c244x_common_muxes));
> +               samsung_clk_register_fixed_factor(s3c244x_common_ffactor,
> +                               ARRAY_SIZE(s3c244x_common_ffactor));
> +       }
> +
> +       /* Register SoC-specific clocks. */
> +       switch (current_soc) {
> +       case S3C2410:
> +               samsung_clk_register_div(s3c2410_dividers,
> +                               ARRAY_SIZE(s3c2410_dividers));
> +               samsung_clk_register_fixed_factor(s3c2410_ffactor,
> +                               ARRAY_SIZE(s3c2410_ffactor));
> +               samsung_clk_register_alias(s3c2410_aliases,
> +                       ARRAY_SIZE(s3c2410_common_aliases));
> +               break;
> +       case S3C2440:
> +               samsung_clk_register_mux(s3c2440_muxes,
> +                               ARRAY_SIZE(s3c2440_muxes));
> +               samsung_clk_register_gate(s3c2440_gates,
> +                               ARRAY_SIZE(s3c2440_gates));
> +               break;
> +       case S3C2442:
> +               samsung_clk_register_mux(s3c2442_muxes,
> +                               ARRAY_SIZE(s3c2442_muxes));
> +               samsung_clk_register_fixed_factor(s3c2442_ffactor,
> +                               ARRAY_SIZE(s3c2442_ffactor));
> +               break;
> +       }
> +
> +       /*
> +        * Register common aliases at the end, as some of the aliased clocks
> +        * are SoC specific.
> +        */
> +       samsung_clk_register_alias(s3c2410_common_aliases,
> +               ARRAY_SIZE(s3c2410_common_aliases));
> +
> +       if (current_soc == S3C2440 || current_soc == S3C2442) {
> +               samsung_clk_register_alias(s3c244x_common_aliases,
> +                       ARRAY_SIZE(s3c244x_common_aliases));
> +       }
> +}
> +
> +static void __init s3c2410_clk_init(struct device_node *np)
> +{
> +       s3c2410_common_clk_init(np, 0, S3C2410, 0);
> +}
> +CLK_OF_DECLARE(s3c2410_clk, "samsung,s3c2410-clock", s3c2410_clk_init);
> +
> +static void __init s3c2440_clk_init(struct device_node *np)
> +{
> +       s3c2410_common_clk_init(np, 0, S3C2440, 0);
> +}
> +CLK_OF_DECLARE(s3c2440_clk, "samsung,s3c2440-clock", s3c2440_clk_init);
> +
> +static void __init s3c2442_clk_init(struct device_node *np)
> +{
> +       s3c2410_common_clk_init(np, 0, S3C2442, 0);
> +}
> +CLK_OF_DECLARE(s3c2442_clk, "samsung,s3c2442-clock", s3c2442_clk_init);
> diff --git a/include/dt-bindings/clock/samsung,s3c2410-clock.h b/include/dt-bindings/clock/samsung,s3c2410-clock.h
> new file mode 100644
> index 0000000..66c278f
> --- /dev/null
> +++ b/include/dt-bindings/clock/samsung,s3c2410-clock.h
> @@ -0,0 +1,64 @@
> +/*
> + * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
> + *
> + * 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.
> + *
> + * Device Tree binding constants clock controllers of Samsung S3C2410 and later.
> + */
> +
> +#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C2410_CLOCK_H
> +#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C2410_CLOCK_H
> +
> +/*
> + * Let each exported clock get a unique index, which is used on DT-enabled
> + * platforms to lookup the clock from a clock specifier. These indices are
> + * therefore considered an ABI and so must not be changed. This implies
> + * that new clocks should be added either in free spaces between clock groups
> + * or at the end.
> + */
> +
> +/* Core clocks. */
> +
> +
> +#define MPLL                   1
> +#define UPLL                   2
> +#define FCLK                   3
> +#define HCLK                   4
> +#define PCLK                   5
> +#define UCLK                   6
> +#define ARMCLK                 7
> +
> +#define XTI                    8
> +
> +/* pclk-gates */
> +#define PCLK_UART0             16
> +#define PCLK_UART1             17
> +#define PCLK_UART2             18
> +#define PCLK_I2C               19
> +#define PCLK_SDI               20
> +#define PCLK_SPI               21
> +#define PCLK_ADC               22
> +#define PCLK_AC97              23
> +#define PCLK_I2S               24
> +#define PCLK_PWM               25
> +#define PCLK_RTC               26
> +#define PCLK_GPIO              27
> +
> +
> +/* hclk-gates */
> +#define HCLK_LCD               32
> +#define HCLK_USBH              33
> +#define HCLK_USBD              34
> +#define HCLK_NAND              35
> +#define HCLK_CAM               36
> +
> +
> +#define CAMIF                  40
> +
> +
> +/* Total number of clocks. */
> +#define NR_CLKS                        (CAMIF + 1)
> +
> +#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_S3C2443_CLOCK_H */
> -- 
> 1.7.10.4
> 

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

* Re: [PATCH 01/12] ARM: S3C24XX: cpufreq-utils: don't write raw values to MPLLCON when using ccf
  2013-12-13 12:57   ` Heiko Stübner
@ 2014-02-08 20:23     ` Tomasz Figa
  -1 siblings, 0 replies; 54+ messages in thread
From: Tomasz Figa @ 2014-02-08 20:23 UTC (permalink / raw)
  To: Heiko Stübner, Kukjin Kim
  Cc: t.figa, mturquette, linux-arm-kernel, linux-samsung-soc

Hi Heiko,

On 13.12.2013 13:57, Heiko Stübner wrote:
> The s3c24xx cpufreq driver needs to change the mpll speed and was doing
> this by writing raw values from a translation table into the MPLLCON
> register.
>
> Change this to use a regular clk_set_rate call when using the common
> clock framework and only write the raw value in the samsung_clock case.
>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
>   arch/arm/mach-s3c24xx/cpufreq-utils.c |   13 +++++++++++++
>   1 file changed, 13 insertions(+)
>
> diff --git a/arch/arm/mach-s3c24xx/cpufreq-utils.c b/arch/arm/mach-s3c24xx/cpufreq-utils.c
> index 2a0aa56..680a031 100644
> --- a/arch/arm/mach-s3c24xx/cpufreq-utils.c
> +++ b/arch/arm/mach-s3c24xx/cpufreq-utils.c
> @@ -14,6 +14,7 @@
>   #include <linux/errno.h>
>   #include <linux/cpufreq.h>
>   #include <linux/io.h>
> +#include <linux/clk.h>
>
>   #include <mach/map.h>
>   #include <mach/regs-clock.h>
> @@ -60,5 +61,17 @@ void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
>    */
>   void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg)
>   {
> +#ifdef CONFIG_SAMSUNG_CLOCK
>   	__raw_writel(cfg->pll.driver_data, S3C2410_MPLLCON);
> +#endif
> +
> +#ifdef CONFIG_COMMON_CLK
> +	struct clk *mpll = clk_get(NULL, "mpll");
> +	if (IS_ERR(mpll))
> +		return;

Wouldn't it be more sensible to get the clock only once, at the time 
cpufreq is initialized? This would avoid going through the list of all 
clocks every CPU frequency change and be more semantically correct.

If there is no good place to put this clk_get() then maybe it could be 
simply called on first call to s3c2410_set_fvco() and the clock saved to 
a static variable.

Best regards,
Tomasz

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

* [PATCH 01/12] ARM: S3C24XX: cpufreq-utils: don't write raw values to MPLLCON when using ccf
@ 2014-02-08 20:23     ` Tomasz Figa
  0 siblings, 0 replies; 54+ messages in thread
From: Tomasz Figa @ 2014-02-08 20:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Heiko,

On 13.12.2013 13:57, Heiko St?bner wrote:
> The s3c24xx cpufreq driver needs to change the mpll speed and was doing
> this by writing raw values from a translation table into the MPLLCON
> register.
>
> Change this to use a regular clk_set_rate call when using the common
> clock framework and only write the raw value in the samsung_clock case.
>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
>   arch/arm/mach-s3c24xx/cpufreq-utils.c |   13 +++++++++++++
>   1 file changed, 13 insertions(+)
>
> diff --git a/arch/arm/mach-s3c24xx/cpufreq-utils.c b/arch/arm/mach-s3c24xx/cpufreq-utils.c
> index 2a0aa56..680a031 100644
> --- a/arch/arm/mach-s3c24xx/cpufreq-utils.c
> +++ b/arch/arm/mach-s3c24xx/cpufreq-utils.c
> @@ -14,6 +14,7 @@
>   #include <linux/errno.h>
>   #include <linux/cpufreq.h>
>   #include <linux/io.h>
> +#include <linux/clk.h>
>
>   #include <mach/map.h>
>   #include <mach/regs-clock.h>
> @@ -60,5 +61,17 @@ void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
>    */
>   void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg)
>   {
> +#ifdef CONFIG_SAMSUNG_CLOCK
>   	__raw_writel(cfg->pll.driver_data, S3C2410_MPLLCON);
> +#endif
> +
> +#ifdef CONFIG_COMMON_CLK
> +	struct clk *mpll = clk_get(NULL, "mpll");
> +	if (IS_ERR(mpll))
> +		return;

Wouldn't it be more sensible to get the clock only once, at the time 
cpufreq is initialized? This would avoid going through the list of all 
clocks every CPU frequency change and be more semantically correct.

If there is no good place to put this clk_get() then maybe it could be 
simply called on first call to s3c2410_set_fvco() and the clock saved to 
a static variable.

Best regards,
Tomasz

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

* Re: [PATCH 02/12] dt-bindings: document s3c24xx controller for external clock output
  2013-12-13 12:59   ` Heiko Stübner
@ 2014-02-09  1:54     ` Tomasz Figa
  -1 siblings, 0 replies; 54+ messages in thread
From: Tomasz Figa @ 2014-02-09  1:54 UTC (permalink / raw)
  To: Heiko Stübner, Kukjin Kim
  Cc: t.figa, mturquette, linux-arm-kernel, linux-samsung-soc,
	Rob Herring, Pawel Moll, Mark Rutland, Stephen Warren,
	Ian Campbell, devicetree

Hi Heiko,

On 13.12.2013 13:59, Heiko Stübner wrote:
> The clock settings are distributed over a regular register and parts
> of the misccr register.
>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
>   .../bindings/clock/samsung,s3c2410-dclk.txt        |   53 ++++++++++++++++++++
>   1 file changed, 53 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
>
> diff --git a/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt b/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
> new file mode 100644
> index 0000000..0a1f7b1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
> @@ -0,0 +1,53 @@
> +* Samsung S3C24XX External Clock Output Controller
> +
> +The S3C24XX series can generate clock signals on two clock output pads.
> +The clock binding described here is applicable to all SoCs in
> +the s3c24x family.
> +
> +Required Properties:
> +
> +- compatible: should be one of the following.
> +  - "samsung,s3c2410-dclk" - controller in S3C2410 SoCs.
> +  - "samsung,s3c2412-dclk" - controller in S3C2412 SoCs.
> +  - "samsung,s3c2440-dclk" - controller in S3C2440 and S3C2442 SoCs.
> +  - "samsung,s3c2443-dclk" - controller in S3C2443 and later SoCs.
> +- reg: physical base address of the controller and length of memory mapped
> +  region.
> +- #clock-cells: should be 1.
> +- samsung,misccr: phandle to the syscon managing the misccr register, which
> +  holds configuration settings for different soc-components (clocks, usb, ...).

Hmm, looking at the datasheet, DCLK and CLKOUT registers seem to be part 
of the pin controller. I wonder if there is really a need for different 
driver and device node to handle them.

Could this be simply made a part of the s3c24xx pinctrl driver, 
extending it to register also a clock provider under the same DT node?

Best regards,
Tomasz

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

* [PATCH 02/12] dt-bindings: document s3c24xx controller for external clock output
@ 2014-02-09  1:54     ` Tomasz Figa
  0 siblings, 0 replies; 54+ messages in thread
From: Tomasz Figa @ 2014-02-09  1:54 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Heiko,

On 13.12.2013 13:59, Heiko St?bner wrote:
> The clock settings are distributed over a regular register and parts
> of the misccr register.
>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
>   .../bindings/clock/samsung,s3c2410-dclk.txt        |   53 ++++++++++++++++++++
>   1 file changed, 53 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
>
> diff --git a/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt b/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
> new file mode 100644
> index 0000000..0a1f7b1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
> @@ -0,0 +1,53 @@
> +* Samsung S3C24XX External Clock Output Controller
> +
> +The S3C24XX series can generate clock signals on two clock output pads.
> +The clock binding described here is applicable to all SoCs in
> +the s3c24x family.
> +
> +Required Properties:
> +
> +- compatible: should be one of the following.
> +  - "samsung,s3c2410-dclk" - controller in S3C2410 SoCs.
> +  - "samsung,s3c2412-dclk" - controller in S3C2412 SoCs.
> +  - "samsung,s3c2440-dclk" - controller in S3C2440 and S3C2442 SoCs.
> +  - "samsung,s3c2443-dclk" - controller in S3C2443 and later SoCs.
> +- reg: physical base address of the controller and length of memory mapped
> +  region.
> +- #clock-cells: should be 1.
> +- samsung,misccr: phandle to the syscon managing the misccr register, which
> +  holds configuration settings for different soc-components (clocks, usb, ...).

Hmm, looking at the datasheet, DCLK and CLKOUT registers seem to be part 
of the pin controller. I wonder if there is really a need for different 
driver and device node to handle them.

Could this be simply made a part of the s3c24xx pinctrl driver, 
extending it to register also a clock provider under the same DT node?

Best regards,
Tomasz

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

* Re: [PATCH 03/12] clk: samsung: add clock driver for external clock outputs
  2013-12-13 12:59   ` Heiko Stübner
@ 2014-02-09  2:25     ` Tomasz Figa
  -1 siblings, 0 replies; 54+ messages in thread
From: Tomasz Figa @ 2014-02-09  2:25 UTC (permalink / raw)
  To: Heiko Stübner, Kukjin Kim
  Cc: t.figa, mturquette, linux-arm-kernel, linux-samsung-soc

Hi Heiko,

On 13.12.2013 13:59, Heiko Stübner wrote:
> This adds a driver for controlling the external clock outputs of
> s3c24xx architectures including the dclk muxes and dividers.
>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
>   drivers/clk/samsung/Makefile                     |    1 +
>   drivers/clk/samsung/clk-s3c2410-dclk.c           |  517 ++++++++++++++++++++++
>   include/dt-bindings/clock/samsung,s3c2410-dclk.h |   28 ++
>   3 files changed, 546 insertions(+)
>   create mode 100644 drivers/clk/samsung/clk-s3c2410-dclk.c
>   create mode 100644 include/dt-bindings/clock/samsung,s3c2410-dclk.h
>
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> index 4c892c6..568683c 100644
> --- a/drivers/clk/samsung/Makefile
> +++ b/drivers/clk/samsung/Makefile
> @@ -8,5 +8,6 @@ obj-$(CONFIG_SOC_EXYNOS5250)	+= clk-exynos5250.o
>   obj-$(CONFIG_SOC_EXYNOS5420)	+= clk-exynos5420.o
>   obj-$(CONFIG_SOC_EXYNOS5440)	+= clk-exynos5440.o
>   obj-$(CONFIG_ARCH_EXYNOS)	+= clk-exynos-audss.o
> +obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
>   obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
>   obj-$(CONFIG_ARCH_S3C64XX)	+= clk-s3c64xx.o
> diff --git a/drivers/clk/samsung/clk-s3c2410-dclk.c b/drivers/clk/samsung/clk-s3c2410-dclk.c
> new file mode 100644
> index 0000000..de10e5c
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-s3c2410-dclk.c
> @@ -0,0 +1,517 @@
> +/*
> + * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * Common Clock Framework support for s3c24xx external clock output.
> + */
> +
> +#include <linux/platform_device.h>
> +#include <linux/module.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/clk-provider.h>
> +#include <linux/regmap.h>
> +#include <linux/of.h>
> +#include <dt-bindings/clock/samsung,s3c2410-dclk.h>
> +#include "clk.h"
> +
> +/* legacy access to misccr, until dt conversion is finished */
> +#include <mach/hardware.h>
> +#include <mach/regs-gpio.h>
> +
> +enum supported_socs {
> +	S3C2410,
> +	S3C2412,
> +	S3C2440,
> +	S3C2443,
> +};
> +
> +struct s3c24xx_dclk_drv_data {
> +	int cpu_type;
> +};
> +
> +/*
> + * Clock for output-parent selection in misccr
> + */
> +
> +struct s3c24xx_clkout {
> +	struct clk_hw		hw;
> +	struct regmap		*misccr;
> +	u32			mask;
> +	u8			shift;
> +};
> +
> +#define to_s3c24xx_clkout(_hw) container_of(_hw, struct s3c24xx_clkout, hw)
> +
> +static u8 s3c24xx_clkout_get_parent(struct clk_hw *hw)
> +{
> +	struct s3c24xx_clkout *clkout = to_s3c24xx_clkout(hw);
> +	int num_parents = __clk_get_num_parents(hw->clk);
> +	u32 val;
> +	int ret = 0;
> +
> +	if (clkout->misccr)
> +		ret = regmap_read(clkout->misccr, 0, &val);
> +	else
> +		val = readl_relaxed(S3C24XX_MISCCR) >> clkout->shift;

I wonder if this couldn't be simplified by always providing a regmap.

> +
> +	if (ret)
> +		return ret;
> +
> +	val >>= clkout->shift;
> +	val &= clkout->mask;
> +
> +	if (val >= num_parents)
> +		return -EINVAL;
> +
> +	return val;
> +}

[snip]

> +#define to_s3c24xx_dclk0(x) \
> +		container_of(x, struct s3c24xx_dclk, dclk0_div_change_nb)
> +
> +#define to_s3c24xx_dclk1(x) \
> +		container_of(x, struct s3c24xx_dclk, dclk1_div_change_nb)
> +
> +static const char dummy_nm[] __initconst = "dummy_name";

What's the advantage of having it defined this way instead of using 
"dummy_name" (or probably "reserved" or "none", as in Samsung clock 
drivers) directly in parent lists?

> +
> +PNAME(dclk_s3c2410_p) = { "pclk", "uclk" };
> +PNAME(clkout0_s3c2410_p) = { "mpll", "upll", "fclk", "hclk", "pclk",
> +			     "gate_dclk0" };
> +PNAME(clkout1_s3c2410_p) = { "mpll", "upll", "fclk", "hclk", "pclk",
> +			     "gate_dclk1" };
> +
> +PNAME(clkout0_s3c2412_p) = { "mpll", "upll", dummy_nm /* rtc clock output */,
> +			     "hclk", "pclk", "gate_dclk0" };

Hmm, this would suggest that instead of dummy_nm, a real name should be 
used here, even if such clock doesn't exist yet. CCF will handle this fine.

> +PNAME(clkout1_s3c2412_p) = { "xti", "upll", "fclk", "hclk", "pclk",
> +			     "gate_dclk1" };
> +
> +PNAME(clkout0_s3c2440_p) = { "xti", "upll", "fclk", "hclk", "pclk",
> +			     "gate_dclk0" };
> +PNAME(clkout1_s3c2440_p) = { "mpll", "upll", dummy_nm /* rtc clock output */,
> +			     "hclk", "pclk", "gate_dclk1" };

[snip]

> +static int s3c24xx_dclk_probe(struct platform_device *pdev)
> +{
> +	struct s3c24xx_dclk *s3c24xx_dclk;
> +	struct device_node *np = pdev->dev.of_node;
> +	struct regmap *misccr = NULL;
> +	struct resource *mem;
> +	struct clk **clk_table;
> +	const char **clkout0_parent_names, **clkout1_parent_names;
> +	u8 clkout0_num_parents, clkout1_num_parents;
> +	int current_soc, ret, i;
> +
> +	s3c24xx_dclk = devm_kzalloc(&pdev->dev, sizeof(*s3c24xx_dclk),
> +				    GFP_KERNEL);
> +	if (!s3c24xx_dclk)
> +		return -ENOMEM;
> +
> +	s3c24xx_dclk->dev = &pdev->dev;
> +	platform_set_drvdata(pdev, s3c24xx_dclk);
> +	spin_lock_init(&s3c24xx_dclk->dclk_lock);
> +
> +	clk_table = devm_kzalloc(&pdev->dev,
> +				 sizeof(struct clk *) * DCLK_MAX_CLKS,
> +				 GFP_KERNEL);
> +	if (!clk_table)
> +		return -ENOMEM;
> +
> +	s3c24xx_dclk->clk_data.clks = clk_table;
> +	s3c24xx_dclk->clk_data.clk_num = DCLK_MAX_CLKS;
> +
> +	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	s3c24xx_dclk->base = devm_ioremap_resource(&pdev->dev, mem);
> +	if (IS_ERR(s3c24xx_dclk->base))
> +		return PTR_ERR(s3c24xx_dclk->base);
> +
> +	/* when run from devicetree, get the misccr through a syscon-regmap */
> +	if (np) {
> +		misccr = syscon_regmap_lookup_by_phandle(np, "samsung,misccr");
> +		if (IS_ERR(misccr)) {
> +			dev_err(&pdev->dev, "could not get misccr syscon, %ld\n",
> +				PTR_ERR(misccr));
> +			return PTR_ERR(misccr);
> +		}
> +	}
> +
> +	current_soc = s3c24xx_dclk_get_driver_data(pdev);
> +
> +	if (current_soc == S3C2443) {
> +		clk_table[MUX_DCLK0] = clk_register_mux(&pdev->dev,
> +					"mux_dclk0", dclk_s3c2443_p,
> +					ARRAY_SIZE(dclk_s3c2443_p), 0,
> +					s3c24xx_dclk->base, 1, 1, 0,
> +					&s3c24xx_dclk->dclk_lock);
> +		clk_table[MUX_DCLK1] = clk_register_mux(&pdev->dev,
> +					"mux_dclk1", dclk_s3c2443_p,
> +					ARRAY_SIZE(dclk_s3c2443_p), 0,
> +					s3c24xx_dclk->base, 17, 1, 0,
> +					&s3c24xx_dclk->dclk_lock);
> +	} else {
> +		clk_table[MUX_DCLK0] = clk_register_mux(&pdev->dev,
> +					"mux_dclk0", dclk_s3c2410_p,
> +					ARRAY_SIZE(dclk_s3c2410_p), 0,
> +					s3c24xx_dclk->base, 1, 1, 0,
> +					&s3c24xx_dclk->dclk_lock);
> +		clk_table[MUX_DCLK1] = clk_register_mux(&pdev->dev,
> +					"mux_dclk1", dclk_s3c2410_p,
> +					ARRAY_SIZE(dclk_s3c2410_p), 0,
> +					s3c24xx_dclk->base, 17, 1, 0,
> +					&s3c24xx_dclk->dclk_lock);
> +	}

What about using a variant struct instead? Match tables would simply 
contain pointers to respective structs and here the code would refer to 
appropriate fields in a struct returned by s3c24xx_dclk_get_driver_data().

> +
> +	clk_table[DIV_DCLK0] = clk_register_divider(&pdev->dev, "div_dclk0",
> +					"mux_dclk0", 0, s3c24xx_dclk->base,
> +					4, 4, 0, &s3c24xx_dclk->dclk_lock);
> +	clk_table[DIV_DCLK1] = clk_register_divider(&pdev->dev, "div_dclk1",
> +					"mux_dclk1", 0, s3c24xx_dclk->base,
> +					20, 4, 0, &s3c24xx_dclk->dclk_lock);
> +
> +	clk_table[GATE_DCLK0] = clk_register_gate(&pdev->dev, "gate_dclk0",
> +					"div_dclk0", CLK_SET_RATE_PARENT,
> +					s3c24xx_dclk->base, 0, 0,
> +					&s3c24xx_dclk->dclk_lock);
> +	clk_table[GATE_DCLK1] = clk_register_gate(&pdev->dev, "gate_dclk1",
> +					"div_dclk1", CLK_SET_RATE_PARENT,
> +					s3c24xx_dclk->base, 16, 0,
> +					&s3c24xx_dclk->dclk_lock);
> +
> +	switch (current_soc) {
> +	case S3C2410:
> +		clkout0_parent_names = clkout0_s3c2410_p;
> +		clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2410_p);
> +		clkout1_parent_names = clkout1_s3c2410_p;
> +		clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2410_p);
> +		break;
> +	case S3C2412:
> +		clkout0_parent_names = clkout0_s3c2412_p;
> +		clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2412_p);
> +		clkout1_parent_names = clkout1_s3c2412_p;
> +		clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2412_p);
> +		break;
> +	case S3C2440:
> +		clkout0_parent_names = clkout0_s3c2440_p;
> +		clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2440_p);
> +		clkout1_parent_names = clkout1_s3c2440_p;
> +		clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2440_p);
> +		break;
> +	case S3C2443:
> +		clkout0_parent_names = clkout0_s3c2443_p;
> +		clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2443_p);
> +		clkout1_parent_names = clkout1_s3c2443_p;
> +		clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2443_p);
> +		break;
> +	default:
> +		dev_err(&pdev->dev, "unsupported soc %d\n", current_soc);
> +		ret = -EINVAL;
> +		goto err_clk_register;
> +	}

Ditto.

> +
> +	clk_table[MUX_CLKOUT0] = s3c24xx_register_clkout(&pdev->dev,
> +				"clkout0", clkout0_parent_names,
> +				clkout0_num_parents, misccr, 4, 7);
> +	clk_table[MUX_CLKOUT1] = s3c24xx_register_clkout(&pdev->dev, "clkout1",
> +				clkout1_parent_names,
> +				clkout1_num_parents, misccr, 8, 7);
> +
> +	for (i = 0; i < DCLK_MAX_CLKS; i++)
> +		if (IS_ERR(clk_table[i])) {
> +			dev_err(&pdev->dev, "clock %d failed to register\n", i);
> +			ret = PTR_ERR(clk_table[i]);
> +			goto err_clk_register;
> +		}
> +
> +	ret = clk_register_clkdev(clk_table[MUX_DCLK0], "dclk0", NULL);
> +	ret |= clk_register_clkdev(clk_table[MUX_DCLK1], "dclk1", NULL);
> +	ret |= clk_register_clkdev(clk_table[MUX_CLKOUT0], "clkout0", NULL);
> +	ret |= clk_register_clkdev(clk_table[MUX_CLKOUT1], "clkout1", NULL);

Hmm, won't it break the error value if two calls return different error 
codes?

I guess that

if (!ret)
	ret = ...
if (!ret)
	ret = ...

construct would be more appropriate here, if you don't want error 
message per call.


> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to register aliases\n");
> +		goto err_clk_register;
> +	}
> +
> +	s3c24xx_dclk->dclk0_div_change_nb.notifier_call =
> +						s3c24xx_dclk0_div_notify;
> +	s3c24xx_dclk->dclk0_div_change_nb.next = NULL;

Do you need to set this field to NULL explicitly?

Best regards,
Tomasz

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

* [PATCH 03/12] clk: samsung: add clock driver for external clock outputs
@ 2014-02-09  2:25     ` Tomasz Figa
  0 siblings, 0 replies; 54+ messages in thread
From: Tomasz Figa @ 2014-02-09  2:25 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Heiko,

On 13.12.2013 13:59, Heiko St?bner wrote:
> This adds a driver for controlling the external clock outputs of
> s3c24xx architectures including the dclk muxes and dividers.
>
> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> ---
>   drivers/clk/samsung/Makefile                     |    1 +
>   drivers/clk/samsung/clk-s3c2410-dclk.c           |  517 ++++++++++++++++++++++
>   include/dt-bindings/clock/samsung,s3c2410-dclk.h |   28 ++
>   3 files changed, 546 insertions(+)
>   create mode 100644 drivers/clk/samsung/clk-s3c2410-dclk.c
>   create mode 100644 include/dt-bindings/clock/samsung,s3c2410-dclk.h
>
> diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile
> index 4c892c6..568683c 100644
> --- a/drivers/clk/samsung/Makefile
> +++ b/drivers/clk/samsung/Makefile
> @@ -8,5 +8,6 @@ obj-$(CONFIG_SOC_EXYNOS5250)	+= clk-exynos5250.o
>   obj-$(CONFIG_SOC_EXYNOS5420)	+= clk-exynos5420.o
>   obj-$(CONFIG_SOC_EXYNOS5440)	+= clk-exynos5440.o
>   obj-$(CONFIG_ARCH_EXYNOS)	+= clk-exynos-audss.o
> +obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
>   obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
>   obj-$(CONFIG_ARCH_S3C64XX)	+= clk-s3c64xx.o
> diff --git a/drivers/clk/samsung/clk-s3c2410-dclk.c b/drivers/clk/samsung/clk-s3c2410-dclk.c
> new file mode 100644
> index 0000000..de10e5c
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-s3c2410-dclk.c
> @@ -0,0 +1,517 @@
> +/*
> + * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * Common Clock Framework support for s3c24xx external clock output.
> + */
> +
> +#include <linux/platform_device.h>
> +#include <linux/module.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/clk-provider.h>
> +#include <linux/regmap.h>
> +#include <linux/of.h>
> +#include <dt-bindings/clock/samsung,s3c2410-dclk.h>
> +#include "clk.h"
> +
> +/* legacy access to misccr, until dt conversion is finished */
> +#include <mach/hardware.h>
> +#include <mach/regs-gpio.h>
> +
> +enum supported_socs {
> +	S3C2410,
> +	S3C2412,
> +	S3C2440,
> +	S3C2443,
> +};
> +
> +struct s3c24xx_dclk_drv_data {
> +	int cpu_type;
> +};
> +
> +/*
> + * Clock for output-parent selection in misccr
> + */
> +
> +struct s3c24xx_clkout {
> +	struct clk_hw		hw;
> +	struct regmap		*misccr;
> +	u32			mask;
> +	u8			shift;
> +};
> +
> +#define to_s3c24xx_clkout(_hw) container_of(_hw, struct s3c24xx_clkout, hw)
> +
> +static u8 s3c24xx_clkout_get_parent(struct clk_hw *hw)
> +{
> +	struct s3c24xx_clkout *clkout = to_s3c24xx_clkout(hw);
> +	int num_parents = __clk_get_num_parents(hw->clk);
> +	u32 val;
> +	int ret = 0;
> +
> +	if (clkout->misccr)
> +		ret = regmap_read(clkout->misccr, 0, &val);
> +	else
> +		val = readl_relaxed(S3C24XX_MISCCR) >> clkout->shift;

I wonder if this couldn't be simplified by always providing a regmap.

> +
> +	if (ret)
> +		return ret;
> +
> +	val >>= clkout->shift;
> +	val &= clkout->mask;
> +
> +	if (val >= num_parents)
> +		return -EINVAL;
> +
> +	return val;
> +}

[snip]

> +#define to_s3c24xx_dclk0(x) \
> +		container_of(x, struct s3c24xx_dclk, dclk0_div_change_nb)
> +
> +#define to_s3c24xx_dclk1(x) \
> +		container_of(x, struct s3c24xx_dclk, dclk1_div_change_nb)
> +
> +static const char dummy_nm[] __initconst = "dummy_name";

What's the advantage of having it defined this way instead of using 
"dummy_name" (or probably "reserved" or "none", as in Samsung clock 
drivers) directly in parent lists?

> +
> +PNAME(dclk_s3c2410_p) = { "pclk", "uclk" };
> +PNAME(clkout0_s3c2410_p) = { "mpll", "upll", "fclk", "hclk", "pclk",
> +			     "gate_dclk0" };
> +PNAME(clkout1_s3c2410_p) = { "mpll", "upll", "fclk", "hclk", "pclk",
> +			     "gate_dclk1" };
> +
> +PNAME(clkout0_s3c2412_p) = { "mpll", "upll", dummy_nm /* rtc clock output */,
> +			     "hclk", "pclk", "gate_dclk0" };

Hmm, this would suggest that instead of dummy_nm, a real name should be 
used here, even if such clock doesn't exist yet. CCF will handle this fine.

> +PNAME(clkout1_s3c2412_p) = { "xti", "upll", "fclk", "hclk", "pclk",
> +			     "gate_dclk1" };
> +
> +PNAME(clkout0_s3c2440_p) = { "xti", "upll", "fclk", "hclk", "pclk",
> +			     "gate_dclk0" };
> +PNAME(clkout1_s3c2440_p) = { "mpll", "upll", dummy_nm /* rtc clock output */,
> +			     "hclk", "pclk", "gate_dclk1" };

[snip]

> +static int s3c24xx_dclk_probe(struct platform_device *pdev)
> +{
> +	struct s3c24xx_dclk *s3c24xx_dclk;
> +	struct device_node *np = pdev->dev.of_node;
> +	struct regmap *misccr = NULL;
> +	struct resource *mem;
> +	struct clk **clk_table;
> +	const char **clkout0_parent_names, **clkout1_parent_names;
> +	u8 clkout0_num_parents, clkout1_num_parents;
> +	int current_soc, ret, i;
> +
> +	s3c24xx_dclk = devm_kzalloc(&pdev->dev, sizeof(*s3c24xx_dclk),
> +				    GFP_KERNEL);
> +	if (!s3c24xx_dclk)
> +		return -ENOMEM;
> +
> +	s3c24xx_dclk->dev = &pdev->dev;
> +	platform_set_drvdata(pdev, s3c24xx_dclk);
> +	spin_lock_init(&s3c24xx_dclk->dclk_lock);
> +
> +	clk_table = devm_kzalloc(&pdev->dev,
> +				 sizeof(struct clk *) * DCLK_MAX_CLKS,
> +				 GFP_KERNEL);
> +	if (!clk_table)
> +		return -ENOMEM;
> +
> +	s3c24xx_dclk->clk_data.clks = clk_table;
> +	s3c24xx_dclk->clk_data.clk_num = DCLK_MAX_CLKS;
> +
> +	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	s3c24xx_dclk->base = devm_ioremap_resource(&pdev->dev, mem);
> +	if (IS_ERR(s3c24xx_dclk->base))
> +		return PTR_ERR(s3c24xx_dclk->base);
> +
> +	/* when run from devicetree, get the misccr through a syscon-regmap */
> +	if (np) {
> +		misccr = syscon_regmap_lookup_by_phandle(np, "samsung,misccr");
> +		if (IS_ERR(misccr)) {
> +			dev_err(&pdev->dev, "could not get misccr syscon, %ld\n",
> +				PTR_ERR(misccr));
> +			return PTR_ERR(misccr);
> +		}
> +	}
> +
> +	current_soc = s3c24xx_dclk_get_driver_data(pdev);
> +
> +	if (current_soc == S3C2443) {
> +		clk_table[MUX_DCLK0] = clk_register_mux(&pdev->dev,
> +					"mux_dclk0", dclk_s3c2443_p,
> +					ARRAY_SIZE(dclk_s3c2443_p), 0,
> +					s3c24xx_dclk->base, 1, 1, 0,
> +					&s3c24xx_dclk->dclk_lock);
> +		clk_table[MUX_DCLK1] = clk_register_mux(&pdev->dev,
> +					"mux_dclk1", dclk_s3c2443_p,
> +					ARRAY_SIZE(dclk_s3c2443_p), 0,
> +					s3c24xx_dclk->base, 17, 1, 0,
> +					&s3c24xx_dclk->dclk_lock);
> +	} else {
> +		clk_table[MUX_DCLK0] = clk_register_mux(&pdev->dev,
> +					"mux_dclk0", dclk_s3c2410_p,
> +					ARRAY_SIZE(dclk_s3c2410_p), 0,
> +					s3c24xx_dclk->base, 1, 1, 0,
> +					&s3c24xx_dclk->dclk_lock);
> +		clk_table[MUX_DCLK1] = clk_register_mux(&pdev->dev,
> +					"mux_dclk1", dclk_s3c2410_p,
> +					ARRAY_SIZE(dclk_s3c2410_p), 0,
> +					s3c24xx_dclk->base, 17, 1, 0,
> +					&s3c24xx_dclk->dclk_lock);
> +	}

What about using a variant struct instead? Match tables would simply 
contain pointers to respective structs and here the code would refer to 
appropriate fields in a struct returned by s3c24xx_dclk_get_driver_data().

> +
> +	clk_table[DIV_DCLK0] = clk_register_divider(&pdev->dev, "div_dclk0",
> +					"mux_dclk0", 0, s3c24xx_dclk->base,
> +					4, 4, 0, &s3c24xx_dclk->dclk_lock);
> +	clk_table[DIV_DCLK1] = clk_register_divider(&pdev->dev, "div_dclk1",
> +					"mux_dclk1", 0, s3c24xx_dclk->base,
> +					20, 4, 0, &s3c24xx_dclk->dclk_lock);
> +
> +	clk_table[GATE_DCLK0] = clk_register_gate(&pdev->dev, "gate_dclk0",
> +					"div_dclk0", CLK_SET_RATE_PARENT,
> +					s3c24xx_dclk->base, 0, 0,
> +					&s3c24xx_dclk->dclk_lock);
> +	clk_table[GATE_DCLK1] = clk_register_gate(&pdev->dev, "gate_dclk1",
> +					"div_dclk1", CLK_SET_RATE_PARENT,
> +					s3c24xx_dclk->base, 16, 0,
> +					&s3c24xx_dclk->dclk_lock);
> +
> +	switch (current_soc) {
> +	case S3C2410:
> +		clkout0_parent_names = clkout0_s3c2410_p;
> +		clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2410_p);
> +		clkout1_parent_names = clkout1_s3c2410_p;
> +		clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2410_p);
> +		break;
> +	case S3C2412:
> +		clkout0_parent_names = clkout0_s3c2412_p;
> +		clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2412_p);
> +		clkout1_parent_names = clkout1_s3c2412_p;
> +		clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2412_p);
> +		break;
> +	case S3C2440:
> +		clkout0_parent_names = clkout0_s3c2440_p;
> +		clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2440_p);
> +		clkout1_parent_names = clkout1_s3c2440_p;
> +		clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2440_p);
> +		break;
> +	case S3C2443:
> +		clkout0_parent_names = clkout0_s3c2443_p;
> +		clkout0_num_parents = ARRAY_SIZE(clkout0_s3c2443_p);
> +		clkout1_parent_names = clkout1_s3c2443_p;
> +		clkout1_num_parents = ARRAY_SIZE(clkout1_s3c2443_p);
> +		break;
> +	default:
> +		dev_err(&pdev->dev, "unsupported soc %d\n", current_soc);
> +		ret = -EINVAL;
> +		goto err_clk_register;
> +	}

Ditto.

> +
> +	clk_table[MUX_CLKOUT0] = s3c24xx_register_clkout(&pdev->dev,
> +				"clkout0", clkout0_parent_names,
> +				clkout0_num_parents, misccr, 4, 7);
> +	clk_table[MUX_CLKOUT1] = s3c24xx_register_clkout(&pdev->dev, "clkout1",
> +				clkout1_parent_names,
> +				clkout1_num_parents, misccr, 8, 7);
> +
> +	for (i = 0; i < DCLK_MAX_CLKS; i++)
> +		if (IS_ERR(clk_table[i])) {
> +			dev_err(&pdev->dev, "clock %d failed to register\n", i);
> +			ret = PTR_ERR(clk_table[i]);
> +			goto err_clk_register;
> +		}
> +
> +	ret = clk_register_clkdev(clk_table[MUX_DCLK0], "dclk0", NULL);
> +	ret |= clk_register_clkdev(clk_table[MUX_DCLK1], "dclk1", NULL);
> +	ret |= clk_register_clkdev(clk_table[MUX_CLKOUT0], "clkout0", NULL);
> +	ret |= clk_register_clkdev(clk_table[MUX_CLKOUT1], "clkout1", NULL);

Hmm, won't it break the error value if two calls return different error 
codes?

I guess that

if (!ret)
	ret = ...
if (!ret)
	ret = ...

construct would be more appropriate here, if you don't want error 
message per call.


> +	if (ret) {
> +		dev_err(&pdev->dev, "failed to register aliases\n");
> +		goto err_clk_register;
> +	}
> +
> +	s3c24xx_dclk->dclk0_div_change_nb.notifier_call =
> +						s3c24xx_dclk0_div_notify;
> +	s3c24xx_dclk->dclk0_div_change_nb.next = NULL;

Do you need to set this field to NULL explicitly?

Best regards,
Tomasz

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

* Re: [PATCH 08/12] clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442
  2013-12-13 13:01   ` Heiko Stübner
@ 2014-02-09 19:34     ` Tomasz Figa
  -1 siblings, 0 replies; 54+ messages in thread
From: Tomasz Figa @ 2014-02-09 19:34 UTC (permalink / raw)
  To: Heiko Stübner, Kukjin Kim
  Cc: t.figa, mturquette, linux-arm-kernel, linux-samsung-soc

Hi Heiko,

On 13.12.2013 14:01, Heiko Stübner wrote:
> This driver can handle the clock controllers of the socs mentioned above,
> as they share a common clock tree with only small differences.

[snip]

> diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c
> new file mode 100644
> index 0000000..8358cad
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-s3c2410.c

[snip]

> +static struct clk_div_table divslow_d[] = {
> +	{ .val = 0, .div = 1 },
> +	{ .val = 1, .div = 2 },
> +	{ .val = 2, .div = 4 },
> +	{ .val = 3, .div = 6 },
> +	{ .val = 4, .div = 8 },
> +	{ .val = 5, .div = 10 },
> +	{ .val = 6, .div = 12 },
> +	{ .val = 7, .div = 14 },
> +	{ .div = 0 },

nit: It might be just a matter of preference, but I'd say the more 
common pattern is to define the last entry as:

	{ /* sentinel */ },

It will be initialized to all-zeroes anyway, but the comment will tell 
its purpose.

> +};
> +
> +struct samsung_div_clock s3c2410_common_dividers[] __initdata = {
> +	DIV_T(0, "div_slow", "xti", CLKSLOW, 0, 3, divslow_d),
> +	DIV(PCLK, "pclk", "hclk", CLKDIVN, 0, 1),
> +};

[snip]

> +static struct samsung_pll_rate_table pll_s3c2410_12mhz_tbl[] __initdata = {
> +	/* sorted in descending order */
> +	/* 2410A extras */
> +	PLL_35XX_RATE(270000000, 127, 1, 1),
> +	PLL_35XX_RATE(268000000, 126, 1, 1),
> +	PLL_35XX_RATE(266000000, 125, 1, 1),
> +	PLL_35XX_RATE(226000000, 105, 1, 1),
> +	PLL_35XX_RATE(210000000, 132, 2, 1),
> +	/* 2410 common */
> +	PLL_35XX_RATE(203000000, 161, 3, 1),
> +	PLL_35XX_RATE(192000000, 88, 1, 1),
> +	PLL_35XX_RATE(186000000, 85, 1, 1),
> +	PLL_35XX_RATE(180000000, 82, 1, 1),
> +	PLL_35XX_RATE(170000000, 77, 1, 1),
> +	PLL_35XX_RATE(158000000, 71, 1, 1),
> +	PLL_35XX_RATE(152000000, 68, 1, 1),
> +	PLL_35XX_RATE(147000000, 90, 2, 1),
> +	PLL_35XX_RATE(135000000, 82, 2, 1),
> +	PLL_35XX_RATE(124000000, 116, 1, 2),
> +	PLL_35XX_RATE(118000000, 150, 2, 2),
> +	PLL_35XX_RATE(113000000, 105, 1, 2),
> +	PLL_35XX_RATE(101000000, 127, 2, 2),
> +	PLL_35XX_RATE(90000000, 112, 2, 2),
> +	PLL_35XX_RATE(85000000, 105, 2, 2),
> +	PLL_35XX_RATE(79000000, 71, 1, 2),
> +	PLL_35XX_RATE(68000000, 82, 2, 2),
> +	PLL_35XX_RATE(56000000, 142, 2, 3),
> +	PLL_35XX_RATE(48000000, 120, 2, 3),
> +	PLL_35XX_RATE(51000000, 161, 3, 3),
> +	PLL_35XX_RATE(45000000, 82, 1, 3),
> +	PLL_35XX_RATE(34000000, 82, 2, 3),
> +	{ },

nit: The same comment about the sentinel as above.

> +};
> +
> +static struct samsung_pll_clock s3c2410_plls[] __initdata = {
> +	[mpll] = PLL(pll_s3c2410_mpll, MPLL, "mpll", "xti",
> +						LOCKTIME, MPLLCON, NULL),
> +	[upll] = PLL(pll_s3c2410_upll, UPLL, "upll", "xti",
> +						LOCKTIME, UPLLCON, NULL),
> +};

[snip]

> +static struct samsung_pll_rate_table pll_s3c244x_12mhz_tbl[] __initdata = {
> +	/* sorted in descending order */
> +	PLL_35XX_RATE(400000000, 0x5c, 1, 1),
> +	PLL_35XX_RATE(390000000, 0x7a, 2, 1),
> +	PLL_35XX_RATE(380000000, 0x57, 1, 1),
> +	PLL_35XX_RATE(370000000, 0xb1, 4, 1),
> +	PLL_35XX_RATE(360000000, 0x70, 2, 1),
> +	PLL_35XX_RATE(350000000, 0xa7, 4, 1),
> +	PLL_35XX_RATE(340000000, 0x4d, 1, 1),
> +	PLL_35XX_RATE(330000000, 0x66, 2, 1),
> +	PLL_35XX_RATE(320000000, 0x98, 4, 1),
> +	PLL_35XX_RATE(310000000, 0x93, 4, 1),
> +	PLL_35XX_RATE(300000000, 0x75, 3, 1),
> +	PLL_35XX_RATE(240000000, 0x70, 1, 2),
> +	PLL_35XX_RATE(230000000, 0x6b, 1, 2),
> +	PLL_35XX_RATE(220000000, 0x66, 1, 2),
> +	PLL_35XX_RATE(210000000, 0x84, 2, 2),
> +	PLL_35XX_RATE(200000000, 0x5c, 1, 2),
> +	PLL_35XX_RATE(190000000, 0x57, 1, 2),
> +	PLL_35XX_RATE(180000000, 0x70, 2, 2),
> +	PLL_35XX_RATE(170000000, 0x4d, 1, 2),
> +	PLL_35XX_RATE(160000000, 0x98, 4, 2),
> +	PLL_35XX_RATE(150000000, 0x75, 3, 2),
> +	PLL_35XX_RATE(120000000, 0x70, 1, 3),
> +	PLL_35XX_RATE(110000000, 0x66, 1, 3),
> +	PLL_35XX_RATE(100000000, 0x5c, 1, 3),
> +	PLL_35XX_RATE(90000000, 0x70, 2, 3),
> +	PLL_35XX_RATE(80000000, 0x98, 4, 3),
> +	PLL_35XX_RATE(75000000, 0x75, 3, 3),

Hmm, don't you need a sentinel here?

> +};
> +
> +static struct samsung_pll_clock s3c244x_common_plls[] __initdata = {
> +	[mpll] = PLL(pll_s3c2440_mpll, MPLL, "mpll", "xti",
> +						LOCKTIME, MPLLCON, NULL),
> +	[upll] = PLL(pll_s3c2410_upll, UPLL, "upll", "xti",
> +						LOCKTIME, UPLLCON, NULL),
> +};
> +
> +PNAME(hclk_p) = { "fclk", "div_hclk_2", "div_hclk_4", "div_hclk_3" };
> +PNAME(armclk_p) = { "fclk", "hclk" };
> +
> +struct samsung_mux_clock s3c244x_common_muxes[] __initdata = {
> +	MUX(HCLK, "hclk", hclk_p, CLKDIVN, 1, 2),
> +	MUX(ARMCLK, "armclk", armclk_p, CAMDIVN, 12, 1),
> +};
> +
> +struct samsung_fixed_factor_clock s3c244x_common_ffactor[] __initdata = {
> +	FFACTOR(0, "div_hclk_2", "fclk", 1, 2, 0),
> +	FFACTOR(0, "ff_cam", "div_cam", 2, 1, CLK_SET_RATE_PARENT),
> +};
> +
> +static struct clk_div_table div_hclk_4_d[] = {
> +	{ .val = 0, .div = 4 },
> +	{ .val = 1, .div = 8 },

Missing sentinel?

> +};
> +
> +static struct clk_div_table div_hclk_3_d[] = {
> +	{ .val = 0, .div = 3 },
> +	{ .val = 1, .div = 6 },

Ditto.

> +};
> +
> +struct samsung_div_clock s3c244x_common_dividers[] __initdata = {
> +	DIV(UCLK, "uclk", "upll", CLKDIVN, 3, 1),
> +	DIV(0, "div_hclk", "fclk", CLKDIVN, 1, 1),
> +	DIV_T(0, "div_hclk_4", "fclk", CAMDIVN, 9, 1, div_hclk_4_d),
> +	DIV_T(0, "div_hclk_3", "fclk", CAMDIVN, 8, 1, div_hclk_3_d),
> +	DIV(0, "div_cam", "upll", CAMDIVN, 0, 3),
> +};

[snip]

> +/*
> + * fixed rate clocks generated outside the soc
> + * Only necessary until the devicetree-move is complete
> + */
> +struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata = {
> +	FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0),

Do you need to assign this clock an ID? When DT is used, it's defined as 
a separate clock provider using fixed clock bindings, so it is not 
provided by this driver.

> +};
> +
> +static void __init s3c2410_common_clk_register_fixed_ext(unsigned long xti_f)
> +{
> +	struct samsung_clock_alias xti_alias = ALIAS(XTI, NULL, "xtal");
> +
> +	s3c2410_common_frate_clks[0].fixed_rate = xti_f;
> +	samsung_clk_register_fixed_rate(s3c2410_common_frate_clks,
> +				ARRAY_SIZE(s3c2410_common_frate_clks));
> +
> +	samsung_clk_register_alias(&xti_alias, 1);
> +}

[snip]

> diff --git a/include/dt-bindings/clock/samsung,s3c2410-clock.h b/include/dt-bindings/clock/samsung,s3c2410-clock.h
> new file mode 100644
> index 0000000..66c278f
> --- /dev/null
> +++ b/include/dt-bindings/clock/samsung,s3c2410-clock.h

I know this is nitpiccking, but I'd say that the name of this file could 
be made a simple "s3c2410.h", as it's already located in "clock" 
directory and "s3c2410" is specific enough to not add "samsung" prefix.

At the time of writing the s3c64xx CCF driver I went for full compatible 
string as the file name, but at that time there was just a few DT 
binding headers available and so no widely used naming convention. Now 
looking at file names, other platforms seem to use just a simple name 
and we decided to do the same for Exynos as well, so I think s3c24xx 
should follow the same.

Best regards,
Tomasz

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

* [PATCH 08/12] clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442
@ 2014-02-09 19:34     ` Tomasz Figa
  0 siblings, 0 replies; 54+ messages in thread
From: Tomasz Figa @ 2014-02-09 19:34 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Heiko,

On 13.12.2013 14:01, Heiko St?bner wrote:
> This driver can handle the clock controllers of the socs mentioned above,
> as they share a common clock tree with only small differences.

[snip]

> diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c
> new file mode 100644
> index 0000000..8358cad
> --- /dev/null
> +++ b/drivers/clk/samsung/clk-s3c2410.c

[snip]

> +static struct clk_div_table divslow_d[] = {
> +	{ .val = 0, .div = 1 },
> +	{ .val = 1, .div = 2 },
> +	{ .val = 2, .div = 4 },
> +	{ .val = 3, .div = 6 },
> +	{ .val = 4, .div = 8 },
> +	{ .val = 5, .div = 10 },
> +	{ .val = 6, .div = 12 },
> +	{ .val = 7, .div = 14 },
> +	{ .div = 0 },

nit: It might be just a matter of preference, but I'd say the more 
common pattern is to define the last entry as:

	{ /* sentinel */ },

It will be initialized to all-zeroes anyway, but the comment will tell 
its purpose.

> +};
> +
> +struct samsung_div_clock s3c2410_common_dividers[] __initdata = {
> +	DIV_T(0, "div_slow", "xti", CLKSLOW, 0, 3, divslow_d),
> +	DIV(PCLK, "pclk", "hclk", CLKDIVN, 0, 1),
> +};

[snip]

> +static struct samsung_pll_rate_table pll_s3c2410_12mhz_tbl[] __initdata = {
> +	/* sorted in descending order */
> +	/* 2410A extras */
> +	PLL_35XX_RATE(270000000, 127, 1, 1),
> +	PLL_35XX_RATE(268000000, 126, 1, 1),
> +	PLL_35XX_RATE(266000000, 125, 1, 1),
> +	PLL_35XX_RATE(226000000, 105, 1, 1),
> +	PLL_35XX_RATE(210000000, 132, 2, 1),
> +	/* 2410 common */
> +	PLL_35XX_RATE(203000000, 161, 3, 1),
> +	PLL_35XX_RATE(192000000, 88, 1, 1),
> +	PLL_35XX_RATE(186000000, 85, 1, 1),
> +	PLL_35XX_RATE(180000000, 82, 1, 1),
> +	PLL_35XX_RATE(170000000, 77, 1, 1),
> +	PLL_35XX_RATE(158000000, 71, 1, 1),
> +	PLL_35XX_RATE(152000000, 68, 1, 1),
> +	PLL_35XX_RATE(147000000, 90, 2, 1),
> +	PLL_35XX_RATE(135000000, 82, 2, 1),
> +	PLL_35XX_RATE(124000000, 116, 1, 2),
> +	PLL_35XX_RATE(118000000, 150, 2, 2),
> +	PLL_35XX_RATE(113000000, 105, 1, 2),
> +	PLL_35XX_RATE(101000000, 127, 2, 2),
> +	PLL_35XX_RATE(90000000, 112, 2, 2),
> +	PLL_35XX_RATE(85000000, 105, 2, 2),
> +	PLL_35XX_RATE(79000000, 71, 1, 2),
> +	PLL_35XX_RATE(68000000, 82, 2, 2),
> +	PLL_35XX_RATE(56000000, 142, 2, 3),
> +	PLL_35XX_RATE(48000000, 120, 2, 3),
> +	PLL_35XX_RATE(51000000, 161, 3, 3),
> +	PLL_35XX_RATE(45000000, 82, 1, 3),
> +	PLL_35XX_RATE(34000000, 82, 2, 3),
> +	{ },

nit: The same comment about the sentinel as above.

> +};
> +
> +static struct samsung_pll_clock s3c2410_plls[] __initdata = {
> +	[mpll] = PLL(pll_s3c2410_mpll, MPLL, "mpll", "xti",
> +						LOCKTIME, MPLLCON, NULL),
> +	[upll] = PLL(pll_s3c2410_upll, UPLL, "upll", "xti",
> +						LOCKTIME, UPLLCON, NULL),
> +};

[snip]

> +static struct samsung_pll_rate_table pll_s3c244x_12mhz_tbl[] __initdata = {
> +	/* sorted in descending order */
> +	PLL_35XX_RATE(400000000, 0x5c, 1, 1),
> +	PLL_35XX_RATE(390000000, 0x7a, 2, 1),
> +	PLL_35XX_RATE(380000000, 0x57, 1, 1),
> +	PLL_35XX_RATE(370000000, 0xb1, 4, 1),
> +	PLL_35XX_RATE(360000000, 0x70, 2, 1),
> +	PLL_35XX_RATE(350000000, 0xa7, 4, 1),
> +	PLL_35XX_RATE(340000000, 0x4d, 1, 1),
> +	PLL_35XX_RATE(330000000, 0x66, 2, 1),
> +	PLL_35XX_RATE(320000000, 0x98, 4, 1),
> +	PLL_35XX_RATE(310000000, 0x93, 4, 1),
> +	PLL_35XX_RATE(300000000, 0x75, 3, 1),
> +	PLL_35XX_RATE(240000000, 0x70, 1, 2),
> +	PLL_35XX_RATE(230000000, 0x6b, 1, 2),
> +	PLL_35XX_RATE(220000000, 0x66, 1, 2),
> +	PLL_35XX_RATE(210000000, 0x84, 2, 2),
> +	PLL_35XX_RATE(200000000, 0x5c, 1, 2),
> +	PLL_35XX_RATE(190000000, 0x57, 1, 2),
> +	PLL_35XX_RATE(180000000, 0x70, 2, 2),
> +	PLL_35XX_RATE(170000000, 0x4d, 1, 2),
> +	PLL_35XX_RATE(160000000, 0x98, 4, 2),
> +	PLL_35XX_RATE(150000000, 0x75, 3, 2),
> +	PLL_35XX_RATE(120000000, 0x70, 1, 3),
> +	PLL_35XX_RATE(110000000, 0x66, 1, 3),
> +	PLL_35XX_RATE(100000000, 0x5c, 1, 3),
> +	PLL_35XX_RATE(90000000, 0x70, 2, 3),
> +	PLL_35XX_RATE(80000000, 0x98, 4, 3),
> +	PLL_35XX_RATE(75000000, 0x75, 3, 3),

Hmm, don't you need a sentinel here?

> +};
> +
> +static struct samsung_pll_clock s3c244x_common_plls[] __initdata = {
> +	[mpll] = PLL(pll_s3c2440_mpll, MPLL, "mpll", "xti",
> +						LOCKTIME, MPLLCON, NULL),
> +	[upll] = PLL(pll_s3c2410_upll, UPLL, "upll", "xti",
> +						LOCKTIME, UPLLCON, NULL),
> +};
> +
> +PNAME(hclk_p) = { "fclk", "div_hclk_2", "div_hclk_4", "div_hclk_3" };
> +PNAME(armclk_p) = { "fclk", "hclk" };
> +
> +struct samsung_mux_clock s3c244x_common_muxes[] __initdata = {
> +	MUX(HCLK, "hclk", hclk_p, CLKDIVN, 1, 2),
> +	MUX(ARMCLK, "armclk", armclk_p, CAMDIVN, 12, 1),
> +};
> +
> +struct samsung_fixed_factor_clock s3c244x_common_ffactor[] __initdata = {
> +	FFACTOR(0, "div_hclk_2", "fclk", 1, 2, 0),
> +	FFACTOR(0, "ff_cam", "div_cam", 2, 1, CLK_SET_RATE_PARENT),
> +};
> +
> +static struct clk_div_table div_hclk_4_d[] = {
> +	{ .val = 0, .div = 4 },
> +	{ .val = 1, .div = 8 },

Missing sentinel?

> +};
> +
> +static struct clk_div_table div_hclk_3_d[] = {
> +	{ .val = 0, .div = 3 },
> +	{ .val = 1, .div = 6 },

Ditto.

> +};
> +
> +struct samsung_div_clock s3c244x_common_dividers[] __initdata = {
> +	DIV(UCLK, "uclk", "upll", CLKDIVN, 3, 1),
> +	DIV(0, "div_hclk", "fclk", CLKDIVN, 1, 1),
> +	DIV_T(0, "div_hclk_4", "fclk", CAMDIVN, 9, 1, div_hclk_4_d),
> +	DIV_T(0, "div_hclk_3", "fclk", CAMDIVN, 8, 1, div_hclk_3_d),
> +	DIV(0, "div_cam", "upll", CAMDIVN, 0, 3),
> +};

[snip]

> +/*
> + * fixed rate clocks generated outside the soc
> + * Only necessary until the devicetree-move is complete
> + */
> +struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata = {
> +	FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0),

Do you need to assign this clock an ID? When DT is used, it's defined as 
a separate clock provider using fixed clock bindings, so it is not 
provided by this driver.

> +};
> +
> +static void __init s3c2410_common_clk_register_fixed_ext(unsigned long xti_f)
> +{
> +	struct samsung_clock_alias xti_alias = ALIAS(XTI, NULL, "xtal");
> +
> +	s3c2410_common_frate_clks[0].fixed_rate = xti_f;
> +	samsung_clk_register_fixed_rate(s3c2410_common_frate_clks,
> +				ARRAY_SIZE(s3c2410_common_frate_clks));
> +
> +	samsung_clk_register_alias(&xti_alias, 1);
> +}

[snip]

> diff --git a/include/dt-bindings/clock/samsung,s3c2410-clock.h b/include/dt-bindings/clock/samsung,s3c2410-clock.h
> new file mode 100644
> index 0000000..66c278f
> --- /dev/null
> +++ b/include/dt-bindings/clock/samsung,s3c2410-clock.h

I know this is nitpiccking, but I'd say that the name of this file could 
be made a simple "s3c2410.h", as it's already located in "clock" 
directory and "s3c2410" is specific enough to not add "samsung" prefix.

At the time of writing the s3c64xx CCF driver I went for full compatible 
string as the file name, but at that time there was just a few DT 
binding headers available and so no widely used naming convention. Now 
looking at file names, other platforms seem to use just a simple name 
and we decided to do the same for Exynos as well, so I think s3c24xx 
should follow the same.

Best regards,
Tomasz

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

* Re: [PATCH 00/12] ARM: S3C24XX: convert s3c2410, s3c2440 s3c2442 to common clock framework
  2013-12-13 12:56 ` Heiko Stübner
@ 2014-02-09 19:56   ` Tomasz Figa
  -1 siblings, 0 replies; 54+ messages in thread
From: Tomasz Figa @ 2014-02-09 19:56 UTC (permalink / raw)
  To: Heiko Stübner, Kukjin Kim, t.figa
  Cc: mturquette, linux-arm-kernel, linux-samsung-soc

Hi Heiko,

On 13.12.2013 13:56, Heiko Stübner wrote:
> This series converts the earliest s3c socs to use a clock driver based on the
> common clock framework instead of the old Samsung clock implementation.
>
> The only obstacle I found was the configuration of the clkout outputs in
> the different machines. As I lack hardware test and knowledge on what is
> expected there, somebody with interest in these machines will have to
> step up to implement the clkout configuration
> This can for example be done in the machine_init function after
> the platform-devices (and thus the dclk-device) are populated.
>
> This leaves the s3c2412 soc to be converted, as it has yet another different
> clock tree.
>
> Tested on an Openmoko Neo Freerunner (S3C2442), but of course more tests
> would be really helpful.
>
> Heiko Stuebner (12):
>    ARM: S3C24XX: cpufreq-utils: don't write raw values to MPLLCON when using ccf
>    dt-bindings: document s3c24xx controller for external clock output
>    clk: samsung: add clock driver for external clock outputs
>    ARM: S3C24XX: enable usage of common dclk if common clock framework is enabled
>    ARM: S3C24XX: only store clock registers when old clock code is active
>    clk: samsung: add plls used by the early s3c24xx cpus
>    dt-bindings: add documentation for s3c2410 clock controller
>    clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442
>    ARM: S3C24XX: add platform code for conversion to the common clock framework
>    ARM: S3C24XX: convert s3c2440 and s3c2442 to common clock framework
>    ARM: S3C24XX: convert s3c2410 to common clock framework
>    ARM: S3C24XX: remove legacy clock code
>
>   .../bindings/clock/samsung,s3c2410-clock.txt       |   50 ++
>   .../bindings/clock/samsung,s3c2410-dclk.txt        |   53 ++
>   arch/arm/mach-s3c24xx/Kconfig                      |   50 +-
>   arch/arm/mach-s3c24xx/Makefile                     |    6 +-
>   arch/arm/mach-s3c24xx/clock-dclk.c                 |  195 --------
>   arch/arm/mach-s3c24xx/clock-s3c2410.c              |  285 -----------
>   arch/arm/mach-s3c24xx/clock-s3c2440.c              |  217 --------
>   arch/arm/mach-s3c24xx/clock-s3c244x.c              |  141 ------
>   arch/arm/mach-s3c24xx/common.c                     |   45 +-
>   arch/arm/mach-s3c24xx/common.h                     |   11 +-
>   arch/arm/mach-s3c24xx/cpufreq-utils.c              |   13 +
>   arch/arm/mach-s3c24xx/include/mach/regs-clock.h    |   18 -
>   arch/arm/mach-s3c24xx/include/mach/regs-gpio.h     |    3 -
>   arch/arm/mach-s3c24xx/mach-amlm5900.c              |    9 +-
>   arch/arm/mach-s3c24xx/mach-anubis.c                |   15 +-
>   arch/arm/mach-s3c24xx/mach-at2440evb.c             |   10 +-
>   arch/arm/mach-s3c24xx/mach-bast.c                  |   15 +-
>   arch/arm/mach-s3c24xx/mach-gta02.c                 |    8 +-
>   arch/arm/mach-s3c24xx/mach-h1940.c                 |   10 +-
>   arch/arm/mach-s3c24xx/mach-mini2440.c              |   10 +-
>   arch/arm/mach-s3c24xx/mach-n30.c                   |   12 +-
>   arch/arm/mach-s3c24xx/mach-nexcoder.c              |   10 +-
>   arch/arm/mach-s3c24xx/mach-osiris.c                |   15 +-
>   arch/arm/mach-s3c24xx/mach-otom.c                  |   10 +-
>   arch/arm/mach-s3c24xx/mach-qt2410.c                |    9 +-
>   arch/arm/mach-s3c24xx/mach-rx1950.c                |   15 +-
>   arch/arm/mach-s3c24xx/mach-rx3715.c                |   10 +-
>   arch/arm/mach-s3c24xx/mach-smdk2410.c              |    9 +-
>   arch/arm/mach-s3c24xx/mach-smdk2440.c              |   10 +-
>   arch/arm/mach-s3c24xx/mach-tct_hammer.c            |    9 +-
>   arch/arm/mach-s3c24xx/mach-vr1000.c                |   15 +-
>   arch/arm/mach-s3c24xx/pm.c                         |   13 +-
>   arch/arm/mach-s3c24xx/s3c2410.c                    |   56 ---
>   arch/arm/mach-s3c24xx/s3c2442.c                    |  111 -----
>   arch/arm/mach-s3c24xx/s3c244x.c                    |   59 +--
>   drivers/clk/samsung/Makefile                       |    2 +
>   drivers/clk/samsung/clk-pll.c                      |  182 +++++++
>   drivers/clk/samsung/clk-pll.h                      |    3 +
>   drivers/clk/samsung/clk-s3c2410-dclk.c             |  517 ++++++++++++++++++++
>   drivers/clk/samsung/clk-s3c2410.c                  |  428 ++++++++++++++++
>   include/dt-bindings/clock/samsung,s3c2410-clock.h  |   64 +++
>   include/dt-bindings/clock/samsung,s3c2410-dclk.h   |   28 ++
>   42 files changed, 1575 insertions(+), 1176 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt
>   create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
>   delete mode 100644 arch/arm/mach-s3c24xx/clock-dclk.c
>   delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2410.c
>   delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2440.c
>   delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c244x.c
>   create mode 100644 drivers/clk/samsung/clk-s3c2410-dclk.c
>   create mode 100644 drivers/clk/samsung/clk-s3c2410.c
>   create mode 100644 include/dt-bindings/clock/samsung,s3c2410-clock.h
>   create mode 100644 include/dt-bindings/clock/samsung,s3c2410-dclk.h
>

For patches 4, 5, 9, 10, 11, 12:

Reviewed-by: Tomasz Figa <t.figa@samsung.com>

For patches 6, 7:

Acked-by: Tomasz Figa <t.figa@samsung.com>

Best regards,
Tomasz

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

* [PATCH 00/12] ARM: S3C24XX: convert s3c2410, s3c2440 s3c2442 to common clock framework
@ 2014-02-09 19:56   ` Tomasz Figa
  0 siblings, 0 replies; 54+ messages in thread
From: Tomasz Figa @ 2014-02-09 19:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Heiko,

On 13.12.2013 13:56, Heiko St?bner wrote:
> This series converts the earliest s3c socs to use a clock driver based on the
> common clock framework instead of the old Samsung clock implementation.
>
> The only obstacle I found was the configuration of the clkout outputs in
> the different machines. As I lack hardware test and knowledge on what is
> expected there, somebody with interest in these machines will have to
> step up to implement the clkout configuration
> This can for example be done in the machine_init function after
> the platform-devices (and thus the dclk-device) are populated.
>
> This leaves the s3c2412 soc to be converted, as it has yet another different
> clock tree.
>
> Tested on an Openmoko Neo Freerunner (S3C2442), but of course more tests
> would be really helpful.
>
> Heiko Stuebner (12):
>    ARM: S3C24XX: cpufreq-utils: don't write raw values to MPLLCON when using ccf
>    dt-bindings: document s3c24xx controller for external clock output
>    clk: samsung: add clock driver for external clock outputs
>    ARM: S3C24XX: enable usage of common dclk if common clock framework is enabled
>    ARM: S3C24XX: only store clock registers when old clock code is active
>    clk: samsung: add plls used by the early s3c24xx cpus
>    dt-bindings: add documentation for s3c2410 clock controller
>    clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442
>    ARM: S3C24XX: add platform code for conversion to the common clock framework
>    ARM: S3C24XX: convert s3c2440 and s3c2442 to common clock framework
>    ARM: S3C24XX: convert s3c2410 to common clock framework
>    ARM: S3C24XX: remove legacy clock code
>
>   .../bindings/clock/samsung,s3c2410-clock.txt       |   50 ++
>   .../bindings/clock/samsung,s3c2410-dclk.txt        |   53 ++
>   arch/arm/mach-s3c24xx/Kconfig                      |   50 +-
>   arch/arm/mach-s3c24xx/Makefile                     |    6 +-
>   arch/arm/mach-s3c24xx/clock-dclk.c                 |  195 --------
>   arch/arm/mach-s3c24xx/clock-s3c2410.c              |  285 -----------
>   arch/arm/mach-s3c24xx/clock-s3c2440.c              |  217 --------
>   arch/arm/mach-s3c24xx/clock-s3c244x.c              |  141 ------
>   arch/arm/mach-s3c24xx/common.c                     |   45 +-
>   arch/arm/mach-s3c24xx/common.h                     |   11 +-
>   arch/arm/mach-s3c24xx/cpufreq-utils.c              |   13 +
>   arch/arm/mach-s3c24xx/include/mach/regs-clock.h    |   18 -
>   arch/arm/mach-s3c24xx/include/mach/regs-gpio.h     |    3 -
>   arch/arm/mach-s3c24xx/mach-amlm5900.c              |    9 +-
>   arch/arm/mach-s3c24xx/mach-anubis.c                |   15 +-
>   arch/arm/mach-s3c24xx/mach-at2440evb.c             |   10 +-
>   arch/arm/mach-s3c24xx/mach-bast.c                  |   15 +-
>   arch/arm/mach-s3c24xx/mach-gta02.c                 |    8 +-
>   arch/arm/mach-s3c24xx/mach-h1940.c                 |   10 +-
>   arch/arm/mach-s3c24xx/mach-mini2440.c              |   10 +-
>   arch/arm/mach-s3c24xx/mach-n30.c                   |   12 +-
>   arch/arm/mach-s3c24xx/mach-nexcoder.c              |   10 +-
>   arch/arm/mach-s3c24xx/mach-osiris.c                |   15 +-
>   arch/arm/mach-s3c24xx/mach-otom.c                  |   10 +-
>   arch/arm/mach-s3c24xx/mach-qt2410.c                |    9 +-
>   arch/arm/mach-s3c24xx/mach-rx1950.c                |   15 +-
>   arch/arm/mach-s3c24xx/mach-rx3715.c                |   10 +-
>   arch/arm/mach-s3c24xx/mach-smdk2410.c              |    9 +-
>   arch/arm/mach-s3c24xx/mach-smdk2440.c              |   10 +-
>   arch/arm/mach-s3c24xx/mach-tct_hammer.c            |    9 +-
>   arch/arm/mach-s3c24xx/mach-vr1000.c                |   15 +-
>   arch/arm/mach-s3c24xx/pm.c                         |   13 +-
>   arch/arm/mach-s3c24xx/s3c2410.c                    |   56 ---
>   arch/arm/mach-s3c24xx/s3c2442.c                    |  111 -----
>   arch/arm/mach-s3c24xx/s3c244x.c                    |   59 +--
>   drivers/clk/samsung/Makefile                       |    2 +
>   drivers/clk/samsung/clk-pll.c                      |  182 +++++++
>   drivers/clk/samsung/clk-pll.h                      |    3 +
>   drivers/clk/samsung/clk-s3c2410-dclk.c             |  517 ++++++++++++++++++++
>   drivers/clk/samsung/clk-s3c2410.c                  |  428 ++++++++++++++++
>   include/dt-bindings/clock/samsung,s3c2410-clock.h  |   64 +++
>   include/dt-bindings/clock/samsung,s3c2410-dclk.h   |   28 ++
>   42 files changed, 1575 insertions(+), 1176 deletions(-)
>   create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt
>   create mode 100644 Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
>   delete mode 100644 arch/arm/mach-s3c24xx/clock-dclk.c
>   delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2410.c
>   delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2440.c
>   delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c244x.c
>   create mode 100644 drivers/clk/samsung/clk-s3c2410-dclk.c
>   create mode 100644 drivers/clk/samsung/clk-s3c2410.c
>   create mode 100644 include/dt-bindings/clock/samsung,s3c2410-clock.h
>   create mode 100644 include/dt-bindings/clock/samsung,s3c2410-dclk.h
>

For patches 4, 5, 9, 10, 11, 12:

Reviewed-by: Tomasz Figa <t.figa@samsung.com>

For patches 6, 7:

Acked-by: Tomasz Figa <t.figa@samsung.com>

Best regards,
Tomasz

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

* Re: [PATCH 00/12] ARM: S3C24XX: convert s3c2410, s3c2440 s3c2442 to common clock framework
  2014-02-09 19:56   ` Tomasz Figa
@ 2014-02-11  6:16     ` Kukjin Kim
  -1 siblings, 0 replies; 54+ messages in thread
From: Kukjin Kim @ 2014-02-11  6:16 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Heiko Stübner, Tomasz Figa, Mike Turquette,
	linux-arm-kernel, linux-samsung-soc

2014-02-10 1:26 GMT+05:30 Tomasz Figa <tomasz.figa@gmail.com>:
> Hi Heiko,
>
>
> On 13.12.2013 13:56, Heiko Stübner wrote:
>>
>> This series converts the earliest s3c socs to use a clock driver based on
>> the
>> common clock framework instead of the old Samsung clock implementation.
>>
>> The only obstacle I found was the configuration of the clkout outputs in
>> the different machines. As I lack hardware test and knowledge on what is
>> expected there, somebody with interest in these machines will have to
>> step up to implement the clkout configuration
>> This can for example be done in the machine_init function after
>> the platform-devices (and thus the dclk-device) are populated.
>>
>> This leaves the s3c2412 soc to be converted, as it has yet another
>> different
>> clock tree.
>>
>> Tested on an Openmoko Neo Freerunner (S3C2442), but of course more tests
>> would be really helpful.
>>
>> Heiko Stuebner (12):
>>    ARM: S3C24XX: cpufreq-utils: don't write raw values to MPLLCON when
>> using ccf
>>    dt-bindings: document s3c24xx controller for external clock output
>>    clk: samsung: add clock driver for external clock outputs
>>    ARM: S3C24XX: enable usage of common dclk if common clock framework is
>> enabled
>>    ARM: S3C24XX: only store clock registers when old clock code is active
>>    clk: samsung: add plls used by the early s3c24xx cpus
>>    dt-bindings: add documentation for s3c2410 clock controller
>>    clk: samsung: add clock controller driver for s3c2410, s3c2440 and
>> s3c2442
>>    ARM: S3C24XX: add platform code for conversion to the common clock
>> framework
>>    ARM: S3C24XX: convert s3c2440 and s3c2442 to common clock framework
>>    ARM: S3C24XX: convert s3c2410 to common clock framework
>>    ARM: S3C24XX: remove legacy clock code
>>
>>   .../bindings/clock/samsung,s3c2410-clock.txt       |   50 ++
>>   .../bindings/clock/samsung,s3c2410-dclk.txt        |   53 ++
>>   arch/arm/mach-s3c24xx/Kconfig                      |   50 +-
>>   arch/arm/mach-s3c24xx/Makefile                     |    6 +-
>>   arch/arm/mach-s3c24xx/clock-dclk.c                 |  195 --------
>>   arch/arm/mach-s3c24xx/clock-s3c2410.c              |  285 -----------
>>   arch/arm/mach-s3c24xx/clock-s3c2440.c              |  217 --------
>>   arch/arm/mach-s3c24xx/clock-s3c244x.c              |  141 ------
>>   arch/arm/mach-s3c24xx/common.c                     |   45 +-
>>   arch/arm/mach-s3c24xx/common.h                     |   11 +-
>>   arch/arm/mach-s3c24xx/cpufreq-utils.c              |   13 +
>>   arch/arm/mach-s3c24xx/include/mach/regs-clock.h    |   18 -
>>   arch/arm/mach-s3c24xx/include/mach/regs-gpio.h     |    3 -
>>   arch/arm/mach-s3c24xx/mach-amlm5900.c              |    9 +-
>>   arch/arm/mach-s3c24xx/mach-anubis.c                |   15 +-
>>   arch/arm/mach-s3c24xx/mach-at2440evb.c             |   10 +-
>>   arch/arm/mach-s3c24xx/mach-bast.c                  |   15 +-
>>   arch/arm/mach-s3c24xx/mach-gta02.c                 |    8 +-
>>   arch/arm/mach-s3c24xx/mach-h1940.c                 |   10 +-
>>   arch/arm/mach-s3c24xx/mach-mini2440.c              |   10 +-
>>   arch/arm/mach-s3c24xx/mach-n30.c                   |   12 +-
>>   arch/arm/mach-s3c24xx/mach-nexcoder.c              |   10 +-
>>   arch/arm/mach-s3c24xx/mach-osiris.c                |   15 +-
>>   arch/arm/mach-s3c24xx/mach-otom.c                  |   10 +-
>>   arch/arm/mach-s3c24xx/mach-qt2410.c                |    9 +-
>>   arch/arm/mach-s3c24xx/mach-rx1950.c                |   15 +-
>>   arch/arm/mach-s3c24xx/mach-rx3715.c                |   10 +-
>>   arch/arm/mach-s3c24xx/mach-smdk2410.c              |    9 +-
>>   arch/arm/mach-s3c24xx/mach-smdk2440.c              |   10 +-
>>   arch/arm/mach-s3c24xx/mach-tct_hammer.c            |    9 +-
>>   arch/arm/mach-s3c24xx/mach-vr1000.c                |   15 +-
>>   arch/arm/mach-s3c24xx/pm.c                         |   13 +-
>>   arch/arm/mach-s3c24xx/s3c2410.c                    |   56 ---
>>   arch/arm/mach-s3c24xx/s3c2442.c                    |  111 -----
>>   arch/arm/mach-s3c24xx/s3c244x.c                    |   59 +--
>>   drivers/clk/samsung/Makefile                       |    2 +
>>   drivers/clk/samsung/clk-pll.c                      |  182 +++++++
>>   drivers/clk/samsung/clk-pll.h                      |    3 +
>>   drivers/clk/samsung/clk-s3c2410-dclk.c             |  517
>> ++++++++++++++++++++
>>   drivers/clk/samsung/clk-s3c2410.c                  |  428
>> ++++++++++++++++
>>   include/dt-bindings/clock/samsung,s3c2410-clock.h  |   64 +++
>>   include/dt-bindings/clock/samsung,s3c2410-dclk.h   |   28 ++
>>   42 files changed, 1575 insertions(+), 1176 deletions(-)
>>   create mode 100644
>> Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt
>>   create mode 100644
>> Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
>>   delete mode 100644 arch/arm/mach-s3c24xx/clock-dclk.c
>>   delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2410.c
>>   delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2440.c
>>   delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c244x.c
>>   create mode 100644 drivers/clk/samsung/clk-s3c2410-dclk.c
>>   create mode 100644 drivers/clk/samsung/clk-s3c2410.c
>>   create mode 100644 include/dt-bindings/clock/samsung,s3c2410-clock.h
>>   create mode 100644 include/dt-bindings/clock/samsung,s3c2410-dclk.h
>>
>
> For patches 4, 5, 9, 10, 11, 12:
>
> Reviewed-by: Tomasz Figa <t.figa@samsung.com>
>
> For patches 6, 7:
>
> Acked-by: Tomasz Figa <t.figa@samsung.com>
>

Really nice series.
Heiko, thanks for your effort and Tomasz, thanks for your review and ack.

OK, I'll apply this whole series and this will be sent to arm-soc in this week.

Thanks,
Kukjin

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

* [PATCH 00/12] ARM: S3C24XX: convert s3c2410, s3c2440 s3c2442 to common clock framework
@ 2014-02-11  6:16     ` Kukjin Kim
  0 siblings, 0 replies; 54+ messages in thread
From: Kukjin Kim @ 2014-02-11  6:16 UTC (permalink / raw)
  To: linux-arm-kernel

2014-02-10 1:26 GMT+05:30 Tomasz Figa <tomasz.figa@gmail.com>:
> Hi Heiko,
>
>
> On 13.12.2013 13:56, Heiko St?bner wrote:
>>
>> This series converts the earliest s3c socs to use a clock driver based on
>> the
>> common clock framework instead of the old Samsung clock implementation.
>>
>> The only obstacle I found was the configuration of the clkout outputs in
>> the different machines. As I lack hardware test and knowledge on what is
>> expected there, somebody with interest in these machines will have to
>> step up to implement the clkout configuration
>> This can for example be done in the machine_init function after
>> the platform-devices (and thus the dclk-device) are populated.
>>
>> This leaves the s3c2412 soc to be converted, as it has yet another
>> different
>> clock tree.
>>
>> Tested on an Openmoko Neo Freerunner (S3C2442), but of course more tests
>> would be really helpful.
>>
>> Heiko Stuebner (12):
>>    ARM: S3C24XX: cpufreq-utils: don't write raw values to MPLLCON when
>> using ccf
>>    dt-bindings: document s3c24xx controller for external clock output
>>    clk: samsung: add clock driver for external clock outputs
>>    ARM: S3C24XX: enable usage of common dclk if common clock framework is
>> enabled
>>    ARM: S3C24XX: only store clock registers when old clock code is active
>>    clk: samsung: add plls used by the early s3c24xx cpus
>>    dt-bindings: add documentation for s3c2410 clock controller
>>    clk: samsung: add clock controller driver for s3c2410, s3c2440 and
>> s3c2442
>>    ARM: S3C24XX: add platform code for conversion to the common clock
>> framework
>>    ARM: S3C24XX: convert s3c2440 and s3c2442 to common clock framework
>>    ARM: S3C24XX: convert s3c2410 to common clock framework
>>    ARM: S3C24XX: remove legacy clock code
>>
>>   .../bindings/clock/samsung,s3c2410-clock.txt       |   50 ++
>>   .../bindings/clock/samsung,s3c2410-dclk.txt        |   53 ++
>>   arch/arm/mach-s3c24xx/Kconfig                      |   50 +-
>>   arch/arm/mach-s3c24xx/Makefile                     |    6 +-
>>   arch/arm/mach-s3c24xx/clock-dclk.c                 |  195 --------
>>   arch/arm/mach-s3c24xx/clock-s3c2410.c              |  285 -----------
>>   arch/arm/mach-s3c24xx/clock-s3c2440.c              |  217 --------
>>   arch/arm/mach-s3c24xx/clock-s3c244x.c              |  141 ------
>>   arch/arm/mach-s3c24xx/common.c                     |   45 +-
>>   arch/arm/mach-s3c24xx/common.h                     |   11 +-
>>   arch/arm/mach-s3c24xx/cpufreq-utils.c              |   13 +
>>   arch/arm/mach-s3c24xx/include/mach/regs-clock.h    |   18 -
>>   arch/arm/mach-s3c24xx/include/mach/regs-gpio.h     |    3 -
>>   arch/arm/mach-s3c24xx/mach-amlm5900.c              |    9 +-
>>   arch/arm/mach-s3c24xx/mach-anubis.c                |   15 +-
>>   arch/arm/mach-s3c24xx/mach-at2440evb.c             |   10 +-
>>   arch/arm/mach-s3c24xx/mach-bast.c                  |   15 +-
>>   arch/arm/mach-s3c24xx/mach-gta02.c                 |    8 +-
>>   arch/arm/mach-s3c24xx/mach-h1940.c                 |   10 +-
>>   arch/arm/mach-s3c24xx/mach-mini2440.c              |   10 +-
>>   arch/arm/mach-s3c24xx/mach-n30.c                   |   12 +-
>>   arch/arm/mach-s3c24xx/mach-nexcoder.c              |   10 +-
>>   arch/arm/mach-s3c24xx/mach-osiris.c                |   15 +-
>>   arch/arm/mach-s3c24xx/mach-otom.c                  |   10 +-
>>   arch/arm/mach-s3c24xx/mach-qt2410.c                |    9 +-
>>   arch/arm/mach-s3c24xx/mach-rx1950.c                |   15 +-
>>   arch/arm/mach-s3c24xx/mach-rx3715.c                |   10 +-
>>   arch/arm/mach-s3c24xx/mach-smdk2410.c              |    9 +-
>>   arch/arm/mach-s3c24xx/mach-smdk2440.c              |   10 +-
>>   arch/arm/mach-s3c24xx/mach-tct_hammer.c            |    9 +-
>>   arch/arm/mach-s3c24xx/mach-vr1000.c                |   15 +-
>>   arch/arm/mach-s3c24xx/pm.c                         |   13 +-
>>   arch/arm/mach-s3c24xx/s3c2410.c                    |   56 ---
>>   arch/arm/mach-s3c24xx/s3c2442.c                    |  111 -----
>>   arch/arm/mach-s3c24xx/s3c244x.c                    |   59 +--
>>   drivers/clk/samsung/Makefile                       |    2 +
>>   drivers/clk/samsung/clk-pll.c                      |  182 +++++++
>>   drivers/clk/samsung/clk-pll.h                      |    3 +
>>   drivers/clk/samsung/clk-s3c2410-dclk.c             |  517
>> ++++++++++++++++++++
>>   drivers/clk/samsung/clk-s3c2410.c                  |  428
>> ++++++++++++++++
>>   include/dt-bindings/clock/samsung,s3c2410-clock.h  |   64 +++
>>   include/dt-bindings/clock/samsung,s3c2410-dclk.h   |   28 ++
>>   42 files changed, 1575 insertions(+), 1176 deletions(-)
>>   create mode 100644
>> Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt
>>   create mode 100644
>> Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
>>   delete mode 100644 arch/arm/mach-s3c24xx/clock-dclk.c
>>   delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2410.c
>>   delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c2440.c
>>   delete mode 100644 arch/arm/mach-s3c24xx/clock-s3c244x.c
>>   create mode 100644 drivers/clk/samsung/clk-s3c2410-dclk.c
>>   create mode 100644 drivers/clk/samsung/clk-s3c2410.c
>>   create mode 100644 include/dt-bindings/clock/samsung,s3c2410-clock.h
>>   create mode 100644 include/dt-bindings/clock/samsung,s3c2410-dclk.h
>>
>
> For patches 4, 5, 9, 10, 11, 12:
>
> Reviewed-by: Tomasz Figa <t.figa@samsung.com>
>
> For patches 6, 7:
>
> Acked-by: Tomasz Figa <t.figa@samsung.com>
>

Really nice series.
Heiko, thanks for your effort and Tomasz, thanks for your review and ack.

OK, I'll apply this whole series and this will be sent to arm-soc in this week.

Thanks,
Kukjin

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

* Re: [PATCH 00/12] ARM: S3C24XX: convert s3c2410, s3c2440 s3c2442 to common clock framework
  2014-02-11  6:16     ` Kukjin Kim
@ 2014-02-11  9:20       ` Heiko Stübner
  -1 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2014-02-11  9:20 UTC (permalink / raw)
  To: Kukjin Kim
  Cc: Tomasz Figa, Tomasz Figa, Mike Turquette, linux-arm-kernel,
	linux-samsung-soc

Hi Kukjin,

Am Dienstag, 11. Februar 2014, 11:46:13 schrieb Kukjin Kim:
> 2014-02-10 1:26 GMT+05:30 Tomasz Figa <tomasz.figa@gmail.com>:
> > 
> > For patches 4, 5, 9, 10, 11, 12:
> > 
> > Reviewed-by: Tomasz Figa <t.figa@samsung.com>
> > 
> > For patches 6, 7:
> > 
> > Acked-by: Tomasz Figa <t.figa@samsung.com>
> 
> Really nice series.
> Heiko, thanks for your effort and Tomasz, thanks for your review and ack.
> 
> OK, I'll apply this whole series and this will be sent to arm-soc in this
> week.

not this fast :-)

Tomasz hat some comments about the two clk-drivers included, which I'll need 
to address first.

Also, this series, as well as the other two at the moment conflict with Tomasz' 
clock-pm changes. Our (Tomasz and me) current plan was for me to respin the 3 
ccf conversion series against his clock-pm series, which I hope to do in the 
next two days or so.


Heiko

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

* [PATCH 00/12] ARM: S3C24XX: convert s3c2410, s3c2440 s3c2442 to common clock framework
@ 2014-02-11  9:20       ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2014-02-11  9:20 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Kukjin,

Am Dienstag, 11. Februar 2014, 11:46:13 schrieb Kukjin Kim:
> 2014-02-10 1:26 GMT+05:30 Tomasz Figa <tomasz.figa@gmail.com>:
> > 
> > For patches 4, 5, 9, 10, 11, 12:
> > 
> > Reviewed-by: Tomasz Figa <t.figa@samsung.com>
> > 
> > For patches 6, 7:
> > 
> > Acked-by: Tomasz Figa <t.figa@samsung.com>
> 
> Really nice series.
> Heiko, thanks for your effort and Tomasz, thanks for your review and ack.
> 
> OK, I'll apply this whole series and this will be sent to arm-soc in this
> week.

not this fast :-)

Tomasz hat some comments about the two clk-drivers included, which I'll need 
to address first.

Also, this series, as well as the other two at the moment conflict with Tomasz' 
clock-pm changes. Our (Tomasz and me) current plan was for me to respin the 3 
ccf conversion series against his clock-pm series, which I hope to do in the 
next two days or so.


Heiko

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

* Re: [PATCH 02/12] dt-bindings: document s3c24xx controller for external clock output
  2014-02-09  1:54     ` Tomasz Figa
@ 2014-02-16 20:33       ` Heiko Stübner
  -1 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2014-02-16 20:33 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Kukjin Kim, t.figa, mturquette, linux-arm-kernel,
	linux-samsung-soc, Rob Herring, Pawel Moll, Mark Rutland,
	Stephen Warren, Ian Campbell, devicetree

Am Sonntag, 9. Februar 2014, 02:54:40 schrieb Tomasz Figa:
> Hi Heiko,
> 
> On 13.12.2013 13:59, Heiko Stübner wrote:
> > The clock settings are distributed over a regular register and parts
> > of the misccr register.
> > 
> > Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> > ---
> > 
> >   .../bindings/clock/samsung,s3c2410-dclk.txt        |   53
> >   ++++++++++++++++++++ 1 file changed, 53 insertions(+)
> >   create mode 100644
> >   Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt> 
> > diff --git
> > a/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
> > b/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt new
> > file mode 100644
> > index 0000000..0a1f7b1
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
> > @@ -0,0 +1,53 @@
> > +* Samsung S3C24XX External Clock Output Controller
> > +
> > +The S3C24XX series can generate clock signals on two clock output pads.
> > +The clock binding described here is applicable to all SoCs in
> > +the s3c24x family.
> > +
> > +Required Properties:
> > +
> > +- compatible: should be one of the following.
> > +  - "samsung,s3c2410-dclk" - controller in S3C2410 SoCs.
> > +  - "samsung,s3c2412-dclk" - controller in S3C2412 SoCs.
> > +  - "samsung,s3c2440-dclk" - controller in S3C2440 and S3C2442 SoCs.
> > +  - "samsung,s3c2443-dclk" - controller in S3C2443 and later SoCs.
> > +- reg: physical base address of the controller and length of memory
> > mapped
> > +  region.
> > +- #clock-cells: should be 1.
> > +- samsung,misccr: phandle to the syscon managing the misccr register,
> > which +  holds configuration settings for different soc-components
> > (clocks, usb, ...).
> Hmm, looking at the datasheet, DCLK and CLKOUT registers seem to be part
> of the pin controller. I wonder if there is really a need for different
> driver and device node to handle them.
> 
> Could this be simply made a part of the s3c24xx pinctrl driver,
> extending it to register also a clock provider under the same DT node?

it could, but of course the non-dt platforms would not be able to use it in 
this case.

So I guess, we could get rid of this dt binding, implement the clkout handling 
in the pinctrl driver for dt platforms, but use the platform-driver this 
binding described for the time we're still handling non-dt s3c24xx machines.


Heiko

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

* [PATCH 02/12] dt-bindings: document s3c24xx controller for external clock output
@ 2014-02-16 20:33       ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2014-02-16 20:33 UTC (permalink / raw)
  To: linux-arm-kernel

Am Sonntag, 9. Februar 2014, 02:54:40 schrieb Tomasz Figa:
> Hi Heiko,
> 
> On 13.12.2013 13:59, Heiko St?bner wrote:
> > The clock settings are distributed over a regular register and parts
> > of the misccr register.
> > 
> > Signed-off-by: Heiko Stuebner <heiko@sntech.de>
> > ---
> > 
> >   .../bindings/clock/samsung,s3c2410-dclk.txt        |   53
> >   ++++++++++++++++++++ 1 file changed, 53 insertions(+)
> >   create mode 100644
> >   Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt> 
> > diff --git
> > a/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
> > b/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt new
> > file mode 100644
> > index 0000000..0a1f7b1
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
> > @@ -0,0 +1,53 @@
> > +* Samsung S3C24XX External Clock Output Controller
> > +
> > +The S3C24XX series can generate clock signals on two clock output pads.
> > +The clock binding described here is applicable to all SoCs in
> > +the s3c24x family.
> > +
> > +Required Properties:
> > +
> > +- compatible: should be one of the following.
> > +  - "samsung,s3c2410-dclk" - controller in S3C2410 SoCs.
> > +  - "samsung,s3c2412-dclk" - controller in S3C2412 SoCs.
> > +  - "samsung,s3c2440-dclk" - controller in S3C2440 and S3C2442 SoCs.
> > +  - "samsung,s3c2443-dclk" - controller in S3C2443 and later SoCs.
> > +- reg: physical base address of the controller and length of memory
> > mapped
> > +  region.
> > +- #clock-cells: should be 1.
> > +- samsung,misccr: phandle to the syscon managing the misccr register,
> > which +  holds configuration settings for different soc-components
> > (clocks, usb, ...).
> Hmm, looking at the datasheet, DCLK and CLKOUT registers seem to be part
> of the pin controller. I wonder if there is really a need for different
> driver and device node to handle them.
> 
> Could this be simply made a part of the s3c24xx pinctrl driver,
> extending it to register also a clock provider under the same DT node?

it could, but of course the non-dt platforms would not be able to use it in 
this case.

So I guess, we could get rid of this dt binding, implement the clkout handling 
in the pinctrl driver for dt platforms, but use the platform-driver this 
binding described for the time we're still handling non-dt s3c24xx machines.


Heiko

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

* Re: [PATCH 02/12] dt-bindings: document s3c24xx controller for external clock output
  2014-02-16 20:33       ` Heiko Stübner
@ 2014-02-16 20:51         ` Tomasz Figa
  -1 siblings, 0 replies; 54+ messages in thread
From: Tomasz Figa @ 2014-02-16 20:51 UTC (permalink / raw)
  To: Heiko Stübner
  Cc: Kukjin Kim, t.figa, mturquette, linux-arm-kernel,
	linux-samsung-soc, Rob Herring, Pawel Moll, Mark Rutland,
	Stephen Warren, Ian Campbell, devicetree



On 16.02.2014 21:33, Heiko Stübner wrote:
> Am Sonntag, 9. Februar 2014, 02:54:40 schrieb Tomasz Figa:
>> Hi Heiko,
>>
>> On 13.12.2013 13:59, Heiko Stübner wrote:
>>> The clock settings are distributed over a regular register and parts
>>> of the misccr register.
>>>
>>> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
>>> ---
>>>
>>>    .../bindings/clock/samsung,s3c2410-dclk.txt        |   53
>>>    ++++++++++++++++++++ 1 file changed, 53 insertions(+)
>>>    create mode 100644
>>>    Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt>
>>> diff --git
>>> a/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
>>> b/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt new
>>> file mode 100644
>>> index 0000000..0a1f7b1
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
>>> @@ -0,0 +1,53 @@
>>> +* Samsung S3C24XX External Clock Output Controller
>>> +
>>> +The S3C24XX series can generate clock signals on two clock output pads.
>>> +The clock binding described here is applicable to all SoCs in
>>> +the s3c24x family.
>>> +
>>> +Required Properties:
>>> +
>>> +- compatible: should be one of the following.
>>> +  - "samsung,s3c2410-dclk" - controller in S3C2410 SoCs.
>>> +  - "samsung,s3c2412-dclk" - controller in S3C2412 SoCs.
>>> +  - "samsung,s3c2440-dclk" - controller in S3C2440 and S3C2442 SoCs.
>>> +  - "samsung,s3c2443-dclk" - controller in S3C2443 and later SoCs.
>>> +- reg: physical base address of the controller and length of memory
>>> mapped
>>> +  region.
>>> +- #clock-cells: should be 1.
>>> +- samsung,misccr: phandle to the syscon managing the misccr register,
>>> which +  holds configuration settings for different soc-components
>>> (clocks, usb, ...).
>> Hmm, looking at the datasheet, DCLK and CLKOUT registers seem to be part
>> of the pin controller. I wonder if there is really a need for different
>> driver and device node to handle them.
>>
>> Could this be simply made a part of the s3c24xx pinctrl driver,
>> extending it to register also a clock provider under the same DT node?
>
> it could, but of course the non-dt platforms would not be able to use it in
> this case.

Hmm, that's true.

> So I guess, we could get rid of this dt binding, implement the clkout handling
> in the pinctrl driver for dt platforms, but use the platform-driver this
> binding described for the time we're still handling non-dt s3c24xx machines.

I guess you could make this a separate driver that would be instantiated 
by pinctrl driver registering another platform device in DT case and a 
static platform device registered by board files in non-DT case.

Best regards,
Tomasz

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

* [PATCH 02/12] dt-bindings: document s3c24xx controller for external clock output
@ 2014-02-16 20:51         ` Tomasz Figa
  0 siblings, 0 replies; 54+ messages in thread
From: Tomasz Figa @ 2014-02-16 20:51 UTC (permalink / raw)
  To: linux-arm-kernel



On 16.02.2014 21:33, Heiko St?bner wrote:
> Am Sonntag, 9. Februar 2014, 02:54:40 schrieb Tomasz Figa:
>> Hi Heiko,
>>
>> On 13.12.2013 13:59, Heiko St?bner wrote:
>>> The clock settings are distributed over a regular register and parts
>>> of the misccr register.
>>>
>>> Signed-off-by: Heiko Stuebner <heiko@sntech.de>
>>> ---
>>>
>>>    .../bindings/clock/samsung,s3c2410-dclk.txt        |   53
>>>    ++++++++++++++++++++ 1 file changed, 53 insertions(+)
>>>    create mode 100644
>>>    Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt>
>>> diff --git
>>> a/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
>>> b/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt new
>>> file mode 100644
>>> index 0000000..0a1f7b1
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/clock/samsung,s3c2410-dclk.txt
>>> @@ -0,0 +1,53 @@
>>> +* Samsung S3C24XX External Clock Output Controller
>>> +
>>> +The S3C24XX series can generate clock signals on two clock output pads.
>>> +The clock binding described here is applicable to all SoCs in
>>> +the s3c24x family.
>>> +
>>> +Required Properties:
>>> +
>>> +- compatible: should be one of the following.
>>> +  - "samsung,s3c2410-dclk" - controller in S3C2410 SoCs.
>>> +  - "samsung,s3c2412-dclk" - controller in S3C2412 SoCs.
>>> +  - "samsung,s3c2440-dclk" - controller in S3C2440 and S3C2442 SoCs.
>>> +  - "samsung,s3c2443-dclk" - controller in S3C2443 and later SoCs.
>>> +- reg: physical base address of the controller and length of memory
>>> mapped
>>> +  region.
>>> +- #clock-cells: should be 1.
>>> +- samsung,misccr: phandle to the syscon managing the misccr register,
>>> which +  holds configuration settings for different soc-components
>>> (clocks, usb, ...).
>> Hmm, looking at the datasheet, DCLK and CLKOUT registers seem to be part
>> of the pin controller. I wonder if there is really a need for different
>> driver and device node to handle them.
>>
>> Could this be simply made a part of the s3c24xx pinctrl driver,
>> extending it to register also a clock provider under the same DT node?
>
> it could, but of course the non-dt platforms would not be able to use it in
> this case.

Hmm, that's true.

> So I guess, we could get rid of this dt binding, implement the clkout handling
> in the pinctrl driver for dt platforms, but use the platform-driver this
> binding described for the time we're still handling non-dt s3c24xx machines.

I guess you could make this a separate driver that would be instantiated 
by pinctrl driver registering another platform device in DT case and a 
static platform device registered by board files in non-DT case.

Best regards,
Tomasz

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

* Re: [PATCH 08/12] clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442
  2014-02-09 19:34     ` Tomasz Figa
@ 2014-02-17 21:05       ` Heiko Stübner
  -1 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2014-02-17 21:05 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Kukjin Kim, t.figa, mturquette, linux-arm-kernel, linux-samsung-soc

Hi Tomasz,

Am Sonntag, 9. Februar 2014, 20:34:26 schrieb Tomasz Figa:
> > +/*
> > + * fixed rate clocks generated outside the soc
> > + * Only necessary until the devicetree-move is complete
> > + */
> > +struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata =
> > {
> > +	FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0),
> 
> Do you need to assign this clock an ID? When DT is used, it's defined as
> a separate clock provider using fixed clock bindings, so it is not
> provided by this driver.

I think that I'll need this (and similar on the s3c2412). This is due to the 
cpufreq driver for the earlier SoCs needing the xtal-frequency to calculate 
the pll lock time (s3c24xx-cpufreq.c s3c_cpufreq_update_loctkime).

Or do you have an idea on how to fix up the cpufreq driver in an easy way?


Heiko

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

* [PATCH 08/12] clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442
@ 2014-02-17 21:05       ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2014-02-17 21:05 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tomasz,

Am Sonntag, 9. Februar 2014, 20:34:26 schrieb Tomasz Figa:
> > +/*
> > + * fixed rate clocks generated outside the soc
> > + * Only necessary until the devicetree-move is complete
> > + */
> > +struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata =
> > {
> > +	FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0),
> 
> Do you need to assign this clock an ID? When DT is used, it's defined as
> a separate clock provider using fixed clock bindings, so it is not
> provided by this driver.

I think that I'll need this (and similar on the s3c2412). This is due to the 
cpufreq driver for the earlier SoCs needing the xtal-frequency to calculate 
the pll lock time (s3c24xx-cpufreq.c s3c_cpufreq_update_loctkime).

Or do you have an idea on how to fix up the cpufreq driver in an easy way?


Heiko

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

* Re: [PATCH 08/12] clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442
  2014-02-17 21:05       ` Heiko Stübner
@ 2014-02-17 22:37         ` Tomasz Figa
  -1 siblings, 0 replies; 54+ messages in thread
From: Tomasz Figa @ 2014-02-17 22:37 UTC (permalink / raw)
  To: Heiko Stübner
  Cc: Kukjin Kim, t.figa, mturquette, linux-arm-kernel, linux-samsung-soc

On 17.02.2014 22:05, Heiko Stübner wrote:
> Hi Tomasz,
>
> Am Sonntag, 9. Februar 2014, 20:34:26 schrieb Tomasz Figa:
>>> +/*
>>> + * fixed rate clocks generated outside the soc
>>> + * Only necessary until the devicetree-move is complete
>>> + */
>>> +struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata =
>>> {
>>> +	FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0),
>>
>> Do you need to assign this clock an ID? When DT is used, it's defined as
>> a separate clock provider using fixed clock bindings, so it is not
>> provided by this driver.
>
> I think that I'll need this (and similar on the s3c2412). This is due to the
> cpufreq driver for the earlier SoCs needing the xtal-frequency to calculate
> the pll lock time (s3c24xx-cpufreq.c s3c_cpufreq_update_loctkime).
>
> Or do you have an idea on how to fix up the cpufreq driver in an easy way?

OK, I get the problem here. So you need the ID to register an alias.

Still, the ID would be invalid when booted with DT and xti clock 
registered using fixed rate clock bindings. So I'd suggest moving the 
XTI clock ID definition from your DT binding header back to your driver, 
leaving a comment in the header that this ID is reserved.

What do you think?

Best regards,
Tomasz

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

* [PATCH 08/12] clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442
@ 2014-02-17 22:37         ` Tomasz Figa
  0 siblings, 0 replies; 54+ messages in thread
From: Tomasz Figa @ 2014-02-17 22:37 UTC (permalink / raw)
  To: linux-arm-kernel

On 17.02.2014 22:05, Heiko St?bner wrote:
> Hi Tomasz,
>
> Am Sonntag, 9. Februar 2014, 20:34:26 schrieb Tomasz Figa:
>>> +/*
>>> + * fixed rate clocks generated outside the soc
>>> + * Only necessary until the devicetree-move is complete
>>> + */
>>> +struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata =
>>> {
>>> +	FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0),
>>
>> Do you need to assign this clock an ID? When DT is used, it's defined as
>> a separate clock provider using fixed clock bindings, so it is not
>> provided by this driver.
>
> I think that I'll need this (and similar on the s3c2412). This is due to the
> cpufreq driver for the earlier SoCs needing the xtal-frequency to calculate
> the pll lock time (s3c24xx-cpufreq.c s3c_cpufreq_update_loctkime).
>
> Or do you have an idea on how to fix up the cpufreq driver in an easy way?

OK, I get the problem here. So you need the ID to register an alias.

Still, the ID would be invalid when booted with DT and xti clock 
registered using fixed rate clock bindings. So I'd suggest moving the 
XTI clock ID definition from your DT binding header back to your driver, 
leaving a comment in the header that this ID is reserved.

What do you think?

Best regards,
Tomasz

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

* Re: [PATCH 08/12] clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442
  2014-02-17 22:37         ` Tomasz Figa
@ 2014-02-17 22:48           ` Heiko Stübner
  -1 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2014-02-17 22:48 UTC (permalink / raw)
  To: Tomasz Figa
  Cc: Kukjin Kim, t.figa, mturquette, linux-arm-kernel, linux-samsung-soc

Am Montag, 17. Februar 2014, 23:37:16 schrieb Tomasz Figa:
> On 17.02.2014 22:05, Heiko Stübner wrote:
> > Hi Tomasz,
> > 
> > Am Sonntag, 9. Februar 2014, 20:34:26 schrieb Tomasz Figa:
> >>> +/*
> >>> + * fixed rate clocks generated outside the soc
> >>> + * Only necessary until the devicetree-move is complete
> >>> + */
> >>> +struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata
> >>> =
> >>> {
> >>> +	FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0),
> >> 
> >> Do you need to assign this clock an ID? When DT is used, it's defined as
> >> a separate clock provider using fixed clock bindings, so it is not
> >> provided by this driver.
> > 
> > I think that I'll need this (and similar on the s3c2412). This is due to
> > the cpufreq driver for the earlier SoCs needing the xtal-frequency to
> > calculate the pll lock time (s3c24xx-cpufreq.c
> > s3c_cpufreq_update_loctkime).
> > 
> > Or do you have an idea on how to fix up the cpufreq driver in an easy way?
> 
> OK, I get the problem here. So you need the ID to register an alias.
> 
> Still, the ID would be invalid when booted with DT and xti clock
> registered using fixed rate clock bindings. So I'd suggest moving the
> XTI clock ID definition from your DT binding header back to your driver,
> leaving a comment in the header that this ID is reserved.
> 
> What do you think?

nice idea, thanks :-). I'll use it for the s3c2410 (+ variants) and s3c2412.


Heiko

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

* [PATCH 08/12] clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442
@ 2014-02-17 22:48           ` Heiko Stübner
  0 siblings, 0 replies; 54+ messages in thread
From: Heiko Stübner @ 2014-02-17 22:48 UTC (permalink / raw)
  To: linux-arm-kernel

Am Montag, 17. Februar 2014, 23:37:16 schrieb Tomasz Figa:
> On 17.02.2014 22:05, Heiko St?bner wrote:
> > Hi Tomasz,
> > 
> > Am Sonntag, 9. Februar 2014, 20:34:26 schrieb Tomasz Figa:
> >>> +/*
> >>> + * fixed rate clocks generated outside the soc
> >>> + * Only necessary until the devicetree-move is complete
> >>> + */
> >>> +struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata
> >>> =
> >>> {
> >>> +	FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0),
> >> 
> >> Do you need to assign this clock an ID? When DT is used, it's defined as
> >> a separate clock provider using fixed clock bindings, so it is not
> >> provided by this driver.
> > 
> > I think that I'll need this (and similar on the s3c2412). This is due to
> > the cpufreq driver for the earlier SoCs needing the xtal-frequency to
> > calculate the pll lock time (s3c24xx-cpufreq.c
> > s3c_cpufreq_update_loctkime).
> > 
> > Or do you have an idea on how to fix up the cpufreq driver in an easy way?
> 
> OK, I get the problem here. So you need the ID to register an alias.
> 
> Still, the ID would be invalid when booted with DT and xti clock
> registered using fixed rate clock bindings. So I'd suggest moving the
> XTI clock ID definition from your DT binding header back to your driver,
> leaving a comment in the header that this ID is reserved.
> 
> What do you think?

nice idea, thanks :-). I'll use it for the s3c2410 (+ variants) and s3c2412.


Heiko

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

end of thread, other threads:[~2014-02-17 22:49 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-12-13 12:56 [PATCH 00/12] ARM: S3C24XX: convert s3c2410, s3c2440 s3c2442 to common clock framework Heiko Stübner
2013-12-13 12:56 ` Heiko Stübner
2013-12-13 12:57 ` [PATCH 01/12] ARM: S3C24XX: cpufreq-utils: don't write raw values to MPLLCON when using ccf Heiko Stübner
2013-12-13 12:57   ` Heiko Stübner
2014-02-08 20:23   ` Tomasz Figa
2014-02-08 20:23     ` Tomasz Figa
2013-12-13 12:59 ` [PATCH 02/12] dt-bindings: document s3c24xx controller for external clock output Heiko Stübner
2013-12-13 12:59   ` Heiko Stübner
2014-02-09  1:54   ` Tomasz Figa
2014-02-09  1:54     ` Tomasz Figa
2014-02-16 20:33     ` Heiko Stübner
2014-02-16 20:33       ` Heiko Stübner
2014-02-16 20:51       ` Tomasz Figa
2014-02-16 20:51         ` Tomasz Figa
2013-12-13 12:59 ` [PATCH 03/12] clk: samsung: add clock driver for external clock outputs Heiko Stübner
2013-12-13 12:59   ` Heiko Stübner
2013-12-31 19:46   ` Mike Turquette
2013-12-31 19:46     ` Mike Turquette
2014-02-09  2:25   ` Tomasz Figa
2014-02-09  2:25     ` Tomasz Figa
2013-12-13 13:00 ` [PATCH 04/12] ARM: S3C24XX: enable usage of common dclk if common clock framework is enabled Heiko Stübner
2013-12-13 13:00   ` Heiko Stübner
2013-12-13 13:00 ` [PATCH 05/12] ARM: S3C24XX: only store clock registers when old clock code is active Heiko Stübner
2013-12-13 13:00   ` Heiko Stübner
2013-12-13 13:00 ` [PATCH 06/12] clk: samsung: add plls used by the early s3c24xx cpus Heiko Stübner
2013-12-13 13:00   ` Heiko Stübner
2013-12-31 19:45   ` Mike Turquette
2013-12-31 19:45     ` Mike Turquette
2013-12-13 13:01 ` [PATCH 08/12] clk: samsung: add clock controller driver for s3c2410, s3c2440 and s3c2442 Heiko Stübner
2013-12-13 13:01   ` Heiko Stübner
2014-02-06 14:12   ` Mike Turquette
2014-02-06 14:12     ` Mike Turquette
2014-02-09 19:34   ` Tomasz Figa
2014-02-09 19:34     ` Tomasz Figa
2014-02-17 21:05     ` Heiko Stübner
2014-02-17 21:05       ` Heiko Stübner
2014-02-17 22:37       ` Tomasz Figa
2014-02-17 22:37         ` Tomasz Figa
2014-02-17 22:48         ` Heiko Stübner
2014-02-17 22:48           ` Heiko Stübner
2013-12-13 13:02 ` [PATCH 09/12] ARM: S3C24XX: add platform code for conversion to the common clock framework Heiko Stübner
2013-12-13 13:02   ` Heiko Stübner
2013-12-13 13:02 ` [PATCH 10/12] ARM: S3C24XX: convert s3c2440 and s3c2442 to " Heiko Stübner
2013-12-13 13:02   ` Heiko Stübner
2013-12-13 13:03 ` [PATCH 11/12] ARM: S3C24XX: convert s3c2410 " Heiko Stübner
2013-12-13 13:03   ` Heiko Stübner
2013-12-13 13:03 ` [PATCH 12/12] ARM: S3C24XX: remove legacy clock code Heiko Stübner
2013-12-13 13:03   ` Heiko Stübner
2014-02-09 19:56 ` [PATCH 00/12] ARM: S3C24XX: convert s3c2410, s3c2440 s3c2442 to common clock framework Tomasz Figa
2014-02-09 19:56   ` Tomasz Figa
2014-02-11  6:16   ` Kukjin Kim
2014-02-11  6:16     ` Kukjin Kim
2014-02-11  9:20     ` Heiko Stübner
2014-02-11  9:20       ` Heiko Stübner

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.