pmu.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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. #ifndef _MRST_PMU_H_
  20. #define _MRST_PMU_H_
  21. #define PCI_DEV_ID_MRST_PMU 0x0810
  22. #define MRST_PMU_DRV_NAME "mrst_pmu"
  23. #define PCI_SUB_CLASS_MASK 0xFF00
  24. #define PCI_VENDOR_CAP_LOG_ID_MASK 0x7F
  25. #define PCI_VENDOR_CAP_LOG_SS_MASK 0x80
  26. #define SUB_SYS_ALL_D0I1 0x01155555
  27. #define S0I3_WAKE_SOURCES 0x00001FFF
  28. #define PM_S0I3_COMMAND \
  29. ((0 << 31) | /* Reserved */ \
  30. (0 << 30) | /* Core must be idle */ \
  31. (0xc2 << 22) | /* ACK C6 trigger */ \
  32. (3 << 19) | /* Trigger on DMI message */ \
  33. (3 << 16) | /* Enter S0i3 */ \
  34. (0 << 13) | /* Numeric mode ID (sw) */ \
  35. (3 << 9) | /* Trigger mode */ \
  36. (0 << 8) | /* Do not interrupt */ \
  37. (1 << 0)) /* Set configuration */
  38. #define LSS_DMI 0
  39. #define LSS_SD_HC0 1
  40. #define LSS_SD_HC1 2
  41. #define LSS_NAND 3
  42. #define LSS_IMAGING 4
  43. #define LSS_SECURITY 5
  44. #define LSS_DISPLAY 6
  45. #define LSS_USB_HC 7
  46. #define LSS_USB_OTG 8
  47. #define LSS_AUDIO 9
  48. #define LSS_AUDIO_LPE 9
  49. #define LSS_AUDIO_SSP 9
  50. #define LSS_I2C0 10
  51. #define LSS_I2C1 10
  52. #define LSS_I2C2 10
  53. #define LSS_KBD 10
  54. #define LSS_SPI0 10
  55. #define LSS_SPI1 10
  56. #define LSS_SPI2 10
  57. #define LSS_GPIO 10
  58. #define LSS_SRAM 11 /* used by SCU, do not touch */
  59. #define LSS_SD_HC2 12
  60. /* LSS hardware bits 15,14,13 are hardwired to 0, thus unusable */
  61. #define MRST_NUM_LSS 13
  62. #define MIN(a, b) (((a) < (b)) ? (a) : (b))
  63. #define SSMSK(mask, lss) ((mask) << ((lss) * 2))
  64. #define D0 0
  65. #define D0i1 1
  66. #define D0i2 2
  67. #define D0i3 3
  68. #define S0I3_SSS_TARGET ( \
  69. SSMSK(D0i1, LSS_DMI) | \
  70. SSMSK(D0i3, LSS_SD_HC0) | \
  71. SSMSK(D0i3, LSS_SD_HC1) | \
  72. SSMSK(D0i3, LSS_NAND) | \
  73. SSMSK(D0i3, LSS_SD_HC2) | \
  74. SSMSK(D0i3, LSS_IMAGING) | \
  75. SSMSK(D0i3, LSS_SECURITY) | \
  76. SSMSK(D0i3, LSS_DISPLAY) | \
  77. SSMSK(D0i3, LSS_USB_HC) | \
  78. SSMSK(D0i3, LSS_USB_OTG) | \
  79. SSMSK(D0i3, LSS_AUDIO) | \
  80. SSMSK(D0i1, LSS_I2C0))
  81. /*
  82. * D0i1 on Langwell is Autonomous Clock Gating (ACG).
  83. * Enable ACG on every LSS except camera and audio
  84. */
  85. #define D0I1_ACG_SSS_TARGET \
  86. (SUB_SYS_ALL_D0I1 & ~SSMSK(D0i1, LSS_IMAGING) & ~SSMSK(D0i1, LSS_AUDIO))
  87. enum cm_mode {
  88. CM_NOP, /* ignore the config mode value */
  89. CM_IMMEDIATE,
  90. CM_DELAY,
  91. CM_TRIGGER,
  92. CM_INVALID
  93. };
  94. enum sys_state {
  95. SYS_STATE_S0I0,
  96. SYS_STATE_S0I1,
  97. SYS_STATE_S0I2,
  98. SYS_STATE_S0I3,
  99. SYS_STATE_S3,
  100. SYS_STATE_S5
  101. };
  102. #define SET_CFG_CMD 1
  103. enum int_status {
  104. INT_SPURIOUS = 0,
  105. INT_CMD_DONE = 1,
  106. INT_CMD_ERR = 2,
  107. INT_WAKE_RX = 3,
  108. INT_SS_ERROR = 4,
  109. INT_S0IX_MISS = 5,
  110. INT_NO_ACKC6 = 6,
  111. INT_INVALID = 7,
  112. };
  113. /* PMU register interface */
  114. static struct mrst_pmu_reg {
  115. u32 pm_sts; /* 0x00 */
  116. u32 pm_cmd; /* 0x04 */
  117. u32 pm_ics; /* 0x08 */
  118. u32 _resv1; /* 0x0C */
  119. u32 pm_wkc[2]; /* 0x10 */
  120. u32 pm_wks[2]; /* 0x18 */
  121. u32 pm_ssc[4]; /* 0x20 */
  122. u32 pm_sss[4]; /* 0x30 */
  123. u32 pm_wssc[4]; /* 0x40 */
  124. u32 pm_c3c4; /* 0x50 */
  125. u32 pm_c5c6; /* 0x54 */
  126. u32 pm_msi_disable; /* 0x58 */
  127. } *pmu_reg;
  128. static inline u32 pmu_read_sts(void) { return readl(&pmu_reg->pm_sts); }
  129. static inline u32 pmu_read_ics(void) { return readl(&pmu_reg->pm_ics); }
  130. static inline u32 pmu_read_wks(void) { return readl(&pmu_reg->pm_wks[0]); }
  131. static inline u32 pmu_read_sss(void) { return readl(&pmu_reg->pm_sss[0]); }
  132. static inline void pmu_write_cmd(u32 arg) { writel(arg, &pmu_reg->pm_cmd); }
  133. static inline void pmu_write_ics(u32 arg) { writel(arg, &pmu_reg->pm_ics); }
  134. static inline void pmu_write_wkc(u32 arg) { writel(arg, &pmu_reg->pm_wkc[0]); }
  135. static inline void pmu_write_ssc(u32 arg) { writel(arg, &pmu_reg->pm_ssc[0]); }
  136. static inline void pmu_write_wssc(u32 arg)
  137. { writel(arg, &pmu_reg->pm_wssc[0]); }
  138. static inline void pmu_msi_enable(void) { writel(0, &pmu_reg->pm_msi_disable); }
  139. static inline u32 pmu_msi_is_disabled(void)
  140. { return readl(&pmu_reg->pm_msi_disable); }
  141. union pmu_pm_ics {
  142. struct {
  143. u32 cause:8;
  144. u32 enable:1;
  145. u32 pending:1;
  146. u32 reserved:22;
  147. } bits;
  148. u32 value;
  149. };
  150. static inline void pmu_irq_enable(void)
  151. {
  152. union pmu_pm_ics pmu_ics;
  153. pmu_ics.value = pmu_read_ics();
  154. pmu_ics.bits.enable = 1;
  155. pmu_write_ics(pmu_ics.value);
  156. }
  157. union pmu_pm_status {
  158. struct {
  159. u32 pmu_rev:8;
  160. u32 pmu_busy:1;
  161. u32 mode_id:4;
  162. u32 Reserved:19;
  163. } pmu_status_parts;
  164. u32 pmu_status_value;
  165. };
  166. static inline int pmu_read_busy_status(void)
  167. {
  168. union pmu_pm_status result;
  169. result.pmu_status_value = pmu_read_sts();
  170. return result.pmu_status_parts.pmu_busy;
  171. }
  172. /* pmu set config parameters */
  173. struct cfg_delay_param_t {
  174. u32 cmd:8;
  175. u32 ioc:1;
  176. u32 cfg_mode:4;
  177. u32 mode_id:3;
  178. u32 sys_state:3;
  179. u32 cfg_delay:8;
  180. u32 rsvd:5;
  181. };
  182. struct cfg_trig_param_t {
  183. u32 cmd:8;
  184. u32 ioc:1;
  185. u32 cfg_mode:4;
  186. u32 mode_id:3;
  187. u32 sys_state:3;
  188. u32 cfg_trig_type:3;
  189. u32 cfg_trig_val:8;
  190. u32 cmbi:1;
  191. u32 rsvd1:1;
  192. };
  193. union pmu_pm_set_cfg_cmd_t {
  194. union {
  195. struct cfg_delay_param_t d_param;
  196. struct cfg_trig_param_t t_param;
  197. } pmu2_params;
  198. u32 pmu_pm_set_cfg_cmd_value;
  199. };
  200. #ifdef FUTURE_PATCH
  201. extern int mrst_s0i3_entry(u32 regval, u32 *regaddr);
  202. #else
  203. static inline int mrst_s0i3_entry(u32 regval, u32 *regaddr) { return -1; }
  204. #endif
  205. #endif