aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorKyongHo Cho <pullip.cho@samsung.com>2011-03-06 19:10:24 -0500
committerKukjin Kim <kgene.kim@samsung.com>2011-03-15 08:37:38 -0400
commitb0b6ff0b21057bb8e58b0be8b427a4713fd4b5a5 (patch)
tree911aa86fbe18c818d619304c2e8e458ccd739936 /arch
parentb34f003f271d477f61a980d280afc77929047440 (diff)
ARM: EXYNOS4: Implement Clock gating for System MMU
This patch includes the implementation of the clock gating for System MMU. Initially, all System MMUs are not asserted the system clock. Asserting the system clock to a System MMU is enabled only when s5p_sysmmu_enable() is called. Likewise, it is disabled only when s5p_sysmmu_disable() is called. Therefore, clock gating on System MMUs are still invisible to the outside of the System MMU driver. Signed-off-by: KyongHo Cho <pullip.cho@samsung.com> Signed-off-by: Kukjin Kim <kgene.kim@samsung.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-exynos4/clock.c83
-rw-r--r--arch/arm/mach-exynos4/dev-sysmmu.c22
-rw-r--r--arch/arm/mach-exynos4/include/mach/regs-clock.h13
-rw-r--r--arch/arm/mach-exynos4/include/mach/sysmmu.h4
-rw-r--r--arch/arm/plat-s5p/sysmmu.c6
5 files changed, 117 insertions, 11 deletions
diff --git a/arch/arm/mach-exynos4/clock.c b/arch/arm/mach-exynos4/clock.c
index 15f13338f74c..871f9d508fde 100644
--- a/arch/arm/mach-exynos4/clock.c
+++ b/arch/arm/mach-exynos4/clock.c
@@ -23,6 +23,7 @@
23 23
24#include <mach/map.h> 24#include <mach/map.h>
25#include <mach/regs-clock.h> 25#include <mach/regs-clock.h>
26#include <mach/sysmmu.h>
26 27
27static struct clk clk_sclk_hdmi27m = { 28static struct clk clk_sclk_hdmi27m = {
28 .name = "sclk_hdmi27m", 29 .name = "sclk_hdmi27m",
@@ -81,11 +82,21 @@ static int exynos4_clksrc_mask_peril1_ctrl(struct clk *clk, int enable)
81 return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable); 82 return s5p_gatectrl(S5P_CLKSRC_MASK_PERIL1, clk, enable);
82} 83}
83 84
85static int exynos4_clk_ip_mfc_ctrl(struct clk *clk, int enable)
86{
87 return s5p_gatectrl(S5P_CLKGATE_IP_MFC, clk, enable);
88}
89
84static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable) 90static int exynos4_clk_ip_cam_ctrl(struct clk *clk, int enable)
85{ 91{
86 return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable); 92 return s5p_gatectrl(S5P_CLKGATE_IP_CAM, clk, enable);
87} 93}
88 94
95static int exynos4_clk_ip_tv_ctrl(struct clk *clk, int enable)
96{
97 return s5p_gatectrl(S5P_CLKGATE_IP_TV, clk, enable);
98}
99
89static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable) 100static int exynos4_clk_ip_image_ctrl(struct clk *clk, int enable)
90{ 101{
91 return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable); 102 return s5p_gatectrl(S5P_CLKGATE_IP_IMAGE, clk, enable);
@@ -602,7 +613,77 @@ static struct clk init_clocks_off[] = {
602 .parent = &clk_aclk_100.clk, 613 .parent = &clk_aclk_100.clk,
603 .enable = exynos4_clk_ip_peril_ctrl, 614 .enable = exynos4_clk_ip_peril_ctrl,
604 .ctrlbit = (1 << 13), 615 .ctrlbit = (1 << 13),
605 }, 616 }, {
617 .name = "SYSMMU_MDMA",
618 .id = -1,
619 .enable = exynos4_clk_ip_image_ctrl,
620 .ctrlbit = (1 << 5),
621 }, {
622 .name = "SYSMMU_FIMC0",
623 .id = -1,
624 .enable = exynos4_clk_ip_cam_ctrl,
625 .ctrlbit = (1 << 7),
626 }, {
627 .name = "SYSMMU_FIMC1",
628 .id = -1,
629 .enable = exynos4_clk_ip_cam_ctrl,
630 .ctrlbit = (1 << 8),
631 }, {
632 .name = "SYSMMU_FIMC2",
633 .id = -1,
634 .enable = exynos4_clk_ip_cam_ctrl,
635 .ctrlbit = (1 << 9),
636 }, {
637 .name = "SYSMMU_FIMC3",
638 .id = -1,
639 .enable = exynos4_clk_ip_cam_ctrl,
640 .ctrlbit = (1 << 10),
641 }, {
642 .name = "SYSMMU_JPEG",
643 .id = -1,
644 .enable = exynos4_clk_ip_cam_ctrl,
645 .ctrlbit = (1 << 11),
646 }, {
647 .name = "SYSMMU_FIMD0",
648 .id = -1,
649 .enable = exynos4_clk_ip_lcd0_ctrl,
650 .ctrlbit = (1 << 4),
651 }, {
652 .name = "SYSMMU_FIMD1",
653 .id = -1,
654 .enable = exynos4_clk_ip_lcd1_ctrl,
655 .ctrlbit = (1 << 4),
656 }, {
657 .name = "SYSMMU_PCIe",
658 .id = -1,
659 .enable = exynos4_clk_ip_fsys_ctrl,
660 .ctrlbit = (1 << 18),
661 }, {
662 .name = "SYSMMU_G2D",
663 .id = -1,
664 .enable = exynos4_clk_ip_image_ctrl,
665 .ctrlbit = (1 << 3),
666 }, {
667 .name = "SYSMMU_ROTATOR",
668 .id = -1,
669 .enable = exynos4_clk_ip_image_ctrl,
670 .ctrlbit = (1 << 4),
671 }, {
672 .name = "SYSMMU_TV",
673 .id = -1,
674 .enable = exynos4_clk_ip_tv_ctrl,
675 .ctrlbit = (1 << 4),
676 }, {
677 .name = "SYSMMU_MFC_L",
678 .id = -1,
679 .enable = exynos4_clk_ip_mfc_ctrl,
680 .ctrlbit = (1 << 1),
681 }, {
682 .name = "SYSMMU_MFC_R",
683 .id = -1,
684 .enable = exynos4_clk_ip_mfc_ctrl,
685 .ctrlbit = (1 << 2),
686 }
606}; 687};
607 688
608static struct clk init_clocks[] = { 689static struct clk init_clocks[] = {
diff --git a/arch/arm/mach-exynos4/dev-sysmmu.c b/arch/arm/mach-exynos4/dev-sysmmu.c
index 6889c9aa6493..3b7cae0fe23e 100644
--- a/arch/arm/mach-exynos4/dev-sysmmu.c
+++ b/arch/arm/mach-exynos4/dev-sysmmu.c
@@ -208,3 +208,25 @@ struct platform_device exynos4_device_sysmmu = {
208 .resource = exynos4_sysmmu_resource, 208 .resource = exynos4_sysmmu_resource,
209}; 209};
210EXPORT_SYMBOL(exynos4_device_sysmmu); 210EXPORT_SYMBOL(exynos4_device_sysmmu);
211
212static struct clk *sysmmu_clk[S5P_SYSMMU_TOTAL_IPNUM];
213void sysmmu_clk_init(struct device *dev, sysmmu_ips ips)
214{
215 sysmmu_clk[ips] = clk_get(dev, sysmmu_ips_name[ips]);
216 if (IS_ERR(sysmmu_clk[ips]))
217 sysmmu_clk[ips] = NULL;
218 else
219 clk_put(sysmmu_clk[ips]);
220}
221
222void sysmmu_clk_enable(sysmmu_ips ips)
223{
224 if (sysmmu_clk[ips])
225 clk_enable(sysmmu_clk[ips]);
226}
227
228void sysmmu_clk_disable(sysmmu_ips ips)
229{
230 if (sysmmu_clk[ips])
231 clk_disable(sysmmu_clk[ips]);
232}
diff --git a/arch/arm/mach-exynos4/include/mach/regs-clock.h b/arch/arm/mach-exynos4/include/mach/regs-clock.h
index c91f93054589..6e311c1157f5 100644
--- a/arch/arm/mach-exynos4/include/mach/regs-clock.h
+++ b/arch/arm/mach-exynos4/include/mach/regs-clock.h
@@ -19,11 +19,11 @@
19 19
20#define S5P_CLKDIV_LEFTBUS S5P_CLKREG(0x04500) 20#define S5P_CLKDIV_LEFTBUS S5P_CLKREG(0x04500)
21#define S5P_CLKDIV_STAT_LEFTBUS S5P_CLKREG(0x04600) 21#define S5P_CLKDIV_STAT_LEFTBUS S5P_CLKREG(0x04600)
22#define S5P_CLKGATE_IP_LEFTBUS S5P_CLKREG(0x04800) 22#define S5P_CLKGATE_IP_LEFTBUS S5P_CLKREG(0x04800)
23 23
24#define S5P_CLKDIV_RIGHTBUS S5P_CLKREG(0x08500) 24#define S5P_CLKDIV_RIGHTBUS S5P_CLKREG(0x08500)
25#define S5P_CLKDIV_STAT_RIGHTBUS S5P_CLKREG(0x08600) 25#define S5P_CLKDIV_STAT_RIGHTBUS S5P_CLKREG(0x08600)
26#define S5P_CLKGATE_IP_RIGHTBUS S5P_CLKREG(0x08800) 26#define S5P_CLKGATE_IP_RIGHTBUS S5P_CLKREG(0x08800)
27 27
28#define S5P_EPLL_CON0 S5P_CLKREG(0x0C110) 28#define S5P_EPLL_CON0 S5P_CLKREG(0x0C110)
29#define S5P_EPLL_CON1 S5P_CLKREG(0x0C114) 29#define S5P_EPLL_CON1 S5P_CLKREG(0x0C114)
@@ -76,7 +76,7 @@
76 76
77#define S5P_CLKGATE_SCLKCAM S5P_CLKREG(0x0C820) 77#define S5P_CLKGATE_SCLKCAM S5P_CLKREG(0x0C820)
78#define S5P_CLKGATE_IP_CAM S5P_CLKREG(0x0C920) 78#define S5P_CLKGATE_IP_CAM S5P_CLKREG(0x0C920)
79#define S5P_CLKGATE_IP_TV S5P_CLKREG(0x0C924) 79#define S5P_CLKGATE_IP_TV S5P_CLKREG(0x0C924)
80#define S5P_CLKGATE_IP_MFC S5P_CLKREG(0x0C928) 80#define S5P_CLKGATE_IP_MFC S5P_CLKREG(0x0C928)
81#define S5P_CLKGATE_IP_G3D S5P_CLKREG(0x0C92C) 81#define S5P_CLKGATE_IP_G3D S5P_CLKREG(0x0C92C)
82#define S5P_CLKGATE_IP_IMAGE S5P_CLKREG(0x0C930) 82#define S5P_CLKGATE_IP_IMAGE S5P_CLKREG(0x0C930)
@@ -113,20 +113,16 @@
113#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800) 113#define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800)
114#define S5P_CLKGATE_IP_CPU S5P_CLKREG(0x14900) 114#define S5P_CLKGATE_IP_CPU S5P_CLKREG(0x14900)
115 115
116/* APLL_LOCK */
117#define S5P_APLL_LOCKTIME (0x1C20) /* 300us */ 116#define S5P_APLL_LOCKTIME (0x1C20) /* 300us */
118 117
119/* APLL_CON0 */
120#define S5P_APLLCON0_ENABLE_SHIFT (31) 118#define S5P_APLLCON0_ENABLE_SHIFT (31)
121#define S5P_APLLCON0_LOCKED_SHIFT (29) 119#define S5P_APLLCON0_LOCKED_SHIFT (29)
122#define S5P_APLL_VAL_1000 ((250 << 16) | (6 << 8) | 1) 120#define S5P_APLL_VAL_1000 ((250 << 16) | (6 << 8) | 1)
123#define S5P_APLL_VAL_800 ((200 << 16) | (6 << 8) | 1) 121#define S5P_APLL_VAL_800 ((200 << 16) | (6 << 8) | 1)
124 122
125/* CLK_SRC_CPU */
126#define S5P_CLKSRC_CPU_MUXCORE_SHIFT (16) 123#define S5P_CLKSRC_CPU_MUXCORE_SHIFT (16)
127#define S5P_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << S5P_CLKSRC_CPU_MUXCORE_SHIFT) 124#define S5P_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << S5P_CLKSRC_CPU_MUXCORE_SHIFT)
128 125
129/* CLKDIV_CPU0 */
130#define S5P_CLKDIV_CPU0_CORE_SHIFT (0) 126#define S5P_CLKDIV_CPU0_CORE_SHIFT (0)
131#define S5P_CLKDIV_CPU0_CORE_MASK (0x7 << S5P_CLKDIV_CPU0_CORE_SHIFT) 127#define S5P_CLKDIV_CPU0_CORE_MASK (0x7 << S5P_CLKDIV_CPU0_CORE_SHIFT)
132#define S5P_CLKDIV_CPU0_COREM0_SHIFT (4) 128#define S5P_CLKDIV_CPU0_COREM0_SHIFT (4)
@@ -142,7 +138,6 @@
142#define S5P_CLKDIV_CPU0_APLL_SHIFT (24) 138#define S5P_CLKDIV_CPU0_APLL_SHIFT (24)
143#define S5P_CLKDIV_CPU0_APLL_MASK (0x7 << S5P_CLKDIV_CPU0_APLL_SHIFT) 139#define S5P_CLKDIV_CPU0_APLL_MASK (0x7 << S5P_CLKDIV_CPU0_APLL_SHIFT)
144 140
145/* CLKDIV_DMC0 */
146#define S5P_CLKDIV_DMC0_ACP_SHIFT (0) 141#define S5P_CLKDIV_DMC0_ACP_SHIFT (0)
147#define S5P_CLKDIV_DMC0_ACP_MASK (0x7 << S5P_CLKDIV_DMC0_ACP_SHIFT) 142#define S5P_CLKDIV_DMC0_ACP_MASK (0x7 << S5P_CLKDIV_DMC0_ACP_SHIFT)
148#define S5P_CLKDIV_DMC0_ACPPCLK_SHIFT (4) 143#define S5P_CLKDIV_DMC0_ACPPCLK_SHIFT (4)
@@ -160,7 +155,6 @@
160#define S5P_CLKDIV_DMC0_CORETI_SHIFT (28) 155#define S5P_CLKDIV_DMC0_CORETI_SHIFT (28)
161#define S5P_CLKDIV_DMC0_CORETI_MASK (0x7 << S5P_CLKDIV_DMC0_CORETI_SHIFT) 156#define S5P_CLKDIV_DMC0_CORETI_MASK (0x7 << S5P_CLKDIV_DMC0_CORETI_SHIFT)
162 157
163/* CLKDIV_TOP */
164#define S5P_CLKDIV_TOP_ACLK200_SHIFT (0) 158#define S5P_CLKDIV_TOP_ACLK200_SHIFT (0)
165#define S5P_CLKDIV_TOP_ACLK200_MASK (0x7 << S5P_CLKDIV_TOP_ACLK200_SHIFT) 159#define S5P_CLKDIV_TOP_ACLK200_MASK (0x7 << S5P_CLKDIV_TOP_ACLK200_SHIFT)
166#define S5P_CLKDIV_TOP_ACLK100_SHIFT (4) 160#define S5P_CLKDIV_TOP_ACLK100_SHIFT (4)
@@ -172,7 +166,6 @@
172#define S5P_CLKDIV_TOP_ONENAND_SHIFT (16) 166#define S5P_CLKDIV_TOP_ONENAND_SHIFT (16)
173#define S5P_CLKDIV_TOP_ONENAND_MASK (0x7 << S5P_CLKDIV_TOP_ONENAND_SHIFT) 167#define S5P_CLKDIV_TOP_ONENAND_MASK (0x7 << S5P_CLKDIV_TOP_ONENAND_SHIFT)
174 168
175/* CLKDIV_LEFTBUS / CLKDIV_RIGHTBUS*/
176#define S5P_CLKDIV_BUS_GDLR_SHIFT (0) 169#define S5P_CLKDIV_BUS_GDLR_SHIFT (0)
177#define S5P_CLKDIV_BUS_GDLR_MASK (0x7 << S5P_CLKDIV_BUS_GDLR_SHIFT) 170#define S5P_CLKDIV_BUS_GDLR_MASK (0x7 << S5P_CLKDIV_BUS_GDLR_SHIFT)
178#define S5P_CLKDIV_BUS_GPLR_SHIFT (4) 171#define S5P_CLKDIV_BUS_GPLR_SHIFT (4)
diff --git a/arch/arm/mach-exynos4/include/mach/sysmmu.h b/arch/arm/mach-exynos4/include/mach/sysmmu.h
index eff3dc37f3da..6a5fbb534e82 100644
--- a/arch/arm/mach-exynos4/include/mach/sysmmu.h
+++ b/arch/arm/mach-exynos4/include/mach/sysmmu.h
@@ -39,4 +39,8 @@ extern const char *sysmmu_ips_name[EXYNOS4_SYSMMU_TOTAL_IPNUM];
39 39
40typedef enum exynos4_sysmmu_ips sysmmu_ips; 40typedef enum exynos4_sysmmu_ips sysmmu_ips;
41 41
42void sysmmu_clk_init(struct device *dev, sysmmu_ips ips);
43void sysmmu_clk_enable(sysmmu_ips ips);
44void sysmmu_clk_disable(sysmmu_ips ips);
45
42#endif /* __ASM_ARM_ARCH_SYSMMU_H */ 46#endif /* __ASM_ARM_ARCH_SYSMMU_H */
diff --git a/arch/arm/plat-s5p/sysmmu.c b/arch/arm/plat-s5p/sysmmu.c
index 89e024f377bb..54f5eddc921d 100644
--- a/arch/arm/plat-s5p/sysmmu.c
+++ b/arch/arm/plat-s5p/sysmmu.c
@@ -174,6 +174,8 @@ void s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd)
174void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd) 174void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd)
175{ 175{
176 if (!is_sysmmu_active(ips)) { 176 if (!is_sysmmu_active(ips)) {
177 sysmmu_clk_enable(ips);
178
177 __sysmmu_set_ptbase(ips, pgd); 179 __sysmmu_set_ptbase(ips, pgd);
178 180
179 __raw_writel(CTRL_ENABLE, sysmmusfrs[ips] + S5P_MMU_CTRL); 181 __raw_writel(CTRL_ENABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
@@ -190,6 +192,7 @@ void s5p_sysmmu_disable(sysmmu_ips ips)
190 if (is_sysmmu_active(ips)) { 192 if (is_sysmmu_active(ips)) {
191 __raw_writel(CTRL_DISABLE, sysmmusfrs[ips] + S5P_MMU_CTRL); 193 __raw_writel(CTRL_DISABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
192 set_sysmmu_inactive(ips); 194 set_sysmmu_inactive(ips);
195 sysmmu_clk_disable(ips);
193 dev_dbg(dev, "%s is disabled.\n", sysmmu_ips_name[ips]); 196 dev_dbg(dev, "%s is disabled.\n", sysmmu_ips_name[ips]);
194 } else { 197 } else {
195 dev_dbg(dev, "%s is already disabled.\n", sysmmu_ips_name[ips]); 198 dev_dbg(dev, "%s is already disabled.\n", sysmmu_ips_name[ips]);
@@ -218,6 +221,9 @@ static int s5p_sysmmu_probe(struct platform_device *pdev)
218 for (i = 0; i < S5P_SYSMMU_TOTAL_IPNUM; i++) { 221 for (i = 0; i < S5P_SYSMMU_TOTAL_IPNUM; i++) {
219 int irq; 222 int irq;
220 223
224 sysmmu_clk_init(dev, i);
225 sysmmu_clk_disable(i);
226
221 res = platform_get_resource(pdev, IORESOURCE_MEM, i); 227 res = platform_get_resource(pdev, IORESOURCE_MEM, i);
222 if (!res) { 228 if (!res) {
223 dev_err(dev, "Failed to get the resource of %s.\n", 229 dev_err(dev, "Failed to get the resource of %s.\n",