diff options
Diffstat (limited to 'arch/x86/platform/mrst/pmu.h')
-rw-r--r-- | arch/x86/platform/mrst/pmu.h | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/arch/x86/platform/mrst/pmu.h b/arch/x86/platform/mrst/pmu.h new file mode 100644 index 00000000000..bfbfe64b167 --- /dev/null +++ b/arch/x86/platform/mrst/pmu.h @@ -0,0 +1,234 @@ +/* + * mrst/pmu.h - private definitions for MRST Power Management Unit mrst/pmu.c + * + * Copyright (c) 2011, Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _MRST_PMU_H_ +#define _MRST_PMU_H_ + +#define PCI_DEV_ID_MRST_PMU 0x0810 +#define MRST_PMU_DRV_NAME "mrst_pmu" +#define PCI_SUB_CLASS_MASK 0xFF00 + +#define PCI_VENDOR_CAP_LOG_ID_MASK 0x7F +#define PCI_VENDOR_CAP_LOG_SS_MASK 0x80 + +#define SUB_SYS_ALL_D0I1 0x01155555 +#define S0I3_WAKE_SOURCES 0x00001FFF + +#define PM_S0I3_COMMAND \ + ((0 << 31) | /* Reserved */ \ + (0 << 30) | /* Core must be idle */ \ + (0xc2 << 22) | /* ACK C6 trigger */ \ + (3 << 19) | /* Trigger on DMI message */ \ + (3 << 16) | /* Enter S0i3 */ \ + (0 << 13) | /* Numeric mode ID (sw) */ \ + (3 << 9) | /* Trigger mode */ \ + (0 << 8) | /* Do not interrupt */ \ + (1 << 0)) /* Set configuration */ + +#define LSS_DMI 0 +#define LSS_SD_HC0 1 +#define LSS_SD_HC1 2 +#define LSS_NAND 3 +#define LSS_IMAGING 4 +#define LSS_SECURITY 5 +#define LSS_DISPLAY 6 +#define LSS_USB_HC 7 +#define LSS_USB_OTG 8 +#define LSS_AUDIO 9 +#define LSS_AUDIO_LPE 9 +#define LSS_AUDIO_SSP 9 +#define LSS_I2C0 10 +#define LSS_I2C1 10 +#define LSS_I2C2 10 +#define LSS_KBD 10 +#define LSS_SPI0 10 +#define LSS_SPI1 10 +#define LSS_SPI2 10 +#define LSS_GPIO 10 +#define LSS_SRAM 11 /* used by SCU, do not touch */ +#define LSS_SD_HC2 12 +/* LSS hardware bits 15,14,13 are hardwired to 0, thus unusable */ +#define MRST_NUM_LSS 13 + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#define SSMSK(mask, lss) ((mask) << ((lss) * 2)) +#define D0 0 +#define D0i1 1 +#define D0i2 2 +#define D0i3 3 + +#define S0I3_SSS_TARGET ( \ + SSMSK(D0i1, LSS_DMI) | \ + SSMSK(D0i3, LSS_SD_HC0) | \ + SSMSK(D0i3, LSS_SD_HC1) | \ + SSMSK(D0i3, LSS_NAND) | \ + SSMSK(D0i3, LSS_SD_HC2) | \ + SSMSK(D0i3, LSS_IMAGING) | \ + SSMSK(D0i3, LSS_SECURITY) | \ + SSMSK(D0i3, LSS_DISPLAY) | \ + SSMSK(D0i3, LSS_USB_HC) | \ + SSMSK(D0i3, LSS_USB_OTG) | \ + SSMSK(D0i3, LSS_AUDIO) | \ + SSMSK(D0i1, LSS_I2C0)) + +/* + * D0i1 on Langwell is Autonomous Clock Gating (ACG). + * Enable ACG on every LSS except camera and audio + */ +#define D0I1_ACG_SSS_TARGET \ + (SUB_SYS_ALL_D0I1 & ~SSMSK(D0i1, LSS_IMAGING) & ~SSMSK(D0i1, LSS_AUDIO)) + +enum cm_mode { + CM_NOP, /* ignore the config mode value */ + CM_IMMEDIATE, + CM_DELAY, + CM_TRIGGER, + CM_INVALID +}; + +enum sys_state { + SYS_STATE_S0I0, + SYS_STATE_S0I1, + SYS_STATE_S0I2, + SYS_STATE_S0I3, + SYS_STATE_S3, + SYS_STATE_S5 +}; + +#define SET_CFG_CMD 1 + +enum int_status { + INT_SPURIOUS = 0, + INT_CMD_DONE = 1, + INT_CMD_ERR = 2, + INT_WAKE_RX = 3, + INT_SS_ERROR = 4, + INT_S0IX_MISS = 5, + INT_NO_ACKC6 = 6, + INT_INVALID = 7, +}; + +/* PMU register interface */ +static struct mrst_pmu_reg { + u32 pm_sts; /* 0x00 */ + u32 pm_cmd; /* 0x04 */ + u32 pm_ics; /* 0x08 */ + u32 _resv1; /* 0x0C */ + u32 pm_wkc[2]; /* 0x10 */ + u32 pm_wks[2]; /* 0x18 */ + u32 pm_ssc[4]; /* 0x20 */ + u32 pm_sss[4]; /* 0x30 */ + u32 pm_wssc[4]; /* 0x40 */ + u32 pm_c3c4; /* 0x50 */ + u32 pm_c5c6; /* 0x54 */ + u32 pm_msi_disable; /* 0x58 */ +} *pmu_reg; + +static inline u32 pmu_read_sts(void) { return readl(&pmu_reg->pm_sts); } +static inline u32 pmu_read_ics(void) { return readl(&pmu_reg->pm_ics); } +static inline u32 pmu_read_wks(void) { return readl(&pmu_reg->pm_wks[0]); } +static inline u32 pmu_read_sss(void) { return readl(&pmu_reg->pm_sss[0]); } + +static inline void pmu_write_cmd(u32 arg) { writel(arg, &pmu_reg->pm_cmd); } +static inline void pmu_write_ics(u32 arg) { writel(arg, &pmu_reg->pm_ics); } +static inline void pmu_write_wkc(u32 arg) { writel(arg, &pmu_reg->pm_wkc[0]); } +static inline void pmu_write_ssc(u32 arg) { writel(arg, &pmu_reg->pm_ssc[0]); } +static inline void pmu_write_wssc(u32 arg) + { writel(arg, &pmu_reg->pm_wssc[0]); } + +static inline void pmu_msi_enable(void) { writel(0, &pmu_reg->pm_msi_disable); } +static inline u32 pmu_msi_is_disabled(void) + { return readl(&pmu_reg->pm_msi_disable); } + +union pmu_pm_ics { + struct { + u32 cause:8; + u32 enable:1; + u32 pending:1; + u32 reserved:22; + } bits; + u32 value; +}; + +static inline void pmu_irq_enable(void) +{ + union pmu_pm_ics pmu_ics; + + pmu_ics.value = pmu_read_ics(); + pmu_ics.bits.enable = 1; + pmu_write_ics(pmu_ics.value); +} + +union pmu_pm_status { + struct { + u32 pmu_rev:8; + u32 pmu_busy:1; + u32 mode_id:4; + u32 Reserved:19; + } pmu_status_parts; + u32 pmu_status_value; +}; + +static inline int pmu_read_busy_status(void) +{ + union pmu_pm_status result; + + result.pmu_status_value = pmu_read_sts(); + + return result.pmu_status_parts.pmu_busy; +} + +/* pmu set config parameters */ +struct cfg_delay_param_t { + u32 cmd:8; + u32 ioc:1; + u32 cfg_mode:4; + u32 mode_id:3; + u32 sys_state:3; + u32 cfg_delay:8; + u32 rsvd:5; +}; + +struct cfg_trig_param_t { + u32 cmd:8; + u32 ioc:1; + u32 cfg_mode:4; + u32 mode_id:3; + u32 sys_state:3; + u32 cfg_trig_type:3; + u32 cfg_trig_val:8; + u32 cmbi:1; + u32 rsvd1:1; +}; + +union pmu_pm_set_cfg_cmd_t { + union { + struct cfg_delay_param_t d_param; + struct cfg_trig_param_t t_param; + } pmu2_params; + u32 pmu_pm_set_cfg_cmd_value; +}; + +#ifdef FUTURE_PATCH +extern int mrst_s0i3_entry(u32 regval, u32 *regaddr); +#else +static inline int mrst_s0i3_entry(u32 regval, u32 *regaddr) { return -1; } +#endif +#endif |