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> | |
bca10b90 | 29 | #include <mach/sysmmu.h> |
2bc02c0d | 30 | |
cc511b8d | 31 | #include "common.h" |
ce9c00ee | 32 | #include "clock-exynos4.h" |
cc511b8d | 33 | |
7cdf04d7 | 34 | #ifdef CONFIG_PM_SLEEP |
acd35616 | 35 | static struct sleep_save exynos4210_clock_save[] = { |
a855039e KK |
36 | SAVE_ITEM(EXYNOS4_CLKSRC_IMAGE), |
37 | SAVE_ITEM(EXYNOS4_CLKDIV_IMAGE), | |
38 | SAVE_ITEM(EXYNOS4210_CLKSRC_LCD1), | |
39 | SAVE_ITEM(EXYNOS4210_CLKDIV_LCD1), | |
40 | SAVE_ITEM(EXYNOS4210_CLKSRC_MASK_LCD1), | |
41 | SAVE_ITEM(EXYNOS4210_CLKGATE_IP_IMAGE), | |
42 | SAVE_ITEM(EXYNOS4210_CLKGATE_IP_LCD1), | |
43 | SAVE_ITEM(EXYNOS4210_CLKGATE_IP_PERIR), | |
acd35616 | 44 | }; |
7cdf04d7 | 45 | #endif |
acd35616 | 46 | |
2bc02c0d KK |
47 | static struct clksrc_clk *sysclks[] = { |
48 | /* nothing here yet */ | |
49 | }; | |
50 | ||
8bf56466 SK |
51 | static struct clksrc_clk exynos4210_clk_mout_g2d0 = { |
52 | .clk = { | |
53 | .name = "mout_g2d0", | |
54 | }, | |
55 | .sources = &exynos4_clkset_mout_g2d0, | |
56 | .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 0, .size = 1 }, | |
57 | }; | |
58 | ||
59 | static struct clksrc_clk exynos4210_clk_mout_g2d1 = { | |
60 | .clk = { | |
61 | .name = "mout_g2d1", | |
62 | }, | |
63 | .sources = &exynos4_clkset_mout_g2d1, | |
64 | .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 4, .size = 1 }, | |
65 | }; | |
66 | ||
67 | static struct clk *exynos4210_clkset_mout_g2d_list[] = { | |
68 | [0] = &exynos4210_clk_mout_g2d0.clk, | |
69 | [1] = &exynos4210_clk_mout_g2d1.clk, | |
70 | }; | |
71 | ||
72 | static struct clksrc_sources exynos4210_clkset_mout_g2d = { | |
73 | .sources = exynos4210_clkset_mout_g2d_list, | |
74 | .nr_sources = ARRAY_SIZE(exynos4210_clkset_mout_g2d_list), | |
75 | }; | |
76 | ||
2bc02c0d KK |
77 | static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable) |
78 | { | |
a855039e | 79 | return s5p_gatectrl(EXYNOS4210_CLKSRC_MASK_LCD1, clk, enable); |
2bc02c0d KK |
80 | } |
81 | ||
82 | static struct clksrc_clk clksrcs[] = { | |
83 | { | |
84 | .clk = { | |
85 | .name = "sclk_sata", | |
86 | .id = -1, | |
87 | .enable = exynos4_clksrc_mask_fsys_ctrl, | |
88 | .ctrlbit = (1 << 24), | |
89 | }, | |
a855039e KK |
90 | .sources = &exynos4_clkset_mout_corebus, |
91 | .reg_src = { .reg = EXYNOS4_CLKSRC_FSYS, .shift = 24, .size = 1 }, | |
92 | .reg_div = { .reg = EXYNOS4_CLKDIV_FSYS0, .shift = 20, .size = 4 }, | |
2bc02c0d KK |
93 | }, { |
94 | .clk = { | |
95 | .name = "sclk_fimd", | |
96 | .devname = "exynos4-fb.1", | |
97 | .enable = exynos4_clksrc_mask_lcd1_ctrl, | |
98 | .ctrlbit = (1 << 0), | |
99 | }, | |
a855039e KK |
100 | .sources = &exynos4_clkset_group, |
101 | .reg_src = { .reg = EXYNOS4210_CLKSRC_LCD1, .shift = 0, .size = 4 }, | |
102 | .reg_div = { .reg = EXYNOS4210_CLKDIV_LCD1, .shift = 0, .size = 4 }, | |
8bf56466 SK |
103 | }, { |
104 | .clk = { | |
105 | .name = "sclk_fimg2d", | |
106 | }, | |
107 | .sources = &exynos4210_clkset_mout_g2d, | |
108 | .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 8, .size = 1 }, | |
109 | .reg_div = { .reg = EXYNOS4_CLKDIV_IMAGE, .shift = 0, .size = 4 }, | |
2bc02c0d KK |
110 | }, |
111 | }; | |
112 | ||
113 | static struct clk init_clocks_off[] = { | |
114 | { | |
115 | .name = "sataphy", | |
116 | .id = -1, | |
a855039e | 117 | .parent = &exynos4_clk_aclk_133.clk, |
2bc02c0d KK |
118 | .enable = exynos4_clk_ip_fsys_ctrl, |
119 | .ctrlbit = (1 << 3), | |
120 | }, { | |
121 | .name = "sata", | |
122 | .id = -1, | |
a855039e | 123 | .parent = &exynos4_clk_aclk_133.clk, |
2bc02c0d KK |
124 | .enable = exynos4_clk_ip_fsys_ctrl, |
125 | .ctrlbit = (1 << 10), | |
126 | }, { | |
127 | .name = "fimd", | |
128 | .devname = "exynos4-fb.1", | |
129 | .enable = exynos4_clk_ip_lcd1_ctrl, | |
130 | .ctrlbit = (1 << 0), | |
bca10b90 KC |
131 | }, { |
132 | .name = SYSMMU_CLOCK_NAME, | |
133 | .devname = SYSMMU_CLOCK_DEVNAME(2d, 14), | |
134 | .enable = exynos4_clk_ip_image_ctrl, | |
135 | .ctrlbit = (1 << 3), | |
136 | }, { | |
137 | .name = SYSMMU_CLOCK_NAME, | |
138 | .devname = SYSMMU_CLOCK_DEVNAME(fimd1, 11), | |
139 | .enable = exynos4_clk_ip_lcd1_ctrl, | |
140 | .ctrlbit = (1 << 4), | |
8bf56466 SK |
141 | }, { |
142 | .name = "fimg2d", | |
143 | .enable = exynos4_clk_ip_image_ctrl, | |
144 | .ctrlbit = (1 << 0), | |
2bc02c0d KK |
145 | }, |
146 | }; | |
147 | ||
acd35616 JC |
148 | #ifdef CONFIG_PM_SLEEP |
149 | static int exynos4210_clock_suspend(void) | |
150 | { | |
151 | s3c_pm_do_save(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save)); | |
152 | ||
153 | return 0; | |
154 | } | |
155 | ||
156 | static void exynos4210_clock_resume(void) | |
157 | { | |
158 | s3c_pm_do_restore_core(exynos4210_clock_save, ARRAY_SIZE(exynos4210_clock_save)); | |
159 | } | |
160 | ||
161 | #else | |
162 | #define exynos4210_clock_suspend NULL | |
163 | #define exynos4210_clock_resume NULL | |
164 | #endif | |
165 | ||
e745e06f | 166 | static struct syscore_ops exynos4210_clock_syscore_ops = { |
acd35616 JC |
167 | .suspend = exynos4210_clock_suspend, |
168 | .resume = exynos4210_clock_resume, | |
169 | }; | |
170 | ||
2bc02c0d KK |
171 | void __init exynos4210_register_clocks(void) |
172 | { | |
173 | int ptr; | |
174 | ||
a855039e KK |
175 | exynos4_clk_mout_mpll.reg_src.reg = EXYNOS4_CLKSRC_CPU; |
176 | exynos4_clk_mout_mpll.reg_src.shift = 8; | |
177 | exynos4_clk_mout_mpll.reg_src.size = 1; | |
2bc02c0d KK |
178 | |
179 | for (ptr = 0; ptr < ARRAY_SIZE(sysclks); ptr++) | |
180 | s3c_register_clksrc(sysclks[ptr], 1); | |
181 | ||
182 | s3c_register_clksrc(clksrcs, ARRAY_SIZE(clksrcs)); | |
183 | ||
184 | s3c_register_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); | |
185 | s3c_disable_clocks(init_clocks_off, ARRAY_SIZE(init_clocks_off)); | |
acd35616 JC |
186 | |
187 | register_syscore_ops(&exynos4210_clock_syscore_ops); | |
2bc02c0d | 188 | } |