1 /* linux/arch/arm/mach-exynos4/dev-pd.c
2  *
3  * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
4  *		http://www.samsung.com
5  *
6  * EXYNOS4 - Power Domain support
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/io.h>
14 #include <linux/kernel.h>
15 #include <linux/platform_device.h>
16 #include <linux/delay.h>
17 
18 #include <mach/regs-pmu.h>
19 
20 #include <plat/pd.h>
21 
exynos4_pd_enable(struct device * dev)22 static int exynos4_pd_enable(struct device *dev)
23 {
24 	struct samsung_pd_info *pdata =  dev->platform_data;
25 	u32 timeout;
26 
27 	__raw_writel(S5P_INT_LOCAL_PWR_EN, pdata->base);
28 
29 	/* Wait max 1ms */
30 	timeout = 10;
31 	while ((__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN)
32 		!= S5P_INT_LOCAL_PWR_EN) {
33 		if (timeout == 0) {
34 			printk(KERN_ERR "Power domain %s enable failed.\n",
35 				dev_name(dev));
36 			return -ETIMEDOUT;
37 		}
38 		timeout--;
39 		udelay(100);
40 	}
41 
42 	return 0;
43 }
44 
exynos4_pd_disable(struct device * dev)45 static int exynos4_pd_disable(struct device *dev)
46 {
47 	struct samsung_pd_info *pdata =  dev->platform_data;
48 	u32 timeout;
49 
50 	__raw_writel(0, pdata->base);
51 
52 	/* Wait max 1ms */
53 	timeout = 10;
54 	while (__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) {
55 		if (timeout == 0) {
56 			printk(KERN_ERR "Power domain %s disable failed.\n",
57 				dev_name(dev));
58 			return -ETIMEDOUT;
59 		}
60 		timeout--;
61 		udelay(100);
62 	}
63 
64 	return 0;
65 }
66 
67 struct platform_device exynos4_device_pd[] = {
68 	{
69 		.name		= "samsung-pd",
70 		.id		= 0,
71 		.dev = {
72 			.platform_data = &(struct samsung_pd_info) {
73 				.enable		= exynos4_pd_enable,
74 				.disable	= exynos4_pd_disable,
75 				.base		= S5P_PMU_MFC_CONF,
76 			},
77 		},
78 	}, {
79 		.name		= "samsung-pd",
80 		.id		= 1,
81 		.dev = {
82 			.platform_data = &(struct samsung_pd_info) {
83 				.enable		= exynos4_pd_enable,
84 				.disable	= exynos4_pd_disable,
85 				.base		= S5P_PMU_G3D_CONF,
86 			},
87 		},
88 	}, {
89 		.name		= "samsung-pd",
90 		.id		= 2,
91 		.dev = {
92 			.platform_data = &(struct samsung_pd_info) {
93 				.enable		= exynos4_pd_enable,
94 				.disable	= exynos4_pd_disable,
95 				.base		= S5P_PMU_LCD0_CONF,
96 			},
97 		},
98 	}, {
99 		.name		= "samsung-pd",
100 		.id		= 3,
101 		.dev = {
102 			.platform_data = &(struct samsung_pd_info) {
103 				.enable		= exynos4_pd_enable,
104 				.disable	= exynos4_pd_disable,
105 				.base		= S5P_PMU_LCD1_CONF,
106 			},
107 		},
108 	}, {
109 		.name		= "samsung-pd",
110 		.id		= 4,
111 		.dev = {
112 			.platform_data = &(struct samsung_pd_info) {
113 				.enable		= exynos4_pd_enable,
114 				.disable	= exynos4_pd_disable,
115 				.base		= S5P_PMU_TV_CONF,
116 			},
117 		},
118 	}, {
119 		.name		= "samsung-pd",
120 		.id		= 5,
121 		.dev = {
122 			.platform_data = &(struct samsung_pd_info) {
123 				.enable		= exynos4_pd_enable,
124 				.disable	= exynos4_pd_disable,
125 				.base		= S5P_PMU_CAM_CONF,
126 			},
127 		},
128 	}, {
129 		.name		= "samsung-pd",
130 		.id		= 6,
131 		.dev = {
132 			.platform_data = &(struct samsung_pd_info) {
133 				.enable		= exynos4_pd_enable,
134 				.disable	= exynos4_pd_disable,
135 				.base		= S5P_PMU_GPS_CONF,
136 			},
137 		},
138 	},
139 };
140