| /* |
| * 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 |