mirror of https://gitee.com/openkylin/linux.git
235 lines
5.6 KiB
C
235 lines
5.6 KiB
C
/*
|
|
* 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
|