Commit | Line | Data |
---|---|---|
2bc02c0d | 1 | /* |
a855039e | 2 | * Copyright (c) 2011-2012 Samsung Electronics Co., Ltd. |
2bc02c0d KK |
3 | * http://www.samsung.com |
4 | * | |
5 | * EXYNOS4210 - Clock support | |
6 | * | |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License version 2 as | |
9 | * published by the Free Software Foundation. | |
10 | */ | |
11 | ||
12 | #include <linux/kernel.h> | |
13 | #include <linux/err.h> | |
14 | #include <linux/clk.h> | |
15 | #include <linux/io.h> | |
acd35616 | 16 | #include <linux/syscore_ops.h> |
2bc02c0d KK |
17 | |
18 | #include <plat/cpu-freq.h> | |
19 | #include <plat/clock.h> | |
20 | #include <plat/cpu.h> | |
21 | #include <plat/pll.h> | |
22 | #include <plat/s5p-clock.h> | |
23 | #include <plat/clock-clksrc.h> | |
acd35616 | 24 | #include <plat/pm.h> |
2bc02c0d KK |
25 | |
26 | #include <mach/hardware.h> | |
27 | #include <mach/map.h> | |
28 | #include <mach/regs-clock.h> | |
2bc02c0d | 29 | |
cc511b8d | 30 | #include "common.h" |
ce9c00ee | 31 | #include "clock-exynos4.h" |
cc511b8d | 32 | |
7cdf04d7 | 33 | #ifdef CONFIG_PM_SLEEP |
acd35616 | 34 | static struct sleep_save exynos4210_clock_save[] = { |
a855039e KK |
35 | SAVE_ITEM(EXYNOS4_CLKSRC_IMAGE), |
36 | SAVE_ITEM(EXYNOS4_CLKDIV_IMAGE), | |
37 | SAVE_ITEM(EXYNOS4210_CLKSRC_LCD1), | |
38 | SAVE_ITEM(EXYNOS4210_CLKDIV_LCD1), | |
39 | SAVE_ITEM(EXYNOS4210_CLKSRC_MASK_LCD1), | |
40 | SAVE_ITEM(EXYNOS4210_CLKGATE_IP_IMAGE), | |
41 | SAVE_ITEM(EXYNOS4210_CLKGATE_IP_LCD1), | |
42 | SAVE_ITEM(EXYNOS4210_CLKGATE_IP_PERIR), | |
acd35616 | 43 | }; |
7cdf04d7 | 44 | #endif |
acd35616 | 45 | |
2bc02c0d KK |
46 | static struct clksrc_clk *sysclks[] = { |
47 | /* nothing here yet */ | |
48 | }; | |
49 | ||
8bf56466 SK |
50 | static struct clksrc_clk exynos4210_clk_mout_g2d0 = { |
51 | .clk = { | |
52 | .name = "mout_g2d0", | |
53 | }, | |
54 | .sources = &exynos4_clkset_mout_g2d0, | |
55 | .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 0, .size = 1 }, | |
56 | }; | |
57 | ||
58 | static struct clksrc_clk exynos4210_clk_mout_g2d1 = { | |
59 | .clk = { | |
60 | .name = "mout_g2d1", | |
61 | }, | |
62 | .sources = &exynos4_clkset_mout_g2d1, | |
63 | .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 4, .size = 1 }, | |
64 | }; | |
65 | ||
66 | static struct clk *exynos4210_clkset_mout_g2d_list[] = { | |
67 | [0] = &exynos4210_clk_mout_g2d0.clk, | |
68 | [1] = &exynos4210_clk_mout_g2d1.clk, | |
69 | }; | |
70 | ||
71 | static struct clksrc_sources exynos4210_clkset_mout_g2d = { | |
72 | .sources = exynos4210_clkset_mout_g2d_list, | |
73 | .nr_sources = ARRAY_SIZE(exynos4210_clkset_mout_g2d_list), | |
74 | }; | |
75 | ||
2bc02c0d KK |
76 | static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable) |
77 | { | |
a855039e | 78 | return s5p_gatectrl(EXYNOS4210_CLKSRC_MASK_LCD1, clk, enable); |
2bc02c0d KK |
79 | } |
80 | ||
81 | static struct clksrc_clk clksrcs[] = { | |
82 | { | |
83 | .clk = { | |
84 | .name = "sclk_sata", | |
85 | .id = -1, | |
86 | .enable = exynos4_clksrc_mask_fsys_ctrl, | |
87 | .ctrlbit = (1 << 24), | |
88 | }, | |
a855039e KK |
89 | .sources = &exynos4_clkset_mout_corebus, |
90 | .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 24, .size = 1 }, | |
91 | .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS0, .shift = 20, .size = 4 }, | |
2bc02c0d KK |
92 | }, { |
93 | .clk = { | |
94 | .name = "sclk_fimd", | |
95 | .devname = "exynos4-fb.1", | |
96 | .enable = exynos4_clksrc_mask_lcd1_ctrl, | |
97 | .ctrlbit = (1 << 0), | |
98 | }, | |
a855039e KK |
99 | .sources = &exynos4_clkset_group, |
100 | .reg_src = { .reg = EXYNOS4210_CLKSRC_LCD1, .shift = 0, .size = 4 }, | |
101 | .reg_div = { .reg = EXYNOS4210_CLKDIV_LCD1, .shift = 0, .size = 4 }, | |
8bf56466 SK |
102 | }, { |
103 | .clk = { | |
104 | .name = "sclk_fimg2d", | |
105 | }, | |
106 | .sources = &exynos4210_clkset_mout_g2d, | |
107 | .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 8, .size = 1 }, | |
108 | .reg_div = { .reg = EXYNOS4_CLKDIV_IMAGE, .shift = 0, .size = 4 }, | |
2bc02c0d KK |
109 | }, |
110 | }; | |
111 | ||
112 | static struct clk init_clocks_off[] = { | |
113 | { | |
114 | .name = "sataphy", | |
115 | .id = -1, | |
a855039e | 116 | .parent = &exynos4_clk_aclk_133.clk, |
2bc02c0d KK |
117 | .enable = exynos4_clk_ip_fsys_ctrl, |
118 | .ctrlbit = (1 << 3), | |
119 | }, { | |
120 | .name = "sata", | |
121 | .id = -1, | |
a855039e | 122 | .parent = &exynos4_clk_aclk_133.clk, |
2bc02c0d KK |
123 | .enable = exynos4_clk_ip_fsys_ctrl, |
124 | .ctrlbit = (1 << 10), | |
125 | }, { | |
126 | .name = "fimd", | |
127 | .devname = "exynos4-fb.1", | |
128 | .enable = exynos4_clk_ip_lcd1_ctrl, | |
129 | .ctrlbit = (1 << 0), | |
bca10b90 | 130 | }, { |
25e9d28d CK |
131 | .name = "sysmmu", |
132 | .devname = "exynos-sysmmu.9", | |
bca10b90 KC |
133 | .enable = exynos4_clk_ip_image_ctrl, |
134 | .ctrlbit = (1 << 3), | |
135 | }, { | |
25e9d28d CK |
136 | .name = "sysmmu", |
137 | .devname = "exynos-sysmmu.11", | |
bca10b90 KC |
138 | .enable = exynos4_clk_ip_lcd1_ctrl, |
139 | .ctrlbit = (1 << 4), | |
8bf56466 SK |
140 | }, { |
141 | .name = "fimg2d", | |
142 | .enable = exynos4_clk_ip_image_ctrl, | |
143 | .ctrlbit = (1 << 0), | |
2bc02c0d KK |
144 | }, |
145 | }; | |
146 | ||
acd35616 JC |
147 | #ifdef CONFIG_PM_SLEEP |
148 | static int exynos4210_clock_suspend(void) | |
149 | { | |
150 | s3c_pm_do_save(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save)); | |
151 | ||
152 | return 0; | |
153 | } | |
154 | ||
155 | static void exynos4210_clock_resume(void) | |
156 | { | |
157 | s3c_pm_do_restore_core(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save)); | |
158 | } | |
159 | ||
160 | #else | |
161 | #define exynos4210_clock_suspend NULL | |
162 | #define exynos4210_clock_resume NULL | |
163 | #endif | |
164 | ||
e745e06f | 165 | static struct syscore_ops exynos4210_clock_syscore_ops = { |
acd35616 JC |
166 | .suspend = exynos4210_clock_suspend, |
167 | .resume = exynos4210_clock_resume, | |
168 | }; | |
169 | ||
2bc02c0d KK |
170 | void __init exynos4210_register_clocks(void) |
171 | { | |
172 | int ptr; | |
173 | ||
a855039e KK |
174 | exynos4_clk_mout_mpll.reg_src.reg = EXYNOS4_CLKSRC_CPU; |
175 | exynos4_clk_mout_mpll.reg_src.shift = 8; | |
176 | exynos4_clk_mout_mpll.reg_src.size = 1; | |
2bc02c0d KK |
177 | |
178 | for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) | |
179 | s3c_register_clksrc(sysclks[ptr], 1); | |
180 | ||
181 | s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); | |
182 | ||
183 | s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); | |
184 | s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); | |
acd35616 JC |
185 | |
186 | register_syscore_ops(&exynos4210_clock_syscore_ops); | |
2bc02c0d | 187 | } |