Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
b5783dca
Commit
b5783dca
authored
May 26, 2014
by
Kukjin Kim
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'v3.16-next/clk-s3c24xx-3' into v3.16-next/cleanup-samsung
parents
702b691e
34c453ce
Changes
61
Show whitespace changes
Inline
Side-by-side
Showing
61 changed files
with
2655 additions
and
3223 deletions
+2655
-3223
Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt
...ation/devicetree/bindings/clock/samsung,s3c2410-clock.txt
+50
-0
Documentation/devicetree/bindings/clock/samsung,s3c2412-clock.txt
...ation/devicetree/bindings/clock/samsung,s3c2412-clock.txt
+50
-0
Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt
...ation/devicetree/bindings/clock/samsung,s3c2443-clock.txt
+56
-0
arch/arm/boot/dts/s3c2416-smdk2416.dts
arch/arm/boot/dts/s3c2416-smdk2416.dts
+13
-0
arch/arm/boot/dts/s3c2416.dtsi
arch/arm/boot/dts/s3c2416.dtsi
+42
-0
arch/arm/mach-s3c24xx/Kconfig
arch/arm/mach-s3c24xx/Kconfig
+37
-26
arch/arm/mach-s3c24xx/Makefile
arch/arm/mach-s3c24xx/Makefile
+5
-8
arch/arm/mach-s3c24xx/clock-dclk.c
arch/arm/mach-s3c24xx/clock-dclk.c
+0
-195
arch/arm/mach-s3c24xx/clock-s3c2410.c
arch/arm/mach-s3c24xx/clock-s3c2410.c
+0
-284
arch/arm/mach-s3c24xx/clock-s3c2412.c
arch/arm/mach-s3c24xx/clock-s3c2412.c
+0
-760
arch/arm/mach-s3c24xx/clock-s3c2416.c
arch/arm/mach-s3c24xx/clock-s3c2416.c
+0
-171
arch/arm/mach-s3c24xx/clock-s3c2440.c
arch/arm/mach-s3c24xx/clock-s3c2440.c
+0
-217
arch/arm/mach-s3c24xx/clock-s3c2443.c
arch/arm/mach-s3c24xx/clock-s3c2443.c
+0
-212
arch/arm/mach-s3c24xx/clock-s3c244x.c
arch/arm/mach-s3c24xx/clock-s3c244x.c
+0
-141
arch/arm/mach-s3c24xx/common-s3c2443.c
arch/arm/mach-s3c24xx/common-s3c2443.c
+0
-675
arch/arm/mach-s3c24xx/common.c
arch/arm/mach-s3c24xx/common.c
+60
-25
arch/arm/mach-s3c24xx/common.h
arch/arm/mach-s3c24xx/common.h
+19
-2
arch/arm/mach-s3c24xx/cpufreq-utils.c
arch/arm/mach-s3c24xx/cpufreq-utils.c
+3
-1
arch/arm/mach-s3c24xx/include/mach/regs-clock.h
arch/arm/mach-s3c24xx/include/mach/regs-clock.h
+0
-18
arch/arm/mach-s3c24xx/include/mach/regs-gpio.h
arch/arm/mach-s3c24xx/include/mach/regs-gpio.h
+0
-3
arch/arm/mach-s3c24xx/mach-amlm5900.c
arch/arm/mach-s3c24xx/mach-amlm5900.c
+7
-2
arch/arm/mach-s3c24xx/mach-anubis.c
arch/arm/mach-s3c24xx/mach-anubis.c
+8
-26
arch/arm/mach-s3c24xx/mach-at2440evb.c
arch/arm/mach-s3c24xx/mach-at2440evb.c
+7
-3
arch/arm/mach-s3c24xx/mach-bast.c
arch/arm/mach-s3c24xx/mach-bast.c
+8
-26
arch/arm/mach-s3c24xx/mach-gta02.c
arch/arm/mach-s3c24xx/mach-gta02.c
+6
-2
arch/arm/mach-s3c24xx/mach-h1940.c
arch/arm/mach-s3c24xx/mach-h1940.c
+7
-3
arch/arm/mach-s3c24xx/mach-jive.c
arch/arm/mach-s3c24xx/mach-jive.c
+7
-2
arch/arm/mach-s3c24xx/mach-mini2440.c
arch/arm/mach-s3c24xx/mach-mini2440.c
+7
-3
arch/arm/mach-s3c24xx/mach-n30.c
arch/arm/mach-s3c24xx/mach-n30.c
+8
-4
arch/arm/mach-s3c24xx/mach-nexcoder.c
arch/arm/mach-s3c24xx/mach-nexcoder.c
+7
-3
arch/arm/mach-s3c24xx/mach-osiris.c
arch/arm/mach-s3c24xx/mach-osiris.c
+8
-26
arch/arm/mach-s3c24xx/mach-otom.c
arch/arm/mach-s3c24xx/mach-otom.c
+7
-3
arch/arm/mach-s3c24xx/mach-qt2410.c
arch/arm/mach-s3c24xx/mach-qt2410.c
+7
-2
arch/arm/mach-s3c24xx/mach-rx1950.c
arch/arm/mach-s3c24xx/mach-rx1950.c
+8
-13
arch/arm/mach-s3c24xx/mach-rx3715.c
arch/arm/mach-s3c24xx/mach-rx3715.c
+7
-3
arch/arm/mach-s3c24xx/mach-s3c2416-dt.c
arch/arm/mach-s3c24xx/mach-s3c2416-dt.c
+1
-37
arch/arm/mach-s3c24xx/mach-smdk2410.c
arch/arm/mach-s3c24xx/mach-smdk2410.c
+7
-2
arch/arm/mach-s3c24xx/mach-smdk2413.c
arch/arm/mach-s3c24xx/mach-smdk2413.c
+7
-2
arch/arm/mach-s3c24xx/mach-smdk2416.c
arch/arm/mach-s3c24xx/mach-smdk2416.c
+7
-2
arch/arm/mach-s3c24xx/mach-smdk2440.c
arch/arm/mach-s3c24xx/mach-smdk2440.c
+7
-3
arch/arm/mach-s3c24xx/mach-smdk2443.c
arch/arm/mach-s3c24xx/mach-smdk2443.c
+7
-2
arch/arm/mach-s3c24xx/mach-tct_hammer.c
arch/arm/mach-s3c24xx/mach-tct_hammer.c
+7
-2
arch/arm/mach-s3c24xx/mach-vr1000.c
arch/arm/mach-s3c24xx/mach-vr1000.c
+8
-26
arch/arm/mach-s3c24xx/mach-vstms.c
arch/arm/mach-s3c24xx/mach-vstms.c
+7
-2
arch/arm/mach-s3c24xx/pm.c
arch/arm/mach-s3c24xx/pm.c
+0
-17
arch/arm/mach-s3c24xx/s3c2410.c
arch/arm/mach-s3c24xx/s3c2410.c
+0
-56
arch/arm/mach-s3c24xx/s3c2412.c
arch/arm/mach-s3c24xx/s3c2412.c
+0
-43
arch/arm/mach-s3c24xx/s3c2442.c
arch/arm/mach-s3c24xx/s3c2442.c
+0
-111
arch/arm/mach-s3c24xx/s3c244x.c
arch/arm/mach-s3c24xx/s3c244x.c
+2
-57
arch/arm/plat-samsung/include/plat/cpu-freq-core.h
arch/arm/plat-samsung/include/plat/cpu-freq-core.h
+1
-0
drivers/clk/samsung/Makefile
drivers/clk/samsung/Makefile
+4
-0
drivers/clk/samsung/clk-pll.c
drivers/clk/samsung/clk-pll.c
+264
-2
drivers/clk/samsung/clk-pll.h
drivers/clk/samsung/clk-pll.h
+6
-0
drivers/clk/samsung/clk-s3c2410-dclk.c
drivers/clk/samsung/clk-s3c2410-dclk.c
+440
-0
drivers/clk/samsung/clk-s3c2410.c
drivers/clk/samsung/clk-s3c2410.c
+477
-0
drivers/clk/samsung/clk-s3c2412.c
drivers/clk/samsung/clk-s3c2412.c
+269
-0
drivers/clk/samsung/clk-s3c2443.c
drivers/clk/samsung/clk-s3c2443.c
+462
-0
drivers/cpufreq/s3c24xx-cpufreq.c
drivers/cpufreq/s3c24xx-cpufreq.c
+1
-0
include/dt-bindings/clock/s3c2410.h
include/dt-bindings/clock/s3c2410.h
+62
-0
include/dt-bindings/clock/s3c2412.h
include/dt-bindings/clock/s3c2412.h
+73
-0
include/dt-bindings/clock/s3c2443.h
include/dt-bindings/clock/s3c2443.h
+92
-0
No files found.
Documentation/devicetree/bindings/clock/samsung,s3c2410-clock.txt
0 → 100644
View file @
b5783dca
* Samsung S3C2410 Clock Controller
The S3C2410 clock controller generates and supplies clock to various controllers
within the SoC. The clock binding described here is applicable to the s3c2410,
s3c2440 and s3c2442 SoCs in the s3c24x family.
Required Properties:
- compatible: should be one of the following.
- "samsung,s3c2410-clock" - controller compatible with S3C2410 SoC.
- "samsung,s3c2440-clock" - controller compatible with S3C2440 SoC.
- "samsung,s3c2442-clock" - controller compatible with S3C2442 SoC.
- reg: physical base address of the controller and length of memory mapped
region.
- #clock-cells: should be 1.
Each clock is assigned an identifier and client nodes can use this identifier
to specify the clock which they consume. Some of the clocks are available only
on a particular SoC.
All available clocks are defined as preprocessor macros in
dt-bindings/clock/samsung,s3c2410-clock.h header and can be used in device
tree sources.
External clocks:
The xti clock used as input for the plls is generated outside the SoC. It is
expected that is are defined using standard clock bindings with a
clock-output-names value of "xti".
Example: Clock controller node:
clocks: clock-controller@4c000000 {
compatible = "samsung,s3c2410-clock";
reg = <0x4c000000 0x20>;
#clock-cells = <1>;
};
Example: UART controller node that consumes the clock generated by the clock
controller (refer to the standard clock bindings for information about
"clocks" and "clock-names" properties):
serial@50004000 {
compatible = "samsung,s3c2440-uart";
reg = <0x50004000 0x4000>;
interrupts = <1 23 3 4>, <1 23 4 4>;
clock-names = "uart", "clk_uart_baud2";
clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>;
status = "disabled";
};
Documentation/devicetree/bindings/clock/samsung,s3c2412-clock.txt
0 → 100644
View file @
b5783dca
* Samsung S3C2412 Clock Controller
The S3C2412 clock controller generates and supplies clock to various controllers
within the SoC. The clock binding described here is applicable to the s3c2412
and s3c2413 SoCs in the s3c24x family.
Required Properties:
- compatible: should be "samsung,s3c2412-clock"
- reg: physical base address of the controller and length of memory mapped
region.
- #clock-cells: should be 1.
Each clock is assigned an identifier and client nodes can use this identifier
to specify the clock which they consume. Some of the clocks are available only
on a particular SoC.
All available clocks are defined as preprocessor macros in
dt-bindings/clock/s3c2412.h header and can be used in device
tree sources.
External clocks:
There are several clocks that are generated outside the SoC. It is expected
that they are defined using standard clock bindings with following
clock-output-names:
- "xti" - crystal input - required,
- "ext" - external clock source - optional,
Example: Clock controller node:
clocks: clock-controller@4c000000 {
compatible = "samsung,s3c2412-clock";
reg = <0x4c000000 0x20>;
#clock-cells = <1>;
};
Example: UART controller node that consumes the clock generated by the clock
controller (refer to the standard clock bindings for information about
"clocks" and "clock-names" properties):
serial@50004000 {
compatible = "samsung,s3c2412-uart";
reg = <0x50004000 0x4000>;
interrupts = <1 23 3 4>, <1 23 4 4>;
clock-names = "uart", "clk_uart_baud2", "clk_uart_baud3";
clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>,
<&clocks SCLK_UART>;
status = "disabled";
};
Documentation/devicetree/bindings/clock/samsung,s3c2443-clock.txt
0 → 100644
View file @
b5783dca
* Samsung S3C2443 Clock Controller
The S3C2443 clock controller generates and supplies clock to various controllers
within the SoC. The clock binding described here is applicable to all SoCs in
the s3c24x family starting with the s3c2443.
Required Properties:
- compatible: should be one of the following.
- "samsung,s3c2416-clock" - controller compatible with S3C2416 SoC.
- "samsung,s3c2443-clock" - controller compatible with S3C2443 SoC.
- "samsung,s3c2450-clock" - controller compatible with S3C2450 SoC.
- reg: physical base address of the controller and length of memory mapped
region.
- #clock-cells: should be 1.
Each clock is assigned an identifier and client nodes can use this identifier
to specify the clock which they consume. Some of the clocks are available only
on a particular SoC.
All available clocks are defined as preprocessor macros in
dt-bindings/clock/s3c2443.h header and can be used in device
tree sources.
External clocks:
There are several clocks that are generated outside the SoC. It is expected
that they are defined using standard clock bindings with following
clock-output-names:
- "xti" - crystal input - required,
- "ext" - external clock source - optional,
- "ext_i2s" - external I2S clock - optional,
- "ext_uart" - external uart clock - optional,
Example: Clock controller node:
clocks: clock-controller@4c000000 {
compatible = "samsung,s3c2416-clock";
reg = <0x4c000000 0x40>;
#clock-cells = <1>;
};
Example: UART controller node that consumes the clock generated by the clock
controller (refer to the standard clock bindings for information about
"clocks" and "clock-names" properties):
serial@50004000 {
compatible = "samsung,s3c2440-uart";
reg = <0x50004000 0x4000>;
interrupts = <1 23 3 4>, <1 23 4 4>;
clock-names = "uart", "clk_uart_baud2",
"clk_uart_baud3";
clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>,
<&clocks SCLK_UART>;
status = "disabled";
};
arch/arm/boot/dts/s3c2416-smdk2416.dts
View file @
b5783dca
...
...
@@ -19,6 +19,19 @@ memory {
reg
=
<
0x30000000
0x4000000
>;
};
clocks
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
1
>;
xti
:
xti
{
compatible
=
"fixed-clock"
;
clock
-
frequency
=
<
12000000
>;
clock
-
output
-
names
=
"xti"
;
#
clock
-
cells
=
<
0
>;
};
};
serial
@
50000000
{
status
=
"okay"
;
pinctrl
-
names
=
"default"
;
...
...
arch/arm/boot/dts/s3c2416.dtsi
View file @
b5783dca
...
...
@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
#include <dt-bindings/clock/s3c2443.h>
#include "s3c24xx.dtsi"
#include "s3c2416-pinctrl.dtsi"
...
...
@@ -28,26 +29,53 @@ interrupt-controller@4a000000 {
compatible = "samsung,s3c2416-irq";
};
clocks: clock-controller@0x4c000000 {
compatible = "samsung,s3c2416-clock";
reg = <0x4c000000 0x40>;
#clock-cells = <1>;
};
pinctrl@56000000 {
compatible = "samsung,s3c2416-pinctrl";
};
timer@51000000 {
clocks = <&clocks PCLK_PWM>;
clock-names = "timers";
};
serial@50000000 {
compatible = "samsung,s3c2440-uart";
clock-names = "uart", "clk_uart_baud2",
"clk_uart_baud3";
clocks = <&clocks PCLK_UART0>, <&clocks PCLK_UART0>,
<&clocks SCLK_UART>;
};
serial@50004000 {
compatible = "samsung,s3c2440-uart";
clock-names = "uart", "clk_uart_baud2",
"clk_uart_baud3";
clocks = <&clocks PCLK_UART1>, <&clocks PCLK_UART1>,
<&clocks SCLK_UART>;
};
serial@50008000 {
compatible = "samsung,s3c2440-uart";
clock-names = "uart", "clk_uart_baud2",
"clk_uart_baud3";
clocks = <&clocks PCLK_UART2>, <&clocks PCLK_UART2>,
<&clocks SCLK_UART>;
};
serial@5000C000 {
compatible = "samsung,s3c2440-uart";
reg = <0x5000C000 0x4000>;
interrupts = <1 18 24 4>, <1 18 25 4>;
clock-names = "uart", "clk_uart_baud2",
"clk_uart_baud3";
clocks = <&clocks PCLK_UART3>, <&clocks PCLK_UART3>,
<&clocks SCLK_UART>;
status = "disabled";
};
...
...
@@ -55,6 +83,10 @@ sdhci@4AC00000 {
compatible = "samsung,s3c6410-sdhci";
reg = <0x4AC00000 0x100>;
interrupts = <0 0 21 3>;
clock-names = "hsmmc", "mmc_busclk.0",
"mmc_busclk.2";
clocks = <&clocks HCLK_HSMMC0>, <&clocks HCLK_HSMMC0>,
<&clocks MUX_HSMMC0>;
status = "disabled";
};
...
...
@@ -62,18 +94,28 @@ sdhci@4A800000 {
compatible = "samsung,s3c6410-sdhci";
reg = <0x4A800000 0x100>;
interrupts = <0 0 20 3>;
clock-names = "hsmmc", "mmc_busclk.0",
"mmc_busclk.2";
clocks = <&clocks HCLK_HSMMC1>, <&clocks HCLK_HSMMC1>,
<&clocks MUX_HSMMC1>;
status = "disabled";
};
watchdog@53000000 {
interrupts = <1 9 27 3>;
clocks = <&clocks PCLK_WDT>;
clock-names = "watchdog";
};
rtc@57000000 {
compatible = "samsung,s3c2416-rtc";
clocks = <&clocks PCLK_RTC>;
clock-names = "rtc";
};
i2c@54000000 {
compatible = "samsung,s3c2440-i2c";
clocks = <&clocks PCLK_I2C0>;
clock-names = "i2c";
};
};
arch/arm/mach-s3c24xx/Kconfig
View file @
b5783dca
...
...
@@ -18,6 +18,18 @@ 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
help
Temporary symbol to build the dclk driver based on the common clock
framework.
menu "SAMSUNG S3C24XX SoCs Support"
comment "S3C24XX SoCs"
...
...
@@ -25,9 +37,10 @@ comment "S3C24XX SoCs"
config CPU_S3C2410
bool "SAMSUNG S3C2410"
default y
select COMMON_CLK
select CPU_ARM920T
select CPU_LLSERIAL_S3C2410
select S3C2410_C
LOC
K
select S3C2410_C
OMMON_CL
K
select S3C2410_DMA if S3C24XX_DMA
select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ
select S3C2410_PM if PM
...
...
@@ -38,8 +51,10 @@ config CPU_S3C2410
config CPU_S3C2412
bool "SAMSUNG S3C2412"
select COMMON_CLK
select CPU_ARM926T
select CPU_LLSERIAL_S3C2440
select S3C2412_COMMON_CLK
select S3C2412_DMA if S3C24XX_DMA
select S3C2412_PM if PM
help
...
...
@@ -47,20 +62,21 @@ config CPU_S3C2412
config CPU_S3C2416
bool "SAMSUNG S3C2416/S3C2450"
select COMMON_CLK
select CPU_ARM926T
select CPU_LLSERIAL_S3C2440
select S3C2416_PM if PM
select S3C2443_COMMON
select S3C2443_COMMON
_CLK
select S3C2443_DMA if S3C24XX_DMA
select SAMSUNG_CLKSRC
help
Support for the S3C2416 SoC from the S3C24XX line
config CPU_S3C2440
bool "SAMSUNG S3C2440"
select COMMON_CLK
select CPU_ARM920T
select CPU_LLSERIAL_S3C2440
select S3C2410_C
LOC
K
select S3C2410_C
OMMON_CL
K
select S3C2410_PM if PM
select S3C2440_DMA if S3C24XX_DMA
help
...
...
@@ -68,9 +84,10 @@ config CPU_S3C2440
config CPU_S3C2442
bool "SAMSUNG S3C2442"
select COMMON_CLK
select CPU_ARM920T
select CPU_LLSERIAL_S3C2440
select S3C2410_C
LOC
K
select S3C2410_C
OMMON_CL
K
select S3C2410_DMA if S3C24XX_DMA
select S3C2410_PM if PM
help
...
...
@@ -83,27 +100,16 @@ config CPU_S3C244X
config CPU_S3C2443
bool "SAMSUNG S3C2443"
select COMMON_CLK
select CPU_ARM920T
select CPU_LLSERIAL_S3C2440
select S3C2443_COMMON
select S3C2443_COMMON
_CLK
select S3C2443_DMA if S3C24XX_DMA
select SAMSUNG_CLKSRC
help
Support for the S3C2443 SoC from the S3C24XX line
# 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
...
...
@@ -258,8 +264,8 @@ config ARCH_BAST
bool "Simtec Electronics BAST (EB2410ITX)"
select ISA
select MACH_BAST_IDE
select S3C2410_COMMON_DCLK if COMMON_CLK
select S3C2410_IOTIMING if ARM_S3C2410_CPUFREQ
select S3C24XX_DCLK
select S3C24XX_SIMTEC_NOR
select S3C24XX_SIMTEC_PM if PM
select S3C24XX_SIMTEC_USB
...
...
@@ -340,7 +346,7 @@ config MACH_TCT_HAMMER
config MACH_VR1000
bool "Thorcom VR1000"
select MACH_BAST_IDE
select S3C24
XX_D
CLK
select S3C24
10_COMMON_DCLK if COMMON_
CLK
select S3C24XX_SIMTEC_NOR
select S3C24XX_SIMTEC_PM if PM
select S3C24XX_SIMTEC_USB
...
...
@@ -359,6 +365,11 @@ config S3C2412_PM_SLEEP
if CPU_S3C2412
config S3C2412_COMMON_CLK
bool
help
Build the s3c2412 clock driver based on the common clock framework.
config CPU_S3C2412_ONLY
bool
depends on !CPU_S3C2410 && !CPU_S3C2416 && !CPU_S3C2440 && \
...
...
@@ -519,8 +530,8 @@ comment "S3C2440 Boards"
config MACH_ANUBIS
bool "Simtec Electronics ANUBIS"
select HAVE_PATA_PLATFORM
select S3C2410_COMMON_DCLK if COMMON_CLK
select S3C2440_XTAL_12000000
select S3C24XX_DCLK
select S3C24XX_SIMTEC_PM if PM
select S3C_DEV_USB_HOST
help
...
...
@@ -558,9 +569,9 @@ config MACH_NEXCODER_2440
config MACH_OSIRIS
bool "Simtec IM2440D20 (OSIRIS) module"
select S3C2410_COMMON_DCLK if COMMON_CLK
select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
select S3C2440_XTAL_12000000
select S3C24XX_DCLK
select S3C24XX_SIMTEC_PM if PM
select S3C_DEV_NAND
select S3C_DEV_USB_HOST
...
...
@@ -629,9 +640,9 @@ config MACH_RX1950
bool "HP iPAQ rx1950"
select I2C
select PM_H1940 if PM
select S3C2410_COMMON_DCLK if COMMON_CLK
select S3C2410_IOTIMING if ARM_S3C2440_CPUFREQ
select S3C2440_XTAL_16934400
select S3C24XX_DCLK
select S3C24XX_PWM
select S3C_DEV_NAND
help
...
...
@@ -641,11 +652,11 @@ endif # CPU_S3C2442
if CPU_S3C2443 || CPU_S3C2416
config S3C2443_COMMON
config S3C2443_COMMON
_CLK
bool
help
Common code for the S3C2443 and similar processors, which includes
the S3C2416 and S3C2450
.
Temporary symbol to build the clock driver based on the common clock
framework
.
config S3C2443_DMA
bool
...
...
arch/arm/mach-s3c24xx/Makefile
View file @
b5783dca
...
...
@@ -21,22 +21,22 @@ obj-$(CONFIG_S3C2410_DMA) += dma-s3c2410.o
obj-$(CONFIG_S3C2410_PLL)
+=
pll-s3c2410.o
obj-$(CONFIG_S3C2410_PM)
+=
pm-s3c2410.o sleep-s3c2410.o
obj-$(CONFIG_CPU_S3C2412)
+=
s3c2412.o
clock-s3c2412.o
obj-$(CONFIG_CPU_S3C2412)
+=
s3c2412.o
obj-$(CONFIG_S3C2412_DMA)
+=
dma-s3c2412.o
obj-$(CONFIG_S3C2412_PM)
+=
pm-s3c2412.o
obj-$(CONFIG_S3C2412_PM_SLEEP)
+=
sleep-s3c2412.o
obj-$(CONFIG_CPU_S3C2416)
+=
s3c2416.o
clock-s3c2416.o
obj-$(CONFIG_CPU_S3C2416)
+=
s3c2416.o
obj-$(CONFIG_S3C2416_PM)
+=
pm-s3c2416.o
obj-$(CONFIG_CPU_S3C2440)
+=
s3c2440.o
clock-s3c2440.o
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
obj-$(CONFIG_CPU_S3C2443)
+=
s3c2443.o
clock-s3c2443.o
obj-$(CONFIG_CPU_S3C2443)
+=
s3c2443.o
# PM
...
...
@@ -44,16 +44,13 @@ 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
obj-$(CONFIG_S3C2412_IOTIMING)
+=
iotiming-s3c2412.o
obj-$(CONFIG_S3C2443_COMMON)
+=
common-s3c2443.o
obj-$(CONFIG_S3C2443_DMA)
+=
dma-s3c2443.o
#
...
...
arch/arm/mach-s3c24xx/clock-dclk.c
deleted
100644 → 0
View file @
702b691e
/*
* 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
,
};
arch/arm/mach-s3c24xx/clock-s3c2410.c
deleted
100644 → 0
View file @
702b691e
/*
* 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/serial_s3c.h>
#include <linux/io.h>
#include <asm/mach/map.h>
#include <mach/hardware.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
;
}
arch/arm/mach-s3c24xx/clock-s3c2412.c
deleted
100644 → 0
View file @
702b691e
/* linux/arch/arm/mach-s3c2412/clock.c
*
* Copyright (c) 2006 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2412,S3C2413 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/serial_s3c.h>
#include <linux/io.h>
#include <asm/mach/map.h>
#include <mach/hardware.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>
#include <plat/clock.h>
#include <plat/cpu.h>
/* We currently have to assume that the system is running
* from the XTPll input, and that all ***REFCLKs are being
* fed from it, as we cannot read the state of OM[4] from
* software.
*
* It would be possible for each board initialisation to
* set the correct muxing at initialisation
*/
static
int
s3c2412_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
;
__raw_writel
(
clkcon
,
S3C2410_CLKCON
);
return
0
;
}
static
int
s3c2412_upll_enable
(
struct
clk
*
clk
,
int
enable
)
{
unsigned
long
upllcon
=
__raw_readl
(
S3C2410_UPLLCON
);
unsigned
long
orig
=
upllcon
;
if
(
!
enable
)
upllcon
|=
S3C2412_PLLCON_OFF
;
else
upllcon
&=
~
S3C2412_PLLCON_OFF
;
__raw_writel
(
upllcon
,
S3C2410_UPLLCON
);
/* allow ~150uS for the PLL to settle and lock */
if
(
enable
&&
(
orig
&
S3C2412_PLLCON_OFF
))
udelay
(
150
);
return
0
;
}
/* clock selections */
static
struct
clk
clk_erefclk
=
{
.
name
=
"erefclk"
,
};
static
struct
clk
clk_urefclk
=
{
.
name
=
"urefclk"
,
};
static
int
s3c2412_setparent_usysclk
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
unsigned
long
clksrc
=
__raw_readl
(
S3C2412_CLKSRC
);
if
(
parent
==
&
clk_urefclk
)
clksrc
&=
~
S3C2412_CLKSRC_USYSCLK_UPLL
;
else
if
(
parent
==
&
clk_upll
)
clksrc
|=
S3C2412_CLKSRC_USYSCLK_UPLL
;
else
return
-
EINVAL
;
clk
->
parent
=
parent
;
__raw_writel
(
clksrc
,
S3C2412_CLKSRC
);
return
0
;
}
static
struct
clk
clk_usysclk
=
{
.
name
=
"usysclk"
,
.
parent
=
&
clk_xtal
,
.
ops
=
&
(
struct
clk_ops
)
{
.
set_parent
=
s3c2412_setparent_usysclk
,
},
};
static
struct
clk
clk_mrefclk
=
{
.
name
=
"mrefclk"
,
.
parent
=
&
clk_xtal
,
};
static
struct
clk
clk_mdivclk
=
{
.
name
=
"mdivclk"
,
.
parent
=
&
clk_xtal
,
};
static
int
s3c2412_setparent_usbsrc
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
unsigned
long
clksrc
=
__raw_readl
(
S3C2412_CLKSRC
);
if
(
parent
==
&
clk_usysclk
)
clksrc
&=
~
S3C2412_CLKSRC_USBCLK_HCLK
;
else
if
(
parent
==
&
clk_h
)
clksrc
|=
S3C2412_CLKSRC_USBCLK_HCLK
;
else
return
-
EINVAL
;
clk
->
parent
=
parent
;
__raw_writel
(
clksrc
,
S3C2412_CLKSRC
);
return
0
;
}
static
unsigned
long
s3c2412_roundrate_usbsrc
(
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
>
2
)
div
=
2
;
return
parent_rate
/
div
;
}
static
unsigned
long
s3c2412_getrate_usbsrc
(
struct
clk
*
clk
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
div
=
__raw_readl
(
S3C2410_CLKDIVN
);
return
parent_rate
/
((
div
&
S3C2412_CLKDIVN_USB48DIV
)
?
2
:
1
);
}
static
int
s3c2412_setrate_usbsrc
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
clkdivn
=
__raw_readl
(
S3C2410_CLKDIVN
);
rate
=
s3c2412_roundrate_usbsrc
(
clk
,
rate
);
if
((
parent_rate
/
rate
)
==
2
)
clkdivn
|=
S3C2412_CLKDIVN_USB48DIV
;
else
clkdivn
&=
~
S3C2412_CLKDIVN_USB48DIV
;
__raw_writel
(
clkdivn
,
S3C2410_CLKDIVN
);
return
0
;
}
static
struct
clk
clk_usbsrc
=
{
.
name
=
"usbsrc"
,
.
ops
=
&
(
struct
clk_ops
)
{
.
get_rate
=
s3c2412_getrate_usbsrc
,
.
set_rate
=
s3c2412_setrate_usbsrc
,
.
round_rate
=
s3c2412_roundrate_usbsrc
,
.
set_parent
=
s3c2412_setparent_usbsrc
,
},
};
static
int
s3c2412_setparent_msysclk
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
unsigned
long
clksrc
=
__raw_readl
(
S3C2412_CLKSRC
);
if
(
parent
==
&
clk_mdivclk
)
clksrc
&=
~
S3C2412_CLKSRC_MSYSCLK_MPLL
;
else
if
(
parent
==
&
clk_mpll
)
clksrc
|=
S3C2412_CLKSRC_MSYSCLK_MPLL
;
else
return
-
EINVAL
;
clk
->
parent
=
parent
;
__raw_writel
(
clksrc
,
S3C2412_CLKSRC
);
return
0
;
}
static
struct
clk
clk_msysclk
=
{
.
name
=
"msysclk"
,
.
ops
=
&
(
struct
clk_ops
)
{
.
set_parent
=
s3c2412_setparent_msysclk
,
},
};
static
int
s3c2412_setparent_armclk
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
unsigned
long
flags
;
unsigned
long
clkdiv
;
unsigned
long
dvs
;
/* Note, we current equate fclk andf msysclk for S3C2412 */
if
(
parent
==
&
clk_msysclk
||
parent
==
&
clk_f
)
dvs
=
0
;
else
if
(
parent
==
&
clk_h
)
dvs
=
S3C2412_CLKDIVN_DVSEN
;
else
return
-
EINVAL
;
clk
->
parent
=
parent
;
/* update this under irq lockdown, clkdivn is not protected
* by the clock system. */
local_irq_save
(
flags
);
clkdiv
=
__raw_readl
(
S3C2410_CLKDIVN
);
clkdiv
&=
~
S3C2412_CLKDIVN_DVSEN
;
clkdiv
|=
dvs
;
__raw_writel
(
clkdiv
,
S3C2410_CLKDIVN
);
local_irq_restore
(
flags
);
return
0
;
}
static
struct
clk
clk_armclk
=
{
.
name
=
"armclk"
,
.
parent
=
&
clk_msysclk
,
.
ops
=
&
(
struct
clk_ops
)
{
.
set_parent
=
s3c2412_setparent_armclk
,
},
};
/* these next clocks have an divider immediately after them,
* so we can register them with their divider and leave out the
* intermediate clock stage
*/
static
unsigned
long
s3c2412_roundrate_clksrc
(
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 as they cancel out */
div
=
(
rate
/
parent_rate
);
if
(
div
<
1
)
div
=
1
;
else
if
(
div
>
16
)
div
=
16
;
return
parent_rate
/
div
;
}
static
int
s3c2412_setparent_uart
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
unsigned
long
clksrc
=
__raw_readl
(
S3C2412_CLKSRC
);
if
(
parent
==
&
clk_erefclk
)
clksrc
&=
~
S3C2412_CLKSRC_UARTCLK_MPLL
;
else
if
(
parent
==
&
clk_mpll
)
clksrc
|=
S3C2412_CLKSRC_UARTCLK_MPLL
;
else
return
-
EINVAL
;
clk
->
parent
=
parent
;
__raw_writel
(
clksrc
,
S3C2412_CLKSRC
);
return
0
;
}
static
unsigned
long
s3c2412_getrate_uart
(
struct
clk
*
clk
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
div
=
__raw_readl
(
S3C2410_CLKDIVN
);
div
&=
S3C2412_CLKDIVN_UARTDIV_MASK
;
div
>>=
S3C2412_CLKDIVN_UARTDIV_SHIFT
;
return
parent_rate
/
(
div
+
1
);
}
static
int
s3c2412_setrate_uart
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
clkdivn
=
__raw_readl
(
S3C2410_CLKDIVN
);
rate
=
s3c2412_roundrate_clksrc
(
clk
,
rate
);
clkdivn
&=
~
S3C2412_CLKDIVN_UARTDIV_MASK
;
clkdivn
|=
((
parent_rate
/
rate
)
-
1
)
<<
S3C2412_CLKDIVN_UARTDIV_SHIFT
;
__raw_writel
(
clkdivn
,
S3C2410_CLKDIVN
);
return
0
;
}
static
struct
clk
clk_uart
=
{
.
name
=
"uartclk"
,
.
ops
=
&
(
struct
clk_ops
)
{
.
get_rate
=
s3c2412_getrate_uart
,
.
set_rate
=
s3c2412_setrate_uart
,
.
set_parent
=
s3c2412_setparent_uart
,
.
round_rate
=
s3c2412_roundrate_clksrc
,
},
};
static
int
s3c2412_setparent_i2s
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
unsigned
long
clksrc
=
__raw_readl
(
S3C2412_CLKSRC
);
if
(
parent
==
&
clk_erefclk
)
clksrc
&=
~
S3C2412_CLKSRC_I2SCLK_MPLL
;
else
if
(
parent
==
&
clk_mpll
)
clksrc
|=
S3C2412_CLKSRC_I2SCLK_MPLL
;
else
return
-
EINVAL
;
clk
->
parent
=
parent
;
__raw_writel
(
clksrc
,
S3C2412_CLKSRC
);
return
0
;
}
static
unsigned
long
s3c2412_getrate_i2s
(
struct
clk
*
clk
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
div
=
__raw_readl
(
S3C2410_CLKDIVN
);
div
&=
S3C2412_CLKDIVN_I2SDIV_MASK
;
div
>>=
S3C2412_CLKDIVN_I2SDIV_SHIFT
;
return
parent_rate
/
(
div
+
1
);
}
static
int
s3c2412_setrate_i2s
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
clkdivn
=
__raw_readl
(
S3C2410_CLKDIVN
);
rate
=
s3c2412_roundrate_clksrc
(
clk
,
rate
);
clkdivn
&=
~
S3C2412_CLKDIVN_I2SDIV_MASK
;
clkdivn
|=
((
parent_rate
/
rate
)
-
1
)
<<
S3C2412_CLKDIVN_I2SDIV_SHIFT
;
__raw_writel
(
clkdivn
,
S3C2410_CLKDIVN
);
return
0
;
}
static
struct
clk
clk_i2s
=
{
.
name
=
"i2sclk"
,
.
ops
=
&
(
struct
clk_ops
)
{
.
get_rate
=
s3c2412_getrate_i2s
,
.
set_rate
=
s3c2412_setrate_i2s
,
.
set_parent
=
s3c2412_setparent_i2s
,
.
round_rate
=
s3c2412_roundrate_clksrc
,
},
};
static
int
s3c2412_setparent_cam
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
unsigned
long
clksrc
=
__raw_readl
(
S3C2412_CLKSRC
);
if
(
parent
==
&
clk_usysclk
)
clksrc
&=
~
S3C2412_CLKSRC_CAMCLK_HCLK
;
else
if
(
parent
==
&
clk_h
)
clksrc
|=
S3C2412_CLKSRC_CAMCLK_HCLK
;
else
return
-
EINVAL
;
clk
->
parent
=
parent
;
__raw_writel
(
clksrc
,
S3C2412_CLKSRC
);
return
0
;
}
static
unsigned
long
s3c2412_getrate_cam
(
struct
clk
*
clk
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
div
=
__raw_readl
(
S3C2410_CLKDIVN
);
div
&=
S3C2412_CLKDIVN_CAMDIV_MASK
;
div
>>=
S3C2412_CLKDIVN_CAMDIV_SHIFT
;
return
parent_rate
/
(
div
+
1
);
}
static
int
s3c2412_setrate_cam
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
clkdivn
=
__raw_readl
(
S3C2410_CLKDIVN
);
rate
=
s3c2412_roundrate_clksrc
(
clk
,
rate
);
clkdivn
&=
~
S3C2412_CLKDIVN_CAMDIV_MASK
;
clkdivn
|=
((
parent_rate
/
rate
)
-
1
)
<<
S3C2412_CLKDIVN_CAMDIV_SHIFT
;
__raw_writel
(
clkdivn
,
S3C2410_CLKDIVN
);
return
0
;
}
static
struct
clk
clk_cam
=
{
.
name
=
"camif-upll"
,
/* same as 2440 name */
.
ops
=
&
(
struct
clk_ops
)
{
.
get_rate
=
s3c2412_getrate_cam
,
.
set_rate
=
s3c2412_setrate_cam
,
.
set_parent
=
s3c2412_setparent_cam
,
.
round_rate
=
s3c2412_roundrate_clksrc
,
},
};
/* standard clock definitions */
static
struct
clk
init_clocks_disable
[]
=
{
{
.
name
=
"nand"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_NAND
,
},
{
.
name
=
"sdi"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_SDI
,
},
{
.
name
=
"adc"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_ADC
,
},
{
.
name
=
"i2c"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_IIC
,
},
{
.
name
=
"iis"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_IIS
,
},
{
.
name
=
"spi"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_SPI
,
}
};
static
struct
clk
init_clocks
[]
=
{
{
.
name
=
"dma.0"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_DMA0
,
},
{
.
name
=
"dma.1"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_DMA1
,
},
{
.
name
=
"dma.2"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_DMA2
,
},
{
.
name
=
"dma.3"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_DMA3
,
},
{
.
name
=
"lcd"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_LCDC
,
},
{
.
name
=
"gpio"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_GPIO
,
},
{
.
name
=
"usb-host"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_USBH
,
},
{
.
name
=
"usb-device"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_USBD
,
},
{
.
name
=
"timers"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_PWMT
,
},
{
.
name
=
"uart"
,
.
devname
=
"s3c2412-uart.0"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_UART0
,
},
{
.
name
=
"uart"
,
.
devname
=
"s3c2412-uart.1"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_UART1
,
},
{
.
name
=
"uart"
,
.
devname
=
"s3c2412-uart.2"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_UART2
,
},
{
.
name
=
"rtc"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_RTC
,
},
{
.
name
=
"watchdog"
,
.
parent
=
&
clk_p
,
.
ctrlbit
=
0
,
},
{
.
name
=
"usb-bus-gadget"
,
.
parent
=
&
clk_usb_bus
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_USB_DEV48
,
},
{
.
name
=
"usb-bus-host"
,
.
parent
=
&
clk_usb_bus
,
.
enable
=
s3c2412_clkcon_enable
,
.
ctrlbit
=
S3C2412_CLKCON_USB_HOST48
,
}
};
/* clocks to add where we need to check their parentage */
struct
clk_init
{
struct
clk
*
clk
;
unsigned
int
bit
;
struct
clk
*
src_0
;
struct
clk
*
src_1
;
};
static
struct
clk_init
clks_src
[]
__initdata
=
{
{
.
clk
=
&
clk_usysclk
,
.
bit
=
S3C2412_CLKSRC_USBCLK_HCLK
,
.
src_0
=
&
clk_urefclk
,
.
src_1
=
&
clk_upll
,
},
{
.
clk
=
&
clk_i2s
,
.
bit
=
S3C2412_CLKSRC_I2SCLK_MPLL
,
.
src_0
=
&
clk_erefclk
,
.
src_1
=
&
clk_mpll
,
},
{
.
clk
=
&
clk_cam
,
.
bit
=
S3C2412_CLKSRC_CAMCLK_HCLK
,
.
src_0
=
&
clk_usysclk
,
.
src_1
=
&
clk_h
,
},
{
.
clk
=
&
clk_msysclk
,
.
bit
=
S3C2412_CLKSRC_MSYSCLK_MPLL
,
.
src_0
=
&
clk_mdivclk
,
.
src_1
=
&
clk_mpll
,
},
{
.
clk
=
&
clk_uart
,
.
bit
=
S3C2412_CLKSRC_UARTCLK_MPLL
,
.
src_0
=
&
clk_erefclk
,
.
src_1
=
&
clk_mpll
,
},
{
.
clk
=
&
clk_usbsrc
,
.
bit
=
S3C2412_CLKSRC_USBCLK_HCLK
,
.
src_0
=
&
clk_usysclk
,
.
src_1
=
&
clk_h
,
/* here we assume OM[4] select xtal */
},
{
.
clk
=
&
clk_erefclk
,
.
bit
=
S3C2412_CLKSRC_EREFCLK_EXTCLK
,
.
src_0
=
&
clk_xtal
,
.
src_1
=
&
clk_ext
,
},
{
.
clk
=
&
clk_urefclk
,
.
bit
=
S3C2412_CLKSRC_UREFCLK_EXTCLK
,
.
src_0
=
&
clk_xtal
,
.
src_1
=
&
clk_ext
,
},
};
/* s3c2412_clk_initparents
*
* Initialise the parents for the clocks that we get at start-time
*/
static
void
__init
s3c2412_clk_initparents
(
void
)
{
unsigned
long
clksrc
=
__raw_readl
(
S3C2412_CLKSRC
);
struct
clk_init
*
cip
=
clks_src
;
struct
clk
*
src
;
int
ptr
;
int
ret
;
for
(
ptr
=
0
;
ptr
<
ARRAY_SIZE
(
clks_src
);
ptr
++
,
cip
++
)
{
ret
=
s3c24xx_register_clock
(
cip
->
clk
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"Failed to register clock %s (%d)
\n
"
,
cip
->
clk
->
name
,
ret
);
}
src
=
(
clksrc
&
cip
->
bit
)
?
cip
->
src_1
:
cip
->
src_0
;
printk
(
KERN_INFO
"%s: parent %s
\n
"
,
cip
->
clk
->
name
,
src
->
name
);
clk_set_parent
(
cip
->
clk
,
src
);
}
}
/* clocks to add straight away */
static
struct
clk
*
clks
[]
__initdata
=
{
&
clk_ext
,
&
clk_usb_bus
,
&
clk_mrefclk
,
&
clk_armclk
,
};
static
struct
clk_lookup
s3c2412_clk_lookup
[]
=
{
CLKDEV_INIT
(
NULL
,
"clk_uart_baud1"
,
&
s3c24xx_uclk
),
CLKDEV_INIT
(
NULL
,
"clk_uart_baud2"
,
&
clk_p
),
CLKDEV_INIT
(
NULL
,
"clk_uart_baud3"
,
&
clk_usysclk
),
};
int
__init
s3c2412_baseclk_add
(
void
)
{
unsigned
long
clkcon
=
__raw_readl
(
S3C2410_CLKCON
);
unsigned
int
dvs
;
struct
clk
*
clkp
;
int
ret
;
int
ptr
;
clk_upll
.
enable
=
s3c2412_upll_enable
;
clk_usb_bus
.
parent
=
&
clk_usbsrc
;
clk_usb_bus
.
rate
=
0x0
;
clk_f
.
parent
=
&
clk_msysclk
;
s3c2412_clk_initparents
();
for
(
ptr
=
0
;
ptr
<
ARRAY_SIZE
(
clks
);
ptr
++
)
{
clkp
=
clks
[
ptr
];
ret
=
s3c24xx_register_clock
(
clkp
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"Failed to register clock %s (%d)
\n
"
,
clkp
->
name
,
ret
);
}
}
/* set the dvs state according to what we got at boot time */
dvs
=
__raw_readl
(
S3C2410_CLKDIVN
)
&
S3C2412_CLKDIVN_DVSEN
;
if
(
dvs
)
clk_armclk
.
parent
=
&
clk_h
;
printk
(
KERN_INFO
"S3C2412: DVS is %s
\n
"
,
dvs
?
"on"
:
"off"
);
/* ensure usb bus clock is within correct rate of 48MHz */
if
(
clk_get_rate
(
&
clk_usb_bus
)
!=
(
48
*
1000
*
1000
))
{
printk
(
KERN_INFO
"Warning: USB bus clock not at 48MHz
\n
"
);
/* for the moment, let's use the UPLL, and see if we can
* get 48MHz */
clk_set_parent
(
&
clk_usysclk
,
&
clk_upll
);
clk_set_parent
(
&
clk_usbsrc
,
&
clk_usysclk
);
clk_set_rate
(
&
clk_usbsrc
,
48
*
1000
*
1000
);
}
printk
(
"S3C2412: upll %s, %ld.%03ld MHz, usb-bus %ld.%03ld MHz
\n
"
,
(
__raw_readl
(
S3C2410_UPLLCON
)
&
S3C2412_PLLCON_OFF
)
?
"off"
:
"on"
,
print_mhz
(
clk_get_rate
(
&
clk_upll
)),
print_mhz
(
clk_get_rate
(
&
clk_usb_bus
)));
/* register clocks from clock array */
clkp
=
init_clocks
;
for
(
ptr
=
0
;
ptr
<
ARRAY_SIZE
(
init_clocks
);
ptr
++
,
clkp
++
)
{
/* 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 */
clkp
=
init_clocks_disable
;
for
(
ptr
=
0
;
ptr
<
ARRAY_SIZE
(
init_clocks_disable
);
ptr
++
,
clkp
++
)
{
ret
=
s3c24xx_register_clock
(
clkp
);
if
(
ret
<
0
)
{
printk
(
KERN_ERR
"Failed to register clock %s (%d)
\n
"
,
clkp
->
name
,
ret
);
}
s3c2412_clkcon_enable
(
clkp
,
0
);
}
clkdev_add_table
(
s3c2412_clk_lookup
,
ARRAY_SIZE
(
s3c2412_clk_lookup
));
return
0
;
}
arch/arm/mach-s3c24xx/clock-s3c2416.c
deleted
100644 → 0
View file @
702b691e
/* linux/arch/arm/mach-s3c2416/clock.c
*
* Copyright (c) 2010 Simtec Electronics
* Copyright (c) 2010 Ben Dooks <ben-linux@fluff.org>
*
* S3C2416 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.
*/
#include <linux/init.h>
#include <linux/clk.h>
#include <plat/clock.h>
#include <plat/clock-clksrc.h>
#include <plat/cpu.h>
#include <plat/cpu-freq.h>
#include <plat/pll.h>
#include <asm/mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-s3c2443-clock.h>
/* armdiv
*
* this clock is sourced from msysclk and can have a number of
* divider values applied to it to then be fed into armclk.
* The real clock definition is done in s3c2443-clock.c,
* only the armdiv divisor table must be defined here.
*/
static
unsigned
int
armdiv
[
8
]
=
{
[
0
]
=
1
,
[
1
]
=
2
,
[
2
]
=
3
,
[
3
]
=
4
,
[
5
]
=
6
,
[
7
]
=
8
,
};
static
struct
clksrc_clk
hsspi_eplldiv
=
{
.
clk
=
{
.
name
=
"hsspi-eplldiv"
,
.
parent
=
&
clk_esysclk
.
clk
,
.
ctrlbit
=
(
1
<<
14
),
.
enable
=
s3c2443_clkcon_enable_s
,
},
.
reg_div
=
{
.
reg
=
S3C2443_CLKDIV1
,
.
size
=
2
,
.
shift
=
24
},
};
static
struct
clk
*
hsspi_sources
[]
=
{
[
0
]
=
&
hsspi_eplldiv
.
clk
,
[
1
]
=
NULL
,
/* to fix */
};
static
struct
clksrc_clk
hsspi_mux
=
{
.
clk
=
{
.
name
=
"hsspi-if"
,
},
.
sources
=
&
(
struct
clksrc_sources
)
{
.
sources
=
hsspi_sources
,
.
nr_sources
=
ARRAY_SIZE
(
hsspi_sources
),
},
.
reg_src
=
{
.
reg
=
S3C2443_CLKSRC
,
.
size
=
1
,
.
shift
=
18
},
};
static
struct
clksrc_clk
hsmmc_div
[]
=
{
[
0
]
=
{
.
clk
=
{
.
name
=
"hsmmc-div"
,
.
devname
=
"s3c-sdhci.0"
,
.
parent
=
&
clk_esysclk
.
clk
,
},
.
reg_div
=
{
.
reg
=
S3C2416_CLKDIV2
,
.
size
=
2
,
.
shift
=
6
},
},
[
1
]
=
{
.
clk
=
{
.
name
=
"hsmmc-div"
,
.
devname
=
"s3c-sdhci.1"
,
.
parent
=
&
clk_esysclk
.
clk
,
},
.
reg_div
=
{
.
reg
=
S3C2443_CLKDIV1
,
.
size
=
2
,
.
shift
=
6
},
},
};
static
struct
clksrc_clk
hsmmc_mux0
=
{
.
clk
=
{
.
name
=
"hsmmc-if"
,
.
devname
=
"s3c-sdhci.0"
,
.
ctrlbit
=
(
1
<<
6
),
.
enable
=
s3c2443_clkcon_enable_s
,
},
.
sources
=
&
(
struct
clksrc_sources
)
{
.
nr_sources
=
2
,
.
sources
=
(
struct
clk
*
[])
{
[
0
]
=
&
hsmmc_div
[
0
].
clk
,
[
1
]
=
NULL
,
/* to fix */
},
},
.
reg_src
=
{
.
reg
=
S3C2443_CLKSRC
,
.
size
=
1
,
.
shift
=
16
},
};
static
struct
clksrc_clk
hsmmc_mux1
=
{
.
clk
=
{
.
name
=
"hsmmc-if"
,
.
devname
=
"s3c-sdhci.1"
,
.
ctrlbit
=
(
1
<<
12
),
.
enable
=
s3c2443_clkcon_enable_s
,
},
.
sources
=
&
(
struct
clksrc_sources
)
{
.
nr_sources
=
2
,
.
sources
=
(
struct
clk
*
[])
{
[
0
]
=
&
hsmmc_div
[
1
].
clk
,
[
1
]
=
NULL
,
/* to fix */
},
},
.
reg_src
=
{
.
reg
=
S3C2443_CLKSRC
,
.
size
=
1
,
.
shift
=
17
},
};
static
struct
clk
hsmmc0_clk
=
{
.
name
=
"hsmmc"
,
.
devname
=
"s3c-sdhci.0"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2443_clkcon_enable_h
,
.
ctrlbit
=
S3C2416_HCLKCON_HSMMC0
,
};
static
struct
clksrc_clk
*
clksrcs
[]
__initdata
=
{
&
hsspi_eplldiv
,
&
hsspi_mux
,
&
hsmmc_div
[
0
],
&
hsmmc_div
[
1
],
&
hsmmc_mux0
,
&
hsmmc_mux1
,
};
static
struct
clk_lookup
s3c2416_clk_lookup
[]
=
{
CLKDEV_INIT
(
"s3c-sdhci.0"
,
"mmc_busclk.0"
,
&
hsmmc0_clk
),
CLKDEV_INIT
(
"s3c-sdhci.0"
,
"mmc_busclk.2"
,
&
hsmmc_mux0
.
clk
),
CLKDEV_INIT
(
"s3c-sdhci.1"
,
"mmc_busclk.2"
,
&
hsmmc_mux1
.
clk
),
/* s3c2443-spi.0 is used on s3c2416 and s3c2450 as well */
CLKDEV_INIT
(
"s3c2443-spi.0"
,
"spi_busclk2"
,
&
hsspi_mux
.
clk
),
};
void
__init
s3c2416_init_clocks
(
int
xtal
)
{
u32
epllcon
=
__raw_readl
(
S3C2443_EPLLCON
);
u32
epllcon1
=
__raw_readl
(
S3C2443_EPLLCON
+
4
);
int
ptr
;
/* s3c2416 EPLL compatible with s3c64xx */
clk_epll
.
rate
=
s3c_get_pll6553x
(
xtal
,
epllcon
,
epllcon1
);
clk_epll
.
parent
=
&
clk_epllref
.
clk
;
s3c2443_common_init_clocks
(
xtal
,
s3c2416_get_pll
,
armdiv
,
ARRAY_SIZE
(
armdiv
),
S3C2416_CLKDIV0_ARMDIV_MASK
);
for
(
ptr
=
0
;
ptr
<
ARRAY_SIZE
(
clksrcs
);
ptr
++
)
s3c_register_clksrc
(
clksrcs
[
ptr
],
1
);
s3c24xx_register_clock
(
&
hsmmc0_clk
);
clkdev_add_table
(
s3c2416_clk_lookup
,
ARRAY_SIZE
(
s3c2416_clk_lookup
));
}
arch/arm/mach-s3c24xx/clock-s3c2440.c
deleted
100644 → 0
View file @
702b691e
/* 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 <linux/serial_s3c.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>
/* 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
);
arch/arm/mach-s3c24xx/clock-s3c2443.c
deleted
100644 → 0
View file @
702b691e
/* linux/arch/arm/mach-s3c2443/clock.c
*
* Copyright (c) 2007, 2010 Simtec Electronics
* Ben Dooks <ben@simtec.co.uk>
*
* S3C2443 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/serial_core.h>
#include <linux/io.h>
#include <asm/mach/map.h>
#include <mach/hardware.h>
#include <mach/regs-s3c2443-clock.h>
#include <plat/cpu-freq.h>
#include <plat/clock.h>
#include <plat/clock-clksrc.h>
#include <plat/cpu.h>
/* We currently have to assume that the system is running
* from the XTPll input, and that all ***REFCLKs are being
* fed from it, as we cannot read the state of OM[4] from
* software.
*
* It would be possible for each board initialisation to
* set the correct muxing at initialisation
*/
/* clock selections */
/* armdiv
*
* this clock is sourced from msysclk and can have a number of
* divider values applied to it to then be fed into armclk.
* The real clock definition is done in s3c2443-clock.c,
* only the armdiv divisor table must be defined here.
*/
static
unsigned
int
armdiv
[
16
]
=
{
[
S3C2443_CLKDIV0_ARMDIV_1
>>
S3C2443_CLKDIV0_ARMDIV_SHIFT
]
=
1
,
[
S3C2443_CLKDIV0_ARMDIV_2
>>
S3C2443_CLKDIV0_ARMDIV_SHIFT
]
=
2
,
[
S3C2443_CLKDIV0_ARMDIV_3
>>
S3C2443_CLKDIV0_ARMDIV_SHIFT
]
=
3
,
[
S3C2443_CLKDIV0_ARMDIV_4
>>
S3C2443_CLKDIV0_ARMDIV_SHIFT
]
=
4
,
[
S3C2443_CLKDIV0_ARMDIV_6
>>
S3C2443_CLKDIV0_ARMDIV_SHIFT
]
=
6
,
[
S3C2443_CLKDIV0_ARMDIV_8
>>
S3C2443_CLKDIV0_ARMDIV_SHIFT
]
=
8
,
[
S3C2443_CLKDIV0_ARMDIV_12
>>
S3C2443_CLKDIV0_ARMDIV_SHIFT
]
=
12
,
[
S3C2443_CLKDIV0_ARMDIV_16
>>
S3C2443_CLKDIV0_ARMDIV_SHIFT
]
=
16
,
};
/* hsspi
*
* high-speed spi clock, sourced from esysclk
*/
static
struct
clksrc_clk
clk_hsspi
=
{
.
clk
=
{
.
name
=
"hsspi-if"
,
.
parent
=
&
clk_esysclk
.
clk
,
.
ctrlbit
=
S3C2443_SCLKCON_HSSPICLK
,
.
enable
=
s3c2443_clkcon_enable_s
,
},
.
reg_div
=
{
.
reg
=
S3C2443_CLKDIV1
,
.
size
=
2
,
.
shift
=
4
},
};
/* clk_hsmcc_div
*
* this clock is sourced from epll, and is fed through a divider,
* to a mux controlled by sclkcon where either it or a extclk can
* be fed to the hsmmc block
*/
static
struct
clksrc_clk
clk_hsmmc_div
=
{
.
clk
=
{
.
name
=
"hsmmc-div"
,
.
devname
=
"s3c-sdhci.1"
,
.
parent
=
&
clk_esysclk
.
clk
,
},
.
reg_div
=
{
.
reg
=
S3C2443_CLKDIV1
,
.
size
=
2
,
.
shift
=
6
},
};
static
int
s3c2443_setparent_hsmmc
(
struct
clk
*
clk
,
struct
clk
*
parent
)
{
unsigned
long
clksrc
=
__raw_readl
(
S3C2443_SCLKCON
);
clksrc
&=
~
(
S3C2443_SCLKCON_HSMMCCLK_EXT
|
S3C2443_SCLKCON_HSMMCCLK_EPLL
);
if
(
parent
==
&
clk_epll
)
clksrc
|=
S3C2443_SCLKCON_HSMMCCLK_EPLL
;
else
if
(
parent
==
&
clk_ext
)
clksrc
|=
S3C2443_SCLKCON_HSMMCCLK_EXT
;
else
return
-
EINVAL
;
if
(
clk
->
usage
>
0
)
{
__raw_writel
(
clksrc
,
S3C2443_SCLKCON
);
}
clk
->
parent
=
parent
;
return
0
;
}
static
int
s3c2443_enable_hsmmc
(
struct
clk
*
clk
,
int
enable
)
{
return
s3c2443_setparent_hsmmc
(
clk
,
clk
->
parent
);
}
static
struct
clk
clk_hsmmc
=
{
.
name
=
"hsmmc-if"
,
.
devname
=
"s3c-sdhci.1"
,
.
parent
=
&
clk_hsmmc_div
.
clk
,
.
enable
=
s3c2443_enable_hsmmc
,
.
ops
=
&
(
struct
clk_ops
)
{
.
set_parent
=
s3c2443_setparent_hsmmc
,
},
};
/* standard clock definitions */
static
struct
clk
init_clocks_off
[]
=
{
{
.
name
=
"sdi"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2443_clkcon_enable_p
,
.
ctrlbit
=
S3C2443_PCLKCON_SDI
,
},
{
.
name
=
"spi"
,
.
devname
=
"s3c2410-spi.0"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2443_clkcon_enable_p
,
.
ctrlbit
=
S3C2443_PCLKCON_SPI1
,
}
};
/* clocks to add straight away */
static
struct
clksrc_clk
*
clksrcs
[]
__initdata
=
{
&
clk_hsspi
,
&
clk_hsmmc_div
,
};
static
struct
clk
*
clks
[]
__initdata
=
{
&
clk_hsmmc
,
};
static
struct
clk_lookup
s3c2443_clk_lookup
[]
=
{
CLKDEV_INIT
(
"s3c-sdhci.1"
,
"mmc_busclk.2"
,
&
clk_hsmmc
),
CLKDEV_INIT
(
"s3c2443-spi.0"
,
"spi_busclk2"
,
&
clk_hsspi
.
clk
),
};
void
__init
s3c2443_init_clocks
(
int
xtal
)
{
unsigned
long
epllcon
=
__raw_readl
(
S3C2443_EPLLCON
);
int
ptr
;
clk_epll
.
rate
=
s3c2443_get_epll
(
epllcon
,
xtal
);
clk_epll
.
parent
=
&
clk_epllref
.
clk
;
s3c2443_common_init_clocks
(
xtal
,
s3c2443_get_mpll
,
armdiv
,
ARRAY_SIZE
(
armdiv
),
S3C2443_CLKDIV0_ARMDIV_MASK
);
s3c24xx_register_clocks
(
clks
,
ARRAY_SIZE
(
clks
));
for
(
ptr
=
0
;
ptr
<
ARRAY_SIZE
(
clksrcs
);
ptr
++
)
s3c_register_clksrc
(
clksrcs
[
ptr
],
1
);
/* 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
));
clkdev_add_table
(
s3c2443_clk_lookup
,
ARRAY_SIZE
(
s3c2443_clk_lookup
));
}
arch/arm/mach-s3c24xx/clock-s3c244x.c
deleted
100644 → 0
View file @
702b691e
/* 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
);
arch/arm/mach-s3c24xx/common-s3c2443.c
deleted
100644 → 0
View file @
702b691e
/*
* Common code for SoCs starting with the S3C2443
*
* Copyright (c) 2007, 2010 Simtec Electronics
* Ben Dooks <ben@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 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.
*/
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <mach/regs-s3c2443-clock.h>
#include <plat/clock.h>
#include <plat/clock-clksrc.h>
#include <plat/cpu.h>
#include <plat/cpu-freq.h>
static
int
s3c2443_gate
(
void
__iomem
*
reg
,
struct
clk
*
clk
,
int
enable
)
{
u32
ctrlbit
=
clk
->
ctrlbit
;
u32
con
=
__raw_readl
(
reg
);
if
(
enable
)
con
|=
ctrlbit
;
else
con
&=
~
ctrlbit
;
__raw_writel
(
con
,
reg
);
return
0
;
}
int
s3c2443_clkcon_enable_h
(
struct
clk
*
clk
,
int
enable
)
{
return
s3c2443_gate
(
S3C2443_HCLKCON
,
clk
,
enable
);
}
int
s3c2443_clkcon_enable_p
(
struct
clk
*
clk
,
int
enable
)
{
return
s3c2443_gate
(
S3C2443_PCLKCON
,
clk
,
enable
);
}
int
s3c2443_clkcon_enable_s
(
struct
clk
*
clk
,
int
enable
)
{
return
s3c2443_gate
(
S3C2443_SCLKCON
,
clk
,
enable
);
}
/* mpllref is a direct descendant of clk_xtal by default, but it is not
* elided as the EPLL can be either sourced by the XTAL or EXTCLK and as
* such directly equating the two source clocks is impossible.
*/
static
struct
clk
clk_mpllref
=
{
.
name
=
"mpllref"
,
.
parent
=
&
clk_xtal
,
};
static
struct
clk
*
clk_epllref_sources
[]
=
{
[
0
]
=
&
clk_mpllref
,
[
1
]
=
&
clk_mpllref
,
[
2
]
=
&
clk_xtal
,
[
3
]
=
&
clk_ext
,
};
struct
clksrc_clk
clk_epllref
=
{
.
clk
=
{
.
name
=
"epllref"
,
},
.
sources
=
&
(
struct
clksrc_sources
)
{
.
sources
=
clk_epllref_sources
,
.
nr_sources
=
ARRAY_SIZE
(
clk_epllref_sources
),
},
.
reg_src
=
{
.
reg
=
S3C2443_CLKSRC
,
.
size
=
2
,
.
shift
=
7
},
};
/* esysclk
*
* this is sourced from either the EPLL or the EPLLref clock
*/
static
struct
clk
*
clk_sysclk_sources
[]
=
{
[
0
]
=
&
clk_epllref
.
clk
,
[
1
]
=
&
clk_epll
,
};
struct
clksrc_clk
clk_esysclk
=
{
.
clk
=
{
.
name
=
"esysclk"
,
.
parent
=
&
clk_epll
,
},
.
sources
=
&
(
struct
clksrc_sources
)
{
.
sources
=
clk_sysclk_sources
,
.
nr_sources
=
ARRAY_SIZE
(
clk_sysclk_sources
),
},
.
reg_src
=
{
.
reg
=
S3C2443_CLKSRC
,
.
size
=
1
,
.
shift
=
6
},
};
static
unsigned
long
s3c2443_getrate_mdivclk
(
struct
clk
*
clk
)
{
unsigned
long
parent_rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
div
=
__raw_readl
(
S3C2443_CLKDIV0
);
div
&=
S3C2443_CLKDIV0_EXTDIV_MASK
;
div
>>=
(
S3C2443_CLKDIV0_EXTDIV_SHIFT
-
1
);
/* x2 */
return
parent_rate
/
(
div
+
1
);
}
static
struct
clk
clk_mdivclk
=
{
.
name
=
"mdivclk"
,
.
parent
=
&
clk_mpllref
,
.
ops
=
&
(
struct
clk_ops
)
{
.
get_rate
=
s3c2443_getrate_mdivclk
,
},
};
static
struct
clk
*
clk_msysclk_sources
[]
=
{
[
0
]
=
&
clk_mpllref
,
[
1
]
=
&
clk_mpll
,
[
2
]
=
&
clk_mdivclk
,
[
3
]
=
&
clk_mpllref
,
};
static
struct
clksrc_clk
clk_msysclk
=
{
.
clk
=
{
.
name
=
"msysclk"
,
.
parent
=
&
clk_xtal
,
},
.
sources
=
&
(
struct
clksrc_sources
)
{
.
sources
=
clk_msysclk_sources
,
.
nr_sources
=
ARRAY_SIZE
(
clk_msysclk_sources
),
},
.
reg_src
=
{
.
reg
=
S3C2443_CLKSRC
,
.
size
=
2
,
.
shift
=
3
},
};
/* prediv
*
* this divides the msysclk down to pass to h/p/etc.
*/
static
unsigned
long
s3c2443_prediv_getrate
(
struct
clk
*
clk
)
{
unsigned
long
rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
clkdiv0
=
__raw_readl
(
S3C2443_CLKDIV0
);
clkdiv0
&=
S3C2443_CLKDIV0_PREDIV_MASK
;
clkdiv0
>>=
S3C2443_CLKDIV0_PREDIV_SHIFT
;
return
rate
/
(
clkdiv0
+
1
);
}
static
struct
clk
clk_prediv
=
{
.
name
=
"prediv"
,
.
parent
=
&
clk_msysclk
.
clk
,
.
ops
=
&
(
struct
clk_ops
)
{
.
get_rate
=
s3c2443_prediv_getrate
,
},
};
/* hclk divider
*
* divides the prediv and provides the hclk.
*/
static
unsigned
long
s3c2443_hclkdiv_getrate
(
struct
clk
*
clk
)
{
unsigned
long
rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
clkdiv0
=
__raw_readl
(
S3C2443_CLKDIV0
);
clkdiv0
&=
S3C2443_CLKDIV0_HCLKDIV_MASK
;
return
rate
/
(
clkdiv0
+
1
);
}
static
struct
clk_ops
clk_h_ops
=
{
.
get_rate
=
s3c2443_hclkdiv_getrate
,
};
/* pclk divider
*
* divides the hclk and provides the pclk.
*/
static
unsigned
long
s3c2443_pclkdiv_getrate
(
struct
clk
*
clk
)
{
unsigned
long
rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
clkdiv0
=
__raw_readl
(
S3C2443_CLKDIV0
);
clkdiv0
=
((
clkdiv0
&
S3C2443_CLKDIV0_HALF_PCLK
)
?
1
:
0
);
return
rate
/
(
clkdiv0
+
1
);
}
static
struct
clk_ops
clk_p_ops
=
{
.
get_rate
=
s3c2443_pclkdiv_getrate
,
};
/* armdiv
*
* this clock is sourced from msysclk and can have a number of
* divider values applied to it to then be fed into armclk.
*/
static
unsigned
int
*
armdiv
;
static
int
nr_armdiv
;
static
int
armdivmask
;
static
unsigned
long
s3c2443_armclk_roundrate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
long
parent
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
calc
;
unsigned
best
=
256
;
/* bigger than any value */
unsigned
div
;
int
ptr
;
if
(
!
nr_armdiv
)
return
-
EINVAL
;
for
(
ptr
=
0
;
ptr
<
nr_armdiv
;
ptr
++
)
{
div
=
armdiv
[
ptr
];
if
(
div
)
{
/* cpufreq provides 266mhz as 266666000 not 266666666 */
calc
=
(
parent
/
div
/
1000
)
*
1000
;
if
(
calc
<=
rate
&&
div
<
best
)
best
=
div
;
}
}
return
parent
/
best
;
}
static
unsigned
long
s3c2443_armclk_getrate
(
struct
clk
*
clk
)
{
unsigned
long
rate
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
clkcon0
;
int
val
;
if
(
!
nr_armdiv
||
!
armdivmask
)
return
-
EINVAL
;
clkcon0
=
__raw_readl
(
S3C2443_CLKDIV0
);
clkcon0
&=
armdivmask
;
val
=
clkcon0
>>
S3C2443_CLKDIV0_ARMDIV_SHIFT
;
return
rate
/
armdiv
[
val
];
}
static
int
s3c2443_armclk_setrate
(
struct
clk
*
clk
,
unsigned
long
rate
)
{
unsigned
long
parent
=
clk_get_rate
(
clk
->
parent
);
unsigned
long
calc
;
unsigned
div
;
unsigned
best
=
256
;
/* bigger than any value */
int
ptr
;
int
val
=
-
1
;
if
(
!
nr_armdiv
||
!
armdivmask
)
return
-
EINVAL
;
for
(
ptr
=
0
;
ptr
<
nr_armdiv
;
ptr
++
)
{
div
=
armdiv
[
ptr
];
if
(
div
)
{
/* cpufreq provides 266mhz as 266666000 not 266666666 */
calc
=
(
parent
/
div
/
1000
)
*
1000
;
if
(
calc
<=
rate
&&
div
<
best
)
{
best
=
div
;
val
=
ptr
;
}
}
}
if
(
val
>=
0
)
{
unsigned
long
clkcon0
;
clkcon0
=
__raw_readl
(
S3C2443_CLKDIV0
);
clkcon0
&=
~
armdivmask
;
clkcon0
|=
val
<<
S3C2443_CLKDIV0_ARMDIV_SHIFT
;
__raw_writel
(
clkcon0
,
S3C2443_CLKDIV0
);
}
return
(
val
==
-
1
)
?
-
EINVAL
:
0
;
}
static
struct
clk
clk_armdiv
=
{
.
name
=
"armdiv"
,
.
parent
=
&
clk_msysclk
.
clk
,
.
ops
=
&
(
struct
clk_ops
)
{
.
round_rate
=
s3c2443_armclk_roundrate
,
.
get_rate
=
s3c2443_armclk_getrate
,
.
set_rate
=
s3c2443_armclk_setrate
,
},
};
/* armclk
*
* this is the clock fed into the ARM core itself, from armdiv or from hclk.
*/
static
struct
clk
*
clk_arm_sources
[]
=
{
[
0
]
=
&
clk_armdiv
,
[
1
]
=
&
clk_h
,
};
static
struct
clksrc_clk
clk_arm
=
{
.
clk
=
{
.
name
=
"armclk"
,
},
.
sources
=
&
(
struct
clksrc_sources
)
{
.
sources
=
clk_arm_sources
,
.
nr_sources
=
ARRAY_SIZE
(
clk_arm_sources
),
},
.
reg_src
=
{
.
reg
=
S3C2443_CLKDIV0
,
.
size
=
1
,
.
shift
=
13
},
};
/* usbhost
*
* usb host bus-clock, usually 48MHz to provide USB bus clock timing
*/
static
struct
clksrc_clk
clk_usb_bus_host
=
{
.
clk
=
{
.
name
=
"usb-bus-host-parent"
,
.
parent
=
&
clk_esysclk
.
clk
,
.
ctrlbit
=
S3C2443_SCLKCON_USBHOST
,
.
enable
=
s3c2443_clkcon_enable_s
,
},
.
reg_div
=
{
.
reg
=
S3C2443_CLKDIV1
,
.
size
=
2
,
.
shift
=
4
},
};
/* common clksrc clocks */
static
struct
clksrc_clk
clksrc_clks
[]
=
{
{
/* camera interface bus-clock, divided down from esysclk */
.
clk
=
{
.
name
=
"camif-upll"
,
/* same as 2440 name */
.
parent
=
&
clk_esysclk
.
clk
,
.
ctrlbit
=
S3C2443_SCLKCON_CAMCLK
,
.
enable
=
s3c2443_clkcon_enable_s
,
},
.
reg_div
=
{
.
reg
=
S3C2443_CLKDIV1
,
.
size
=
4
,
.
shift
=
26
},
},
{
.
clk
=
{
.
name
=
"display-if"
,
.
parent
=
&
clk_esysclk
.
clk
,
.
ctrlbit
=
S3C2443_SCLKCON_DISPCLK
,
.
enable
=
s3c2443_clkcon_enable_s
,
},
.
reg_div
=
{
.
reg
=
S3C2443_CLKDIV1
,
.
size
=
8
,
.
shift
=
16
},
},
};
static
struct
clksrc_clk
clk_esys_uart
=
{
/* ART baud-rate clock sourced from esysclk via a divisor */
.
clk
=
{
.
name
=
"uartclk"
,
.
parent
=
&
clk_esysclk
.
clk
,
},
.
reg_div
=
{
.
reg
=
S3C2443_CLKDIV1
,
.
size
=
4
,
.
shift
=
8
},
};
static
struct
clk
clk_i2s_ext
=
{
.
name
=
"i2s-ext"
,
};
/* i2s_eplldiv
*
* This clock is the output from the I2S divisor of ESYSCLK, and is separate
* from the mux that comes after it (cannot merge into one single clock)
*/
static
struct
clksrc_clk
clk_i2s_eplldiv
=
{
.
clk
=
{
.
name
=
"i2s-eplldiv"
,
.
parent
=
&
clk_esysclk
.
clk
,
},
.
reg_div
=
{
.
reg
=
S3C2443_CLKDIV1
,
.
size
=
4
,
.
shift
=
12
,
},
};
/* i2s-ref
*
* i2s bus reference clock, selectable from external, esysclk or epllref
*
* Note, this used to be two clocks, but was compressed into one.
*/
static
struct
clk
*
clk_i2s_srclist
[]
=
{
[
0
]
=
&
clk_i2s_eplldiv
.
clk
,
[
1
]
=
&
clk_i2s_ext
,
[
2
]
=
&
clk_epllref
.
clk
,
[
3
]
=
&
clk_epllref
.
clk
,
};
static
struct
clksrc_clk
clk_i2s
=
{
.
clk
=
{
.
name
=
"i2s-if"
,
.
ctrlbit
=
S3C2443_SCLKCON_I2SCLK
,
.
enable
=
s3c2443_clkcon_enable_s
,
},
.
sources
=
&
(
struct
clksrc_sources
)
{
.
sources
=
clk_i2s_srclist
,
.
nr_sources
=
ARRAY_SIZE
(
clk_i2s_srclist
),
},
.
reg_src
=
{
.
reg
=
S3C2443_CLKSRC
,
.
size
=
2
,
.
shift
=
14
},
};
static
struct
clk
init_clocks_off
[]
=
{
{
.
name
=
"iis"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2443_clkcon_enable_p
,
.
ctrlbit
=
S3C2443_PCLKCON_IIS
,
},
{
.
name
=
"adc"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2443_clkcon_enable_p
,
.
ctrlbit
=
S3C2443_PCLKCON_ADC
,
},
{
.
name
=
"i2c"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2443_clkcon_enable_p
,
.
ctrlbit
=
S3C2443_PCLKCON_IIC
,
}
};
static
struct
clk
init_clocks
[]
=
{
{
.
name
=
"dma.0"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2443_clkcon_enable_h
,
.
ctrlbit
=
S3C2443_HCLKCON_DMA0
,
},
{
.
name
=
"dma.1"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2443_clkcon_enable_h
,
.
ctrlbit
=
S3C2443_HCLKCON_DMA1
,
},
{
.
name
=
"dma.2"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2443_clkcon_enable_h
,
.
ctrlbit
=
S3C2443_HCLKCON_DMA2
,
},
{
.
name
=
"dma.3"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2443_clkcon_enable_h
,
.
ctrlbit
=
S3C2443_HCLKCON_DMA3
,
},
{
.
name
=
"dma.4"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2443_clkcon_enable_h
,
.
ctrlbit
=
S3C2443_HCLKCON_DMA4
,
},
{
.
name
=
"dma.5"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2443_clkcon_enable_h
,
.
ctrlbit
=
S3C2443_HCLKCON_DMA5
,
},
{
.
name
=
"gpio"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2443_clkcon_enable_p
,
.
ctrlbit
=
S3C2443_PCLKCON_GPIO
,
},
{
.
name
=
"usb-host"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2443_clkcon_enable_h
,
.
ctrlbit
=
S3C2443_HCLKCON_USBH
,
},
{
.
name
=
"usb-device"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2443_clkcon_enable_h
,
.
ctrlbit
=
S3C2443_HCLKCON_USBD
,
},
{
.
name
=
"lcd"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2443_clkcon_enable_h
,
.
ctrlbit
=
S3C2443_HCLKCON_LCDC
,
},
{
.
name
=
"timers"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2443_clkcon_enable_p
,
.
ctrlbit
=
S3C2443_PCLKCON_PWMT
,
},
{
.
name
=
"cfc"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2443_clkcon_enable_h
,
.
ctrlbit
=
S3C2443_HCLKCON_CFC
,
},
{
.
name
=
"ssmc"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2443_clkcon_enable_h
,
.
ctrlbit
=
S3C2443_HCLKCON_SSMC
,
},
{
.
name
=
"uart"
,
.
devname
=
"s3c2440-uart.0"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2443_clkcon_enable_p
,
.
ctrlbit
=
S3C2443_PCLKCON_UART0
,
},
{
.
name
=
"uart"
,
.
devname
=
"s3c2440-uart.1"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2443_clkcon_enable_p
,
.
ctrlbit
=
S3C2443_PCLKCON_UART1
,
},
{
.
name
=
"uart"
,
.
devname
=
"s3c2440-uart.2"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2443_clkcon_enable_p
,
.
ctrlbit
=
S3C2443_PCLKCON_UART2
,
},
{
.
name
=
"uart"
,
.
devname
=
"s3c2440-uart.3"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2443_clkcon_enable_p
,
.
ctrlbit
=
S3C2443_PCLKCON_UART3
,
},
{
.
name
=
"rtc"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2443_clkcon_enable_p
,
.
ctrlbit
=
S3C2443_PCLKCON_RTC
,
},
{
.
name
=
"watchdog"
,
.
parent
=
&
clk_p
,
.
ctrlbit
=
S3C2443_PCLKCON_WDT
,
},
{
.
name
=
"ac97"
,
.
parent
=
&
clk_p
,
.
ctrlbit
=
S3C2443_PCLKCON_AC97
,
},
{
.
name
=
"nand"
,
.
parent
=
&
clk_h
,
},
{
.
name
=
"usb-bus-host"
,
.
parent
=
&
clk_usb_bus_host
.
clk
,
}
};
static
struct
clk
hsmmc1_clk
=
{
.
name
=
"hsmmc"
,
.
devname
=
"s3c-sdhci.1"
,
.
parent
=
&
clk_h
,
.
enable
=
s3c2443_clkcon_enable_h
,
.
ctrlbit
=
S3C2443_HCLKCON_HSMMC
,
};
static
struct
clk
hsspi_clk
=
{
.
name
=
"spi"
,
.
devname
=
"s3c2443-spi.0"
,
.
parent
=
&
clk_p
,
.
enable
=
s3c2443_clkcon_enable_p
,
.
ctrlbit
=
S3C2443_PCLKCON_HSSPI
,
};
/* EPLLCON compatible enough to get on/off information */
void
__init_or_cpufreq
s3c2443_common_setup_clocks
(
pll_fn
get_mpll
)
{
unsigned
long
epllcon
=
__raw_readl
(
S3C2443_EPLLCON
);
unsigned
long
mpllcon
=
__raw_readl
(
S3C2443_MPLLCON
);
struct
clk
*
xtal_clk
;
unsigned
long
xtal
;
unsigned
long
pll
;
int
ptr
;
xtal_clk
=
clk_get
(
NULL
,
"xtal"
);
xtal
=
clk_get_rate
(
xtal_clk
);
clk_put
(
xtal_clk
);
pll
=
get_mpll
(
mpllcon
,
xtal
);
clk_msysclk
.
clk
.
rate
=
pll
;
clk_mpll
.
rate
=
pll
;
printk
(
"CPU: MPLL %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz
\n
"
,
(
mpllcon
&
S3C2443_PLLCON_OFF
)
?
"off"
:
"on"
,
print_mhz
(
pll
),
print_mhz
(
clk_get_rate
(
&
clk_armdiv
)),
print_mhz
(
clk_get_rate
(
&
clk_h
)),
print_mhz
(
clk_get_rate
(
&
clk_p
)));
for
(
ptr
=
0
;
ptr
<
ARRAY_SIZE
(
clksrc_clks
);
ptr
++
)
s3c_set_clksrc
(
&
clksrc_clks
[
ptr
],
true
);
/* ensure usb bus clock is within correct rate of 48MHz */
if
(
clk_get_rate
(
&
clk_usb_bus_host
.
clk
)
!=
(
48
*
1000
*
1000
))
{
printk
(
KERN_INFO
"Warning: USB host bus not at 48MHz
\n
"
);
clk_set_rate
(
&
clk_usb_bus_host
.
clk
,
48
*
1000
*
1000
);
}
printk
(
"CPU: EPLL %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz
\n
"
,
(
epllcon
&
S3C2443_PLLCON_OFF
)
?
"off"
:
"on"
,
print_mhz
(
clk_get_rate
(
&
clk_epll
)),
print_mhz
(
clk_get_rate
(
&
clk_usb_bus
)));
}
static
struct
clk
*
clks
[]
__initdata
=
{
&
clk_prediv
,
&
clk_mpllref
,
&
clk_mdivclk
,
&
clk_ext
,
&
clk_epll
,
&
clk_usb_bus
,
&
clk_armdiv
,
&
hsmmc1_clk
,
&
hsspi_clk
,
};
static
struct
clksrc_clk
*
clksrcs
[]
__initdata
=
{
&
clk_i2s_eplldiv
,
&
clk_i2s
,
&
clk_usb_bus_host
,
&
clk_epllref
,
&
clk_esysclk
,
&
clk_msysclk
,
&
clk_arm
,
};
static
struct
clk_lookup
s3c2443_clk_lookup
[]
=
{
CLKDEV_INIT
(
NULL
,
"clk_uart_baud1"
,
&
s3c24xx_uclk
),
CLKDEV_INIT
(
NULL
,
"clk_uart_baud2"
,
&
clk_p
),
CLKDEV_INIT
(
NULL
,
"clk_uart_baud3"
,
&
clk_esys_uart
.
clk
),
CLKDEV_INIT
(
"s3c-sdhci.1"
,
"mmc_busclk.0"
,
&
hsmmc1_clk
),
CLKDEV_INIT
(
"s3c2443-spi.0"
,
"spi_busclk0"
,
&
hsspi_clk
),
};
void
__init
s3c2443_common_init_clocks
(
int
xtal
,
pll_fn
get_mpll
,
unsigned
int
*
divs
,
int
nr_divs
,
int
divmask
)
{
int
ptr
;
armdiv
=
divs
;
nr_armdiv
=
nr_divs
;
armdivmask
=
divmask
;
/* s3c2443 parents h clock from prediv */
clk_h
.
parent
=
&
clk_prediv
;
clk_h
.
ops
=
&
clk_h_ops
;
/* and p clock from h clock */
clk_p
.
parent
=
&
clk_h
;
clk_p
.
ops
=
&
clk_p_ops
;
clk_usb_bus
.
parent
=
&
clk_usb_bus_host
.
clk
;
clk_epll
.
parent
=
&
clk_epllref
.
clk
;
s3c24xx_register_baseclocks
(
xtal
);
s3c24xx_register_clocks
(
clks
,
ARRAY_SIZE
(
clks
));
for
(
ptr
=
0
;
ptr
<
ARRAY_SIZE
(
clksrcs
);
ptr
++
)
s3c_register_clksrc
(
clksrcs
[
ptr
],
1
);
s3c_register_clksrc
(
clksrc_clks
,
ARRAY_SIZE
(
clksrc_clks
));
s3c_register_clocks
(
init_clocks
,
ARRAY_SIZE
(
init_clocks
));
/* See s3c2443/etc notes on disabling clocks at init time */
s3c_register_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
s3c_disable_clocks
(
init_clocks_off
,
ARRAY_SIZE
(
init_clocks_off
));
clkdev_add_table
(
s3c2443_clk_lookup
,
ARRAY_SIZE
(
s3c2443_clk_lookup
));
s3c2443_common_setup_clocks
(
get_mpll
);
}
arch/arm/mach-s3c24xx/common.c
View file @
b5783dca
...
...
@@ -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"
...
...
@@ -73,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
...
...
@@ -82,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
...
...
@@ -91,7 +90,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
...
...
@@ -100,7 +98,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
...
...
@@ -109,7 +106,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
...
...
@@ -118,7 +114,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
...
...
@@ -127,7 +122,6 @@ static struct cpu_table cpu_ids[] __initdata = {
.
idcode
=
0x32412001
,
.
idmask
=
0xffffffff
,
.
map_io
=
s3c2412_map_io
,
.
init_clocks
=
s3c2412_init_clocks
,
.
init_uarts
=
s3c2412_init_uarts
,
.
init
=
s3c2412_init
,
.
name
=
name_s3c2412
,
...
...
@@ -136,7 +130,6 @@ static struct cpu_table cpu_ids[] __initdata = {
.
idcode
=
0x32412003
,
.
idmask
=
0xffffffff
,
.
map_io
=
s3c2412_map_io
,
.
init_clocks
=
s3c2412_init_clocks
,
.
init_uarts
=
s3c2412_init_uarts
,
.
init
=
s3c2412_init
,
.
name
=
name_s3c2412
,
...
...
@@ -145,7 +138,6 @@ static struct cpu_table cpu_ids[] __initdata = {
.
idcode
=
0x32450003
,
.
idmask
=
0xffffffff
,
.
map_io
=
s3c2416_map_io
,
.
init_clocks
=
s3c2416_init_clocks
,
.
init_uarts
=
s3c2416_init_uarts
,
.
init
=
s3c2416_init
,
.
name
=
name_s3c2416
,
...
...
@@ -154,7 +146,6 @@ static struct cpu_table cpu_ids[] __initdata = {
.
idcode
=
0x32443001
,
.
idmask
=
0xffffffff
,
.
map_io
=
s3c2443_map_io
,
.
init_clocks
=
s3c2443_init_clocks
,
.
init_uarts
=
s3c2443_init_uarts
,
.
init
=
s3c2443_init
,
.
name
=
name_s3c2443
,
...
...
@@ -316,21 +307,6 @@ struct s3c24xx_uart_resources s3c2410_uart_resources[] __initdata = {
},
};
/* initialise all the clocks */
void
__init_or_cpufreq
s3c24xx_setup_clocks
(
unsigned
long
fclk
,
unsigned
long
hclk
,
unsigned
long
pclk
)
{
clk_upll
.
rate
=
s3c24xx_get_pll
(
__raw_readl
(
S3C2410_UPLLCON
),
clk_xtal
.
rate
);
clk_mpll
.
rate
=
fclk
;
clk_h
.
rate
=
hclk
;
clk_p
.
rate
=
pclk
;
clk_f
.
rate
=
fclk
;
}
#if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \
defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442)
static
struct
resource
s3c2410_dma_resource
[]
=
{
...
...
@@ -534,3 +510,62 @@ 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_S3C2412
void
__init
s3c2412_init_clocks
(
int
xtal
)
{
s3c2412_common_clk_init
(
NULL
,
xtal
,
0
,
S3C24XX_VA_CLKPWR
);
}
#endif
#ifdef CONFIG_CPU_S3C2416
void
__init
s3c2416_init_clocks
(
int
xtal
)
{
s3c2443_common_clk_init
(
NULL
,
xtal
,
0
,
S3C24XX_VA_CLKPWR
);
}
#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
)
{
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
arch/arm/mach-s3c24xx/common.h
View file @
b5783dca
...
...
@@ -67,16 +67,15 @@ 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
#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 +85,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
...
...
@@ -114,4 +114,21 @@ 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_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_S3C2412_COMMON_CLK
void
__init
s3c2412_common_clk_init
(
struct
device_node
*
np
,
unsigned
long
xti_f
,
unsigned
long
ext_f
,
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
,
void
__iomem
*
reg_base
);
#endif
#endif
/* __ARCH_ARM_MACH_S3C24XX_COMMON_H */
arch/arm/mach-s3c24xx/cpufreq-utils.c
View file @
b5783dca
...
...
@@ -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,6 @@ void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg)
*/
void
s3c2410_set_fvco
(
struct
s3c_cpufreq_config
*
cfg
)
{
__raw_writel
(
cfg
->
pll
.
driver_data
,
S3C2410_MPLLCON
);
if
(
!
IS_ERR
(
cfg
->
mpll
))
clk_set_rate
(
cfg
->
mpll
,
cfg
->
pll
.
frequency
);
}
arch/arm/mach-s3c24xx/include/mach/regs-clock.h
View file @
b5783dca
...
...
@@ -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)
...
...
arch/arm/mach-s3c24xx/include/mach/regs-gpio.h
View file @
b5783dca
...
...
@@ -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 */
...
...
arch/arm/mach-s3c24xx/mach-amlm5900.c
View file @
b5783dca
...
...
@@ -161,11 +161,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
,
...
...
@@ -241,6 +246,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
arch/arm/mach-s3c24xx/mach-anubis.c
View file @
b5783dca
...
...
@@ -46,7 +46,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>
...
...
@@ -352,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
,
...
...
@@ -364,14 +364,6 @@ static struct platform_device *anubis_devices[] __initdata = {
&
anubis_device_sm501
,
};
static
struct
clk
*
anubis_clocks
[]
__initdata
=
{
&
s3c24xx_dclk0
,
&
s3c24xx_dclk1
,
&
s3c24xx_clkout0
,
&
s3c24xx_clkout1
,
&
s3c24xx_uclk
,
};
/* I2C devices. */
static
struct
i2c_board_info
anubis_i2c_devs
[]
__initdata
=
{
...
...
@@ -394,23 +386,7 @@ static struct s3c24xx_audio_simtec_pdata __initdata anubis_audio = {
static
void
__init
anubis_map_io
(
void
)
{
/* initialise the clocks */
s3c24xx_dclk0
.
parent
=
&
clk_upll
;
s3c24xx_dclk0
.
rate
=
12
*
1000
*
1000
;
s3c24xx_dclk1
.
parent
=
&
clk_upll
;
s3c24xx_dclk1
.
rate
=
24
*
1000
*
1000
;
s3c24xx_clkout0
.
parent
=
&
s3c24xx_dclk0
;
s3c24xx_clkout1
.
parent
=
&
s3c24xx_dclk1
;
s3c24xx_uclk
.
parent
=
&
s3c24xx_clkout1
;
s3c24xx_register_clocks
(
anubis_clocks
,
ARRAY_SIZE
(
anubis_clocks
));
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
);
...
...
@@ -428,6 +404,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
);
...
...
@@ -447,6 +429,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
arch/arm/mach-s3c24xx/mach-at2440evb.c
View file @
b5783dca
...
...
@@ -45,7 +45,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>
...
...
@@ -192,11 +191,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
);
...
...
@@ -213,6 +217,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
arch/arm/mach-s3c24xx/mach-bast.c
View file @
b5783dca
...
...
@@ -51,7 +51,6 @@
#include <mach/regs-lcd.h>
#include <mach/gpio-samsung.h>
#include <plat/clock.h>
#include <plat/cpu.h>
#include <plat/cpu-freq.h>
#include <plat/devs.h>
...
...
@@ -523,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
,
...
...
@@ -537,14 +537,6 @@ static struct platform_device *bast_devices[] __initdata = {
&
bast_sio
,
};
static
struct
clk
*
bast_clocks
[]
__initdata
=
{
&
s3c24xx_dclk0
,
&
s3c24xx_dclk1
,
&
s3c24xx_clkout0
,
&
s3c24xx_clkout1
,
&
s3c24xx_uclk
,
};
static
struct
s3c_cpufreq_board
__initdata
bast_cpufreq
=
{
.
refresh
=
7800
,
/* 7.8usec */
.
auto_io
=
1
,
...
...
@@ -558,29 +550,19 @@ static struct s3c24xx_audio_simtec_pdata __initdata bast_audio = {
static
void
__init
bast_map_io
(
void
)
{
/* initialise the clocks */
s3c24xx_dclk0
.
parent
=
&
clk_upll
;
s3c24xx_dclk0
.
rate
=
12
*
1000
*
1000
;
s3c24xx_dclk1
.
parent
=
&
clk_upll
;
s3c24xx_dclk1
.
rate
=
24
*
1000
*
1000
;
s3c24xx_clkout0
.
parent
=
&
s3c24xx_dclk0
;
s3c24xx_clkout1
.
parent
=
&
s3c24xx_dclk1
;
s3c24xx_uclk
.
parent
=
&
s3c24xx_clkout1
;
s3c24xx_register_clocks
(
bast_clocks
,
ARRAY_SIZE
(
bast_clocks
));
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
);
...
...
@@ -608,6 +590,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
arch/arm/mach-s3c24xx/mach-gta02.c
View file @
b5783dca
...
...
@@ -501,7 +501,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
);
}
...
...
@@ -585,6 +584,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> */
...
...
@@ -592,6 +596,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
arch/arm/mach-s3c24xx/mach-h1940.c
View file @
b5783dca
...
...
@@ -57,7 +57,6 @@
#include <mach/regs-lcd.h>
#include <mach/gpio-samsung.h>
#include <plat/clock.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/gpio-cfg.h>
...
...
@@ -646,7 +645,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
);
...
...
@@ -662,6 +660,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
)
{
...
...
@@ -739,6 +743,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
arch/arm/mach-s3c24xx/mach-jive.c
View file @
b5783dca
...
...
@@ -507,11 +507,16 @@ static struct syscore_ops jive_pm_syscore_ops = {
static
void
__init
jive_map_io
(
void
)
{
s3c24xx_init_io
(
jive_iodesc
,
ARRAY_SIZE
(
jive_iodesc
));
s3c24xx_init_clocks
(
12000000
);
s3c24xx_init_uarts
(
jive_uartcfgs
,
ARRAY_SIZE
(
jive_uartcfgs
));
samsung_set_timer_source
(
SAMSUNG_PWM3
,
SAMSUNG_PWM4
);
}
static
void
__init
jive_init_time
(
void
)
{
s3c2412_init_clocks
(
12000000
);
samsung_timer_init
();
}
static
void
jive_power_off
(
void
)
{
printk
(
KERN_INFO
"powering system down...
\n
"
);
...
...
@@ -665,6 +670,6 @@ MACHINE_START(JIVE, "JIVE")
.
init_irq
=
s3c2412_init_irq
,
.
map_io
=
jive_map_io
,
.
init_machine
=
jive_machine_init
,
.
init_time
=
samsung_timer_init
,
.
init_time
=
jive_init_time
,
.
restart
=
s3c2412_restart
,
MACHINE_END
arch/arm/mach-s3c24xx/mach-mini2440.c
View file @
b5783dca
...
...
@@ -54,7 +54,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>
...
...
@@ -525,11 +524,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
*
...
...
@@ -690,6 +694,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
arch/arm/mach-s3c24xx/mach-n30.c
View file @
b5783dca
...
...
@@ -45,7 +45,6 @@
#include <linux/platform_data/i2c-s3c2410.h>
#include <plat/clock.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <linux/platform_data/mmc-s3cmci.h>
...
...
@@ -535,11 +534,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
)
...
...
@@ -591,7 +595,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
,
...
...
@@ -602,7 +606,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
,
...
...
arch/arm/mach-s3c24xx/mach-nexcoder.c
View file @
b5783dca
...
...
@@ -42,7 +42,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>
...
...
@@ -135,13 +134,18 @@ 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
)
{
s3c2440_init_clocks
(
12000000
);
samsung_timer_init
();
}
static
void
__init
nexcoder_init
(
void
)
{
s3c_i2c0_set_platdata
(
NULL
);
...
...
@@ -154,6 +158,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
arch/arm/mach-s3c24xx/mach-osiris.c
View file @
b5783dca
...
...
@@ -40,7 +40,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>
...
...
@@ -344,20 +343,13 @@ 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
,
};
static
struct
clk
*
osiris_clocks
[]
__initdata
=
{
&
s3c24xx_dclk0
,
&
s3c24xx_dclk1
,
&
s3c24xx_clkout0
,
&
s3c24xx_clkout1
,
&
s3c24xx_uclk
,
};
static
struct
s3c_cpufreq_board
__initdata
osiris_cpufreq
=
{
.
refresh
=
7800
,
/* refresh period is 7.8usec */
.
auto_io
=
1
,
...
...
@@ -368,23 +360,7 @@ static void __init osiris_map_io(void)
{
unsigned
long
flags
;
/* initialise the clocks */
s3c24xx_dclk0
.
parent
=
&
clk_upll
;
s3c24xx_dclk0
.
rate
=
12
*
1000
*
1000
;
s3c24xx_dclk1
.
parent
=
&
clk_upll
;
s3c24xx_dclk1
.
rate
=
24
*
1000
*
1000
;
s3c24xx_clkout0
.
parent
=
&
s3c24xx_dclk0
;
s3c24xx_clkout1
.
parent
=
&
s3c24xx_dclk1
;
s3c24xx_uclk
.
parent
=
&
s3c24xx_clkout1
;
s3c24xx_register_clocks
(
osiris_clocks
,
ARRAY_SIZE
(
osiris_clocks
));
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
);
...
...
@@ -408,6 +384,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
);
...
...
@@ -429,6 +411,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
arch/arm/mach-s3c24xx/mach-otom.c
View file @
b5783dca
...
...
@@ -30,7 +30,6 @@
#include <mach/hardware.h>
#include <mach/regs-gpio.h>
#include <plat/clock.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/samsung-time.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
arch/arm/mach-s3c24xx/mach-qt2410.c
View file @
b5783dca
...
...
@@ -304,11 +304,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
);
...
...
@@ -346,6 +351,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
arch/arm/mach-s3c24xx/mach-rx1950.c
View file @
b5783dca
...
...
@@ -54,7 +54,6 @@
#include <mach/regs-lcd.h>
#include <mach/gpio-samsung.h>
#include <plat/clock.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/pm.h>
...
...
@@ -710,6 +709,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
,
...
...
@@ -728,20 +728,9 @@ static struct platform_device *rx1950_devices[] __initdata = {
&
rx1950_leds
,
};
static
struct
clk
*
rx1950_clocks
[]
__initdata
=
{
&
s3c24xx_clkout0
,
&
s3c24xx_clkout1
,
};
static
void
__init
rx1950_map_io
(
void
)
{
s3c24xx_clkout0
.
parent
=
&
clk_h
;
s3c24xx_clkout1
.
parent
=
&
clk_f
;
s3c24xx_register_clocks
(
rx1950_clocks
,
ARRAY_SIZE
(
rx1950_clocks
));
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
);
...
...
@@ -754,6 +743,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
;
...
...
@@ -816,6 +811,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
arch/arm/mach-s3c24xx/mach-rx3715.c
View file @
b5783dca
...
...
@@ -46,7 +46,6 @@
#include <mach/regs-lcd.h>
#include <mach/gpio-samsung.h>
#include <plat/clock.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/pm.h>
...
...
@@ -179,11 +178,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
)
{
...
...
@@ -210,6 +214,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
arch/arm/mach-s3c24xx/mach-s3c2416-dt.c
View file @
b5783dca
...
...
@@ -18,7 +18,6 @@
#include <linux/clocksource.h>
#include <linux/irqchip.h>
#include <linux/of_platform.h>
#include <linux/serial_core.h>
#include <linux/serial_s3c.h>
#include <asm/mach/arch.h>
...
...
@@ -29,48 +28,14 @@
#include "common.h"
/*
* The following lookup table is used to override device names when devices
* are registered from device tree. This is temporarily added to enable
* device tree support addition for the S3C2416 architecture.
*
* For drivers that require platform data to be provided from the machine
* file, a platform data pointer can also be supplied along with the
* devices names. Usually, the platform data elements that cannot be parsed
* from the device tree by the drivers (example: function pointers) are
* supplied. But it should be noted that this is a temporary mechanism and
* at some point, the drivers should be capable of parsing all the platform
* data from the device tree.
*/
static
const
struct
of_dev_auxdata
s3c2416_auxdata_lookup
[]
__initconst
=
{
OF_DEV_AUXDATA
(
"samsung,s3c2440-uart"
,
S3C24XX_PA_UART
,
"s3c2440-uart.0"
,
NULL
),
OF_DEV_AUXDATA
(
"samsung,s3c2440-uart"
,
S3C24XX_PA_UART
+
0x4000
,
"s3c2440-uart.1"
,
NULL
),
OF_DEV_AUXDATA
(
"samsung,s3c2440-uart"
,
S3C24XX_PA_UART
+
0x8000
,
"s3c2440-uart.2"
,
NULL
),
OF_DEV_AUXDATA
(
"samsung,s3c2440-uart"
,
S3C24XX_PA_UART
+
0xC000
,
"s3c2440-uart.3"
,
NULL
),
OF_DEV_AUXDATA
(
"samsung,s3c6410-sdhci"
,
S3C_PA_HSMMC0
,
"s3c-sdhci.0"
,
NULL
),
OF_DEV_AUXDATA
(
"samsung,s3c6410-sdhci"
,
S3C_PA_HSMMC1
,
"s3c-sdhci.1"
,
NULL
),
OF_DEV_AUXDATA
(
"samsung,s3c2440-i2c"
,
S3C_PA_IIC
,
"s3c2440-i2c.0"
,
NULL
),
{},
};
static
void
__init
s3c2416_dt_map_io
(
void
)
{
s3c24xx_init_io
(
NULL
,
0
);
s3c24xx_init_clocks
(
12000000
);
}
static
void
__init
s3c2416_dt_machine_init
(
void
)
{
of_platform_populate
(
NULL
,
of_default_bus_match_table
,
s3c2416_auxdata_lookup
,
NULL
);
of_platform_populate
(
NULL
,
of_default_bus_match_table
,
NULL
,
NULL
);
s3c_pm_init
();
}
...
...
@@ -86,6 +51,5 @@ DT_MACHINE_START(S3C2416_DT, "Samsung S3C2416 (Flattened Device Tree)")
.
map_io
=
s3c2416_dt_map_io
,
.
init_irq
=
irqchip_init
,
.
init_machine
=
s3c2416_dt_machine_init
,
.
init_time
=
clocksource_of_init
,
.
restart
=
s3c2416_restart
,
MACHINE_END
arch/arm/mach-s3c24xx/mach-smdk2410.c
View file @
b5783dca
...
...
@@ -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
=
s
amsung_timer_init
,
.
init_time
=
s
mdk2410_init_time
,
.
restart
=
s3c2410_restart
,
MACHINE_END
arch/arm/mach-s3c24xx/mach-smdk2413.c
View file @
b5783dca
...
...
@@ -106,11 +106,16 @@ static void __init smdk2413_fixup(struct tag *tags, char **cmdline,
static
void
__init
smdk2413_map_io
(
void
)
{
s3c24xx_init_io
(
smdk2413_iodesc
,
ARRAY_SIZE
(
smdk2413_iodesc
));
s3c24xx_init_clocks
(
12000000
);
s3c24xx_init_uarts
(
smdk2413_uartcfgs
,
ARRAY_SIZE
(
smdk2413_uartcfgs
));
samsung_set_timer_source
(
SAMSUNG_PWM3
,
SAMSUNG_PWM4
);
}
static
void
__init
smdk2413_init_time
(
void
)
{
s3c2412_init_clocks
(
12000000
);
samsung_timer_init
();
}
static
void
__init
smdk2413_machine_init
(
void
)
{
/* Turn off suspend on both USB ports, and switch the
* selectable USB port to USB device mode. */
...
...
@@ -159,6 +164,6 @@ MACHINE_START(SMDK2413, "SMDK2413")
.
init_irq
=
s3c2412_init_irq
,
.
map_io
=
smdk2413_map_io
,
.
init_machine
=
smdk2413_machine_init
,
.
init_time
=
s
amsung_timer_init
,
.
init_time
=
s
mdk2413_init_time
,
.
restart
=
s3c2412_restart
,
MACHINE_END
arch/arm/mach-s3c24xx/mach-smdk2416.c
View file @
b5783dca
...
...
@@ -219,10 +219,15 @@ static struct platform_device *smdk2416_devices[] __initdata = {
&
s3c2443_device_dma
,
};
static
void
__init
smdk2416_init_time
(
void
)
{
s3c2416_init_clocks
(
12000000
);
samsung_timer_init
();
}
static
void
__init
smdk2416_map_io
(
void
)
{
s3c24xx_init_io
(
smdk2416_iodesc
,
ARRAY_SIZE
(
smdk2416_iodesc
));
s3c24xx_init_clocks
(
12000000
);
s3c24xx_init_uarts
(
smdk2416_uartcfgs
,
ARRAY_SIZE
(
smdk2416_uartcfgs
));
samsung_set_timer_source
(
SAMSUNG_PWM3
,
SAMSUNG_PWM4
);
}
...
...
@@ -257,6 +262,6 @@ MACHINE_START(SMDK2416, "SMDK2416")
.
init_irq
=
s3c2416_init_irq
,
.
map_io
=
smdk2416_map_io
,
.
init_machine
=
smdk2416_machine_init
,
.
init_time
=
s
amsung_timer_init
,
.
init_time
=
s
mdk2416_init_time
,
.
restart
=
s3c2416_restart
,
MACHINE_END
arch/arm/mach-s3c24xx/mach-smdk2440.c
View file @
b5783dca
...
...
@@ -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
=
s
amsung_timer_init
,
.
init_time
=
s
mdk2440_init_time
,
.
restart
=
s3c244x_restart
,
MACHINE_END
arch/arm/mach-s3c24xx/mach-smdk2443.c
View file @
b5783dca
...
...
@@ -121,11 +121,16 @@ static struct platform_device *smdk2443_devices[] __initdata = {
static
void
__init
smdk2443_map_io
(
void
)
{
s3c24xx_init_io
(
smdk2443_iodesc
,
ARRAY_SIZE
(
smdk2443_iodesc
));
s3c24xx_init_clocks
(
12000000
);
s3c24xx_init_uarts
(
smdk2443_uartcfgs
,
ARRAY_SIZE
(
smdk2443_uartcfgs
));
samsung_set_timer_source
(
SAMSUNG_PWM3
,
SAMSUNG_PWM4
);
}
static
void
__init
smdk2443_init_time
(
void
)
{
s3c2443_init_clocks
(
12000000
);
samsung_timer_init
();
}
static
void
__init
smdk2443_machine_init
(
void
)
{
s3c_i2c0_set_platdata
(
NULL
);
...
...
@@ -145,6 +150,6 @@ MACHINE_START(SMDK2443, "SMDK2443")
.
init_irq
=
s3c2443_init_irq
,
.
map_io
=
smdk2443_map_io
,
.
init_machine
=
smdk2443_machine_init
,
.
init_time
=
s
amsung_timer_init
,
.
init_time
=
s
mdk2443_init_time
,
.
restart
=
s3c2443_restart
,
MACHINE_END
arch/arm/mach-s3c24xx/mach-tct_hammer.c
View file @
b5783dca
...
...
@@ -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
arch/arm/mach-s3c24xx/mach-vr1000.c
View file @
b5783dca
...
...
@@ -43,7 +43,6 @@
#include <mach/regs-gpio.h>
#include <mach/gpio-samsung.h>
#include <plat/clock.h>
#include <plat/cpu.h>
#include <plat/devs.h>
#include <plat/samsung-time.h>
...
...
@@ -286,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
,
...
...
@@ -299,14 +299,6 @@ static struct platform_device *vr1000_devices[] __initdata = {
&
vr1000_led3
,
};
static
struct
clk
*
vr1000_clocks
[]
__initdata
=
{
&
s3c24xx_dclk0
,
&
s3c24xx_dclk1
,
&
s3c24xx_clkout0
,
&
s3c24xx_clkout1
,
&
s3c24xx_uclk
,
};
static
void
vr1000_power_off
(
void
)
{
gpio_direction_output
(
S3C2410_GPB
(
9
),
1
);
...
...
@@ -314,29 +306,19 @@ static void vr1000_power_off(void)
static
void
__init
vr1000_map_io
(
void
)
{
/* initialise clock sources */
s3c24xx_dclk0
.
parent
=
&
clk_upll
;
s3c24xx_dclk0
.
rate
=
12
*
1000
*
1000
;
s3c24xx_dclk1
.
parent
=
NULL
;
s3c24xx_dclk1
.
rate
=
3692307
;
s3c24xx_clkout0
.
parent
=
&
s3c24xx_dclk0
;
s3c24xx_clkout1
.
parent
=
&
s3c24xx_dclk1
;
s3c24xx_uclk
.
parent
=
&
s3c24xx_clkout1
;
s3c24xx_register_clocks
(
vr1000_clocks
,
ARRAY_SIZE
(
vr1000_clocks
));
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
);
...
...
@@ -357,6 +339,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
arch/arm/mach-s3c24xx/mach-vstms.c
View file @
b5783dca
...
...
@@ -142,11 +142,16 @@ static void __init vstms_fixup(struct tag *tags, char **cmdline,
static
void
__init
vstms_map_io
(
void
)
{
s3c24xx_init_io
(
vstms_iodesc
,
ARRAY_SIZE
(
vstms_iodesc
));
s3c24xx_init_clocks
(
12000000
);
s3c24xx_init_uarts
(
vstms_uartcfgs
,
ARRAY_SIZE
(
vstms_uartcfgs
));
samsung_set_timer_source
(
SAMSUNG_PWM3
,
SAMSUNG_PWM4
);
}
static
void
__init
vstms_init_time
(
void
)
{
s3c2412_init_clocks
(
12000000
);
samsung_timer_init
();
}
static
void
__init
vstms_init
(
void
)
{
s3c_i2c0_set_platdata
(
NULL
);
...
...
@@ -162,6 +167,6 @@ MACHINE_START(VSTMS, "VSTMS")
.
init_irq
=
s3c2412_init_irq
,
.
init_machine
=
vstms_init
,
.
map_io
=
vstms_map_io
,
.
init_time
=
samsung_timer_init
,
.
init_time
=
vstms_init_time
,
.
restart
=
s3c2412_restart
,
MACHINE_END
arch/arm/mach-s3c24xx/pm.c
View file @
b5783dca
...
...
@@ -51,9 +51,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,18 +66,6 @@ static struct sleep_save core_save[] = {
SAVE_ITEM
(
S3C2410_BANKCON3
),
SAVE_ITEM
(
S3C2410_BANKCON4
),
SAVE_ITEM
(
S3C2410_BANKCON5
),
#ifndef CONFIG_CPU_FREQ
SAVE_ITEM
(
S3C2410_CLKDIVN
),
SAVE_ITEM
(
S3C2410_MPLLCON
),
SAVE_ITEM
(
S3C2410_REFRESH
),
#endif
SAVE_ITEM
(
S3C2410_UPLLCON
),
SAVE_ITEM
(
S3C2410_CLKSLOW
),
};
static
struct
sleep_save
misc_save
[]
=
{
SAVE_ITEM
(
S3C2410_DCLKCON
),
};
/* s3c_pm_check_resume_pin
...
...
@@ -140,12 +125,10 @@ void s3c_pm_configure_extint(void)
void
s3c_pm_restore_core
(
void
)
{
s3c_pm_do_restore_core
(
core_save
,
ARRAY_SIZE
(
core_save
));
s3c_pm_do_restore
(
misc_save
,
ARRAY_SIZE
(
misc_save
));
}
void
s3c_pm_save_core
(
void
)
{
s3c_pm_do_save
(
misc_save
,
ARRAY_SIZE
(
misc_save
));
s3c_pm_do_save
(
core_save
,
ARRAY_SIZE
(
core_save
));
}
arch/arm/mach-s3c24xx/s3c2410.c
View file @
b5783dca
...
...
@@ -85,62 +85,6 @@ void __init s3c2410_map_io(void)
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
);
}
struct
bus_type
s3c2410_subsys
=
{
...
...
arch/arm/mach-s3c24xx/s3c2412.c
View file @
b5783dca
...
...
@@ -173,49 +173,6 @@ void __init s3c2412_map_io(void)
void
__init_or_cpufreq
s3c2412_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
*
2
);
clk_mpll
.
rate
=
fclk
;
tmp
=
__raw_readl
(
S3C2410_CLKDIVN
);
/* work out clock scalings */
hclk
=
fclk
/
((
tmp
&
S3C2412_CLKDIVN_HDIVN_MASK
)
+
1
);
hclk
/=
((
tmp
&
S3C2412_CLKDIVN_ARMDIVN
)
?
2
:
1
);
pclk
=
hclk
/
((
tmp
&
S3C2412_CLKDIVN_PDIVN
)
?
2
:
1
);
/* print brieft summary of clocks, etc */
printk
(
"S3C2412: 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
s3c2412_init_clocks
(
int
xtal
)
{
/* initialise the clocks here, to allow other things like the
* console to use them
*/
s3c24xx_register_baseclocks
(
xtal
);
s3c2412_setup_clocks
();
s3c2412_baseclk_add
();
}
/* need to register the subsystem before we actually register the device, and
...
...
arch/arm/mach-s3c24xx/s3c2442.c
View file @
b5783dca
...
...
@@ -53,117 +53,6 @@
#include "common.h"
/* 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
);
static
struct
device
s3c2442_dev
=
{
.
bus
=
&
s3c2442_subsys
,
};
...
...
arch/arm/mach-s3c24xx/s3c244x.c
View file @
b5783dca
...
...
@@ -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,67 +75,11 @@ 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
)
{
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
);
}
/* Since the S3C2442 and S3C2440 share items, put both subsystems here */
...
...
arch/arm/plat-samsung/include/plat/cpu-freq-core.h
View file @
b5783dca
...
...
@@ -119,6 +119,7 @@ struct s3c_plltab {
struct
s3c_cpufreq_config
{
struct
s3c_freq
freq
;
struct
s3c_freq
max
;
struct
clk
*
mpll
;
struct
cpufreq_frequency_table
pll
;
struct
s3c_clkdivs
divs
;
struct
s3c_cpufreq_info
*
info
;
/* for core, not drivers */
...
...
drivers/clk/samsung/Makefile
View file @
b5783dca
...
...
@@ -8,4 +8,8 @@ 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_S3C2412_COMMON_CLK)
+=
clk-s3c2412.o
obj-$(CONFIG_S3C2443_COMMON_CLK)
+=
clk-s3c2443.o
obj-$(CONFIG_ARCH_S3C64XX)
+=
clk-s3c64xx.o
drivers/clk/samsung/clk-pll.c
View file @
b5783dca
...
...
@@ -11,6 +11,7 @@
#include <linux/errno.h>
#include <linux/hrtimer.h>
#include <linux/delay.h>
#include "clk.h"
#include "clk-pll.h"
...
...
@@ -58,6 +59,72 @@ static long samsung_pll_round_rate(struct clk_hw *hw,
return
rate_table
[
i
-
1
].
rate
;
}
/*
* PLL2126 Clock Type
*/
#define PLL2126_MDIV_MASK (0xff)
#define PLL2126_PDIV_MASK (0x3f)
#define PLL2126_SDIV_MASK (0x3)
#define PLL2126_MDIV_SHIFT (16)
#define PLL2126_PDIV_SHIFT (8)
#define PLL2126_SDIV_SHIFT (0)
static
unsigned
long
samsung_pll2126_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
>>
PLL2126_MDIV_SHIFT
)
&
PLL2126_MDIV_MASK
;
pdiv
=
(
pll_con
>>
PLL2126_PDIV_SHIFT
)
&
PLL2126_PDIV_MASK
;
sdiv
=
(
pll_con
>>
PLL2126_SDIV_SHIFT
)
&
PLL2126_SDIV_MASK
;
fvco
*=
(
mdiv
+
8
);
do_div
(
fvco
,
(
pdiv
+
2
)
<<
sdiv
);
return
(
unsigned
long
)
fvco
;
}
static
const
struct
clk_ops
samsung_pll2126_clk_ops
=
{
.
recalc_rate
=
samsung_pll2126_recalc_rate
,
};
/*
* PLL3000 Clock Type
*/
#define PLL3000_MDIV_MASK (0xff)
#define PLL3000_PDIV_MASK (0x3)
#define PLL3000_SDIV_MASK (0x3)
#define PLL3000_MDIV_SHIFT (16)
#define PLL3000_PDIV_SHIFT (8)
#define PLL3000_SDIV_SHIFT (0)
static
unsigned
long
samsung_pll3000_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
>>
PLL3000_MDIV_SHIFT
)
&
PLL3000_MDIV_MASK
;
pdiv
=
(
pll_con
>>
PLL3000_PDIV_SHIFT
)
&
PLL3000_PDIV_MASK
;
sdiv
=
(
pll_con
>>
PLL3000_SDIV_SHIFT
)
&
PLL3000_SDIV_MASK
;
fvco
*=
(
2
*
(
mdiv
+
8
));
do_div
(
fvco
,
pdiv
<<
sdiv
);
return
(
unsigned
long
)
fvco
;
}
static
const
struct
clk_ops
samsung_pll3000_clk_ops
=
{
.
recalc_rate
=
samsung_pll3000_recalc_rate
,
};
/*
* PLL35xx Clock Type
*/
...
...
@@ -564,7 +631,9 @@ static const struct clk_ops samsung_pll46xx_clk_min_ops = {
#define PLL6552_PDIV_MASK 0x3f
#define PLL6552_SDIV_MASK 0x7
#define PLL6552_MDIV_SHIFT 16
#define PLL6552_MDIV_SHIFT_2416 14
#define PLL6552_PDIV_SHIFT 8
#define PLL6552_PDIV_SHIFT_2416 5
#define PLL6552_SDIV_SHIFT 0
static
unsigned
long
samsung_pll6552_recalc_rate
(
struct
clk_hw
*
hw
,
...
...
@@ -575,8 +644,13 @@ static unsigned long samsung_pll6552_recalc_rate(struct clk_hw *hw,
u64
fvco
=
parent_rate
;
pll_con
=
__raw_readl
(
pll
->
con_reg
);
if
(
pll
->
type
==
pll_6552_s3c2416
)
{
mdiv
=
(
pll_con
>>
PLL6552_MDIV_SHIFT_2416
)
&
PLL6552_MDIV_MASK
;
pdiv
=
(
pll_con
>>
PLL6552_PDIV_SHIFT_2416
)
&
PLL6552_PDIV_MASK
;
}
else
{
mdiv
=
(
pll_con
>>
PLL6552_MDIV_SHIFT
)
&
PLL6552_MDIV_MASK
;
pdiv
=
(
pll_con
>>
PLL6552_PDIV_SHIFT
)
&
PLL6552_PDIV_MASK
;
}
sdiv
=
(
pll_con
>>
PLL6552_SDIV_SHIFT
)
&
PLL6552_SDIV_MASK
;
fvco
*=
mdiv
;
...
...
@@ -627,6 +701,169 @@ static const struct clk_ops samsung_pll6553_clk_ops = {
.
recalc_rate
=
samsung_pll6553_recalc_rate
,
};
/*
* 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
*/
...
...
@@ -746,6 +983,12 @@ static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
}
switch
(
pll_clk
->
type
)
{
case
pll_2126
:
init
.
ops
=
&
samsung_pll2126_clk_ops
;
break
;
case
pll_3000
:
init
.
ops
=
&
samsung_pll3000_clk_ops
;
break
;
/* clk_ops for 35xx and 2550 are similar */
case
pll_35xx
:
case
pll_2550
:
...
...
@@ -773,6 +1016,7 @@ static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk,
init
.
ops
=
&
samsung_pll36xx_clk_ops
;
break
;
case
pll_6552
:
case
pll_6552_s3c2416
:
init
.
ops
=
&
samsung_pll6552_clk_ops
;
break
;
case
pll_6553
:
...
...
@@ -786,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
);
...
...
drivers/clk/samsung/clk-pll.h
View file @
b5783dca
...
...
@@ -13,6 +13,8 @@
#define __SAMSUNG_CLK_PLL_H
enum
samsung_pll_type
{
pll_2126
,
pll_3000
,
pll_35xx
,
pll_36xx
,
pll_2550
,
...
...
@@ -24,7 +26,11 @@ enum samsung_pll_type {
pll_4650
,
pll_4650c
,
pll_6552
,
pll_6552_s3c2416
,
pll_6553
,
pll_s3c2410_mpll
,
pll_s3c2410_upll
,
pll_s3c2440_mpll
,
};
#define PLL_35XX_RATE(_rate, _m, _p, _s) \
...
...
drivers/clk/samsung/clk-s3c2410-dclk.c
0 → 100644
View file @
b5783dca
/*
* 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 "clk.h"
/* legacy access to misccr, until dt conversion is finished */
#include <mach/hardware.h>
#include <mach/regs-gpio.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)
enum
supported_socs
{
S3C2410
,
S3C2412
,
S3C2440
,
S3C2443
,
};
struct
s3c24xx_dclk_drv_data
{
const
char
**
clkout0_parent_names
;
int
clkout0_num_parents
;
const
char
**
clkout1_parent_names
;
int
clkout1_num_parents
;
const
char
**
mux_parent_names
;
int
mux_num_parents
;
};
/*
* Clock for output-parent selection in misccr
*/
struct
s3c24xx_clkout
{
struct
clk_hw
hw
;
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
;
val
=
readl_relaxed
(
S3C24XX_MISCCR
)
>>
clkout
->
shift
;
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
;
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
,
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
->
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)
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"
,
"rtc_clkout"
,
"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"
,
"rtc_clkout"
,
"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"
,
"epll"
,
"rtc_clkout"
,
"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
int
s3c24xx_dclk_probe
(
struct
platform_device
*
pdev
)
{
struct
s3c24xx_dclk
*
s3c24xx_dclk
;
struct
resource
*
mem
;
struct
clk
**
clk_table
;
struct
s3c24xx_dclk_drv_data
*
dclk_variant
;
int
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
);
dclk_variant
=
(
struct
s3c24xx_dclk_drv_data
*
)
platform_get_device_id
(
pdev
)
->
driver_data
;
clk_table
[
MUX_DCLK0
]
=
clk_register_mux
(
&
pdev
->
dev
,
"mux_dclk0"
,
dclk_variant
->
mux_parent_names
,
dclk_variant
->
mux_num_parents
,
0
,
s3c24xx_dclk
->
base
,
1
,
1
,
0
,
&
s3c24xx_dclk
->
dclk_lock
);
clk_table
[
MUX_DCLK1
]
=
clk_register_mux
(
&
pdev
->
dev
,
"mux_dclk1"
,
dclk_variant
->
mux_parent_names
,
dclk_variant
->
mux_num_parents
,
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
);
clk_table
[
MUX_CLKOUT0
]
=
s3c24xx_register_clkout
(
&
pdev
->
dev
,
"clkout0"
,
dclk_variant
->
clkout0_parent_names
,
dclk_variant
->
clkout0_num_parents
,
4
,
7
);
clk_table
[
MUX_CLKOUT1
]
=
s3c24xx_register_clkout
(
&
pdev
->
dev
,
"clkout1"
,
dclk_variant
->
clkout1_parent_names
,
dclk_variant
->
clkout1_num_parents
,
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
);
if
(
!
ret
)
ret
=
clk_register_clkdev
(
clk_table
[
MUX_DCLK1
],
"dclk1"
,
NULL
);
if
(
!
ret
)
ret
=
clk_register_clkdev
(
clk_table
[
MUX_CLKOUT0
],
"clkout0"
,
NULL
);
if
(
!
ret
)
ret
=
clk_register_clkdev
(
clk_table
[
MUX_CLKOUT1
],
"clkout1"
,
NULL
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"failed to register aliases, %d
\n
"
,
ret
);
goto
err_clk_register
;
}
s3c24xx_dclk
->
dclk0_div_change_nb
.
notifier_call
=
s3c24xx_dclk0_div_notify
;
s3c24xx_dclk
->
dclk1_div_change_nb
.
notifier_call
=
s3c24xx_dclk1_div_notify
;
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
;
return
0
;
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
;
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
dclk_variants
[]
=
{
[
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
),
.
mux_parent_names
=
dclk_s3c2410_p
,
.
mux_num_parents
=
ARRAY_SIZE
(
dclk_s3c2410_p
),
},
[
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
),
.
mux_parent_names
=
dclk_s3c2410_p
,
.
mux_num_parents
=
ARRAY_SIZE
(
dclk_s3c2410_p
),
},
[
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
),
.
mux_parent_names
=
dclk_s3c2410_p
,
.
mux_num_parents
=
ARRAY_SIZE
(
dclk_s3c2410_p
),
},
[
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
),
.
mux_parent_names
=
dclk_s3c2443_p
,
.
mux_num_parents
=
ARRAY_SIZE
(
dclk_s3c2443_p
),
},
};
static
struct
platform_device_id
s3c24xx_dclk_driver_ids
[]
=
{
{
.
name
=
"s3c2410-dclk"
,
.
driver_data
=
(
kernel_ulong_t
)
&
dclk_variants
[
S3C2410
],
},
{
.
name
=
"s3c2412-dclk"
,
.
driver_data
=
(
kernel_ulong_t
)
&
dclk_variants
[
S3C2412
],
},
{
.
name
=
"s3c2440-dclk"
,
.
driver_data
=
(
kernel_ulong_t
)
&
dclk_variants
[
S3C2440
],
},
{
.
name
=
"s3c2443-dclk"
,
.
driver_data
=
(
kernel_ulong_t
)
&
dclk_variants
[
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
,
},
.
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"
);
drivers/clk/samsung/clk-s3c2410.c
0 → 100644
View file @
b5783dca
/*
* 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 <linux/syscore_ops.h>
#include <dt-bindings/clock/s3c2410.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
,
};
static
void
__iomem
*
reg_base
;
#ifdef CONFIG_PM_SLEEP
static
struct
samsung_clk_reg_dump
*
s3c2410_save
;
/*
* 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
,
};
static
int
s3c2410_clk_suspend
(
void
)
{
samsung_clk_save
(
reg_base
,
s3c2410_save
,
ARRAY_SIZE
(
s3c2410_clk_regs
));
return
0
;
}
static
void
s3c2410_clk_resume
(
void
)
{
samsung_clk_restore
(
reg_base
,
s3c2410_save
,
ARRAY_SIZE
(
s3c2410_clk_regs
));
}
static
struct
syscore_ops
s3c2410_clk_syscore_ops
=
{
.
suspend
=
s3c2410_clk_suspend
,
.
resume
=
s3c2410_clk_resume
,
};
static
void
s3c2410_clk_sleep_init
(
void
)
{
s3c2410_save
=
samsung_clk_alloc_reg_dump
(
s3c2410_clk_regs
,
ARRAY_SIZE
(
s3c2410_clk_regs
));
if
(
!
s3c2410_save
)
{
pr_warn
(
"%s: failed to allocate sleep save data, no sleep support!
\n
"
,
__func__
);
return
;
}
register_syscore_ops
(
&
s3c2410_clk_syscore_ops
);
return
;
}
#else
static
void
s3c2410_clk_sleep_init
(
void
)
{}
#endif
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
},
{
/* sentinel */
},
};
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
),
{
/* sentinel */
},
};
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
),
{
/* sentinel */
},
};
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
},
{
/* sentinel */
},
};
static
struct
clk_div_table
div_hclk_3_d
[]
=
{
{
.
val
=
0
,
.
div
=
3
},
{
.
val
=
1
,
.
div
=
6
},
{
/* sentinel */
},
};
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
*/
#define XTI 1
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
*
base
)
{
reg_base
=
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
);
/* 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
));
}
s3c2410_clk_sleep_init
();
}
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
);
drivers/clk/samsung/clk-s3c2412.c
0 → 100644
View file @
b5783dca
/*
* 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 S3C2412 and S3C2413.
*/
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/syscore_ops.h>
#include <dt-bindings/clock/s3c2412.h>
#include "clk.h"
#include "clk-pll.h"
#define LOCKTIME 0x00
#define MPLLCON 0x04
#define UPLLCON 0x08
#define CLKCON 0x0c
#define CLKDIVN 0x14
#define CLKSRC 0x1c
/* list of PLLs to be registered */
enum
s3c2412_plls
{
mpll
,
upll
,
};
static
void
__iomem
*
reg_base
;
#ifdef CONFIG_PM_SLEEP
static
struct
samsung_clk_reg_dump
*
s3c2412_save
;
/*
* list of controller registers to be saved and restored during a
* suspend/resume cycle.
*/
static
unsigned
long
s3c2412_clk_regs
[]
__initdata
=
{
LOCKTIME
,
MPLLCON
,
UPLLCON
,
CLKCON
,
CLKDIVN
,
CLKSRC
,
};
static
int
s3c2412_clk_suspend
(
void
)
{
samsung_clk_save
(
reg_base
,
s3c2412_save
,
ARRAY_SIZE
(
s3c2412_clk_regs
));
return
0
;
}
static
void
s3c2412_clk_resume
(
void
)
{
samsung_clk_restore
(
reg_base
,
s3c2412_save
,
ARRAY_SIZE
(
s3c2412_clk_regs
));
}
static
struct
syscore_ops
s3c2412_clk_syscore_ops
=
{
.
suspend
=
s3c2412_clk_suspend
,
.
resume
=
s3c2412_clk_resume
,
};
static
void
s3c2412_clk_sleep_init
(
void
)
{
s3c2412_save
=
samsung_clk_alloc_reg_dump
(
s3c2412_clk_regs
,
ARRAY_SIZE
(
s3c2412_clk_regs
));
if
(
!
s3c2412_save
)
{
pr_warn
(
"%s: failed to allocate sleep save data, no sleep support!
\n
"
,
__func__
);
return
;
}
register_syscore_ops
(
&
s3c2412_clk_syscore_ops
);
return
;
}
#else
static
void
s3c2412_clk_sleep_init
(
void
)
{}
#endif
static
struct
clk_div_table
divxti_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
},
{
/* sentinel */
},
};
struct
samsung_div_clock
s3c2412_dividers
[]
__initdata
=
{
DIV_T
(
0
,
"div_xti"
,
"xti"
,
CLKSRC
,
0
,
3
,
divxti_d
),
DIV
(
0
,
"div_cam"
,
"mux_cam"
,
CLKDIVN
,
16
,
4
),
DIV
(
0
,
"div_i2s"
,
"mux_i2s"
,
CLKDIVN
,
12
,
4
),
DIV
(
0
,
"div_uart"
,
"mux_uart"
,
CLKDIVN
,
8
,
4
),
DIV
(
0
,
"div_usb"
,
"mux_usb"
,
CLKDIVN
,
6
,
1
),
DIV
(
0
,
"div_hclk_half"
,
"hclk"
,
CLKDIVN
,
5
,
1
),
DIV
(
ARMDIV
,
"armdiv"
,
"msysclk"
,
CLKDIVN
,
3
,
1
),
DIV
(
PCLK
,
"pclk"
,
"hclk"
,
CLKDIVN
,
2
,
1
),
DIV
(
HCLK
,
"hclk"
,
"armdiv"
,
CLKDIVN
,
0
,
2
),
};
struct
samsung_fixed_factor_clock
s3c2412_ffactor
[]
__initdata
=
{
FFACTOR
(
0
,
"ff_hclk"
,
"hclk"
,
2
,
1
,
CLK_SET_RATE_PARENT
),
};
/*
* The first two use the OM[4] setting, which is not readable from
* software, so assume it is set to xti.
*/
PNAME
(
erefclk_p
)
=
{
"xti"
,
"xti"
,
"xti"
,
"ext"
};
PNAME
(
urefclk_p
)
=
{
"xti"
,
"xti"
,
"xti"
,
"ext"
};
PNAME
(
camclk_p
)
=
{
"usysclk"
,
"hclk"
};
PNAME
(
usbclk_p
)
=
{
"usysclk"
,
"hclk"
};
PNAME
(
i2sclk_p
)
=
{
"erefclk"
,
"mpll"
};
PNAME
(
uartclk_p
)
=
{
"erefclk"
,
"mpll"
};
PNAME
(
usysclk_p
)
=
{
"urefclk"
,
"upll"
};
PNAME
(
msysclk_p
)
=
{
"mdivclk"
,
"mpll"
};
PNAME
(
mdivclk_p
)
=
{
"xti"
,
"div_xti"
};
PNAME
(
armclk_p
)
=
{
"armdiv"
,
"hclk"
};
struct
samsung_mux_clock
s3c2412_muxes
[]
__initdata
=
{
MUX
(
0
,
"erefclk"
,
erefclk_p
,
CLKSRC
,
14
,
2
),
MUX
(
0
,
"urefclk"
,
urefclk_p
,
CLKSRC
,
12
,
2
),
MUX
(
0
,
"mux_cam"
,
camclk_p
,
CLKSRC
,
11
,
1
),
MUX
(
0
,
"mux_usb"
,
usbclk_p
,
CLKSRC
,
10
,
1
),
MUX
(
0
,
"mux_i2s"
,
i2sclk_p
,
CLKSRC
,
9
,
1
),
MUX
(
0
,
"mux_uart"
,
uartclk_p
,
CLKSRC
,
8
,
1
),
MUX
(
USYSCLK
,
"usysclk"
,
usysclk_p
,
CLKSRC
,
5
,
1
),
MUX
(
MSYSCLK
,
"msysclk"
,
msysclk_p
,
CLKSRC
,
4
,
1
),
MUX
(
MDIVCLK
,
"mdivclk"
,
mdivclk_p
,
CLKSRC
,
3
,
1
),
MUX
(
ARMCLK
,
"armclk"
,
armclk_p
,
CLKDIVN
,
4
,
1
),
};
static
struct
samsung_pll_clock
s3c2412_plls
[]
__initdata
=
{
[
mpll
]
=
PLL
(
pll_s3c2440_mpll
,
MPLL
,
"mpll"
,
"xti"
,
LOCKTIME
,
MPLLCON
,
NULL
),
[
upll
]
=
PLL
(
pll_s3c2410_upll
,
UPLL
,
"upll"
,
"urefclk"
,
LOCKTIME
,
UPLLCON
,
NULL
),
};
struct
samsung_gate_clock
s3c2412_gates
[]
__initdata
=
{
GATE
(
PCLK_WDT
,
"wdt"
,
"pclk"
,
CLKCON
,
28
,
0
,
0
),
GATE
(
PCLK_SPI
,
"spi"
,
"pclk"
,
CLKCON
,
27
,
0
,
0
),
GATE
(
PCLK_I2S
,
"i2s"
,
"pclk"
,
CLKCON
,
26
,
0
,
0
),
GATE
(
PCLK_I2C
,
"i2c"
,
"pclk"
,
CLKCON
,
25
,
0
,
0
),
GATE
(
PCLK_ADC
,
"adc"
,
"pclk"
,
CLKCON
,
24
,
0
,
0
),
GATE
(
PCLK_RTC
,
"rtc"
,
"pclk"
,
CLKCON
,
23
,
0
,
0
),
GATE
(
PCLK_GPIO
,
"gpio"
,
"pclk"
,
CLKCON
,
22
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
PCLK_UART2
,
"uart2"
,
"pclk"
,
CLKCON
,
21
,
0
,
0
),
GATE
(
PCLK_UART1
,
"uart1"
,
"pclk"
,
CLKCON
,
20
,
0
,
0
),
GATE
(
PCLK_UART0
,
"uart0"
,
"pclk"
,
CLKCON
,
19
,
0
,
0
),
GATE
(
PCLK_SDI
,
"sdi"
,
"pclk"
,
CLKCON
,
18
,
0
,
0
),
GATE
(
PCLK_PWM
,
"pwm"
,
"pclk"
,
CLKCON
,
17
,
0
,
0
),
GATE
(
PCLK_USBD
,
"usb-device"
,
"pclk"
,
CLKCON
,
16
,
0
,
0
),
GATE
(
SCLK_CAM
,
"sclk_cam"
,
"div_cam"
,
CLKCON
,
15
,
0
,
0
),
GATE
(
SCLK_UART
,
"sclk_uart"
,
"div_uart"
,
CLKCON
,
14
,
0
,
0
),
GATE
(
SCLK_I2S
,
"sclk_i2s"
,
"div_i2s"
,
CLKCON
,
13
,
0
,
0
),
GATE
(
SCLK_USBH
,
"sclk_usbh"
,
"div_usb"
,
CLKCON
,
12
,
0
,
0
),
GATE
(
SCLK_USBD
,
"sclk_usbd"
,
"div_usb"
,
CLKCON
,
11
,
0
,
0
),
GATE
(
HCLK_HALF
,
"hclk_half"
,
"div_hclk_half"
,
CLKCON
,
10
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
HCLK_X2
,
"hclkx2"
,
"ff_hclk"
,
CLKCON
,
9
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
HCLK_SDRAM
,
"sdram"
,
"hclk"
,
CLKCON
,
8
,
CLK_IGNORE_UNUSED
,
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
),
GATE
(
HCLK_DMA3
,
"dma3"
,
"hclk"
,
CLKCON
,
3
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
HCLK_DMA2
,
"dma2"
,
"hclk"
,
CLKCON
,
2
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
HCLK_DMA1
,
"dma1"
,
"hclk"
,
CLKCON
,
1
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
HCLK_DMA0
,
"dma0"
,
"hclk"
,
CLKCON
,
0
,
CLK_IGNORE_UNUSED
,
0
),
};
struct
samsung_clock_alias
s3c2412_aliases
[]
__initdata
=
{
ALIAS
(
PCLK_UART0
,
"s3c2412-uart.0"
,
"uart"
),
ALIAS
(
PCLK_UART1
,
"s3c2412-uart.1"
,
"uart"
),
ALIAS
(
PCLK_UART2
,
"s3c2412-uart.2"
,
"uart"
),
ALIAS
(
PCLK_UART0
,
"s3c2412-uart.0"
,
"clk_uart_baud2"
),
ALIAS
(
PCLK_UART1
,
"s3c2412-uart.1"
,
"clk_uart_baud2"
),
ALIAS
(
PCLK_UART2
,
"s3c2412-uart.2"
,
"clk_uart_baud2"
),
ALIAS
(
SCLK_UART
,
NULL
,
"clk_uart_baud3"
),
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
(
PCLK_USBD
,
NULL
,
"usb-device"
),
ALIAS
(
SCLK_USBD
,
NULL
,
"usb-bus-gadget"
),
ALIAS
(
HCLK_USBH
,
NULL
,
"usb-host"
),
ALIAS
(
SCLK_USBH
,
NULL
,
"usb-bus-host"
),
ALIAS
(
ARMCLK
,
NULL
,
"armclk"
),
ALIAS
(
HCLK
,
NULL
,
"hclk"
),
ALIAS
(
MPLL
,
NULL
,
"mpll"
),
ALIAS
(
MSYSCLK
,
NULL
,
"fclk"
),
};
/*
* fixed rate clocks generated outside the soc
* Only necessary until the devicetree-move is complete
*/
#define XTI 1
struct
samsung_fixed_rate_clock
s3c2412_common_frate_clks
[]
__initdata
=
{
FRATE
(
XTI
,
"xti"
,
NULL
,
CLK_IS_ROOT
,
0
),
FRATE
(
0
,
"ext"
,
NULL
,
CLK_IS_ROOT
,
0
),
};
static
void
__init
s3c2412_common_clk_register_fixed_ext
(
unsigned
long
xti_f
,
unsigned
long
ext_f
)
{
/* xtal alias is necessary for the current cpufreq driver */
struct
samsung_clock_alias
xti_alias
=
ALIAS
(
XTI
,
NULL
,
"xtal"
);
s3c2412_common_frate_clks
[
0
].
fixed_rate
=
xti_f
;
s3c2412_common_frate_clks
[
1
].
fixed_rate
=
ext_f
;
samsung_clk_register_fixed_rate
(
s3c2412_common_frate_clks
,
ARRAY_SIZE
(
s3c2412_common_frate_clks
));
samsung_clk_register_alias
(
&
xti_alias
,
1
);
}
void
__init
s3c2412_common_clk_init
(
struct
device_node
*
np
,
unsigned
long
xti_f
,
unsigned
long
ext_f
,
void
__iomem
*
base
)
{
reg_base
=
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
);
/* Register external clocks only in non-dt cases */
if
(
!
np
)
s3c2412_common_clk_register_fixed_ext
(
xti_f
,
ext_f
);
/* Register PLLs. */
samsung_clk_register_pll
(
s3c2412_plls
,
ARRAY_SIZE
(
s3c2412_plls
),
reg_base
);
/* Register common internal clocks. */
samsung_clk_register_mux
(
s3c2412_muxes
,
ARRAY_SIZE
(
s3c2412_muxes
));
samsung_clk_register_div
(
s3c2412_dividers
,
ARRAY_SIZE
(
s3c2412_dividers
));
samsung_clk_register_gate
(
s3c2412_gates
,
ARRAY_SIZE
(
s3c2412_gates
));
samsung_clk_register_fixed_factor
(
s3c2412_ffactor
,
ARRAY_SIZE
(
s3c2412_ffactor
));
samsung_clk_register_alias
(
s3c2412_aliases
,
ARRAY_SIZE
(
s3c2412_aliases
));
s3c2412_clk_sleep_init
();
}
static
void
__init
s3c2412_clk_init
(
struct
device_node
*
np
)
{
s3c2412_common_clk_init
(
np
,
0
,
0
,
0
);
}
CLK_OF_DECLARE
(
s3c2412_clk
,
"samsung,s3c2412-clock"
,
s3c2412_clk_init
);
drivers/clk/samsung/clk-s3c2443.c
0 → 100644
View file @
b5783dca
/*
* 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 S3C2443 and following SoCs.
*/
#include <linux/clk.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/syscore_ops.h>
#include <dt-bindings/clock/s3c2443.h>
#include "clk.h"
#include "clk-pll.h"
/* S3C2416 clock controller register offsets */
#define LOCKCON0 0x00
#define LOCKCON1 0x04
#define MPLLCON 0x10
#define EPLLCON 0x18
#define EPLLCON_K 0x1C
#define CLKSRC 0x20
#define CLKDIV0 0x24
#define CLKDIV1 0x28
#define CLKDIV2 0x2C
#define HCLKCON 0x30
#define PCLKCON 0x34
#define SCLKCON 0x38
/* the soc types */
enum
supported_socs
{
S3C2416
,
S3C2443
,
S3C2450
,
};
/* list of PLLs to be registered */
enum
s3c2443_plls
{
mpll
,
epll
,
};
static
void
__iomem
*
reg_base
;
#ifdef CONFIG_PM_SLEEP
static
struct
samsung_clk_reg_dump
*
s3c2443_save
;
/*
* list of controller registers to be saved and restored during a
* suspend/resume cycle.
*/
static
unsigned
long
s3c2443_clk_regs
[]
__initdata
=
{
LOCKCON0
,
LOCKCON1
,
MPLLCON
,
EPLLCON
,
EPLLCON_K
,
CLKSRC
,
CLKDIV0
,
CLKDIV1
,
CLKDIV2
,
PCLKCON
,
HCLKCON
,
SCLKCON
,
};
static
int
s3c2443_clk_suspend
(
void
)
{
samsung_clk_save
(
reg_base
,
s3c2443_save
,
ARRAY_SIZE
(
s3c2443_clk_regs
));
return
0
;
}
static
void
s3c2443_clk_resume
(
void
)
{
samsung_clk_restore
(
reg_base
,
s3c2443_save
,
ARRAY_SIZE
(
s3c2443_clk_regs
));
}
static
struct
syscore_ops
s3c2443_clk_syscore_ops
=
{
.
suspend
=
s3c2443_clk_suspend
,
.
resume
=
s3c2443_clk_resume
,
};
static
void
s3c2443_clk_sleep_init
(
void
)
{
s3c2443_save
=
samsung_clk_alloc_reg_dump
(
s3c2443_clk_regs
,
ARRAY_SIZE
(
s3c2443_clk_regs
));
if
(
!
s3c2443_save
)
{
pr_warn
(
"%s: failed to allocate sleep save data, no sleep support!
\n
"
,
__func__
);
return
;
}
register_syscore_ops
(
&
s3c2443_clk_syscore_ops
);
return
;
}
#else
static
void
s3c2443_clk_sleep_init
(
void
)
{}
#endif
PNAME
(
epllref_p
)
=
{
"mpllref"
,
"mpllref"
,
"xti"
,
"ext"
};
PNAME
(
esysclk_p
)
=
{
"epllref"
,
"epll"
};
PNAME
(
mpllref_p
)
=
{
"xti"
,
"mdivclk"
};
PNAME
(
msysclk_p
)
=
{
"mpllref"
,
"mpll"
};
PNAME
(
armclk_p
)
=
{
"armdiv"
,
"hclk"
};
PNAME
(
i2s0_p
)
=
{
"div_i2s0"
,
"ext_i2s"
,
"epllref"
,
"epllref"
};
struct
samsung_mux_clock
s3c2443_common_muxes
[]
__initdata
=
{
MUX
(
0
,
"epllref"
,
epllref_p
,
CLKSRC
,
7
,
2
),
MUX
(
ESYSCLK
,
"esysclk"
,
esysclk_p
,
CLKSRC
,
6
,
1
),
MUX
(
0
,
"mpllref"
,
mpllref_p
,
CLKSRC
,
3
,
1
),
MUX_A
(
MSYSCLK
,
"msysclk"
,
msysclk_p
,
CLKSRC
,
4
,
1
,
"msysclk"
),
MUX_A
(
ARMCLK
,
"armclk"
,
armclk_p
,
CLKDIV0
,
13
,
1
,
"armclk"
),
MUX
(
0
,
"mux_i2s0"
,
i2s0_p
,
CLKSRC
,
14
,
2
),
};
static
struct
clk_div_table
hclk_d
[]
=
{
{
.
val
=
0
,
.
div
=
1
},
{
.
val
=
1
,
.
div
=
2
},
{
.
val
=
3
,
.
div
=
4
},
{
/* sentinel */
},
};
static
struct
clk_div_table
mdivclk_d
[]
=
{
{
.
val
=
0
,
.
div
=
1
},
{
.
val
=
1
,
.
div
=
3
},
{
.
val
=
2
,
.
div
=
5
},
{
.
val
=
3
,
.
div
=
7
},
{
.
val
=
4
,
.
div
=
9
},
{
.
val
=
5
,
.
div
=
11
},
{
.
val
=
6
,
.
div
=
13
},
{
.
val
=
7
,
.
div
=
15
},
{
/* sentinel */
},
};
struct
samsung_div_clock
s3c2443_common_dividers
[]
__initdata
=
{
DIV_T
(
0
,
"mdivclk"
,
"xti"
,
CLKDIV0
,
6
,
3
,
mdivclk_d
),
DIV
(
0
,
"prediv"
,
"msysclk"
,
CLKDIV0
,
4
,
2
),
DIV_T
(
HCLK
,
"hclk"
,
"prediv"
,
CLKDIV0
,
0
,
2
,
hclk_d
),
DIV
(
PCLK
,
"pclk"
,
"hclk"
,
CLKDIV0
,
2
,
1
),
DIV
(
0
,
"div_hsspi0_epll"
,
"esysclk"
,
CLKDIV1
,
24
,
2
),
DIV
(
0
,
"div_fimd"
,
"esysclk"
,
CLKDIV1
,
16
,
8
),
DIV
(
0
,
"div_i2s0"
,
"esysclk"
,
CLKDIV1
,
12
,
4
),
DIV
(
0
,
"div_uart"
,
"esysclk"
,
CLKDIV1
,
8
,
4
),
DIV
(
0
,
"div_hsmmc1"
,
"esysclk"
,
CLKDIV1
,
6
,
2
),
DIV
(
0
,
"div_usbhost"
,
"esysclk"
,
CLKDIV1
,
4
,
2
),
};
struct
samsung_gate_clock
s3c2443_common_gates
[]
__initdata
=
{
GATE
(
SCLK_HSMMC_EXT
,
"sclk_hsmmcext"
,
"ext"
,
SCLKCON
,
13
,
0
,
0
),
GATE
(
SCLK_HSMMC1
,
"sclk_hsmmc1"
,
"div_hsmmc1"
,
SCLKCON
,
12
,
0
,
0
),
GATE
(
SCLK_FIMD
,
"sclk_fimd"
,
"div_fimd"
,
SCLKCON
,
10
,
0
,
0
),
GATE
(
SCLK_I2S0
,
"sclk_i2s0"
,
"mux_i2s0"
,
SCLKCON
,
9
,
0
,
0
),
GATE
(
SCLK_UART
,
"sclk_uart"
,
"div_uart"
,
SCLKCON
,
8
,
0
,
0
),
GATE
(
SCLK_USBH
,
"sclk_usbhost"
,
"div_usbhost"
,
SCLKCON
,
1
,
0
,
0
),
GATE
(
HCLK_DRAM
,
"dram"
,
"hclk"
,
HCLKCON
,
19
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
HCLK_SSMC
,
"ssmc"
,
"hclk"
,
HCLKCON
,
18
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
HCLK_HSMMC1
,
"hsmmc1"
,
"hclk"
,
HCLKCON
,
16
,
0
,
0
),
GATE
(
HCLK_USBD
,
"usb-device"
,
"hclk"
,
HCLKCON
,
12
,
0
,
0
),
GATE
(
HCLK_USBH
,
"usb-host"
,
"hclk"
,
HCLKCON
,
11
,
0
,
0
),
GATE
(
HCLK_LCD
,
"lcd"
,
"hclk"
,
HCLKCON
,
9
,
0
,
0
),
GATE
(
HCLK_DMA5
,
"dma5"
,
"hclk"
,
HCLKCON
,
5
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
HCLK_DMA4
,
"dma4"
,
"hclk"
,
HCLKCON
,
4
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
HCLK_DMA3
,
"dma3"
,
"hclk"
,
HCLKCON
,
3
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
HCLK_DMA2
,
"dma2"
,
"hclk"
,
HCLKCON
,
2
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
HCLK_DMA1
,
"dma1"
,
"hclk"
,
HCLKCON
,
1
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
HCLK_DMA0
,
"dma0"
,
"hclk"
,
HCLKCON
,
0
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
PCLK_GPIO
,
"gpio"
,
"pclk"
,
PCLKCON
,
13
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
PCLK_RTC
,
"rtc"
,
"pclk"
,
PCLKCON
,
12
,
0
,
0
),
GATE
(
PCLK_WDT
,
"wdt"
,
"pclk"
,
PCLKCON
,
11
,
0
,
0
),
GATE
(
PCLK_PWM
,
"pwm"
,
"pclk"
,
PCLKCON
,
10
,
0
,
0
),
GATE
(
PCLK_I2S0
,
"i2s0"
,
"pclk"
,
PCLKCON
,
9
,
0
,
0
),
GATE
(
PCLK_AC97
,
"ac97"
,
"pclk"
,
PCLKCON
,
8
,
0
,
0
),
GATE
(
PCLK_ADC
,
"adc"
,
"pclk"
,
PCLKCON
,
7
,
0
,
0
),
GATE
(
PCLK_SPI0
,
"spi0"
,
"pclk"
,
PCLKCON
,
6
,
0
,
0
),
GATE
(
PCLK_I2C0
,
"i2c0"
,
"pclk"
,
PCLKCON
,
4
,
0
,
0
),
GATE
(
PCLK_UART3
,
"uart3"
,
"pclk"
,
PCLKCON
,
3
,
0
,
0
),
GATE
(
PCLK_UART2
,
"uart2"
,
"pclk"
,
PCLKCON
,
2
,
0
,
0
),
GATE
(
PCLK_UART1
,
"uart1"
,
"pclk"
,
PCLKCON
,
1
,
0
,
0
),
GATE
(
PCLK_UART0
,
"uart0"
,
"pclk"
,
PCLKCON
,
0
,
0
,
0
),
};
struct
samsung_clock_alias
s3c2443_common_aliases
[]
__initdata
=
{
ALIAS
(
HCLK
,
NULL
,
"hclk"
),
ALIAS
(
HCLK_SSMC
,
NULL
,
"nand"
),
ALIAS
(
PCLK_UART0
,
"s3c2440-uart.0"
,
"uart"
),
ALIAS
(
PCLK_UART1
,
"s3c2440-uart.1"
,
"uart"
),
ALIAS
(
PCLK_UART2
,
"s3c2440-uart.2"
,
"uart"
),
ALIAS
(
PCLK_UART3
,
"s3c2440-uart.3"
,
"uart"
),
ALIAS
(
PCLK_UART0
,
"s3c2440-uart.0"
,
"clk_uart_baud2"
),
ALIAS
(
PCLK_UART1
,
"s3c2440-uart.1"
,
"clk_uart_baud2"
),
ALIAS
(
PCLK_UART2
,
"s3c2440-uart.2"
,
"clk_uart_baud2"
),
ALIAS
(
PCLK_UART3
,
"s3c2440-uart.3"
,
"clk_uart_baud2"
),
ALIAS
(
SCLK_UART
,
NULL
,
"clk_uart_baud3"
),
ALIAS
(
PCLK_PWM
,
NULL
,
"timers"
),
ALIAS
(
PCLK_RTC
,
NULL
,
"rtc"
),
ALIAS
(
PCLK_WDT
,
NULL
,
"watchdog"
),
ALIAS
(
PCLK_ADC
,
NULL
,
"adc"
),
ALIAS
(
PCLK_I2C0
,
"s3c2410-i2c.0"
,
"i2c"
),
ALIAS
(
HCLK_USBD
,
NULL
,
"usb-device"
),
ALIAS
(
HCLK_USBH
,
NULL
,
"usb-host"
),
ALIAS
(
SCLK_USBH
,
NULL
,
"usb-bus-host"
),
ALIAS
(
PCLK_SPI0
,
"s3c2443-spi.0"
,
"spi"
),
ALIAS
(
PCLK_SPI0
,
"s3c2443-spi.0"
,
"spi_busclk0"
),
ALIAS
(
HCLK_HSMMC1
,
"s3c-sdhci.1"
,
"hsmmc"
),
ALIAS
(
HCLK_HSMMC1
,
"s3c-sdhci.1"
,
"mmc_busclk.0"
),
ALIAS
(
PCLK_I2S0
,
"samsung-i2s.0"
,
"iis"
),
ALIAS
(
SCLK_I2S0
,
NULL
,
"i2s-if"
),
ALIAS
(
HCLK_LCD
,
NULL
,
"lcd"
),
ALIAS
(
SCLK_FIMD
,
NULL
,
"sclk_fimd"
),
};
/* S3C2416 specific clocks */
static
struct
samsung_pll_clock
s3c2416_pll_clks
[]
__initdata
=
{
[
mpll
]
=
PLL
(
pll_6552_s3c2416
,
0
,
"mpll"
,
"mpllref"
,
LOCKCON0
,
MPLLCON
,
NULL
),
[
epll
]
=
PLL
(
pll_6553
,
0
,
"epll"
,
"epllref"
,
LOCKCON1
,
EPLLCON
,
NULL
),
};
PNAME
(
s3c2416_hsmmc0_p
)
=
{
"sclk_hsmmc0"
,
"sclk_hsmmcext"
};
PNAME
(
s3c2416_hsmmc1_p
)
=
{
"sclk_hsmmc1"
,
"sclk_hsmmcext"
};
PNAME
(
s3c2416_hsspi0_p
)
=
{
"hsspi0_epll"
,
"hsspi0_mpll"
};
static
struct
clk_div_table
armdiv_s3c2416_d
[]
=
{
{
.
val
=
0
,
.
div
=
1
},
{
.
val
=
1
,
.
div
=
2
},
{
.
val
=
2
,
.
div
=
3
},
{
.
val
=
3
,
.
div
=
4
},
{
.
val
=
5
,
.
div
=
6
},
{
.
val
=
7
,
.
div
=
8
},
{
/* sentinel */
},
};
struct
samsung_div_clock
s3c2416_dividers
[]
__initdata
=
{
DIV_T
(
ARMDIV
,
"armdiv"
,
"msysclk"
,
CLKDIV0
,
9
,
3
,
armdiv_s3c2416_d
),
DIV
(
0
,
"div_hsspi0_mpll"
,
"msysclk"
,
CLKDIV2
,
0
,
4
),
DIV
(
0
,
"div_hsmmc0"
,
"esysclk"
,
CLKDIV2
,
6
,
2
),
};
struct
samsung_mux_clock
s3c2416_muxes
[]
__initdata
=
{
MUX
(
MUX_HSMMC0
,
"mux_hsmmc0"
,
s3c2416_hsmmc0_p
,
CLKSRC
,
16
,
1
),
MUX
(
MUX_HSMMC1
,
"mux_hsmmc1"
,
s3c2416_hsmmc1_p
,
CLKSRC
,
17
,
1
),
MUX
(
MUX_HSSPI0
,
"mux_hsspi0"
,
s3c2416_hsspi0_p
,
CLKSRC
,
18
,
1
),
};
struct
samsung_gate_clock
s3c2416_gates
[]
__initdata
=
{
GATE
(
0
,
"hsspi0_mpll"
,
"div_hsspi0_mpll"
,
SCLKCON
,
19
,
0
,
0
),
GATE
(
0
,
"hsspi0_epll"
,
"div_hsspi0_epll"
,
SCLKCON
,
14
,
0
,
0
),
GATE
(
0
,
"sclk_hsmmc0"
,
"div_hsmmc0"
,
SCLKCON
,
6
,
0
,
0
),
GATE
(
HCLK_2D
,
"2d"
,
"hclk"
,
HCLKCON
,
20
,
0
,
0
),
GATE
(
HCLK_HSMMC0
,
"hsmmc0"
,
"hclk"
,
HCLKCON
,
15
,
0
,
0
),
GATE
(
HCLK_IROM
,
"irom"
,
"hclk"
,
HCLKCON
,
13
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
PCLK_PCM
,
"pcm"
,
"pclk"
,
PCLKCON
,
19
,
0
,
0
),
};
struct
samsung_clock_alias
s3c2416_aliases
[]
__initdata
=
{
ALIAS
(
HCLK_HSMMC0
,
"s3c-sdhci.0"
,
"hsmmc"
),
ALIAS
(
HCLK_HSMMC0
,
"s3c-sdhci.0"
,
"mmc_busclk.0"
),
ALIAS
(
MUX_HSMMC0
,
"s3c-sdhci.0"
,
"mmc_busclk.2"
),
ALIAS
(
MUX_HSMMC1
,
"s3c-sdhci.1"
,
"mmc_busclk.2"
),
ALIAS
(
MUX_HSSPI0
,
"s3c2443-spi.0"
,
"spi_busclk2"
),
ALIAS
(
ARMDIV
,
NULL
,
"armdiv"
),
};
/* S3C2443 specific clocks */
static
struct
samsung_pll_clock
s3c2443_pll_clks
[]
__initdata
=
{
[
mpll
]
=
PLL
(
pll_3000
,
0
,
"mpll"
,
"mpllref"
,
LOCKCON0
,
MPLLCON
,
NULL
),
[
epll
]
=
PLL
(
pll_2126
,
0
,
"epll"
,
"epllref"
,
LOCKCON1
,
EPLLCON
,
NULL
),
};
static
struct
clk_div_table
armdiv_s3c2443_d
[]
=
{
{
.
val
=
0
,
.
div
=
1
},
{
.
val
=
8
,
.
div
=
2
},
{
.
val
=
2
,
.
div
=
3
},
{
.
val
=
9
,
.
div
=
4
},
{
.
val
=
10
,
.
div
=
6
},
{
.
val
=
11
,
.
div
=
8
},
{
.
val
=
13
,
.
div
=
12
},
{
.
val
=
15
,
.
div
=
16
},
{
/* sentinel */
},
};
struct
samsung_div_clock
s3c2443_dividers
[]
__initdata
=
{
DIV_T
(
ARMDIV
,
"armdiv"
,
"msysclk"
,
CLKDIV0
,
9
,
4
,
armdiv_s3c2443_d
),
DIV
(
0
,
"div_cam"
,
"esysclk"
,
CLKDIV1
,
26
,
4
),
};
struct
samsung_gate_clock
s3c2443_gates
[]
__initdata
=
{
GATE
(
SCLK_HSSPI0
,
"sclk_hsspi0"
,
"div_hsspi0_epll"
,
SCLKCON
,
14
,
0
,
0
),
GATE
(
SCLK_CAM
,
"sclk_cam"
,
"div_cam"
,
SCLKCON
,
11
,
0
,
0
),
GATE
(
HCLK_CFC
,
"cfc"
,
"hclk"
,
HCLKCON
,
17
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
HCLK_CAM
,
"cam"
,
"hclk"
,
HCLKCON
,
8
,
0
,
0
),
GATE
(
PCLK_SPI1
,
"spi1"
,
"pclk"
,
PCLKCON
,
15
,
0
,
0
),
GATE
(
PCLK_SDI
,
"sdi"
,
"pclk"
,
PCLKCON
,
5
,
0
,
0
),
};
struct
samsung_clock_alias
s3c2443_aliases
[]
__initdata
=
{
ALIAS
(
SCLK_HSSPI0
,
"s3c2443-spi.0"
,
"spi_busclk2"
),
ALIAS
(
SCLK_HSMMC1
,
"s3c-sdhci.1"
,
"mmc_busclk.2"
),
ALIAS
(
SCLK_CAM
,
NULL
,
"camif-upll"
),
ALIAS
(
PCLK_SPI1
,
"s3c2410-spi.0"
,
"spi"
),
ALIAS
(
PCLK_SDI
,
NULL
,
"sdi"
),
ALIAS
(
HCLK_CFC
,
NULL
,
"cfc"
),
ALIAS
(
ARMDIV
,
NULL
,
"armdiv"
),
};
/* S3C2450 specific clocks */
PNAME
(
s3c2450_cam_p
)
=
{
"div_cam"
,
"hclk"
};
PNAME
(
s3c2450_hsspi1_p
)
=
{
"hsspi1_epll"
,
"hsspi1_mpll"
};
PNAME
(
i2s1_p
)
=
{
"div_i2s1"
,
"ext_i2s"
,
"epllref"
,
"epllref"
};
struct
samsung_div_clock
s3c2450_dividers
[]
__initdata
=
{
DIV
(
0
,
"div_cam"
,
"esysclk"
,
CLKDIV1
,
26
,
4
),
DIV
(
0
,
"div_hsspi1_epll"
,
"esysclk"
,
CLKDIV2
,
24
,
2
),
DIV
(
0
,
"div_hsspi1_mpll"
,
"msysclk"
,
CLKDIV2
,
16
,
4
),
DIV
(
0
,
"div_i2s1"
,
"esysclk"
,
CLKDIV2
,
12
,
4
),
};
struct
samsung_mux_clock
s3c2450_muxes
[]
__initdata
=
{
MUX
(
0
,
"mux_cam"
,
s3c2450_cam_p
,
CLKSRC
,
20
,
1
),
MUX
(
MUX_HSSPI1
,
"mux_hsspi1"
,
s3c2450_hsspi1_p
,
CLKSRC
,
19
,
1
),
MUX
(
0
,
"mux_i2s1"
,
i2s1_p
,
CLKSRC
,
12
,
2
),
};
struct
samsung_gate_clock
s3c2450_gates
[]
__initdata
=
{
GATE
(
SCLK_I2S1
,
"sclk_i2s1"
,
"div_i2s1"
,
SCLKCON
,
5
,
0
,
0
),
GATE
(
HCLK_CFC
,
"cfc"
,
"hclk"
,
HCLKCON
,
17
,
0
,
0
),
GATE
(
HCLK_CAM
,
"cam"
,
"hclk"
,
HCLKCON
,
8
,
0
,
0
),
GATE
(
HCLK_DMA7
,
"dma7"
,
"hclk"
,
HCLKCON
,
7
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
HCLK_DMA6
,
"dma6"
,
"hclk"
,
HCLKCON
,
6
,
CLK_IGNORE_UNUSED
,
0
),
GATE
(
PCLK_I2S1
,
"i2s1"
,
"pclk"
,
PCLKCON
,
17
,
0
,
0
),
GATE
(
PCLK_I2C1
,
"i2c1"
,
"pclk"
,
PCLKCON
,
16
,
0
,
0
),
GATE
(
PCLK_SPI1
,
"spi1"
,
"pclk"
,
PCLKCON
,
14
,
0
,
0
),
};
struct
samsung_clock_alias
s3c2450_aliases
[]
__initdata
=
{
ALIAS
(
PCLK_SPI1
,
"s3c2443-spi.1"
,
"spi"
),
ALIAS
(
PCLK_SPI1
,
"s3c2443-spi.1"
,
"spi_busclk0"
),
ALIAS
(
MUX_HSSPI1
,
"s3c2443-spi.1"
,
"spi_busclk2"
),
ALIAS
(
PCLK_I2C1
,
"s3c2410-i2c.1"
,
"i2c"
),
};
/*
* fixed rate clocks generated outside the soc
* Only necessary until the devicetree-move is complete
*/
struct
samsung_fixed_rate_clock
s3c2443_common_frate_clks
[]
__initdata
=
{
FRATE
(
0
,
"xti"
,
NULL
,
CLK_IS_ROOT
,
0
),
FRATE
(
0
,
"ext"
,
NULL
,
CLK_IS_ROOT
,
0
),
FRATE
(
0
,
"ext_i2s"
,
NULL
,
CLK_IS_ROOT
,
0
),
FRATE
(
0
,
"ext_uart"
,
NULL
,
CLK_IS_ROOT
,
0
),
};
static
void
__init
s3c2443_common_clk_register_fixed_ext
(
unsigned
long
xti_f
)
{
s3c2443_common_frate_clks
[
0
].
fixed_rate
=
xti_f
;
samsung_clk_register_fixed_rate
(
s3c2443_common_frate_clks
,
ARRAY_SIZE
(
s3c2443_common_frate_clks
));
}
void
__init
s3c2443_common_clk_init
(
struct
device_node
*
np
,
unsigned
long
xti_f
,
int
current_soc
,
void
__iomem
*
base
)
{
reg_base
=
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
);
/* Register external clocks only in non-dt cases */
if
(
!
np
)
s3c2443_common_clk_register_fixed_ext
(
xti_f
);
/* Register PLLs. */
if
(
current_soc
==
S3C2416
||
current_soc
==
S3C2450
)
samsung_clk_register_pll
(
s3c2416_pll_clks
,
ARRAY_SIZE
(
s3c2416_pll_clks
),
reg_base
);
else
samsung_clk_register_pll
(
s3c2443_pll_clks
,
ARRAY_SIZE
(
s3c2443_pll_clks
),
reg_base
);
/* Register common internal clocks. */
samsung_clk_register_mux
(
s3c2443_common_muxes
,
ARRAY_SIZE
(
s3c2443_common_muxes
));
samsung_clk_register_div
(
s3c2443_common_dividers
,
ARRAY_SIZE
(
s3c2443_common_dividers
));
samsung_clk_register_gate
(
s3c2443_common_gates
,
ARRAY_SIZE
(
s3c2443_common_gates
));
samsung_clk_register_alias
(
s3c2443_common_aliases
,
ARRAY_SIZE
(
s3c2443_common_aliases
));
/* Register SoC-specific clocks. */
switch
(
current_soc
)
{
case
S3C2450
:
samsung_clk_register_div
(
s3c2450_dividers
,
ARRAY_SIZE
(
s3c2450_dividers
));
samsung_clk_register_mux
(
s3c2450_muxes
,
ARRAY_SIZE
(
s3c2450_muxes
));
samsung_clk_register_gate
(
s3c2450_gates
,
ARRAY_SIZE
(
s3c2450_gates
));
samsung_clk_register_alias
(
s3c2450_aliases
,
ARRAY_SIZE
(
s3c2450_aliases
));
/* fall through, as s3c2450 extends the s3c2416 clocks */
case
S3C2416
:
samsung_clk_register_div
(
s3c2416_dividers
,
ARRAY_SIZE
(
s3c2416_dividers
));
samsung_clk_register_mux
(
s3c2416_muxes
,
ARRAY_SIZE
(
s3c2416_muxes
));
samsung_clk_register_gate
(
s3c2416_gates
,
ARRAY_SIZE
(
s3c2416_gates
));
samsung_clk_register_alias
(
s3c2416_aliases
,
ARRAY_SIZE
(
s3c2416_aliases
));
break
;
case
S3C2443
:
samsung_clk_register_div
(
s3c2443_dividers
,
ARRAY_SIZE
(
s3c2443_dividers
));
samsung_clk_register_gate
(
s3c2443_gates
,
ARRAY_SIZE
(
s3c2443_gates
));
samsung_clk_register_alias
(
s3c2443_aliases
,
ARRAY_SIZE
(
s3c2443_aliases
));
break
;
}
s3c2443_clk_sleep_init
();
}
static
void
__init
s3c2416_clk_init
(
struct
device_node
*
np
)
{
s3c2443_common_clk_init
(
np
,
0
,
S3C2416
,
0
);
}
CLK_OF_DECLARE
(
s3c2416_clk
,
"samsung,s3c2416-clock"
,
s3c2416_clk_init
);
static
void
__init
s3c2443_clk_init
(
struct
device_node
*
np
)
{
s3c2443_common_clk_init
(
np
,
0
,
S3C2443
,
0
);
}
CLK_OF_DECLARE
(
s3c2443_clk
,
"samsung,s3c2443-clock"
,
s3c2443_clk_init
);
static
void
__init
s3c2450_clk_init
(
struct
device_node
*
np
)
{
s3c2443_common_clk_init
(
np
,
0
,
S3C2450
,
0
);
}
CLK_OF_DECLARE
(
s3c2450_clk
,
"samsung,s3c2450-clock"
,
s3c2450_clk_init
);
drivers/cpufreq/s3c24xx-cpufreq.c
View file @
b5783dca
...
...
@@ -141,6 +141,7 @@ static int s3c_cpufreq_calcdivs(struct s3c_cpufreq_config *cfg)
static
void
s3c_cpufreq_setfvco
(
struct
s3c_cpufreq_config
*
cfg
)
{
cfg
->
mpll
=
_clk_mpll
;
(
cfg
->
info
->
set_fvco
)(
cfg
);
}
...
...
include/dt-bindings/clock/s3c2410.h
0 → 100644
View file @
b5783dca
/*
* 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. */
/* id 1 is reserved */
#define MPLL 2
#define UPLL 3
#define FCLK 4
#define HCLK 5
#define PCLK 6
#define UCLK 7
#define ARMCLK 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 */
include/dt-bindings/clock/s3c2412.h
0 → 100644
View file @
b5783dca
/*
* 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 S3C2412.
*/
#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C2412_CLOCK_H
#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C2412_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. */
/* id 1 is reserved */
#define MPLL 2
#define UPLL 3
#define MDIVCLK 4
#define MSYSCLK 5
#define USYSCLK 6
#define HCLK 7
#define PCLK 8
#define ARMDIV 9
#define ARMCLK 10
/* Special clocks */
#define SCLK_CAM 16
#define SCLK_UART 17
#define SCLK_I2S 18
#define SCLK_USBD 19
#define SCLK_USBH 20
/* pclk-gates */
#define PCLK_WDT 32
#define PCLK_SPI 33
#define PCLK_I2S 34
#define PCLK_I2C 35
#define PCLK_ADC 36
#define PCLK_RTC 37
#define PCLK_GPIO 38
#define PCLK_UART2 39
#define PCLK_UART1 40
#define PCLK_UART0 41
#define PCLK_SDI 42
#define PCLK_PWM 43
#define PCLK_USBD 44
/* hclk-gates */
#define HCLK_HALF 48
#define HCLK_X2 49
#define HCLK_SDRAM 50
#define HCLK_USBH 51
#define HCLK_LCD 52
#define HCLK_NAND 53
#define HCLK_DMA3 54
#define HCLK_DMA2 55
#define HCLK_DMA1 56
#define HCLK_DMA0 57
/* Total number of clocks. */
#define NR_CLKS (HCLK_DMA0 + 1)
#endif
/* _DT_BINDINGS_CLOCK_SAMSUNG_S3C2412_CLOCK_H */
include/dt-bindings/clock/s3c2443.h
0 → 100644
View file @
b5783dca
/*
* 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 S3C2443 and later.
*/
#ifndef _DT_BINDINGS_CLOCK_SAMSUNG_S3C2443_CLOCK_H
#define _DT_BINDINGS_CLOCK_SAMSUNG_S3C2443_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 MSYSCLK 1
#define ESYSCLK 2
#define ARMDIV 3
#define ARMCLK 4
#define HCLK 5
#define PCLK 6
/* Special clocks */
#define SCLK_HSSPI0 16
#define SCLK_FIMD 17
#define SCLK_I2S0 18
#define SCLK_I2S1 19
#define SCLK_HSMMC1 20
#define SCLK_HSMMC_EXT 21
#define SCLK_CAM 22
#define SCLK_UART 23
#define SCLK_USBH 24
/* Muxes */
#define MUX_HSSPI0 32
#define MUX_HSSPI1 33
#define MUX_HSMMC0 34
#define MUX_HSMMC1 35
/* hclk-gates */
#define HCLK_DMA0 48
#define HCLK_DMA1 49
#define HCLK_DMA2 50
#define HCLK_DMA3 51
#define HCLK_DMA4 52
#define HCLK_DMA5 53
#define HCLK_DMA6 54
#define HCLK_DMA7 55
#define HCLK_CAM 56
#define HCLK_LCD 57
#define HCLK_USBH 58
#define HCLK_USBD 59
#define HCLK_IROM 60
#define HCLK_HSMMC0 61
#define HCLK_HSMMC1 62
#define HCLK_CFC 63
#define HCLK_SSMC 64
#define HCLK_DRAM 65
#define HCLK_2D 66
/* pclk-gates */
#define PCLK_UART0 72
#define PCLK_UART1 73
#define PCLK_UART2 74
#define PCLK_UART3 75
#define PCLK_I2C0 76
#define PCLK_SDI 77
#define PCLK_SPI0 78
#define PCLK_ADC 79
#define PCLK_AC97 80
#define PCLK_I2S0 81
#define PCLK_PWM 82
#define PCLK_WDT 83
#define PCLK_RTC 84
#define PCLK_GPIO 85
#define PCLK_SPI1 86
#define PCLK_CHIPID 87
#define PCLK_I2C1 88
#define PCLK_I2S1 89
#define PCLK_PCM 90
/* Total number of clocks. */
#define NR_CLKS (PCLK_PCM + 1)
#endif
/* _DT_BINDINGS_CLOCK_SAMSUNG_S3C2443_CLOCK_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment