aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-s5pc1xx
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-s5pc1xx')
-rw-r--r--arch/arm/plat-s5pc1xx/Kconfig50
-rw-r--r--arch/arm/plat-s5pc1xx/Makefile26
-rw-r--r--arch/arm/plat-s5pc1xx/cpu.c112
-rw-r--r--arch/arm/plat-s5pc1xx/dev-uart.c174
-rw-r--r--arch/arm/plat-s5pc1xx/include/plat/irqs.h182
-rw-r--r--arch/arm/plat-s5pc1xx/include/plat/pll.h38
-rw-r--r--arch/arm/plat-s5pc1xx/include/plat/regs-clock.h421
-rw-r--r--arch/arm/plat-s5pc1xx/include/plat/s5pc100.h65
-rw-r--r--arch/arm/plat-s5pc1xx/irq.c259
-rw-r--r--arch/arm/plat-s5pc1xx/s5pc100-clock.c1139
-rw-r--r--arch/arm/plat-s5pc1xx/s5pc100-init.c27
-rw-r--r--arch/arm/plat-s5pc1xx/setup-i2c0.c25
-rw-r--r--arch/arm/plat-s5pc1xx/setup-i2c1.c25
13 files changed, 2543 insertions, 0 deletions
diff --git a/arch/arm/plat-s5pc1xx/Kconfig b/arch/arm/plat-s5pc1xx/Kconfig
new file mode 100644
index 000000000000..a8a711c3c064
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/Kconfig
@@ -0,0 +1,50 @@
1# arch/arm/plat-s5pc1xx/Kconfig
2#
3# Copyright 2009 Samsung Electronics Co.
4# Byungho Min <bhmin@samsung.com>
5#
6# Licensed under GPLv2
7
8config PLAT_S5PC1XX
9 bool
10 depends on ARCH_S5PC1XX
11 default y
12 select PLAT_S3C
13 select ARM_VIC
14 select NO_IOPORT
15 select ARCH_REQUIRE_GPIOLIB
16 select S3C_GPIO_TRACK
17 select S3C_GPIO_PULL_UPDOWN
18 help
19 Base platform code for any Samsung S5PC1XX device
20
21if PLAT_S5PC1XX
22
23# Configuration options shared by all S3C64XX implementations
24
25config CPU_S5PC100_INIT
26 bool
27 help
28 Common initialisation code for the S5PC1XX
29
30config CPU_S5PC100_CLOCK
31 bool
32 help
33 Common clock support code for the S5PC1XX
34
35# platform specific device setup
36
37config S5PC100_SETUP_I2C0
38 bool
39 default y
40 help
41 Common setup code for i2c bus 0.
42
43 Note, currently since i2c0 is always compiled, this setup helper
44 is always compiled with it.
45
46config S5PC100_SETUP_I2C1
47 bool
48 help
49 Common setup code for i2c bus 1.
50endif
diff --git a/arch/arm/plat-s5pc1xx/Makefile b/arch/arm/plat-s5pc1xx/Makefile
new file mode 100644
index 000000000000..f1ecb2c37ee2
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/Makefile
@@ -0,0 +1,26 @@
1# arch/arm/plat-s5pc1xx/Makefile
2#
3# Copyright 2009 Samsung Electronics Co.
4#
5# Licensed under GPLv2
6
7obj-y :=
8obj-m :=
9obj-n := dummy.o
10obj- :=
11
12# Core files
13
14obj-y += dev-uart.o
15obj-y += cpu.o
16obj-y += irq.o
17
18# CPU support
19
20obj-$(CONFIG_CPU_S5PC100_INIT) += s5pc100-init.o
21obj-$(CONFIG_CPU_S5PC100_CLOCK) += s5pc100-clock.o
22
23# Device setup
24
25obj-$(CONFIG_S5PC100_SETUP_I2C0) += setup-i2c0.o
26obj-$(CONFIG_S5PC100_SETUP_I2C1) += setup-i2c1.o
diff --git a/arch/arm/plat-s5pc1xx/cpu.c b/arch/arm/plat-s5pc1xx/cpu.c
new file mode 100644
index 000000000000..715a7330794d
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/cpu.c
@@ -0,0 +1,112 @@
1/* linux/arch/arm/plat-s5pc1xx/cpu.c
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC1XX CPU Support
7 *
8 * Based on plat-s3c64xx/cpu.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/interrupt.h>
18#include <linux/ioport.h>
19#include <linux/serial_core.h>
20#include <linux/platform_device.h>
21#include <linux/io.h>
22
23#include <mach/hardware.h>
24#include <mach/map.h>
25
26#include <asm/mach/map.h>
27
28#include <plat/regs-serial.h>
29
30#include <plat/cpu.h>
31#include <plat/devs.h>
32#include <plat/clock.h>
33
34#include <plat/s5pc100.h>
35
36/* table of supported CPUs */
37
38static const char name_s5pc100[] = "S5PC100";
39
40static struct cpu_table cpu_ids[] __initdata = {
41 {
42 .idcode = 0x43100000,
43 .idmask = 0xfffff000,
44 .map_io = s5pc100_map_io,
45 .init_clocks = s5pc100_init_clocks,
46 .init_uarts = s5pc100_init_uarts,
47 .init = s5pc100_init,
48 .name = name_s5pc100,
49 },
50};
51/* minimal IO mapping */
52
53/* see notes on uart map in arch/arm/mach-s5pc100/include/mach/debug-macro.S */
54#define UART_OFFS (S3C_PA_UART & 0xffff)
55
56static struct map_desc s5pc1xx_iodesc[] __initdata = {
57 {
58 .virtual = (unsigned long)S5PC1XX_VA_CHIPID,
59 .pfn = __phys_to_pfn(S5PC1XX_PA_CHIPID),
60 .length = SZ_16,
61 .type = MT_DEVICE,
62 }, {
63 .virtual = (unsigned long)S5PC1XX_VA_CLK,
64 .pfn = __phys_to_pfn(S5PC1XX_PA_CLK),
65 .length = SZ_4K,
66 .type = MT_DEVICE,
67 }, {
68 .virtual = (unsigned long)S5PC1XX_VA_PWR,
69 .pfn = __phys_to_pfn(S5PC1XX_PA_PWR),
70 .length = SZ_4K,
71 .type = MT_DEVICE,
72 }, {
73 .virtual = (unsigned long)(S5PC1XX_VA_UART),
74 .pfn = __phys_to_pfn(S5PC1XX_PA_UART),
75 .length = SZ_4K,
76 .type = MT_DEVICE,
77 }, {
78 .virtual = (unsigned long)S5PC1XX_VA_VIC(0),
79 .pfn = __phys_to_pfn(S5PC1XX_PA_VIC(0)),
80 .length = SZ_4K,
81 .type = MT_DEVICE,
82 }, {
83 .virtual = (unsigned long)S5PC1XX_VA_VIC(1),
84 .pfn = __phys_to_pfn(S5PC1XX_PA_VIC(1)),
85 .length = SZ_4K,
86 .type = MT_DEVICE,
87 }, {
88 .virtual = (unsigned long)S5PC1XX_VA_VIC(2),
89 .pfn = __phys_to_pfn(S5PC1XX_PA_VIC(2)),
90 .length = SZ_4K,
91 .type = MT_DEVICE,
92 }, {
93 .virtual = (unsigned long)S5PC1XX_VA_TIMER,
94 .pfn = __phys_to_pfn(S5PC1XX_PA_TIMER),
95 .length = SZ_256,
96 .type = MT_DEVICE,
97 },
98};
99
100/* read cpu identification code */
101
102void __init s5pc1xx_init_io(struct map_desc *mach_desc, int size)
103{
104 unsigned long idcode;
105
106 /* initialise the io descriptors we need for initialisation */
107 iotable_init(s5pc1xx_iodesc, ARRAY_SIZE(s5pc1xx_iodesc));
108 iotable_init(mach_desc, size);
109
110 idcode = __raw_readl(S5PC1XX_VA_CHIPID);
111 s3c_init_cpu(idcode, cpu_ids, ARRAY_SIZE(cpu_ids));
112}
diff --git a/arch/arm/plat-s5pc1xx/dev-uart.c b/arch/arm/plat-s5pc1xx/dev-uart.c
new file mode 100644
index 000000000000..f749bc5407b5
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/dev-uart.c
@@ -0,0 +1,174 @@
1/* linux/arch/arm/plat-s5pc1xx/dev-uart.c
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * Based on plat-s3c64xx/dev-uart.c
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12*/
13
14#include <linux/kernel.h>
15#include <linux/types.h>
16#include <linux/interrupt.h>
17#include <linux/list.h>
18#include <linux/platform_device.h>
19
20#include <asm/mach/arch.h>
21#include <asm/mach/irq.h>
22#include <mach/hardware.h>
23#include <mach/map.h>
24
25#include <plat/devs.h>
26
27/* Serial port registrations */
28
29/* 64xx uarts are closer together */
30
31static struct resource s5pc1xx_uart0_resource[] = {
32 [0] = {
33 .start = S3C_PA_UART0,
34 .end = S3C_PA_UART0 + 0x100,
35 .flags = IORESOURCE_MEM,
36 },
37 [1] = {
38 .start = IRQ_S3CUART_RX0,
39 .end = IRQ_S3CUART_RX0,
40 .flags = IORESOURCE_IRQ,
41 },
42 [2] = {
43 .start = IRQ_S3CUART_TX0,
44 .end = IRQ_S3CUART_TX0,
45 .flags = IORESOURCE_IRQ,
46
47 },
48 [3] = {
49 .start = IRQ_S3CUART_ERR0,
50 .end = IRQ_S3CUART_ERR0,
51 .flags = IORESOURCE_IRQ,
52 }
53};
54
55static struct resource s5pc1xx_uart1_resource[] = {
56 [0] = {
57 .start = S3C_PA_UART1,
58 .end = S3C_PA_UART1 + 0x100,
59 .flags = IORESOURCE_MEM,
60 },
61 [1] = {
62 .start = IRQ_S3CUART_RX1,
63 .end = IRQ_S3CUART_RX1,
64 .flags = IORESOURCE_IRQ,
65 },
66 [2] = {
67 .start = IRQ_S3CUART_TX1,
68 .end = IRQ_S3CUART_TX1,
69 .flags = IORESOURCE_IRQ,
70
71 },
72 [3] = {
73 .start = IRQ_S3CUART_ERR1,
74 .end = IRQ_S3CUART_ERR1,
75 .flags = IORESOURCE_IRQ,
76 },
77};
78
79static struct resource s5pc1xx_uart2_resource[] = {
80 [0] = {
81 .start = S3C_PA_UART2,
82 .end = S3C_PA_UART2 + 0x100,
83 .flags = IORESOURCE_MEM,
84 },
85 [1] = {
86 .start = IRQ_S3CUART_RX2,
87 .end = IRQ_S3CUART_RX2,
88 .flags = IORESOURCE_IRQ,
89 },
90 [2] = {
91 .start = IRQ_S3CUART_TX2,
92 .end = IRQ_S3CUART_TX2,
93 .flags = IORESOURCE_IRQ,
94
95 },
96 [3] = {
97 .start = IRQ_S3CUART_ERR2,
98 .end = IRQ_S3CUART_ERR2,
99 .flags = IORESOURCE_IRQ,
100 },
101};
102
103static struct resource s5pc1xx_uart3_resource[] = {
104 [0] = {
105 .start = S3C_PA_UART3,
106 .end = S3C_PA_UART3 + 0x100,
107 .flags = IORESOURCE_MEM,
108 },
109 [1] = {
110 .start = IRQ_S3CUART_RX3,
111 .end = IRQ_S3CUART_RX3,
112 .flags = IORESOURCE_IRQ,
113 },
114 [2] = {
115 .start = IRQ_S3CUART_TX3,
116 .end = IRQ_S3CUART_TX3,
117 .flags = IORESOURCE_IRQ,
118
119 },
120 [3] = {
121 .start = IRQ_S3CUART_ERR3,
122 .end = IRQ_S3CUART_ERR3,
123 .flags = IORESOURCE_IRQ,
124 },
125};
126
127
128struct s3c24xx_uart_resources s5pc1xx_uart_resources[] __initdata = {
129 [0] = {
130 .resources = s5pc1xx_uart0_resource,
131 .nr_resources = ARRAY_SIZE(s5pc1xx_uart0_resource),
132 },
133 [1] = {
134 .resources = s5pc1xx_uart1_resource,
135 .nr_resources = ARRAY_SIZE(s5pc1xx_uart1_resource),
136 },
137 [2] = {
138 .resources = s5pc1xx_uart2_resource,
139 .nr_resources = ARRAY_SIZE(s5pc1xx_uart2_resource),
140 },
141 [3] = {
142 .resources = s5pc1xx_uart3_resource,
143 .nr_resources = ARRAY_SIZE(s5pc1xx_uart3_resource),
144 },
145};
146
147/* uart devices */
148
149static struct platform_device s3c24xx_uart_device0 = {
150 .id = 0,
151};
152
153static struct platform_device s3c24xx_uart_device1 = {
154 .id = 1,
155};
156
157static struct platform_device s3c24xx_uart_device2 = {
158 .id = 2,
159};
160
161static struct platform_device s3c24xx_uart_device3 = {
162 .id = 3,
163};
164
165struct platform_device *s3c24xx_uart_src[4] = {
166 &s3c24xx_uart_device0,
167 &s3c24xx_uart_device1,
168 &s3c24xx_uart_device2,
169 &s3c24xx_uart_device3,
170};
171
172struct platform_device *s3c24xx_uart_devs[4] = {
173};
174
diff --git a/arch/arm/plat-s5pc1xx/include/plat/irqs.h b/arch/arm/plat-s5pc1xx/include/plat/irqs.h
new file mode 100644
index 000000000000..f07d8c3b25d6
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/irqs.h
@@ -0,0 +1,182 @@
1/* linux/arch/arm/plat-s5pc1xx/include/plat/irqs.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC1XX - Common IRQ support
7 *
8 * Based on plat-s3c64xx/include/plat/irqs.h
9 */
10
11#ifndef __ASM_PLAT_S5PC1XX_IRQS_H
12#define __ASM_PLAT_S5PC1XX_IRQS_H __FILE__
13
14/* we keep the first set of CPU IRQs out of the range of
15 * the ISA space, so that the PC104 has them to itself
16 * and we don't end up having to do horrible things to the
17 * standard ISA drivers....
18 *
19 * note, since we're using the VICs, our start must be a
20 * mulitple of 32 to allow the common code to work
21 */
22
23#define S3C_IRQ_OFFSET (32)
24
25#define S3C_IRQ(x) ((x) + S3C_IRQ_OFFSET)
26
27#define S3C_VIC0_BASE S3C_IRQ(0)
28#define S3C_VIC1_BASE S3C_IRQ(32)
29#define S3C_VIC2_BASE S3C_IRQ(64)
30
31/* UART interrupts, each UART has 4 intterupts per channel so
32 * use the space between the ISA and S3C main interrupts. Note, these
33 * are not in the same order as the S3C24XX series! */
34
35#define IRQ_S3CUART_BASE0 (16)
36#define IRQ_S3CUART_BASE1 (20)
37#define IRQ_S3CUART_BASE2 (24)
38#define IRQ_S3CUART_BASE3 (28)
39
40#define UART_IRQ_RXD (0)
41#define UART_IRQ_ERR (1)
42#define UART_IRQ_TXD (2)
43#define UART_IRQ_MODEM (3)
44
45#define IRQ_S3CUART_RX0 (IRQ_S3CUART_BASE0 + UART_IRQ_RXD)
46#define IRQ_S3CUART_TX0 (IRQ_S3CUART_BASE0 + UART_IRQ_TXD)
47#define IRQ_S3CUART_ERR0 (IRQ_S3CUART_BASE0 + UART_IRQ_ERR)
48
49#define IRQ_S3CUART_RX1 (IRQ_S3CUART_BASE1 + UART_IRQ_RXD)
50#define IRQ_S3CUART_TX1 (IRQ_S3CUART_BASE1 + UART_IRQ_TXD)
51#define IRQ_S3CUART_ERR1 (IRQ_S3CUART_BASE1 + UART_IRQ_ERR)
52
53#define IRQ_S3CUART_RX2 (IRQ_S3CUART_BASE2 + UART_IRQ_RXD)
54#define IRQ_S3CUART_TX2 (IRQ_S3CUART_BASE2 + UART_IRQ_TXD)
55#define IRQ_S3CUART_ERR2 (IRQ_S3CUART_BASE2 + UART_IRQ_ERR)
56
57#define IRQ_S3CUART_RX3 (IRQ_S3CUART_BASE3 + UART_IRQ_RXD)
58#define IRQ_S3CUART_TX3 (IRQ_S3CUART_BASE3 + UART_IRQ_TXD)
59#define IRQ_S3CUART_ERR3 (IRQ_S3CUART_BASE3 + UART_IRQ_ERR)
60
61/* VIC based IRQs */
62
63#define S5PC1XX_IRQ_VIC0(x) (S3C_VIC0_BASE + (x))
64#define S5PC1XX_IRQ_VIC1(x) (S3C_VIC1_BASE + (x))
65#define S5PC1XX_IRQ_VIC2(x) (S3C_VIC2_BASE + (x))
66
67/*
68 * VIC0: system, DMA, timer
69 */
70#define IRQ_EINT0 S5PC1XX_IRQ_VIC0(0)
71#define IRQ_EINT1 S5PC1XX_IRQ_VIC0(1)
72#define IRQ_EINT2 S5PC1XX_IRQ_VIC0(2)
73#define IRQ_EINT3 S5PC1XX_IRQ_VIC0(3)
74#define IRQ_EINT4 S5PC1XX_IRQ_VIC0(4)
75#define IRQ_EINT5 S5PC1XX_IRQ_VIC0(5)
76#define IRQ_EINT6 S5PC1XX_IRQ_VIC0(6)
77#define IRQ_EINT7 S5PC1XX_IRQ_VIC0(7)
78#define IRQ_EINT8 S5PC1XX_IRQ_VIC0(8)
79#define IRQ_EINT9 S5PC1XX_IRQ_VIC0(9)
80#define IRQ_EINT10 S5PC1XX_IRQ_VIC0(10)
81#define IRQ_EINT11 S5PC1XX_IRQ_VIC0(11)
82#define IRQ_EINT12 S5PC1XX_IRQ_VIC0(12)
83#define IRQ_EINT13 S5PC1XX_IRQ_VIC0(13)
84#define IRQ_EINT14 S5PC1XX_IRQ_VIC0(14)
85#define IRQ_EINT15 S5PC1XX_IRQ_VIC0(15)
86#define IRQ_EINT16_31 S5PC1XX_IRQ_VIC0(16)
87#define IRQ_BATF S5PC1XX_IRQ_VIC0(17)
88#define IRQ_MDMA S5PC1XX_IRQ_VIC0(18)
89#define IRQ_PDMA0 S5PC1XX_IRQ_VIC0(19)
90#define IRQ_PDMA1 S5PC1XX_IRQ_VIC0(20)
91#define IRQ_TIMER0 S5PC1XX_IRQ_VIC0(21)
92#define IRQ_TIMER1 S5PC1XX_IRQ_VIC0(22)
93#define IRQ_TIMER2 S5PC1XX_IRQ_VIC0(23)
94#define IRQ_TIMER3 S5PC1XX_IRQ_VIC0(24)
95#define IRQ_TIMER4 S5PC1XX_IRQ_VIC0(25)
96#define IRQ_SYSTIMER S5PC1XX_IRQ_VIC0(26)
97#define IRQ_WDT S5PC1XX_IRQ_VIC0(27)
98#define IRQ_RTC_ALARM S5PC1XX_IRQ_VIC0(28)
99#define IRQ_RTC_TIC S5PC1XX_IRQ_VIC0(29)
100#define IRQ_GPIOINT S5PC1XX_IRQ_VIC0(30)
101
102/*
103 * VIC1: ARM, power, memory, connectivity
104 */
105#define IRQ_CORTEX0 S5PC1XX_IRQ_VIC1(0)
106#define IRQ_CORTEX1 S5PC1XX_IRQ_VIC1(1)
107#define IRQ_CORTEX2 S5PC1XX_IRQ_VIC1(2)
108#define IRQ_CORTEX3 S5PC1XX_IRQ_VIC1(3)
109#define IRQ_CORTEX4 S5PC1XX_IRQ_VIC1(4)
110#define IRQ_IEMAPC S5PC1XX_IRQ_VIC1(5)
111#define IRQ_IEMIEC S5PC1XX_IRQ_VIC1(6)
112#define IRQ_ONENAND S5PC1XX_IRQ_VIC1(7)
113#define IRQ_NFC S5PC1XX_IRQ_VIC1(8)
114#define IRQ_CFC S5PC1XX_IRQ_VIC1(9)
115#define IRQ_UART0 S5PC1XX_IRQ_VIC1(10)
116#define IRQ_UART1 S5PC1XX_IRQ_VIC1(11)
117#define IRQ_UART2 S5PC1XX_IRQ_VIC1(12)
118#define IRQ_UART3 S5PC1XX_IRQ_VIC1(13)
119#define IRQ_IIC S5PC1XX_IRQ_VIC1(14)
120#define IRQ_SPI0 S5PC1XX_IRQ_VIC1(15)
121#define IRQ_SPI1 S5PC1XX_IRQ_VIC1(16)
122#define IRQ_SPI2 S5PC1XX_IRQ_VIC1(17)
123#define IRQ_IRDA S5PC1XX_IRQ_VIC1(18)
124#define IRQ_CAN0 S5PC1XX_IRQ_VIC1(19)
125#define IRQ_CAN1 S5PC1XX_IRQ_VIC1(20)
126#define IRQ_HSIRX S5PC1XX_IRQ_VIC1(21)
127#define IRQ_HSITX S5PC1XX_IRQ_VIC1(22)
128#define IRQ_UHOST S5PC1XX_IRQ_VIC1(23)
129#define IRQ_OTG S5PC1XX_IRQ_VIC1(24)
130#define IRQ_MSM S5PC1XX_IRQ_VIC1(25)
131#define IRQ_HSMMC0 S5PC1XX_IRQ_VIC1(26)
132#define IRQ_HSMMC1 S5PC1XX_IRQ_VIC1(27)
133#define IRQ_HSMMC2 S5PC1XX_IRQ_VIC1(28)
134#define IRQ_MIPICSI S5PC1XX_IRQ_VIC1(29)
135#define IRQ_MIPIDSI S5PC1XX_IRQ_VIC1(30)
136
137/*
138 * VIC2: multimedia, audio, security
139 */
140#define IRQ_LCD0 S5PC1XX_IRQ_VIC2(0)
141#define IRQ_LCD1 S5PC1XX_IRQ_VIC2(1)
142#define IRQ_LCD2 S5PC1XX_IRQ_VIC2(2)
143#define IRQ_LCD3 S5PC1XX_IRQ_VIC2(3)
144#define IRQ_ROTATOR S5PC1XX_IRQ_VIC2(4)
145#define IRQ_FIMC0 S5PC1XX_IRQ_VIC2(5)
146#define IRQ_FIMC1 S5PC1XX_IRQ_VIC2(6)
147#define IRQ_FIMC2 S5PC1XX_IRQ_VIC2(7)
148#define IRQ_JPEG S5PC1XX_IRQ_VIC2(8)
149#define IRQ_2D S5PC1XX_IRQ_VIC2(9)
150#define IRQ_3D S5PC1XX_IRQ_VIC2(10)
151#define IRQ_MIXER S5PC1XX_IRQ_VIC2(11)
152#define IRQ_HDMI S5PC1XX_IRQ_VIC2(12)
153#define IRQ_IIC1 S5PC1XX_IRQ_VIC2(13)
154#define IRQ_MFC S5PC1XX_IRQ_VIC2(14)
155#define IRQ_TVENC S5PC1XX_IRQ_VIC2(15)
156#define IRQ_I2S0 S5PC1XX_IRQ_VIC2(16)
157#define IRQ_I2S1 S5PC1XX_IRQ_VIC2(17)
158#define IRQ_I2S2 S5PC1XX_IRQ_VIC2(18)
159#define IRQ_AC97 S5PC1XX_IRQ_VIC2(19)
160#define IRQ_PCM0 S5PC1XX_IRQ_VIC2(20)
161#define IRQ_PCM1 S5PC1XX_IRQ_VIC2(21)
162#define IRQ_SPDIF S5PC1XX_IRQ_VIC2(22)
163#define IRQ_ADC S5PC1XX_IRQ_VIC2(23)
164#define IRQ_PENDN S5PC1XX_IRQ_VIC2(24)
165#define IRQ_TC IRQ_PENDN
166#define IRQ_KEYPAD S5PC1XX_IRQ_VIC2(25)
167#define IRQ_CG S5PC1XX_IRQ_VIC2(26)
168#define IRQ_SEC S5PC1XX_IRQ_VIC2(27)
169#define IRQ_SECRX S5PC1XX_IRQ_VIC2(28)
170#define IRQ_SECTX S5PC1XX_IRQ_VIC2(29)
171#define IRQ_SDMIRQ S5PC1XX_IRQ_VIC2(30)
172#define IRQ_SDMFIQ S5PC1XX_IRQ_VIC2(31)
173
174#define S3C_IRQ_EINT_BASE (IRQ_SDMFIQ + 1)
175
176#define S3C_EINT(x) ((x) + S3C_IRQ_EINT_BASE)
177#define IRQ_EINT(x) S3C_EINT(x)
178
179#define NR_IRQS (IRQ_EINT(31)+1)
180
181#endif /* __ASM_PLAT_S5PC1XX_IRQS_H */
182
diff --git a/arch/arm/plat-s5pc1xx/include/plat/pll.h b/arch/arm/plat-s5pc1xx/include/plat/pll.h
new file mode 100644
index 000000000000..21afef1573e7
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/pll.h
@@ -0,0 +1,38 @@
1/* arch/arm/plat-s5pc1xx/include/plat/pll.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC1XX PLL code
7 *
8 * Based on plat-s3c64xx/include/plat/pll.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#define S5P_PLL_MDIV_MASK ((1 << (25-16+1)) - 1)
16#define S5P_PLL_PDIV_MASK ((1 << (13-8+1)) - 1)
17#define S5P_PLL_SDIV_MASK ((1 << (2-0+1)) - 1)
18#define S5P_PLL_MDIV_SHIFT (16)
19#define S5P_PLL_PDIV_SHIFT (8)
20#define S5P_PLL_SDIV_SHIFT (0)
21
22#include <asm/div64.h>
23
24static inline unsigned long s5pc1xx_get_pll(unsigned long baseclk,
25 u32 pllcon)
26{
27 u32 mdiv, pdiv, sdiv;
28 u64 fvco = baseclk;
29
30 mdiv = (pllcon >> S5P_PLL_MDIV_SHIFT) & S5P_PLL_MDIV_MASK;
31 pdiv = (pllcon >> S5P_PLL_PDIV_SHIFT) & S5P_PLL_PDIV_MASK;
32 sdiv = (pllcon >> S5P_PLL_SDIV_SHIFT) & S5P_PLL_SDIV_MASK;
33
34 fvco *= mdiv;
35 do_div(fvco, (pdiv << sdiv));
36
37 return (unsigned long)fvco;
38}
diff --git a/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h b/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
new file mode 100644
index 000000000000..75c8390cb827
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
@@ -0,0 +1,421 @@
1/* arch/arm/plat-s5pc1xx/include/plat/regs-clock.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC1XX clock register definitions
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __PLAT_REGS_CLOCK_H
14#define __PLAT_REGS_CLOCK_H __FILE__
15
16#define S5PC1XX_CLKREG(x) (S5PC1XX_VA_CLK + (x))
17
18#define S5PC1XX_APLL_LOCK S5PC1XX_CLKREG(0x00)
19#define S5PC1XX_MPLL_LOCK S5PC1XX_CLKREG(0x04)
20#define S5PC1XX_EPLL_LOCK S5PC1XX_CLKREG(0x08)
21#define S5PC100_HPLL_LOCK S5PC1XX_CLKREG(0x0C)
22
23#define S5PC1XX_APLL_CON S5PC1XX_CLKREG(0x100)
24#define S5PC1XX_MPLL_CON S5PC1XX_CLKREG(0x104)
25#define S5PC1XX_EPLL_CON S5PC1XX_CLKREG(0x108)
26#define S5PC100_HPLL_CON S5PC1XX_CLKREG(0x10C)
27
28#define S5PC1XX_CLK_SRC0 S5PC1XX_CLKREG(0x200)
29#define S5PC1XX_CLK_SRC1 S5PC1XX_CLKREG(0x204)
30#define S5PC1XX_CLK_SRC2 S5PC1XX_CLKREG(0x208)
31#define S5PC1XX_CLK_SRC3 S5PC1XX_CLKREG(0x20C)
32
33#define S5PC1XX_CLK_DIV0 S5PC1XX_CLKREG(0x300)
34#define S5PC1XX_CLK_DIV1 S5PC1XX_CLKREG(0x304)
35#define S5PC1XX_CLK_DIV2 S5PC1XX_CLKREG(0x308)
36#define S5PC1XX_CLK_DIV3 S5PC1XX_CLKREG(0x30C)
37#define S5PC1XX_CLK_DIV4 S5PC1XX_CLKREG(0x310)
38
39#define S5PC100_CLK_OUT S5PC1XX_CLKREG(0x400)
40
41#define S5PC100_CLKGATE_D00 S5PC1XX_CLKREG(0x500)
42#define S5PC100_CLKGATE_D01 S5PC1XX_CLKREG(0x504)
43#define S5PC100_CLKGATE_D02 S5PC1XX_CLKREG(0x508)
44
45#define S5PC100_CLKGATE_D10 S5PC1XX_CLKREG(0x520)
46#define S5PC100_CLKGATE_D11 S5PC1XX_CLKREG(0x524)
47#define S5PC100_CLKGATE_D12 S5PC1XX_CLKREG(0x528)
48#define S5PC100_CLKGATE_D13 S5PC1XX_CLKREG(0x52C)
49#define S5PC100_CLKGATE_D14 S5PC1XX_CLKREG(0x530)
50#define S5PC100_CLKGATE_D15 S5PC1XX_CLKREG(0x534)
51
52#define S5PC100_CLKGATE_D20 S5PC1XX_CLKREG(0x540)
53
54#define S5PC100_SCLKGATE0 S5PC1XX_CLKREG(0x560)
55#define S5PC100_SCLKGATE1 S5PC1XX_CLKREG(0x564)
56
57#define S5PC100_OTHERS S5PC1XX_CLKREG(0x8200)
58
59#define S5PC1XX_EPLL_EN (1<<31)
60#define S5PC1XX_EPLL_MASK 0xffffffff
61#define S5PC1XX_EPLLVAL(_m, _p, _s) ((_m) << 16 | ((_p) << 8) | ((_s)))
62
63/* CLKSRC0 */
64#define S5PC1XX_CLKSRC0_APLL_MASK (0x1<<0)
65#define S5PC1XX_CLKSRC0_APLL_SHIFT (0)
66#define S5PC1XX_CLKSRC0_MPLL_MASK (0x1<<4)
67#define S5PC1XX_CLKSRC0_MPLL_SHIFT (4)
68#define S5PC1XX_CLKSRC0_EPLL_MASK (0x1<<8)
69#define S5PC1XX_CLKSRC0_EPLL_SHIFT (8)
70#define S5PC100_CLKSRC0_HPLL_MASK (0x1<<12)
71#define S5PC100_CLKSRC0_HPLL_SHIFT (12)
72#define S5PC100_CLKSRC0_AMMUX_MASK (0x1<<16)
73#define S5PC100_CLKSRC0_AMMUX_SHIFT (16)
74#define S5PC100_CLKSRC0_HREF_MASK (0x1<<20)
75#define S5PC100_CLKSRC0_HREF_SHIFT (20)
76#define S5PC1XX_CLKSRC0_ONENAND_MASK (0x1<<24)
77#define S5PC1XX_CLKSRC0_ONENAND_SHIFT (24)
78
79
80/* CLKSRC1 */
81#define S5PC100_CLKSRC1_UART_MASK (0x1<<0)
82#define S5PC100_CLKSRC1_UART_SHIFT (0)
83#define S5PC100_CLKSRC1_SPI0_MASK (0x3<<4)
84#define S5PC100_CLKSRC1_SPI0_SHIFT (4)
85#define S5PC100_CLKSRC1_SPI1_MASK (0x3<<8)
86#define S5PC100_CLKSRC1_SPI1_SHIFT (8)
87#define S5PC100_CLKSRC1_SPI2_MASK (0x3<<12)
88#define S5PC100_CLKSRC1_SPI2_SHIFT (12)
89#define S5PC100_CLKSRC1_IRDA_MASK (0x3<<16)
90#define S5PC100_CLKSRC1_IRDA_SHIFT (16)
91#define S5PC100_CLKSRC1_UHOST_MASK (0x3<<20)
92#define S5PC100_CLKSRC1_UHOST_SHIFT (20)
93#define S5PC100_CLKSRC1_CLK48M_MASK (0x1<<24)
94#define S5PC100_CLKSRC1_CLK48M_SHIFT (24)
95
96/* CLKSRC2 */
97#define S5PC100_CLKSRC2_MMC0_MASK (0x3<<0)
98#define S5PC100_CLKSRC2_MMC0_SHIFT (0)
99#define S5PC100_CLKSRC2_MMC1_MASK (0x3<<4)
100#define S5PC100_CLKSRC2_MMC1_SHIFT (4)
101#define S5PC100_CLKSRC2_MMC2_MASK (0x3<<8)
102#define S5PC100_CLKSRC2_MMC2_SHIFT (8)
103#define S5PC100_CLKSRC2_LCD_MASK (0x3<<12)
104#define S5PC100_CLKSRC2_LCD_SHIFT (12)
105#define S5PC100_CLKSRC2_FIMC0_MASK (0x3<<16)
106#define S5PC100_CLKSRC2_FIMC0_SHIFT (16)
107#define S5PC100_CLKSRC2_FIMC1_MASK (0x3<<20)
108#define S5PC100_CLKSRC2_FIMC1_SHIFT (20)
109#define S5PC100_CLKSRC2_FIMC2_MASK (0x3<<24)
110#define S5PC100_CLKSRC2_FIMC2_SHIFT (24)
111#define S5PC100_CLKSRC2_MIXER_MASK (0x3<<28)
112#define S5PC100_CLKSRC2_MIXER_SHIFT (28)
113
114/* CLKSRC3 */
115#define S5PC100_CLKSRC3_PWI_MASK (0x3<<0)
116#define S5PC100_CLKSRC3_PWI_SHIFT (0)
117#define S5PC100_CLKSRC3_HCLKD2_MASK (0x1<<4)
118#define S5PC100_CLKSRC3_HCLKD2_SHIFT (4)
119#define S5PC100_CLKSRC3_I2SD2_MASK (0x3<<8)
120#define S5PC100_CLKSRC3_I2SD2_SHIFT (8)
121#define S5PC100_CLKSRC3_AUDIO0_MASK (0x7<<12)
122#define S5PC100_CLKSRC3_AUDIO0_SHIFT (12)
123#define S5PC100_CLKSRC3_AUDIO1_MASK (0x7<<16)
124#define S5PC100_CLKSRC3_AUDIO1_SHIFT (16)
125#define S5PC100_CLKSRC3_AUDIO2_MASK (0x7<<20)
126#define S5PC100_CLKSRC3_AUDIO2_SHIFT (20)
127#define S5PC100_CLKSRC3_SPDIF_MASK (0x3<<24)
128#define S5PC100_CLKSRC3_SPDIF_SHIFT (24)
129
130
131/* CLKDIV0 */
132#define S5PC1XX_CLKDIV0_APLL_MASK (0x1<<0)
133#define S5PC1XX_CLKDIV0_APLL_SHIFT (0)
134#define S5PC100_CLKDIV0_ARM_MASK (0x7<<4)
135#define S5PC100_CLKDIV0_ARM_SHIFT (4)
136#define S5PC100_CLKDIV0_D0_MASK (0x7<<8)
137#define S5PC100_CLKDIV0_D0_SHIFT (8)
138#define S5PC100_CLKDIV0_PCLKD0_MASK (0x7<<12)
139#define S5PC100_CLKDIV0_PCLKD0_SHIFT (12)
140#define S5PC100_CLKDIV0_SECSS_MASK (0x7<<16)
141#define S5PC100_CLKDIV0_SECSS_SHIFT (16)
142
143/* CLKDIV1 */
144#define S5PC100_CLKDIV1_AM_MASK (0x7<<0)
145#define S5PC100_CLKDIV1_AM_SHIFT (0)
146#define S5PC100_CLKDIV1_MPLL_MASK (0x3<<4)
147#define S5PC100_CLKDIV1_MPLL_SHIFT (4)
148#define S5PC100_CLKDIV1_MPLL2_MASK (0x1<<8)
149#define S5PC100_CLKDIV1_MPLL2_SHIFT (8)
150#define S5PC100_CLKDIV1_D1_MASK (0x7<<12)
151#define S5PC100_CLKDIV1_D1_SHIFT (12)
152#define S5PC100_CLKDIV1_PCLKD1_MASK (0x7<<16)
153#define S5PC100_CLKDIV1_PCLKD1_SHIFT (16)
154#define S5PC100_CLKDIV1_ONENAND_MASK (0x3<<20)
155#define S5PC100_CLKDIV1_ONENAND_SHIFT (20)
156#define S5PC100_CLKDIV1_CAM_MASK (0x1F<<24)
157#define S5PC100_CLKDIV1_CAM_SHIFT (24)
158
159/* CLKDIV2 */
160#define S5PC100_CLKDIV2_UART_MASK (0x7<<0)
161#define S5PC100_CLKDIV2_UART_SHIFT (0)
162#define S5PC100_CLKDIV2_SPI0_MASK (0xf<<4)
163#define S5PC100_CLKDIV2_SPI0_SHIFT (4)
164#define S5PC100_CLKDIV2_SPI1_MASK (0xf<<8)
165#define S5PC100_CLKDIV2_SPI1_SHIFT (8)
166#define S5PC100_CLKDIV2_SPI2_MASK (0xf<<12)
167#define S5PC100_CLKDIV2_SPI2_SHIFT (12)
168#define S5PC100_CLKDIV2_IRDA_MASK (0xf<<16)
169#define S5PC100_CLKDIV2_IRDA_SHIFT (16)
170#define S5PC100_CLKDIV2_UHOST_MASK (0xf<<20)
171#define S5PC100_CLKDIV2_UHOST_SHIFT (20)
172
173/* CLKDIV3 */
174#define S5PC100_CLKDIV3_MMC0_MASK (0xf<<0)
175#define S5PC100_CLKDIV3_MMC0_SHIFT (0)
176#define S5PC100_CLKDIV3_MMC1_MASK (0xf<<4)
177#define S5PC100_CLKDIV3_MMC1_SHIFT (4)
178#define S5PC100_CLKDIV3_MMC2_MASK (0xf<<8)
179#define S5PC100_CLKDIV3_MMC2_SHIFT (8)
180#define S5PC100_CLKDIV3_LCD_MASK (0xf<<12)
181#define S5PC100_CLKDIV3_LCD_SHIFT (12)
182#define S5PC100_CLKDIV3_FIMC0_MASK (0xf<<16)
183#define S5PC100_CLKDIV3_FIMC0_SHIFT (16)
184#define S5PC100_CLKDIV3_FIMC1_MASK (0xf<<20)
185#define S5PC100_CLKDIV3_FIMC1_SHIFT (20)
186#define S5PC100_CLKDIV3_FIMC2_MASK (0xf<<24)
187#define S5PC100_CLKDIV3_FIMC2_SHIFT (24)
188#define S5PC100_CLKDIV3_HDMI_MASK (0xf<<28)
189#define S5PC100_CLKDIV3_HDMI_SHIFT (28)
190
191/* CLKDIV4 */
192#define S5PC100_CLKDIV4_PWI_MASK (0x7<<0)
193#define S5PC100_CLKDIV4_PWI_SHIFT (0)
194#define S5PC100_CLKDIV4_HCLKD2_MASK (0x7<<4)
195#define S5PC100_CLKDIV4_HCLKD2_SHIFT (4)
196#define S5PC100_CLKDIV4_I2SD2_MASK (0xf<<8)
197#define S5PC100_CLKDIV4_I2SD2_SHIFT (8)
198#define S5PC100_CLKDIV4_AUDIO0_MASK (0xf<<12)
199#define S5PC100_CLKDIV4_AUDIO0_SHIFT (12)
200#define S5PC100_CLKDIV4_AUDIO1_MASK (0xf<<16)
201#define S5PC100_CLKDIV4_AUDIO1_SHIFT (16)
202#define S5PC100_CLKDIV4_AUDIO2_MASK (0xf<<20)
203#define S5PC100_CLKDIV4_AUDIO2_SHIFT (20)
204
205
206/* HCLKD0/PCLKD0 Clock Gate 0 Registers */
207#define S5PC100_CLKGATE_D00_INTC (1<<0)
208#define S5PC100_CLKGATE_D00_TZIC (1<<1)
209#define S5PC100_CLKGATE_D00_CFCON (1<<2)
210#define S5PC100_CLKGATE_D00_MDMA (1<<3)
211#define S5PC100_CLKGATE_D00_G2D (1<<4)
212#define S5PC100_CLKGATE_D00_SECSS (1<<5)
213#define S5PC100_CLKGATE_D00_CSSYS (1<<6)
214
215/* HCLKD0/PCLKD0 Clock Gate 1 Registers */
216#define S5PC100_CLKGATE_D01_DMC (1<<0)
217#define S5PC100_CLKGATE_D01_SROMC (1<<1)
218#define S5PC100_CLKGATE_D01_ONENAND (1<<2)
219#define S5PC100_CLKGATE_D01_NFCON (1<<3)
220#define S5PC100_CLKGATE_D01_INTMEM (1<<4)
221#define S5PC100_CLKGATE_D01_EBI (1<<5)
222
223/* PCLKD0 Clock Gate 2 Registers */
224#define S5PC100_CLKGATE_D02_SECKEY (1<<1)
225#define S5PC100_CLKGATE_D02_SDM (1<<2)
226
227/* HCLKD1/PCLKD1 Clock Gate 0 Registers */
228#define S5PC100_CLKGATE_D10_PDMA0 (1<<0)
229#define S5PC100_CLKGATE_D10_PDMA1 (1<<1)
230#define S5PC100_CLKGATE_D10_USBHOST (1<<2)
231#define S5PC100_CLKGATE_D10_USBOTG (1<<3)
232#define S5PC100_CLKGATE_D10_MODEMIF (1<<4)
233#define S5PC100_CLKGATE_D10_HSMMC0 (1<<5)
234#define S5PC100_CLKGATE_D10_HSMMC1 (1<<6)
235#define S5PC100_CLKGATE_D10_HSMMC2 (1<<7)
236
237/* HCLKD1/PCLKD1 Clock Gate 1 Registers */
238#define S5PC100_CLKGATE_D11_LCD (1<<0)
239#define S5PC100_CLKGATE_D11_ROTATOR (1<<1)
240#define S5PC100_CLKGATE_D11_FIMC0 (1<<2)
241#define S5PC100_CLKGATE_D11_FIMC1 (1<<3)
242#define S5PC100_CLKGATE_D11_FIMC2 (1<<4)
243#define S5PC100_CLKGATE_D11_JPEG (1<<5)
244#define S5PC100_CLKGATE_D11_DSI (1<<6)
245#define S5PC100_CLKGATE_D11_CSI (1<<7)
246#define S5PC100_CLKGATE_D11_G3D (1<<8)
247
248/* HCLKD1/PCLKD1 Clock Gate 2 Registers */
249#define S5PC100_CLKGATE_D12_TV (1<<0)
250#define S5PC100_CLKGATE_D12_VP (1<<1)
251#define S5PC100_CLKGATE_D12_MIXER (1<<2)
252#define S5PC100_CLKGATE_D12_HDMI (1<<3)
253#define S5PC100_CLKGATE_D12_MFC (1<<4)
254
255/* HCLKD1/PCLKD1 Clock Gate 3 Registers */
256#define S5PC100_CLKGATE_D13_CHIPID (1<<0)
257#define S5PC100_CLKGATE_D13_GPIO (1<<1)
258#define S5PC100_CLKGATE_D13_APC (1<<2)
259#define S5PC100_CLKGATE_D13_IEC (1<<3)
260#define S5PC100_CLKGATE_D13_PWM (1<<6)
261#define S5PC100_CLKGATE_D13_SYSTIMER (1<<7)
262#define S5PC100_CLKGATE_D13_WDT (1<<8)
263#define S5PC100_CLKGATE_D13_RTC (1<<9)
264
265/* HCLKD1/PCLKD1 Clock Gate 4 Registers */
266#define S5PC100_CLKGATE_D14_UART0 (1<<0)
267#define S5PC100_CLKGATE_D14_UART1 (1<<1)
268#define S5PC100_CLKGATE_D14_UART2 (1<<2)
269#define S5PC100_CLKGATE_D14_UART3 (1<<3)
270#define S5PC100_CLKGATE_D14_IIC (1<<4)
271#define S5PC100_CLKGATE_D14_HDMI_IIC (1<<5)
272#define S5PC100_CLKGATE_D14_SPI0 (1<<6)
273#define S5PC100_CLKGATE_D14_SPI1 (1<<7)
274#define S5PC100_CLKGATE_D14_SPI2 (1<<8)
275#define S5PC100_CLKGATE_D14_IRDA (1<<9)
276#define S5PC100_CLKGATE_D14_CCAN0 (1<<10)
277#define S5PC100_CLKGATE_D14_CCAN1 (1<<11)
278#define S5PC100_CLKGATE_D14_HSITX (1<<12)
279#define S5PC100_CLKGATE_D14_HSIRX (1<<13)
280
281/* HCLKD1/PCLKD1 Clock Gate 5 Registers */
282#define S5PC100_CLKGATE_D15_IIS0 (1<<0)
283#define S5PC100_CLKGATE_D15_IIS1 (1<<1)
284#define S5PC100_CLKGATE_D15_IIS2 (1<<2)
285#define S5PC100_CLKGATE_D15_AC97 (1<<3)
286#define S5PC100_CLKGATE_D15_PCM0 (1<<4)
287#define S5PC100_CLKGATE_D15_PCM1 (1<<5)
288#define S5PC100_CLKGATE_D15_SPDIF (1<<6)
289#define S5PC100_CLKGATE_D15_TSADC (1<<7)
290#define S5PC100_CLKGATE_D15_KEYIF (1<<8)
291#define S5PC100_CLKGATE_D15_CG (1<<9)
292
293/* HCLKD2 Clock Gate 0 Registers */
294#define S5PC100_CLKGATE_D20_HCLKD2 (1<<0)
295#define S5PC100_CLKGATE_D20_I2SD2 (1<<1)
296
297/* Special Clock Gate 0 Registers */
298#define S5PC1XX_CLKGATE_SCLK0_HPM (1<<0)
299#define S5PC1XX_CLKGATE_SCLK0_PWI (1<<1)
300#define S5PC100_CLKGATE_SCLK0_ONENAND (1<<2)
301#define S5PC100_CLKGATE_SCLK0_UART (1<<3)
302#define S5PC100_CLKGATE_SCLK0_SPI0 (1<<4)
303#define S5PC100_CLKGATE_SCLK0_SPI1 (1<<5)
304#define S5PC100_CLKGATE_SCLK0_SPI2 (1<<6)
305#define S5PC100_CLKGATE_SCLK0_SPI0_48 (1<<7)
306#define S5PC100_CLKGATE_SCLK0_SPI1_48 (1<<8)
307#define S5PC100_CLKGATE_SCLK0_SPI2_48 (1<<9)
308#define S5PC100_CLKGATE_SCLK0_IRDA (1<<10)
309#define S5PC100_CLKGATE_SCLK0_USBHOST (1<<11)
310#define S5PC100_CLKGATE_SCLK0_MMC0 (1<<12)
311#define S5PC100_CLKGATE_SCLK0_MMC1 (1<<13)
312#define S5PC100_CLKGATE_SCLK0_MMC2 (1<<14)
313#define S5PC100_CLKGATE_SCLK0_MMC0_48 (1<<15)
314#define S5PC100_CLKGATE_SCLK0_MMC1_48 (1<<16)
315#define S5PC100_CLKGATE_SCLK0_MMC2_48 (1<<17)
316
317/* Special Clock Gate 1 Registers */
318#define S5PC100_CLKGATE_SCLK1_LCD (1<<0)
319#define S5PC100_CLKGATE_SCLK1_FIMC0 (1<<1)
320#define S5PC100_CLKGATE_SCLK1_FIMC1 (1<<2)
321#define S5PC100_CLKGATE_SCLK1_FIMC2 (1<<3)
322#define S5PC100_CLKGATE_SCLK1_TV54 (1<<4)
323#define S5PC100_CLKGATE_SCLK1_VDAC54 (1<<5)
324#define S5PC100_CLKGATE_SCLK1_MIXER (1<<6)
325#define S5PC100_CLKGATE_SCLK1_HDMI (1<<7)
326#define S5PC100_CLKGATE_SCLK1_AUDIO0 (1<<8)
327#define S5PC100_CLKGATE_SCLK1_AUDIO1 (1<<9)
328#define S5PC100_CLKGATE_SCLK1_AUDIO2 (1<<10)
329#define S5PC100_CLKGATE_SCLK1_SPDIF (1<<11)
330#define S5PC100_CLKGATE_SCLK1_CAM (1<<12)
331
332/* register for power management */
333#define S5PC100_PWR_CFG S5PC1XX_CLKREG(0x8000)
334#define S5PC100_EINT_WAKEUP_MASK S5PC1XX_CLKREG(0x8004)
335#define S5PC100_NORMAL_CFG S5PC1XX_CLKREG(0x8010)
336#define S5PC100_STOP_CFG S5PC1XX_CLKREG(0x8014)
337#define S5PC100_SLEEP_CFG S5PC1XX_CLKREG(0x8018)
338#define S5PC100_STOP_MEM_CFG S5PC1XX_CLKREG(0x801C)
339#define S5PC100_OSC_FREQ S5PC1XX_CLKREG(0x8100)
340#define S5PC100_OSC_STABLE S5PC1XX_CLKREG(0x8104)
341#define S5PC100_PWR_STABLE S5PC1XX_CLKREG(0x8108)
342#define S5PC100_MTC_STABLE S5PC1XX_CLKREG(0x8110)
343#define S5PC100_CLAMP_STABLE S5PC1XX_CLKREG(0x8114)
344#define S5PC100_OTHERS S5PC1XX_CLKREG(0x8200)
345#define S5PC100_RST_STAT S5PC1XX_CLKREG(0x8300)
346#define S5PC100_WAKEUP_STAT S5PC1XX_CLKREG(0x8304)
347#define S5PC100_BLK_PWR_STAT S5PC1XX_CLKREG(0x8308)
348#define S5PC100_INFORM0 S5PC1XX_CLKREG(0x8400)
349#define S5PC100_INFORM1 S5PC1XX_CLKREG(0x8404)
350#define S5PC100_INFORM2 S5PC1XX_CLKREG(0x8408)
351#define S5PC100_INFORM3 S5PC1XX_CLKREG(0x840C)
352#define S5PC100_INFORM4 S5PC1XX_CLKREG(0x8410)
353#define S5PC100_INFORM5 S5PC1XX_CLKREG(0x8414)
354#define S5PC100_INFORM6 S5PC1XX_CLKREG(0x8418)
355#define S5PC100_INFORM7 S5PC1XX_CLKREG(0x841C)
356#define S5PC100_DCGIDX_MAP0 S5PC1XX_CLKREG(0x8500)
357#define S5PC100_DCGIDX_MAP1 S5PC1XX_CLKREG(0x8504)
358#define S5PC100_DCGIDX_MAP2 S5PC1XX_CLKREG(0x8508)
359#define S5PC100_DCGPERF_MAP0 S5PC1XX_CLKREG(0x850C)
360#define S5PC100_DCGPERF_MAP1 S5PC1XX_CLKREG(0x8510)
361#define S5PC100_DVCIDX_MAP S5PC1XX_CLKREG(0x8514)
362#define S5PC100_FREQ_CPU S5PC1XX_CLKREG(0x8518)
363#define S5PC100_FREQ_DPM S5PC1XX_CLKREG(0x851C)
364#define S5PC100_DVSEMCLK_EN S5PC1XX_CLKREG(0x8520)
365#define S5PC100_APLL_CON_L8 S5PC1XX_CLKREG(0x8600)
366#define S5PC100_APLL_CON_L7 S5PC1XX_CLKREG(0x8604)
367#define S5PC100_APLL_CON_L6 S5PC1XX_CLKREG(0x8608)
368#define S5PC100_APLL_CON_L5 S5PC1XX_CLKREG(0x860C)
369#define S5PC100_APLL_CON_L4 S5PC1XX_CLKREG(0x8610)
370#define S5PC100_APLL_CON_L3 S5PC1XX_CLKREG(0x8614)
371#define S5PC100_APLL_CON_L2 S5PC1XX_CLKREG(0x8618)
372#define S5PC100_APLL_CON_L1 S5PC1XX_CLKREG(0x861C)
373#define S5PC100_IEM_CONTROL S5PC1XX_CLKREG(0x8620)
374#define S5PC100_CLKDIV_IEM_L8 S5PC1XX_CLKREG(0x8700)
375#define S5PC100_CLKDIV_IEM_L7 S5PC1XX_CLKREG(0x8704)
376#define S5PC100_CLKDIV_IEM_L6 S5PC1XX_CLKREG(0x8708)
377#define S5PC100_CLKDIV_IEM_L5 S5PC1XX_CLKREG(0x870C)
378#define S5PC100_CLKDIV_IEM_L4 S5PC1XX_CLKREG(0x8710)
379#define S5PC100_CLKDIV_IEM_L3 S5PC1XX_CLKREG(0x8714)
380#define S5PC100_CLKDIV_IEM_L2 S5PC1XX_CLKREG(0x8718)
381#define S5PC100_CLKDIV_IEM_L1 S5PC1XX_CLKREG(0x871C)
382#define S5PC100_IEM_HPMCLK_DIV S5PC1XX_CLKREG(0x8724)
383
384#define S5PC100_SWRESET S5PC1XX_CLKREG(0x100000)
385#define S5PC100_OND_SWRESET S5PC1XX_CLKREG(0x100008)
386#define S5PC100_GEN_CTRL S5PC1XX_CLKREG(0x100100)
387#define S5PC100_GEN_STATUS S5PC1XX_CLKREG(0x100104)
388#define S5PC100_MEM_SYS_CFG S5PC1XX_CLKREG(0x100200)
389#define S5PC100_CAM_MUX_SEL S5PC1XX_CLKREG(0x100300)
390#define S5PC100_MIXER_OUT_SEL S5PC1XX_CLKREG(0x100304)
391#define S5PC100_LPMP_MODE_SEL S5PC1XX_CLKREG(0x100308)
392#define S5PC100_MIPI_PHY_CON0 S5PC1XX_CLKREG(0x100400)
393#define S5PC100_MIPI_PHY_CON1 S5PC1XX_CLKREG(0x100414)
394#define S5PC100_HDMI_PHY_CON0 S5PC1XX_CLKREG(0x100420)
395
396#define S5PC100_CFG_WFI_CLEAN (~(3<<5))
397#define S5PC100_CFG_WFI_IDLE (1<<5)
398#define S5PC100_CFG_WFI_STOP (2<<5)
399#define S5PC100_CFG_WFI_SLEEP (3<<5)
400
401#define S5PC100_OTHER_SYS_INT 24
402#define S5PC100_OTHER_STA_TYPE 23
403#define STA_TYPE_EXPON 0
404#define STA_TYPE_SFR 1
405
406#define S5PC100_PWR_STA_EXP_SCALE 0
407#define S5PC100_PWR_STA_CNT 4
408
409#define S5PC100_PWR_STABLE_COUNT 85500
410
411#define S5PC100_SLEEP_CFG_OSC_EN 0
412
413/* OTHERS Resgister */
414#define S5PC100_OTHERS_USB_SIG_MASK (1 << 16)
415#define S5PC100_OTHERS_MIPI_DPHY_EN (1 << 28)
416
417/* MIPI D-PHY Control Register 0 */
418#define S5PC100_MIPI_PHY_CON0_M_RESETN (1 << 1)
419#define S5PC100_MIPI_PHY_CON0_S_RESETN (1 << 0)
420
421#endif /* _PLAT_REGS_CLOCK_H */
diff --git a/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h b/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h
new file mode 100644
index 000000000000..45e275131665
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/include/plat/s5pc100.h
@@ -0,0 +1,65 @@
1/* arch/arm/plat-s5pc1xx/include/plat/s5pc100.h
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * Header file for s5pc100 cpu support
7 *
8 * Based on plat-s3c64xx/include/plat/s3c6400.h
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15/* Common init code for S5PC100 related SoCs */
16extern int s5pc100_init(void);
17extern void s5pc100_map_io(void);
18extern void s5pc100_init_clocks(int xtal);
19extern int s5pc100_register_baseclocks(unsigned long xtal);
20extern void s5pc100_init_irq(void);
21extern void s5pc100_init_io(struct map_desc *mach_desc, int size);
22extern void s5pc100_common_init_uarts(struct s3c2410_uartcfg *cfg, int no);
23extern void s5pc100_register_clocks(void);
24extern void s5pc100_setup_clocks(void);
25extern struct sysdev_class s5pc100_sysclass;
26
27#define s5pc100_init_uarts s5pc100_common_init_uarts
28
29/* Some day, belows will be moved to plat-s5pc/include/plat/cpu.h */
30extern void s5pc1xx_init_irq(u32 *vic_valid, int num);
31extern void s5pc1xx_init_io(struct map_desc *mach_desc, int size);
32
33/* Some day, belows will be moved to plat-s5pc/include/plat/clock.h */
34extern struct clk clk_hpll;
35extern struct clk clk_hd0;
36extern struct clk clk_pd0;
37extern struct clk clk_54m;
38extern struct clk clk_dout_mpll2;
39extern void s5pc1xx_register_clocks(void);
40extern int s5pc1xx_sclk0_ctrl(struct clk *clk, int enable);
41extern int s5pc1xx_sclk1_ctrl(struct clk *clk, int enable);
42
43/* Some day, belows will be moved to plat-s5pc/include/plat/devs.h */
44extern struct s3c24xx_uart_resources s5pc1xx_uart_resources[];
45extern struct platform_device s3c_device_g2d;
46extern struct platform_device s3c_device_g3d;
47extern struct platform_device s3c_device_vpp;
48extern struct platform_device s3c_device_tvenc;
49extern struct platform_device s3c_device_tvscaler;
50extern struct platform_device s3c_device_rotator;
51extern struct platform_device s3c_device_jpeg;
52extern struct platform_device s3c_device_onenand;
53extern struct platform_device s3c_device_usb_otghcd;
54extern struct platform_device s3c_device_keypad;
55extern struct platform_device s3c_device_ts;
56extern struct platform_device s3c_device_g3d;
57extern struct platform_device s3c_device_smc911x;
58extern struct platform_device s3c_device_fimc0;
59extern struct platform_device s3c_device_fimc1;
60extern struct platform_device s3c_device_mfc;
61extern struct platform_device s3c_device_ac97;
62extern struct platform_device s3c_device_fimc0;
63extern struct platform_device s3c_device_fimc1;
64extern struct platform_device s3c_device_fimc2;
65
diff --git a/arch/arm/plat-s5pc1xx/irq.c b/arch/arm/plat-s5pc1xx/irq.c
new file mode 100644
index 000000000000..80d6dd942cb8
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/irq.c
@@ -0,0 +1,259 @@
1/* arch/arm/plat-s5pc1xx/irq.c
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC1XX - Interrupt handling
7 *
8 * Based on plat-s3c64xx/irq.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 */
14
15#include <linux/kernel.h>
16#include <linux/interrupt.h>
17#include <linux/irq.h>
18#include <linux/io.h>
19
20#include <asm/hardware/vic.h>
21
22#include <mach/map.h>
23#include <plat/regs-timer.h>
24#include <plat/cpu.h>
25
26/* Timer interrupt handling */
27
28static void s3c_irq_demux_timer(unsigned int base_irq, unsigned int sub_irq)
29{
30 generic_handle_irq(sub_irq);
31}
32
33static void s3c_irq_demux_timer0(unsigned int irq, struct irq_desc *desc)
34{
35 s3c_irq_demux_timer(irq, IRQ_TIMER0);
36}
37
38static void s3c_irq_demux_timer1(unsigned int irq, struct irq_desc *desc)
39{
40 s3c_irq_demux_timer(irq, IRQ_TIMER1);
41}
42
43static void s3c_irq_demux_timer2(unsigned int irq, struct irq_desc *desc)
44{
45 s3c_irq_demux_timer(irq, IRQ_TIMER2);
46}
47
48static void s3c_irq_demux_timer3(unsigned int irq, struct irq_desc *desc)
49{
50 s3c_irq_demux_timer(irq, IRQ_TIMER3);
51}
52
53static void s3c_irq_demux_timer4(unsigned int irq, struct irq_desc *desc)
54{
55 s3c_irq_demux_timer(irq, IRQ_TIMER4);
56}
57
58/* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */
59
60static void s3c_irq_timer_mask(unsigned int irq)
61{
62 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
63
64 reg &= 0x1f; /* mask out pending interrupts */
65 reg &= ~(1 << (irq - IRQ_TIMER0));
66 __raw_writel(reg, S3C64XX_TINT_CSTAT);
67}
68
69static void s3c_irq_timer_unmask(unsigned int irq)
70{
71 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
72
73 reg &= 0x1f; /* mask out pending interrupts */
74 reg |= 1 << (irq - IRQ_TIMER0);
75 __raw_writel(reg, S3C64XX_TINT_CSTAT);
76}
77
78static void s3c_irq_timer_ack(unsigned int irq)
79{
80 u32 reg = __raw_readl(S3C64XX_TINT_CSTAT);
81
82 reg &= 0x1f;
83 reg |= (1 << 5) << (irq - IRQ_TIMER0);
84 __raw_writel(reg, S3C64XX_TINT_CSTAT);
85}
86
87static struct irq_chip s3c_irq_timer = {
88 .name = "s3c-timer",
89 .mask = s3c_irq_timer_mask,
90 .unmask = s3c_irq_timer_unmask,
91 .ack = s3c_irq_timer_ack,
92};
93
94struct uart_irq {
95 void __iomem *regs;
96 unsigned int base_irq;
97 unsigned int parent_irq;
98};
99
100/* Note, we make use of the fact that the parent IRQs, IRQ_UART[0..3]
101 * are consecutive when looking up the interrupt in the demux routines.
102 */
103static struct uart_irq uart_irqs[] = {
104 [0] = {
105 .regs = (void *)S3C_VA_UART0,
106 .base_irq = IRQ_S3CUART_BASE0,
107 .parent_irq = IRQ_UART0,
108 },
109 [1] = {
110 .regs = (void *)S3C_VA_UART1,
111 .base_irq = IRQ_S3CUART_BASE1,
112 .parent_irq = IRQ_UART1,
113 },
114 [2] = {
115 .regs = (void *)S3C_VA_UART2,
116 .base_irq = IRQ_S3CUART_BASE2,
117 .parent_irq = IRQ_UART2,
118 },
119 [3] = {
120 .regs = (void *)S3C_VA_UART3,
121 .base_irq = IRQ_S3CUART_BASE3,
122 .parent_irq = IRQ_UART3,
123 },
124};
125
126static inline void __iomem *s3c_irq_uart_base(unsigned int irq)
127{
128 struct uart_irq *uirq = get_irq_chip_data(irq);
129 return uirq->regs;
130}
131
132static inline unsigned int s3c_irq_uart_bit(unsigned int irq)
133{
134 return irq & 3;
135}
136
137/* UART interrupt registers, not worth adding to seperate include header */
138#define S3C64XX_UINTP 0x30
139#define S3C64XX_UINTSP 0x34
140#define S3C64XX_UINTM 0x38
141
142static void s3c_irq_uart_mask(unsigned int irq)
143{
144 void __iomem *regs = s3c_irq_uart_base(irq);
145 unsigned int bit = s3c_irq_uart_bit(irq);
146 u32 reg;
147
148 reg = __raw_readl(regs + S3C64XX_UINTM);
149 reg |= (1 << bit);
150 __raw_writel(reg, regs + S3C64XX_UINTM);
151}
152
153static void s3c_irq_uart_maskack(unsigned int irq)
154{
155 void __iomem *regs = s3c_irq_uart_base(irq);
156 unsigned int bit = s3c_irq_uart_bit(irq);
157 u32 reg;
158
159 reg = __raw_readl(regs + S3C64XX_UINTM);
160 reg |= (1 << bit);
161 __raw_writel(reg, regs + S3C64XX_UINTM);
162 __raw_writel(1 << bit, regs + S3C64XX_UINTP);
163}
164
165static void s3c_irq_uart_unmask(unsigned int irq)
166{
167 void __iomem *regs = s3c_irq_uart_base(irq);
168 unsigned int bit = s3c_irq_uart_bit(irq);
169 u32 reg;
170
171 reg = __raw_readl(regs + S3C64XX_UINTM);
172 reg &= ~(1 << bit);
173 __raw_writel(reg, regs + S3C64XX_UINTM);
174}
175
176static void s3c_irq_uart_ack(unsigned int irq)
177{
178 void __iomem *regs = s3c_irq_uart_base(irq);
179 unsigned int bit = s3c_irq_uart_bit(irq);
180
181 __raw_writel(1 << bit, regs + S3C64XX_UINTP);
182}
183
184static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc)
185{
186 struct uart_irq *uirq = &uart_irqs[irq - IRQ_UART0];
187 u32 pend = __raw_readl(uirq->regs + S3C64XX_UINTP);
188 int base = uirq->base_irq;
189
190 if (pend & (1 << 0))
191 generic_handle_irq(base);
192 if (pend & (1 << 1))
193 generic_handle_irq(base + 1);
194 if (pend & (1 << 2))
195 generic_handle_irq(base + 2);
196 if (pend & (1 << 3))
197 generic_handle_irq(base + 3);
198}
199
200static struct irq_chip s3c_irq_uart = {
201 .name = "s3c-uart",
202 .mask = s3c_irq_uart_mask,
203 .unmask = s3c_irq_uart_unmask,
204 .mask_ack = s3c_irq_uart_maskack,
205 .ack = s3c_irq_uart_ack,
206};
207
208static void __init s5pc1xx_uart_irq(struct uart_irq *uirq)
209{
210 void __iomem *reg_base = uirq->regs;
211 unsigned int irq;
212 int offs;
213
214 /* mask all interrupts at the start. */
215 __raw_writel(0xf, reg_base + S3C64XX_UINTM);
216
217 for (offs = 0; offs < 3; offs++) {
218 irq = uirq->base_irq + offs;
219
220 set_irq_chip(irq, &s3c_irq_uart);
221 set_irq_chip_data(irq, uirq);
222 set_irq_handler(irq, handle_level_irq);
223 set_irq_flags(irq, IRQF_VALID);
224 }
225
226 set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
227}
228
229void __init s5pc1xx_init_irq(u32 *vic_valid, int num)
230{
231 int i;
232 int uart, irq;
233
234 printk(KERN_DEBUG "%s: initialising interrupts\n", __func__);
235
236 /* initialise the pair of VICs */
237 for (i = 0; i < num; i++)
238 vic_init((void *)S5PC1XX_VA_VIC(i), S3C_IRQ(i * S3C_IRQ_OFFSET),
239 vic_valid[i], 0);
240
241 /* add the timer sub-irqs */
242
243 set_irq_chained_handler(IRQ_TIMER0, s3c_irq_demux_timer0);
244 set_irq_chained_handler(IRQ_TIMER1, s3c_irq_demux_timer1);
245 set_irq_chained_handler(IRQ_TIMER2, s3c_irq_demux_timer2);
246 set_irq_chained_handler(IRQ_TIMER3, s3c_irq_demux_timer3);
247 set_irq_chained_handler(IRQ_TIMER4, s3c_irq_demux_timer4);
248
249 for (irq = IRQ_TIMER0; irq <= IRQ_TIMER4; irq++) {
250 set_irq_chip(irq, &s3c_irq_timer);
251 set_irq_handler(irq, handle_level_irq);
252 set_irq_flags(irq, IRQF_VALID);
253 }
254
255 for (uart = 0; uart < ARRAY_SIZE(uart_irqs); uart++)
256 s5pc1xx_uart_irq(&uart_irqs[uart]);
257}
258
259
diff --git a/arch/arm/plat-s5pc1xx/s5pc100-clock.c b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
new file mode 100644
index 000000000000..6b24035172fa
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/s5pc100-clock.c
@@ -0,0 +1,1139 @@
1/* linux/arch/arm/plat-s5pc1xx/s5pc100-clock.c
2 *
3 * Copyright 2009 Samsung Electronics, Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC100 based common clock support
7 *
8 * Based on plat-s3c64xx/s3c6400-clock.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/kernel.h>
18#include <linux/list.h>
19#include <linux/errno.h>
20#include <linux/err.h>
21#include <linux/clk.h>
22#include <linux/sysdev.h>
23#include <linux/io.h>
24
25#include <mach/hardware.h>
26#include <mach/map.h>
27
28#include <plat/cpu-freq.h>
29
30#include <plat/regs-clock.h>
31#include <plat/clock.h>
32#include <plat/cpu.h>
33#include <plat/pll.h>
34#include <plat/devs.h>
35#include <plat/s5pc100.h>
36
37/* fin_apll, fin_mpll and fin_epll are all the same clock, which we call
38 * ext_xtal_mux for want of an actual name from the manual.
39*/
40
41static struct clk clk_ext_xtal_mux = {
42 .name = "ext_xtal",
43 .id = -1,
44};
45
46#define clk_fin_apll clk_ext_xtal_mux
47#define clk_fin_mpll clk_ext_xtal_mux
48#define clk_fin_epll clk_ext_xtal_mux
49#define clk_fin_hpll clk_ext_xtal_mux
50
51#define clk_fout_mpll clk_mpll
52
53struct clk_sources {
54 unsigned int nr_sources;
55 struct clk **sources;
56};
57
58struct clksrc_clk {
59 struct clk clk;
60 unsigned int mask;
61 unsigned int shift;
62
63 struct clk_sources *sources;
64
65 unsigned int divider_shift;
66 void __iomem *reg_divider;
67 void __iomem *reg_source;
68};
69
70static int clk_default_setrate(struct clk *clk, unsigned long rate)
71{
72 clk->rate = rate;
73 return 1;
74}
75
76struct clk clk_27m = {
77 .name = "clk_27m",
78 .id = -1,
79 .rate = 27000000,
80};
81
82static int clk_48m_ctrl(struct clk *clk, int enable)
83{
84 unsigned long flags;
85 u32 val;
86
87 /* can't rely on clock lock, this register has other usages */
88 local_irq_save(flags);
89
90 val = __raw_readl(S5PC1XX_CLK_SRC1);
91 if (enable)
92 val |= S5PC100_CLKSRC1_CLK48M_MASK;
93 else
94 val &= ~S5PC100_CLKSRC1_CLK48M_MASK;
95
96 __raw_writel(val, S5PC1XX_CLK_SRC1);
97 local_irq_restore(flags);
98
99 return 0;
100}
101
102struct clk clk_48m = {
103 .name = "clk_48m",
104 .id = -1,
105 .rate = 48000000,
106 .enable = clk_48m_ctrl,
107};
108
109struct clk clk_54m = {
110 .name = "clk_54m",
111 .id = -1,
112 .rate = 54000000,
113};
114
115struct clk clk_hpll = {
116 .name = "hpll",
117 .id = -1,
118};
119
120struct clk clk_hd0 = {
121 .name = "hclkd0",
122 .id = -1,
123 .rate = 0,
124 .parent = NULL,
125 .ctrlbit = 0,
126 .set_rate = clk_default_setrate,
127};
128
129struct clk clk_pd0 = {
130 .name = "pclkd0",
131 .id = -1,
132 .rate = 0,
133 .parent = NULL,
134 .ctrlbit = 0,
135 .set_rate = clk_default_setrate,
136};
137
138static int s5pc1xx_clk_gate(void __iomem *reg,
139 struct clk *clk,
140 int enable)
141{
142 unsigned int ctrlbit = clk->ctrlbit;
143 u32 con;
144
145 con = __raw_readl(reg);
146
147 if (enable)
148 con |= ctrlbit;
149 else
150 con &= ~ctrlbit;
151
152 __raw_writel(con, reg);
153 return 0;
154}
155
156static int s5pc1xx_clk_d00_ctrl(struct clk *clk, int enable)
157{
158 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D00, clk, enable);
159}
160
161static int s5pc1xx_clk_d01_ctrl(struct clk *clk, int enable)
162{
163 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D01, clk, enable);
164}
165
166static int s5pc1xx_clk_d02_ctrl(struct clk *clk, int enable)
167{
168 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D02, clk, enable);
169}
170
171static int s5pc1xx_clk_d10_ctrl(struct clk *clk, int enable)
172{
173 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D10, clk, enable);
174}
175
176static int s5pc1xx_clk_d11_ctrl(struct clk *clk, int enable)
177{
178 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D11, clk, enable);
179}
180
181static int s5pc1xx_clk_d12_ctrl(struct clk *clk, int enable)
182{
183 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D12, clk, enable);
184}
185
186static int s5pc1xx_clk_d13_ctrl(struct clk *clk, int enable)
187{
188 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D13, clk, enable);
189}
190
191static int s5pc1xx_clk_d14_ctrl(struct clk *clk, int enable)
192{
193 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D14, clk, enable);
194}
195
196static int s5pc1xx_clk_d15_ctrl(struct clk *clk, int enable)
197{
198 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D15, clk, enable);
199}
200
201static int s5pc1xx_clk_d20_ctrl(struct clk *clk, int enable)
202{
203 return s5pc1xx_clk_gate(S5PC100_CLKGATE_D20, clk, enable);
204}
205
206int s5pc1xx_sclk0_ctrl(struct clk *clk, int enable)
207{
208 return s5pc1xx_clk_gate(S5PC100_SCLKGATE0, clk, enable);
209}
210
211int s5pc1xx_sclk1_ctrl(struct clk *clk, int enable)
212{
213 return s5pc1xx_clk_gate(S5PC100_SCLKGATE1, clk, enable);
214}
215
216static struct clk init_clocks_disable[] = {
217 {
218 .name = "dsi",
219 .id = -1,
220 .parent = &clk_p,
221 .enable = s5pc1xx_clk_d11_ctrl,
222 .ctrlbit = S5PC100_CLKGATE_D11_DSI,
223 }, {
224 .name = "csi",
225 .id = -1,
226 .parent = &clk_h,
227 .enable = s5pc1xx_clk_d11_ctrl,
228 .ctrlbit = S5PC100_CLKGATE_D11_CSI,
229 }, {
230 .name = "ccan0",
231 .id = 0,
232 .parent = &clk_p,
233 .enable = s5pc1xx_clk_d14_ctrl,
234 .ctrlbit = S5PC100_CLKGATE_D14_CCAN0,
235 }, {
236 .name = "ccan1",
237 .id = 1,
238 .parent = &clk_p,
239 .enable = s5pc1xx_clk_d14_ctrl,
240 .ctrlbit = S5PC100_CLKGATE_D14_CCAN1,
241 }, {
242 .name = "keypad",
243 .id = -1,
244 .parent = &clk_p,
245 .enable = s5pc1xx_clk_d15_ctrl,
246 .ctrlbit = S5PC100_CLKGATE_D15_KEYIF,
247 }, {
248 .name = "hclkd2",
249 .id = -1,
250 .parent = NULL,
251 .enable = s5pc1xx_clk_d20_ctrl,
252 .ctrlbit = S5PC100_CLKGATE_D20_HCLKD2,
253 }, {
254 .name = "iis-d2",
255 .id = -1,
256 .parent = NULL,
257 .enable = s5pc1xx_clk_d20_ctrl,
258 .ctrlbit = S5PC100_CLKGATE_D20_I2SD2,
259 }, {
260 .name = "otg",
261 .id = -1,
262 .parent = &clk_h,
263 .enable = s5pc1xx_clk_d10_ctrl,
264 .ctrlbit = S5PC100_CLKGATE_D10_USBOTG,
265 },
266};
267
268static struct clk init_clocks[] = {
269 /* System1 (D0_0) devices */
270 {
271 .name = "intc",
272 .id = -1,
273 .parent = &clk_hd0,
274 .enable = s5pc1xx_clk_d00_ctrl,
275 .ctrlbit = S5PC100_CLKGATE_D00_INTC,
276 }, {
277 .name = "tzic",
278 .id = -1,
279 .parent = &clk_hd0,
280 .enable = s5pc1xx_clk_d00_ctrl,
281 .ctrlbit = S5PC100_CLKGATE_D00_TZIC,
282 }, {
283 .name = "cf-ata",
284 .id = -1,
285 .parent = &clk_hd0,
286 .enable = s5pc1xx_clk_d00_ctrl,
287 .ctrlbit = S5PC100_CLKGATE_D00_CFCON,
288 }, {
289 .name = "mdma",
290 .id = -1,
291 .parent = &clk_hd0,
292 .enable = s5pc1xx_clk_d00_ctrl,
293 .ctrlbit = S5PC100_CLKGATE_D00_MDMA,
294 }, {
295 .name = "g2d",
296 .id = -1,
297 .parent = &clk_hd0,
298 .enable = s5pc1xx_clk_d00_ctrl,
299 .ctrlbit = S5PC100_CLKGATE_D00_G2D,
300 }, {
301 .name = "secss",
302 .id = -1,
303 .parent = &clk_hd0,
304 .enable = s5pc1xx_clk_d00_ctrl,
305 .ctrlbit = S5PC100_CLKGATE_D00_SECSS,
306 }, {
307 .name = "cssys",
308 .id = -1,
309 .parent = &clk_hd0,
310 .enable = s5pc1xx_clk_d00_ctrl,
311 .ctrlbit = S5PC100_CLKGATE_D00_CSSYS,
312 },
313
314 /* Memory (D0_1) devices */
315 {
316 .name = "dmc",
317 .id = -1,
318 .parent = &clk_hd0,
319 .enable = s5pc1xx_clk_d01_ctrl,
320 .ctrlbit = S5PC100_CLKGATE_D01_DMC,
321 }, {
322 .name = "sromc",
323 .id = -1,
324 .parent = &clk_hd0,
325 .enable = s5pc1xx_clk_d01_ctrl,
326 .ctrlbit = S5PC100_CLKGATE_D01_SROMC,
327 }, {
328 .name = "onenand",
329 .id = -1,
330 .parent = &clk_hd0,
331 .enable = s5pc1xx_clk_d01_ctrl,
332 .ctrlbit = S5PC100_CLKGATE_D01_ONENAND,
333 }, {
334 .name = "nand",
335 .id = -1,
336 .parent = &clk_hd0,
337 .enable = s5pc1xx_clk_d01_ctrl,
338 .ctrlbit = S5PC100_CLKGATE_D01_NFCON,
339 }, {
340 .name = "intmem",
341 .id = -1,
342 .parent = &clk_hd0,
343 .enable = s5pc1xx_clk_d01_ctrl,
344 .ctrlbit = S5PC100_CLKGATE_D01_INTMEM,
345 }, {
346 .name = "ebi",
347 .id = -1,
348 .parent = &clk_hd0,
349 .enable = s5pc1xx_clk_d01_ctrl,
350 .ctrlbit = S5PC100_CLKGATE_D01_EBI,
351 },
352
353 /* System2 (D0_2) devices */
354 {
355 .name = "seckey",
356 .id = -1,
357 .parent = &clk_pd0,
358 .enable = s5pc1xx_clk_d02_ctrl,
359 .ctrlbit = S5PC100_CLKGATE_D02_SECKEY,
360 }, {
361 .name = "sdm",
362 .id = -1,
363 .parent = &clk_hd0,
364 .enable = s5pc1xx_clk_d02_ctrl,
365 .ctrlbit = S5PC100_CLKGATE_D02_SDM,
366 },
367
368 /* File (D1_0) devices */
369 {
370 .name = "pdma0",
371 .id = -1,
372 .parent = &clk_h,
373 .enable = s5pc1xx_clk_d10_ctrl,
374 .ctrlbit = S5PC100_CLKGATE_D10_PDMA0,
375 }, {
376 .name = "pdma1",
377 .id = -1,
378 .parent = &clk_h,
379 .enable = s5pc1xx_clk_d10_ctrl,
380 .ctrlbit = S5PC100_CLKGATE_D10_PDMA1,
381 }, {
382 .name = "usb-host",
383 .id = -1,
384 .parent = &clk_h,
385 .enable = s5pc1xx_clk_d10_ctrl,
386 .ctrlbit = S5PC100_CLKGATE_D10_USBHOST,
387 }, {
388 .name = "modem",
389 .id = -1,
390 .parent = &clk_h,
391 .enable = s5pc1xx_clk_d10_ctrl,
392 .ctrlbit = S5PC100_CLKGATE_D10_MODEMIF,
393 }, {
394 .name = "hsmmc",
395 .id = 0,
396 .parent = &clk_h,
397 .enable = s5pc1xx_clk_d10_ctrl,
398 .ctrlbit = S5PC100_CLKGATE_D10_HSMMC0,
399 }, {
400 .name = "hsmmc",
401 .id = 1,
402 .parent = &clk_h,
403 .enable = s5pc1xx_clk_d10_ctrl,
404 .ctrlbit = S5PC100_CLKGATE_D10_HSMMC1,
405 }, {
406 .name = "hsmmc",
407 .id = 2,
408 .parent = &clk_h,
409 .enable = s5pc1xx_clk_d10_ctrl,
410 .ctrlbit = S5PC100_CLKGATE_D10_HSMMC2,
411 },
412
413 /* Multimedia1 (D1_1) devices */
414 {
415 .name = "lcd",
416 .id = -1,
417 .parent = &clk_h,
418 .enable = s5pc1xx_clk_d11_ctrl,
419 .ctrlbit = S5PC100_CLKGATE_D11_LCD,
420 }, {
421 .name = "rotator",
422 .id = -1,
423 .parent = &clk_h,
424 .enable = s5pc1xx_clk_d11_ctrl,
425 .ctrlbit = S5PC100_CLKGATE_D11_ROTATOR,
426 }, {
427 .name = "fimc",
428 .id = 0,
429 .parent = &clk_h,
430 .enable = s5pc1xx_clk_d11_ctrl,
431 .ctrlbit = S5PC100_CLKGATE_D11_FIMC0,
432 }, {
433 .name = "fimc",
434 .id = 1,
435 .parent = &clk_h,
436 .enable = s5pc1xx_clk_d11_ctrl,
437 .ctrlbit = S5PC100_CLKGATE_D11_FIMC1,
438 }, {
439 .name = "fimc",
440 .id = 2,
441 .parent = &clk_h,
442 .enable = s5pc1xx_clk_d11_ctrl,
443 .ctrlbit = S5PC100_CLKGATE_D11_FIMC2,
444 }, {
445 .name = "jpeg",
446 .id = -1,
447 .parent = &clk_h,
448 .enable = s5pc1xx_clk_d11_ctrl,
449 .ctrlbit = S5PC100_CLKGATE_D11_JPEG,
450 }, {
451 .name = "g3d",
452 .id = -1,
453 .parent = &clk_h,
454 .enable = s5pc1xx_clk_d11_ctrl,
455 .ctrlbit = S5PC100_CLKGATE_D11_G3D,
456 },
457
458 /* Multimedia2 (D1_2) devices */
459 {
460 .name = "tv",
461 .id = -1,
462 .parent = &clk_h,
463 .enable = s5pc1xx_clk_d12_ctrl,
464 .ctrlbit = S5PC100_CLKGATE_D12_TV,
465 }, {
466 .name = "vp",
467 .id = -1,
468 .parent = &clk_h,
469 .enable = s5pc1xx_clk_d12_ctrl,
470 .ctrlbit = S5PC100_CLKGATE_D12_VP,
471 }, {
472 .name = "mixer",
473 .id = -1,
474 .parent = &clk_h,
475 .enable = s5pc1xx_clk_d12_ctrl,
476 .ctrlbit = S5PC100_CLKGATE_D12_MIXER,
477 }, {
478 .name = "hdmi",
479 .id = -1,
480 .parent = &clk_h,
481 .enable = s5pc1xx_clk_d12_ctrl,
482 .ctrlbit = S5PC100_CLKGATE_D12_HDMI,
483 }, {
484 .name = "mfc",
485 .id = -1,
486 .parent = &clk_h,
487 .enable = s5pc1xx_clk_d12_ctrl,
488 .ctrlbit = S5PC100_CLKGATE_D12_MFC,
489 },
490
491 /* System (D1_3) devices */
492 {
493 .name = "chipid",
494 .id = -1,
495 .parent = &clk_p,
496 .enable = s5pc1xx_clk_d13_ctrl,
497 .ctrlbit = S5PC100_CLKGATE_D13_CHIPID,
498 }, {
499 .name = "gpio",
500 .id = -1,
501 .parent = &clk_p,
502 .enable = s5pc1xx_clk_d13_ctrl,
503 .ctrlbit = S5PC100_CLKGATE_D13_GPIO,
504 }, {
505 .name = "apc",
506 .id = -1,
507 .parent = &clk_p,
508 .enable = s5pc1xx_clk_d13_ctrl,
509 .ctrlbit = S5PC100_CLKGATE_D13_APC,
510 }, {
511 .name = "iec",
512 .id = -1,
513 .parent = &clk_p,
514 .enable = s5pc1xx_clk_d13_ctrl,
515 .ctrlbit = S5PC100_CLKGATE_D13_IEC,
516 }, {
517 .name = "timers",
518 .id = -1,
519 .parent = &clk_p,
520 .enable = s5pc1xx_clk_d13_ctrl,
521 .ctrlbit = S5PC100_CLKGATE_D13_PWM,
522 }, {
523 .name = "systimer",
524 .id = -1,
525 .parent = &clk_p,
526 .enable = s5pc1xx_clk_d13_ctrl,
527 .ctrlbit = S5PC100_CLKGATE_D13_SYSTIMER,
528 }, {
529 .name = "watchdog",
530 .id = -1,
531 .parent = &clk_p,
532 .enable = s5pc1xx_clk_d13_ctrl,
533 .ctrlbit = S5PC100_CLKGATE_D13_WDT,
534 }, {
535 .name = "rtc",
536 .id = -1,
537 .parent = &clk_p,
538 .enable = s5pc1xx_clk_d13_ctrl,
539 .ctrlbit = S5PC100_CLKGATE_D13_RTC,
540 },
541
542 /* Connectivity (D1_4) devices */
543 {
544 .name = "uart",
545 .id = 0,
546 .parent = &clk_p,
547 .enable = s5pc1xx_clk_d14_ctrl,
548 .ctrlbit = S5PC100_CLKGATE_D14_UART0,
549 }, {
550 .name = "uart",
551 .id = 1,
552 .parent = &clk_p,
553 .enable = s5pc1xx_clk_d14_ctrl,
554 .ctrlbit = S5PC100_CLKGATE_D14_UART1,
555 }, {
556 .name = "uart",
557 .id = 2,
558 .parent = &clk_p,
559 .enable = s5pc1xx_clk_d14_ctrl,
560 .ctrlbit = S5PC100_CLKGATE_D14_UART2,
561 }, {
562 .name = "uart",
563 .id = 3,
564 .parent = &clk_p,
565 .enable = s5pc1xx_clk_d14_ctrl,
566 .ctrlbit = S5PC100_CLKGATE_D14_UART3,
567 }, {
568 .name = "i2c",
569 .id = -1,
570 .parent = &clk_p,
571 .enable = s5pc1xx_clk_d14_ctrl,
572 .ctrlbit = S5PC100_CLKGATE_D14_IIC,
573 }, {
574 .name = "hdmi-i2c",
575 .id = -1,
576 .parent = &clk_p,
577 .enable = s5pc1xx_clk_d14_ctrl,
578 .ctrlbit = S5PC100_CLKGATE_D14_HDMI_IIC,
579 }, {
580 .name = "spi",
581 .id = 0,
582 .parent = &clk_p,
583 .enable = s5pc1xx_clk_d14_ctrl,
584 .ctrlbit = S5PC100_CLKGATE_D14_SPI0,
585 }, {
586 .name = "spi",
587 .id = 1,
588 .parent = &clk_p,
589 .enable = s5pc1xx_clk_d14_ctrl,
590 .ctrlbit = S5PC100_CLKGATE_D14_SPI1,
591 }, {
592 .name = "spi",
593 .id = 2,
594 .parent = &clk_p,
595 .enable = s5pc1xx_clk_d14_ctrl,
596 .ctrlbit = S5PC100_CLKGATE_D14_SPI2,
597 }, {
598 .name = "irda",
599 .id = -1,
600 .parent = &clk_p,
601 .enable = s5pc1xx_clk_d14_ctrl,
602 .ctrlbit = S5PC100_CLKGATE_D14_IRDA,
603 }, {
604 .name = "hsitx",
605 .id = -1,
606 .parent = &clk_p,
607 .enable = s5pc1xx_clk_d14_ctrl,
608 .ctrlbit = S5PC100_CLKGATE_D14_HSITX,
609 }, {
610 .name = "hsirx",
611 .id = -1,
612 .parent = &clk_p,
613 .enable = s5pc1xx_clk_d14_ctrl,
614 .ctrlbit = S5PC100_CLKGATE_D14_HSIRX,
615 },
616
617 /* Audio (D1_5) devices */
618 {
619 .name = "iis",
620 .id = 0,
621 .parent = &clk_p,
622 .enable = s5pc1xx_clk_d15_ctrl,
623 .ctrlbit = S5PC100_CLKGATE_D15_IIS0,
624 }, {
625 .name = "iis",
626 .id = 1,
627 .parent = &clk_p,
628 .enable = s5pc1xx_clk_d15_ctrl,
629 .ctrlbit = S5PC100_CLKGATE_D15_IIS1,
630 }, {
631 .name = "iis",
632 .id = 2,
633 .parent = &clk_p,
634 .enable = s5pc1xx_clk_d15_ctrl,
635 .ctrlbit = S5PC100_CLKGATE_D15_IIS2,
636 }, {
637 .name = "ac97",
638 .id = -1,
639 .parent = &clk_p,
640 .enable = s5pc1xx_clk_d15_ctrl,
641 .ctrlbit = S5PC100_CLKGATE_D15_AC97,
642 }, {
643 .name = "pcm",
644 .id = 0,
645 .parent = &clk_p,
646 .enable = s5pc1xx_clk_d15_ctrl,
647 .ctrlbit = S5PC100_CLKGATE_D15_PCM0,
648 }, {
649 .name = "pcm",
650 .id = 1,
651 .parent = &clk_p,
652 .enable = s5pc1xx_clk_d15_ctrl,
653 .ctrlbit = S5PC100_CLKGATE_D15_PCM1,
654 }, {
655 .name = "spdif",
656 .id = -1,
657 .parent = &clk_p,
658 .enable = s5pc1xx_clk_d15_ctrl,
659 .ctrlbit = S5PC100_CLKGATE_D15_SPDIF,
660 }, {
661 .name = "adc",
662 .id = -1,
663 .parent = &clk_p,
664 .enable = s5pc1xx_clk_d15_ctrl,
665 .ctrlbit = S5PC100_CLKGATE_D15_TSADC,
666 }, {
667 .name = "keyif",
668 .id = -1,
669 .parent = &clk_p,
670 .enable = s5pc1xx_clk_d15_ctrl,
671 .ctrlbit = S5PC100_CLKGATE_D15_KEYIF,
672 }, {
673 .name = "cg",
674 .id = -1,
675 .parent = &clk_p,
676 .enable = s5pc1xx_clk_d15_ctrl,
677 .ctrlbit = S5PC100_CLKGATE_D15_CG,
678 },
679
680 /* Audio (D2_0) devices: all disabled */
681
682 /* Special Clocks 1 */
683 {
684 .name = "sclk_hpm",
685 .id = -1,
686 .parent = NULL,
687 .enable = s5pc1xx_sclk0_ctrl,
688 .ctrlbit = S5PC1XX_CLKGATE_SCLK0_HPM,
689 }, {
690 .name = "sclk_onenand",
691 .id = -1,
692 .parent = NULL,
693 .enable = s5pc1xx_sclk0_ctrl,
694 .ctrlbit = S5PC100_CLKGATE_SCLK0_ONENAND,
695 }, {
696 .name = "sclk_spi_48",
697 .id = 0,
698 .parent = &clk_48m,
699 .enable = s5pc1xx_sclk0_ctrl,
700 .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI0_48,
701 }, {
702 .name = "sclk_spi_48",
703 .id = 1,
704 .parent = &clk_48m,
705 .enable = s5pc1xx_sclk0_ctrl,
706 .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI1_48,
707 }, {
708 .name = "sclk_spi_48",
709 .id = 2,
710 .parent = &clk_48m,
711 .enable = s5pc1xx_sclk0_ctrl,
712 .ctrlbit = S5PC100_CLKGATE_SCLK0_SPI2_48,
713 }, {
714 .name = "sclk_mmc_48",
715 .id = 0,
716 .parent = &clk_48m,
717 .enable = s5pc1xx_sclk0_ctrl,
718 .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC0_48,
719 }, {
720 .name = "sclk_mmc_48",
721 .id = 1,
722 .parent = &clk_48m,
723 .enable = s5pc1xx_sclk0_ctrl,
724 .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC1_48,
725 }, {
726 .name = "sclk_mmc_48",
727 .id = 2,
728 .parent = &clk_48m,
729 .enable = s5pc1xx_sclk0_ctrl,
730 .ctrlbit = S5PC100_CLKGATE_SCLK0_MMC2_48,
731 },
732
733 /* Special Clocks 2 */
734 {
735 .name = "sclk_tv_54",
736 .id = -1,
737 .parent = &clk_54m,
738 .enable = s5pc1xx_sclk1_ctrl,
739 .ctrlbit = S5PC100_CLKGATE_SCLK1_TV54,
740 }, {
741 .name = "sclk_vdac_54",
742 .id = -1,
743 .parent = &clk_54m,
744 .enable = s5pc1xx_sclk1_ctrl,
745 .ctrlbit = S5PC100_CLKGATE_SCLK1_VDAC54,
746 }, {
747 .name = "sclk_spdif",
748 .id = -1,
749 .parent = NULL,
750 .enable = s5pc1xx_sclk1_ctrl,
751 .ctrlbit = S5PC100_CLKGATE_SCLK1_SPDIF,
752 },
753};
754
755void __init s5pc1xx_register_clocks(void)
756{
757 struct clk *clkp;
758 int ret;
759 int ptr;
760
761 clkp = init_clocks;
762 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
763 ret = s3c24xx_register_clock(clkp);
764 if (ret < 0) {
765 printk(KERN_ERR "Failed to register clock %s (%d)\n",
766 clkp->name, ret);
767 }
768 }
769
770 clkp = init_clocks_disable;
771 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
772
773 ret = s3c24xx_register_clock(clkp);
774 if (ret < 0) {
775 printk(KERN_ERR "Failed to register clock %s (%d)\n",
776 clkp->name, ret);
777 }
778
779 (clkp->enable)(clkp, 0);
780 }
781
782 s3c_pwmclk_init();
783}
784static struct clk clk_fout_apll = {
785 .name = "fout_apll",
786 .id = -1,
787};
788
789static struct clk *clk_src_apll_list[] = {
790 [0] = &clk_fin_apll,
791 [1] = &clk_fout_apll,
792};
793
794static struct clk_sources clk_src_apll = {
795 .sources = clk_src_apll_list,
796 .nr_sources = ARRAY_SIZE(clk_src_apll_list),
797};
798
799static struct clksrc_clk clk_mout_apll = {
800 .clk = {
801 .name = "mout_apll",
802 .id = -1,
803 },
804 .shift = S5PC1XX_CLKSRC0_APLL_SHIFT,
805 .mask = S5PC1XX_CLKSRC0_APLL_MASK,
806 .sources = &clk_src_apll,
807 .reg_source = S5PC1XX_CLK_SRC0,
808};
809
810static struct clk clk_fout_epll = {
811 .name = "fout_epll",
812 .id = -1,
813};
814
815static struct clk *clk_src_epll_list[] = {
816 [0] = &clk_fin_epll,
817 [1] = &clk_fout_epll,
818};
819
820static struct clk_sources clk_src_epll = {
821 .sources = clk_src_epll_list,
822 .nr_sources = ARRAY_SIZE(clk_src_epll_list),
823};
824
825static struct clksrc_clk clk_mout_epll = {
826 .clk = {
827 .name = "mout_epll",
828 .id = -1,
829 },
830 .shift = S5PC1XX_CLKSRC0_EPLL_SHIFT,
831 .mask = S5PC1XX_CLKSRC0_EPLL_MASK,
832 .sources = &clk_src_epll,
833 .reg_source = S5PC1XX_CLK_SRC0,
834};
835
836static struct clk *clk_src_mpll_list[] = {
837 [0] = &clk_fin_mpll,
838 [1] = &clk_fout_mpll,
839};
840
841static struct clk_sources clk_src_mpll = {
842 .sources = clk_src_mpll_list,
843 .nr_sources = ARRAY_SIZE(clk_src_mpll_list),
844};
845
846static struct clksrc_clk clk_mout_mpll = {
847 .clk = {
848 .name = "mout_mpll",
849 .id = -1,
850 },
851 .shift = S5PC1XX_CLKSRC0_MPLL_SHIFT,
852 .mask = S5PC1XX_CLKSRC0_MPLL_MASK,
853 .sources = &clk_src_mpll,
854 .reg_source = S5PC1XX_CLK_SRC0,
855};
856
857static unsigned long s5pc1xx_clk_doutmpll_get_rate(struct clk *clk)
858{
859 unsigned long rate = clk_get_rate(clk->parent);
860 unsigned long clkdiv;
861
862 printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
863
864 clkdiv = __raw_readl(S5PC1XX_CLK_DIV1) & S5PC100_CLKDIV1_MPLL_MASK;
865 rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL_SHIFT) + 1;
866
867 return rate;
868}
869
870static struct clk clk_dout_mpll = {
871 .name = "dout_mpll",
872 .id = -1,
873 .parent = &clk_mout_mpll.clk,
874 .get_rate = s5pc1xx_clk_doutmpll_get_rate,
875};
876
877static unsigned long s5pc1xx_clk_doutmpll2_get_rate(struct clk *clk)
878{
879 unsigned long rate = clk_get_rate(clk->parent);
880 unsigned long clkdiv;
881
882 printk(KERN_DEBUG "%s: parent is %ld\n", __func__, rate);
883
884 clkdiv = __raw_readl(S5PC1XX_CLK_DIV1) & S5PC100_CLKDIV1_MPLL2_MASK;
885 rate /= (clkdiv >> S5PC100_CLKDIV1_MPLL2_SHIFT) + 1;
886
887 return rate;
888}
889
890struct clk clk_dout_mpll2 = {
891 .name = "dout_mpll2",
892 .id = -1,
893 .parent = &clk_mout_mpll.clk,
894 .get_rate = s5pc1xx_clk_doutmpll2_get_rate,
895};
896
897static struct clk *clkset_uart_list[] = {
898 &clk_mout_epll.clk,
899 &clk_dout_mpll,
900 NULL,
901 NULL
902};
903
904static struct clk_sources clkset_uart = {
905 .sources = clkset_uart_list,
906 .nr_sources = ARRAY_SIZE(clkset_uart_list),
907};
908
909static inline struct clksrc_clk *to_clksrc(struct clk *clk)
910{
911 return container_of(clk, struct clksrc_clk, clk);
912}
913
914static unsigned long s5pc1xx_getrate_clksrc(struct clk *clk)
915{
916 struct clksrc_clk *sclk = to_clksrc(clk);
917 unsigned long rate = clk_get_rate(clk->parent);
918 u32 clkdiv = __raw_readl(sclk->reg_divider);
919
920 clkdiv >>= sclk->divider_shift;
921 clkdiv &= 0xf;
922 clkdiv++;
923
924 rate /= clkdiv;
925 return rate;
926}
927
928static int s5pc1xx_setrate_clksrc(struct clk *clk, unsigned long rate)
929{
930 struct clksrc_clk *sclk = to_clksrc(clk);
931 void __iomem *reg = sclk->reg_divider;
932 unsigned int div;
933 u32 val;
934
935 rate = clk_round_rate(clk, rate);
936 div = clk_get_rate(clk->parent) / rate;
937 if (div > 16)
938 return -EINVAL;
939
940 val = __raw_readl(reg);
941 val &= ~(0xf << sclk->shift);
942 val |= (div - 1) << sclk->shift;
943 __raw_writel(val, reg);
944
945 return 0;
946}
947
948static int s5pc1xx_setparent_clksrc(struct clk *clk, struct clk *parent)
949{
950 struct clksrc_clk *sclk = to_clksrc(clk);
951 struct clk_sources *srcs = sclk->sources;
952 u32 clksrc = __raw_readl(sclk->reg_source);
953 int src_nr = -1;
954 int ptr;
955
956 for (ptr = 0; ptr < srcs->nr_sources; ptr++)
957 if (srcs->sources[ptr] == parent) {
958 src_nr = ptr;
959 break;
960 }
961
962 if (src_nr >= 0) {
963 clksrc &= ~sclk->mask;
964 clksrc |= src_nr << sclk->shift;
965
966 __raw_writel(clksrc, sclk->reg_source);
967 return 0;
968 }
969
970 return -EINVAL;
971}
972
973static unsigned long s5pc1xx_roundrate_clksrc(struct clk *clk,
974 unsigned long rate)
975{
976 unsigned long parent_rate = clk_get_rate(clk->parent);
977 int div;
978
979 if (rate > parent_rate)
980 rate = parent_rate;
981 else {
982 div = rate / parent_rate;
983
984 if (div == 0)
985 div = 1;
986 if (div > 16)
987 div = 16;
988
989 rate = parent_rate / div;
990 }
991
992 return rate;
993}
994
995static struct clksrc_clk clk_uart_uclk1 = {
996 .clk = {
997 .name = "uclk1",
998 .id = -1,
999 .ctrlbit = S5PC100_CLKGATE_SCLK0_UART,
1000 .enable = s5pc1xx_sclk0_ctrl,
1001 .set_parent = s5pc1xx_setparent_clksrc,
1002 .get_rate = s5pc1xx_getrate_clksrc,
1003 .set_rate = s5pc1xx_setrate_clksrc,
1004 .round_rate = s5pc1xx_roundrate_clksrc,
1005 },
1006 .shift = S5PC100_CLKSRC1_UART_SHIFT,
1007 .mask = S5PC100_CLKSRC1_UART_MASK,
1008 .sources = &clkset_uart,
1009 .divider_shift = S5PC100_CLKDIV2_UART_SHIFT,
1010 .reg_divider = S5PC1XX_CLK_DIV2,
1011 .reg_source = S5PC1XX_CLK_SRC1,
1012};
1013
1014/* Clock initialisation code */
1015
1016static struct clksrc_clk *init_parents[] = {
1017 &clk_mout_apll,
1018 &clk_mout_epll,
1019 &clk_mout_mpll,
1020 &clk_uart_uclk1,
1021};
1022
1023static void __init_or_cpufreq s5pc1xx_set_clksrc(struct clksrc_clk *clk)
1024{
1025 struct clk_sources *srcs = clk->sources;
1026 u32 clksrc = __raw_readl(clk->reg_source);
1027
1028 clksrc &= clk->mask;
1029 clksrc >>= clk->shift;
1030
1031 if (clksrc > srcs->nr_sources || !srcs->sources[clksrc]) {
1032 printk(KERN_ERR "%s: bad source %d\n",
1033 clk->clk.name, clksrc);
1034 return;
1035 }
1036
1037 clk->clk.parent = srcs->sources[clksrc];
1038
1039 printk(KERN_INFO "%s: source is %s (%d), rate is %ld\n",
1040 clk->clk.name, clk->clk.parent->name, clksrc,
1041 clk_get_rate(&clk->clk));
1042}
1043
1044#define GET_DIV(clk, field) ((((clk) & field##_MASK) >> field##_SHIFT) + 1)
1045
1046void __init_or_cpufreq s5pc100_setup_clocks(void)
1047{
1048 struct clk *xtal_clk;
1049 unsigned long xtal;
1050 unsigned long armclk;
1051 unsigned long hclkd0;
1052 unsigned long hclk;
1053 unsigned long pclkd0;
1054 unsigned long pclk;
1055 unsigned long apll;
1056 unsigned long mpll;
1057 unsigned long hpll;
1058 unsigned long epll;
1059 unsigned int ptr;
1060 u32 clkdiv0, clkdiv1;
1061
1062 printk(KERN_DEBUG "%s: registering clocks\n", __func__);
1063
1064 clkdiv0 = __raw_readl(S5PC1XX_CLK_DIV0);
1065 clkdiv1 = __raw_readl(S5PC1XX_CLK_DIV1);
1066
1067 printk(KERN_DEBUG "%s: clkdiv0 = %08x, clkdiv1 = %08x\n",
1068 __func__, clkdiv0, clkdiv1);
1069
1070 xtal_clk = clk_get(NULL, "xtal");
1071 BUG_ON(IS_ERR(xtal_clk));
1072
1073 xtal = clk_get_rate(xtal_clk);
1074 clk_put(xtal_clk);
1075
1076 printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal);
1077
1078 apll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_APLL_CON));
1079 mpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_MPLL_CON));
1080 epll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC1XX_EPLL_CON));
1081 hpll = s5pc1xx_get_pll(xtal, __raw_readl(S5PC100_HPLL_CON));
1082
1083 printk(KERN_INFO "S5PC100: PLL settings, A=%ld, M=%ld, E=%ld, H=%ld\n",
1084 apll, mpll, epll, hpll);
1085
1086 armclk = apll / GET_DIV(clkdiv0, S5PC1XX_CLKDIV0_APLL);
1087 armclk = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_ARM);
1088 hclkd0 = armclk / GET_DIV(clkdiv0, S5PC100_CLKDIV0_D0);
1089 pclkd0 = hclkd0 / GET_DIV(clkdiv0, S5PC100_CLKDIV0_PCLKD0);
1090 hclk = mpll / GET_DIV(clkdiv1, S5PC100_CLKDIV1_D1);
1091 pclk = hclk / GET_DIV(clkdiv1, S5PC100_CLKDIV1_PCLKD1);
1092
1093 printk(KERN_INFO "S5PC100: ARMCLK=%ld, HCLKD0=%ld, PCLKD0=%ld, HCLK=%ld, PCLK=%ld\n",
1094 armclk, hclkd0, pclkd0, hclk, pclk);
1095
1096 clk_fout_apll.rate = apll;
1097 clk_fout_mpll.rate = mpll;
1098 clk_fout_epll.rate = epll;
1099 clk_fout_apll.rate = apll;
1100
1101 clk_h.rate = hclk;
1102 clk_p.rate = pclk;
1103
1104 for (ptr = 0; ptr < ARRAY_SIZE(init_parents); ptr++)
1105 s5pc1xx_set_clksrc(init_parents[ptr]);
1106}
1107
1108static struct clk *clks[] __initdata = {
1109 &clk_ext_xtal_mux,
1110 &clk_mout_epll.clk,
1111 &clk_fout_epll,
1112 &clk_mout_mpll.clk,
1113 &clk_dout_mpll,
1114 &clk_uart_uclk1.clk,
1115 &clk_ext,
1116 &clk_epll,
1117 &clk_27m,
1118 &clk_48m,
1119 &clk_54m,
1120};
1121
1122void __init s5pc100_register_clocks(void)
1123{
1124 struct clk *clkp;
1125 int ret;
1126 int ptr;
1127
1128 for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
1129 clkp = clks[ptr];
1130 ret = s3c24xx_register_clock(clkp);
1131 if (ret < 0) {
1132 printk(KERN_ERR "Failed to register clock %s (%d)\n",
1133 clkp->name, ret);
1134 }
1135 }
1136
1137 clk_mpll.parent = &clk_mout_mpll.clk;
1138 clk_epll.parent = &clk_mout_epll.clk;
1139}
diff --git a/arch/arm/plat-s5pc1xx/s5pc100-init.c b/arch/arm/plat-s5pc1xx/s5pc100-init.c
new file mode 100644
index 000000000000..c58710884ceb
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/s5pc100-init.c
@@ -0,0 +1,27 @@
1/* linux/arch/arm/plat-s5pc1xx/s5pc100-init.c
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * S5PC100 - CPU initialisation (common with other S5PC1XX chips)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/init.h>
16
17#include <plat/cpu.h>
18#include <plat/devs.h>
19#include <plat/s5pc100.h>
20
21/* uart registration process */
22
23void __init s5pc100_common_init_uarts(struct s3c2410_uartcfg *cfg, int no)
24{
25 /* The driver name is s3c6400-uart to reuse s3c6400_serial_drv */
26 s3c24xx_init_uartdevs("s3c6400-uart", s5pc1xx_uart_resources, cfg, no);
27}
diff --git a/arch/arm/plat-s5pc1xx/setup-i2c0.c b/arch/arm/plat-s5pc1xx/setup-i2c0.c
new file mode 100644
index 000000000000..3d00c025fffb
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/setup-i2c0.c
@@ -0,0 +1,25 @@
1/* linux/arch/arm/plat-s5pc1xx/setup-i2c0.c
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * Base S5PC1XX I2C bus 0 gpio configuration
7 *
8 * Based on plat-s3c64xx/setup-i2c0.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/kernel.h>
16#include <linux/types.h>
17
18struct platform_device; /* don't need the contents */
19
20#include <plat/iic.h>
21
22void s3c_i2c0_cfg_gpio(struct platform_device *dev)
23{
24 /* Pin configuration would be needed */
25}
diff --git a/arch/arm/plat-s5pc1xx/setup-i2c1.c b/arch/arm/plat-s5pc1xx/setup-i2c1.c
new file mode 100644
index 000000000000..c8f3ca42f51d
--- /dev/null
+++ b/arch/arm/plat-s5pc1xx/setup-i2c1.c
@@ -0,0 +1,25 @@
1/* linux/arch/arm/plat-s3c64xx/setup-i2c1.c
2 *
3 * Copyright 2009 Samsung Electronics Co.
4 * Byungho Min <bhmin@samsung.com>
5 *
6 * Base S5PC1XX I2C bus 1 gpio configuration
7 *
8 * Based on plat-s3c64xx/setup-i2c1.c
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/kernel.h>
16#include <linux/types.h>
17
18struct platform_device; /* don't need the contents */
19
20#include <plat/iic.h>
21
22void s3c_i2c1_cfg_gpio(struct platform_device *dev)
23{
24 /* Pin configuration would be needed */
25}