Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[pandora-kernel.git] / arch / x86 / platform / mrst / pmu.h
1 /*
2  * mrst/pmu.h - private definitions for MRST Power Management Unit mrst/pmu.c
3  *
4  * Copyright (c) 2011, Intel Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19
20 #ifndef _MRST_PMU_H_
21 #define _MRST_PMU_H_
22
23 #define PCI_DEV_ID_MRST_PMU             0x0810
24 #define MRST_PMU_DRV_NAME               "mrst_pmu"
25 #define PCI_SUB_CLASS_MASK              0xFF00
26
27 #define PCI_VENDOR_CAP_LOG_ID_MASK      0x7F
28 #define PCI_VENDOR_CAP_LOG_SS_MASK      0x80
29
30 #define SUB_SYS_ALL_D0I1        0x01155555
31 #define S0I3_WAKE_SOURCES       0x00001FFF
32
33 #define PM_S0I3_COMMAND                                 \
34         ((0 << 31) |    /* Reserved */                  \
35         (0 << 30) |     /* Core must be idle */         \
36         (0xc2 << 22) |  /* ACK C6 trigger */            \
37         (3 << 19) |     /* Trigger on DMI message */    \
38         (3 << 16) |     /* Enter S0i3 */                \
39         (0 << 13) |     /* Numeric mode ID (sw) */      \
40         (3 << 9) |      /* Trigger mode */              \
41         (0 << 8) |      /* Do not interrupt */          \
42         (1 << 0))       /* Set configuration */
43
44 #define LSS_DMI         0
45 #define LSS_SD_HC0      1
46 #define LSS_SD_HC1      2
47 #define LSS_NAND        3
48 #define LSS_IMAGING     4
49 #define LSS_SECURITY    5
50 #define LSS_DISPLAY     6
51 #define LSS_USB_HC      7
52 #define LSS_USB_OTG     8
53 #define LSS_AUDIO       9
54 #define LSS_AUDIO_LPE   9
55 #define LSS_AUDIO_SSP   9
56 #define LSS_I2C0        10
57 #define LSS_I2C1        10
58 #define LSS_I2C2        10
59 #define LSS_KBD         10
60 #define LSS_SPI0        10
61 #define LSS_SPI1        10
62 #define LSS_SPI2        10
63 #define LSS_GPIO        10
64 #define LSS_SRAM        11      /* used by SCU, do not touch */
65 #define LSS_SD_HC2      12
66 /* LSS hardware bits 15,14,13 are hardwired to 0, thus unusable */
67 #define MRST_NUM_LSS    13
68
69 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
70
71 #define SSMSK(mask, lss) ((mask) << ((lss) * 2))
72 #define D0      0
73 #define D0i1    1
74 #define D0i2    2
75 #define D0i3    3
76
77 #define S0I3_SSS_TARGET (               \
78         SSMSK(D0i1, LSS_DMI) |          \
79         SSMSK(D0i3, LSS_SD_HC0) |       \
80         SSMSK(D0i3, LSS_SD_HC1) |       \
81         SSMSK(D0i3, LSS_NAND) |         \
82         SSMSK(D0i3, LSS_SD_HC2) |       \
83         SSMSK(D0i3, LSS_IMAGING) |      \
84         SSMSK(D0i3, LSS_SECURITY) |     \
85         SSMSK(D0i3, LSS_DISPLAY) |      \
86         SSMSK(D0i3, LSS_USB_HC) |       \
87         SSMSK(D0i3, LSS_USB_OTG) |      \
88         SSMSK(D0i3, LSS_AUDIO) |        \
89         SSMSK(D0i1, LSS_I2C0))
90
91 /*
92  * D0i1 on Langwell is Autonomous Clock Gating (ACG).
93  * Enable ACG on every LSS except camera and audio
94  */
95 #define D0I1_ACG_SSS_TARGET      \
96         (SUB_SYS_ALL_D0I1 & ~SSMSK(D0i1, LSS_IMAGING) & ~SSMSK(D0i1, LSS_AUDIO))
97
98 enum cm_mode {
99         CM_NOP,                 /* ignore the config mode value */
100         CM_IMMEDIATE,
101         CM_DELAY,
102         CM_TRIGGER,
103         CM_INVALID
104 };
105
106 enum sys_state {
107         SYS_STATE_S0I0,
108         SYS_STATE_S0I1,
109         SYS_STATE_S0I2,
110         SYS_STATE_S0I3,
111         SYS_STATE_S3,
112         SYS_STATE_S5
113 };
114
115 #define SET_CFG_CMD     1
116
117 enum int_status {
118         INT_SPURIOUS = 0,
119         INT_CMD_DONE = 1,
120         INT_CMD_ERR = 2,
121         INT_WAKE_RX = 3,
122         INT_SS_ERROR = 4,
123         INT_S0IX_MISS = 5,
124         INT_NO_ACKC6 = 6,
125         INT_INVALID = 7,
126 };
127
128 /* PMU register interface */
129 static struct mrst_pmu_reg {
130         u32 pm_sts;             /* 0x00 */
131         u32 pm_cmd;             /* 0x04 */
132         u32 pm_ics;             /* 0x08 */
133         u32 _resv1;             /* 0x0C */
134         u32 pm_wkc[2];          /* 0x10 */
135         u32 pm_wks[2];          /* 0x18 */
136         u32 pm_ssc[4];          /* 0x20 */
137         u32 pm_sss[4];          /* 0x30 */
138         u32 pm_wssc[4];         /* 0x40 */
139         u32 pm_c3c4;            /* 0x50 */
140         u32 pm_c5c6;            /* 0x54 */
141         u32 pm_msi_disable;     /* 0x58 */
142 } *pmu_reg;
143
144 static inline u32 pmu_read_sts(void) { return readl(&pmu_reg->pm_sts); }
145 static inline u32 pmu_read_ics(void) { return readl(&pmu_reg->pm_ics); }
146 static inline u32 pmu_read_wks(void) { return readl(&pmu_reg->pm_wks[0]); }
147 static inline u32 pmu_read_sss(void) { return readl(&pmu_reg->pm_sss[0]); }
148
149 static inline void pmu_write_cmd(u32 arg) { writel(arg, &pmu_reg->pm_cmd); }
150 static inline void pmu_write_ics(u32 arg) { writel(arg, &pmu_reg->pm_ics); }
151 static inline void pmu_write_wkc(u32 arg) { writel(arg, &pmu_reg->pm_wkc[0]); }
152 static inline void pmu_write_ssc(u32 arg) { writel(arg, &pmu_reg->pm_ssc[0]); }
153 static inline void pmu_write_wssc(u32 arg)
154                                         { writel(arg, &pmu_reg->pm_wssc[0]); }
155
156 static inline void pmu_msi_enable(void) { writel(0, &pmu_reg->pm_msi_disable); }
157 static inline u32 pmu_msi_is_disabled(void)
158                                 { return readl(&pmu_reg->pm_msi_disable); }
159
160 union pmu_pm_ics {
161         struct {
162                 u32 cause:8;
163                 u32 enable:1;
164                 u32 pending:1;
165                 u32 reserved:22;
166         } bits;
167         u32 value;
168 };
169
170 static inline void pmu_irq_enable(void)
171 {
172         union pmu_pm_ics pmu_ics;
173
174         pmu_ics.value = pmu_read_ics();
175         pmu_ics.bits.enable = 1;
176         pmu_write_ics(pmu_ics.value);
177 }
178
179 union pmu_pm_status {
180         struct {
181                 u32 pmu_rev:8;
182                 u32 pmu_busy:1;
183                 u32 mode_id:4;
184                 u32 Reserved:19;
185         } pmu_status_parts;
186         u32 pmu_status_value;
187 };
188
189 static inline int pmu_read_busy_status(void)
190 {
191         union pmu_pm_status result;
192
193         result.pmu_status_value = pmu_read_sts();
194
195         return result.pmu_status_parts.pmu_busy;
196 }
197
198 /* pmu set config parameters */
199 struct cfg_delay_param_t {
200         u32 cmd:8;
201         u32 ioc:1;
202         u32 cfg_mode:4;
203         u32 mode_id:3;
204         u32 sys_state:3;
205         u32 cfg_delay:8;
206         u32 rsvd:5;
207 };
208
209 struct cfg_trig_param_t {
210         u32 cmd:8;
211         u32 ioc:1;
212         u32 cfg_mode:4;
213         u32 mode_id:3;
214         u32 sys_state:3;
215         u32 cfg_trig_type:3;
216         u32 cfg_trig_val:8;
217         u32 cmbi:1;
218         u32 rsvd1:1;
219 };
220
221 union pmu_pm_set_cfg_cmd_t {
222         union {
223                 struct cfg_delay_param_t d_param;
224                 struct cfg_trig_param_t t_param;
225         } pmu2_params;
226         u32 pmu_pm_set_cfg_cmd_value;
227 };
228
229 #ifdef FUTURE_PATCH
230 extern int mrst_s0i3_entry(u32 regval, u32 *regaddr);
231 #else
232 static inline int mrst_s0i3_entry(u32 regval, u32 *regaddr) { return -1; }
233 #endif
234 #endif