![]() |
|
|||
0001 /* SPDX-License-Identifier: GPL-2.0-only 0002 * 0003 * Copyright (C) 2020-21 Intel Corporation. 0004 */ 0005 0006 #ifndef IOSM_IPC_PM_H 0007 #define IOSM_IPC_PM_H 0008 0009 /* Trigger the doorbell interrupt on cp to change the PM sleep/active status */ 0010 #define ipc_cp_irq_sleep_control(ipc_pcie, data) \ 0011 ipc_doorbell_fire(ipc_pcie, IPC_DOORBELL_IRQ_SLEEP, data) 0012 0013 /* Trigger the doorbell interrupt on CP to do hpda update */ 0014 #define ipc_cp_irq_hpda_update(ipc_pcie, data) \ 0015 ipc_doorbell_fire(ipc_pcie, IPC_DOORBELL_IRQ_HPDA, 0xFF & (data)) 0016 0017 /** 0018 * union ipc_pm_cond - Conditions for D3 and the sleep message to CP. 0019 * @raw: raw/combined value for faster check 0020 * @irq: IRQ towards CP 0021 * @hs: Host Sleep 0022 * @link: Device link state. 0023 */ 0024 union ipc_pm_cond { 0025 unsigned int raw; 0026 0027 struct { 0028 unsigned int irq:1, 0029 hs:1, 0030 link:1; 0031 }; 0032 }; 0033 0034 /** 0035 * enum ipc_mem_host_pm_state - Possible states of the HOST SLEEP finite state 0036 * machine. 0037 * @IPC_MEM_HOST_PM_ACTIVE: Host is active 0038 * @IPC_MEM_HOST_PM_ACTIVE_WAIT: Intermediate state before going to 0039 * active 0040 * @IPC_MEM_HOST_PM_SLEEP_WAIT_IDLE: Intermediate state to wait for idle 0041 * before going into sleep 0042 * @IPC_MEM_HOST_PM_SLEEP_WAIT_D3: Intermediate state to wait for D3 0043 * before going to sleep 0044 * @IPC_MEM_HOST_PM_SLEEP: after this state the interface is not 0045 * accessible host is in suspend to RAM 0046 * @IPC_MEM_HOST_PM_SLEEP_WAIT_EXIT_SLEEP: Intermediate state before exiting 0047 * sleep 0048 */ 0049 enum ipc_mem_host_pm_state { 0050 IPC_MEM_HOST_PM_ACTIVE, 0051 IPC_MEM_HOST_PM_ACTIVE_WAIT, 0052 IPC_MEM_HOST_PM_SLEEP_WAIT_IDLE, 0053 IPC_MEM_HOST_PM_SLEEP_WAIT_D3, 0054 IPC_MEM_HOST_PM_SLEEP, 0055 IPC_MEM_HOST_PM_SLEEP_WAIT_EXIT_SLEEP, 0056 }; 0057 0058 /** 0059 * enum ipc_mem_dev_pm_state - Possible states of the DEVICE SLEEP finite state 0060 * machine. 0061 * @IPC_MEM_DEV_PM_ACTIVE: IPC_MEM_DEV_PM_ACTIVE is the initial 0062 * power management state. 0063 * IRQ(struct ipc_mem_device_info: 0064 * device_sleep_notification) 0065 * and DOORBELL-IRQ-HPDA(data) values. 0066 * @IPC_MEM_DEV_PM_SLEEP: IPC_MEM_DEV_PM_SLEEP is PM state for 0067 * sleep. 0068 * @IPC_MEM_DEV_PM_WAKEUP: DOORBELL-IRQ-DEVICE_WAKE(data). 0069 * @IPC_MEM_DEV_PM_HOST_SLEEP: DOORBELL-IRQ-HOST_SLEEP(data). 0070 * @IPC_MEM_DEV_PM_ACTIVE_WAIT: Local intermediate states. 0071 * @IPC_MEM_DEV_PM_FORCE_SLEEP: DOORBELL-IRQ-FORCE_SLEEP. 0072 * @IPC_MEM_DEV_PM_FORCE_ACTIVE: DOORBELL-IRQ-FORCE_ACTIVE. 0073 */ 0074 enum ipc_mem_dev_pm_state { 0075 IPC_MEM_DEV_PM_ACTIVE, 0076 IPC_MEM_DEV_PM_SLEEP, 0077 IPC_MEM_DEV_PM_WAKEUP, 0078 IPC_MEM_DEV_PM_HOST_SLEEP, 0079 IPC_MEM_DEV_PM_ACTIVE_WAIT, 0080 IPC_MEM_DEV_PM_FORCE_SLEEP = 7, 0081 IPC_MEM_DEV_PM_FORCE_ACTIVE, 0082 }; 0083 0084 /** 0085 * struct iosm_pm - Power management instance 0086 * @pcie: Pointer to iosm_pcie structure 0087 * @dev: Pointer to device structure 0088 * @host_pm_state: PM states for host 0089 * @host_sleep_pend: Variable to indicate Host Sleep Pending 0090 * @host_sleep_complete: Generic wait-for-completion used in 0091 * case of Host Sleep 0092 * @pm_cond: Conditions for power management 0093 * @ap_state: Current power management state, the 0094 * initial state is IPC_MEM_DEV_PM_ACTIVE eq. 0. 0095 * @cp_state: PM State of CP 0096 * @device_sleep_notification: last handled device_sleep_notfication 0097 * @pending_hpda_update: is a HPDA update pending? 0098 */ 0099 struct iosm_pm { 0100 struct iosm_pcie *pcie; 0101 struct device *dev; 0102 enum ipc_mem_host_pm_state host_pm_state; 0103 unsigned long host_sleep_pend; 0104 struct completion host_sleep_complete; 0105 union ipc_pm_cond pm_cond; 0106 enum ipc_mem_dev_pm_state ap_state; 0107 enum ipc_mem_dev_pm_state cp_state; 0108 u32 device_sleep_notification; 0109 u8 pending_hpda_update:1; 0110 }; 0111 0112 /** 0113 * enum ipc_pm_unit - Power management units. 0114 * @IPC_PM_UNIT_IRQ: IRQ towards CP 0115 * @IPC_PM_UNIT_HS: Host Sleep for converged protocol 0116 * @IPC_PM_UNIT_LINK: Link state controlled by CP. 0117 */ 0118 enum ipc_pm_unit { 0119 IPC_PM_UNIT_IRQ, 0120 IPC_PM_UNIT_HS, 0121 IPC_PM_UNIT_LINK, 0122 }; 0123 0124 /** 0125 * ipc_pm_init - Allocate power management component 0126 * @ipc_protocol: Pointer to iosm_protocol structure 0127 */ 0128 void ipc_pm_init(struct iosm_protocol *ipc_protocol); 0129 0130 /** 0131 * ipc_pm_deinit - Free power management component, invalidating its pointer. 0132 * @ipc_protocol: Pointer to iosm_protocol structure 0133 */ 0134 void ipc_pm_deinit(struct iosm_protocol *ipc_protocol); 0135 0136 /** 0137 * ipc_pm_dev_slp_notification - Handle a sleep notification message from the 0138 * device. This can be called from interrupt state 0139 * This function handles Host Sleep requests too 0140 * if the Host Sleep protocol is register based. 0141 * @ipc_pm: Pointer to power management component 0142 * @sleep_notification: Actual notification from device 0143 * 0144 * Returns: true if dev sleep state has to be checked, false otherwise. 0145 */ 0146 bool ipc_pm_dev_slp_notification(struct iosm_pm *ipc_pm, 0147 u32 sleep_notification); 0148 0149 /** 0150 * ipc_pm_set_s2idle_sleep - Set PM variables to sleep/active 0151 * @ipc_pm: Pointer to power management component 0152 * @sleep: true to enter sleep/false to exit sleep 0153 */ 0154 void ipc_pm_set_s2idle_sleep(struct iosm_pm *ipc_pm, bool sleep); 0155 0156 /** 0157 * ipc_pm_prepare_host_sleep - Prepare the PM for sleep by entering 0158 * IPC_MEM_HOST_PM_SLEEP_WAIT_D3 state. 0159 * @ipc_pm: Pointer to power management component 0160 * 0161 * Returns: true on success, false if the host was not active. 0162 */ 0163 bool ipc_pm_prepare_host_sleep(struct iosm_pm *ipc_pm); 0164 0165 /** 0166 * ipc_pm_prepare_host_active - Prepare the PM for wakeup by entering 0167 * IPC_MEM_HOST_PM_ACTIVE_WAIT state. 0168 * @ipc_pm: Pointer to power management component 0169 * 0170 * Returns: true on success, false if the host was not sleeping. 0171 */ 0172 bool ipc_pm_prepare_host_active(struct iosm_pm *ipc_pm); 0173 0174 /** 0175 * ipc_pm_wait_for_device_active - Wait upto IPC_PM_ACTIVE_TIMEOUT_MS ms 0176 * for the device to reach active state 0177 * @ipc_pm: Pointer to power management component 0178 * 0179 * Returns: true if device is active, false on timeout 0180 */ 0181 bool ipc_pm_wait_for_device_active(struct iosm_pm *ipc_pm); 0182 0183 /** 0184 * ipc_pm_signal_hpda_doorbell - Wake up the device if it is in low power mode 0185 * and trigger a head pointer update interrupt. 0186 * @ipc_pm: Pointer to power management component 0187 * @identifier: specifies what component triggered hpda update irq 0188 * @host_slp_check: if set to true then Host Sleep state machine check will 0189 * be performed. If Host Sleep state machine allows HP 0190 * update then only doorbell is triggered otherwise pending 0191 * flag will be set. If set to false then Host Sleep check 0192 * will not be performed. This is helpful for Host Sleep 0193 * negotiation through message ring. 0194 */ 0195 void ipc_pm_signal_hpda_doorbell(struct iosm_pm *ipc_pm, u32 identifier, 0196 bool host_slp_check); 0197 /** 0198 * ipc_pm_trigger - Update power manager and wake up the link if needed 0199 * @ipc_pm: Pointer to power management component 0200 * @unit: Power management units 0201 * @active: Device link state 0202 * 0203 * Returns: true if link is unchanged or active, false otherwise 0204 */ 0205 bool ipc_pm_trigger(struct iosm_pm *ipc_pm, enum ipc_pm_unit unit, bool active); 0206 0207 #endif
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |