Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

soundwire: amd: add soundwire host wake interrupt enable/disable sequence

For wake event, SoundWire host wake interrupt will be asserted based on
below pre-conditions for ACP7.0 & ACP7.1 platforms.
- ACP device should be in D0 state.
- SoundWire manager instance should be in D3 state.
- SoundWire manager device state should be set to D3.
- ACP_PME_EN should be set to 1.

Implement code changes to enable/disable SoundWire host wake interrupt mask
during suspend and resume as per design flow for ACP7.0 & ACP7.1 platforms.

Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Link: https://lore.kernel.org/r/20250207065841.4718-7-Vijendar.Mukunda@amd.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Vijendar Mukunda and committed by
Vinod Koul
3df75289 5818ed36

+60
+58
drivers/soundwire/amd_manager.c
··· 166 166 return 0; 167 167 } 168 168 169 + static int amd_sdw_host_wake_enable(struct amd_sdw_manager *amd_manager, bool enable) 170 + { 171 + u32 intr_cntl1; 172 + u32 sdw_host_wake_irq_mask; 173 + 174 + if (!amd_manager->wake_en_mask) 175 + return 0; 176 + 177 + switch (amd_manager->instance) { 178 + case ACP_SDW0: 179 + sdw_host_wake_irq_mask = AMD_SDW0_HOST_WAKE_INTR_MASK; 180 + break; 181 + case ACP_SDW1: 182 + sdw_host_wake_irq_mask = AMD_SDW1_HOST_WAKE_INTR_MASK; 183 + break; 184 + default: 185 + return -EINVAL; 186 + } 187 + 188 + intr_cntl1 = readl(amd_manager->acp_mmio + ACP_EXTERNAL_INTR_CNTL(ACP_SDW1)); 189 + if (enable) 190 + intr_cntl1 |= sdw_host_wake_irq_mask; 191 + else 192 + intr_cntl1 &= ~sdw_host_wake_irq_mask; 193 + writel(intr_cntl1, amd_manager->acp_mmio + ACP_EXTERNAL_INTR_CNTL(ACP_SDW1)); 194 + return 0; 195 + } 196 + 169 197 static void amd_sdw_ctl_word_prep(u32 *lower_word, u32 *upper_word, struct sdw_msg *msg, 170 198 int cmd_offset) 171 199 { ··· 1210 1182 1211 1183 if (amd_manager->power_mode_mask & AMD_SDW_CLK_STOP_MODE) { 1212 1184 amd_sdw_wake_enable(amd_manager, false); 1185 + if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) { 1186 + ret = amd_sdw_host_wake_enable(amd_manager, false); 1187 + if (ret) 1188 + return ret; 1189 + } 1213 1190 ret = amd_sdw_clock_stop(amd_manager); 1214 1191 if (ret) 1215 1192 return ret; 1216 1193 } else if (amd_manager->power_mode_mask & AMD_SDW_POWER_OFF_MODE) { 1217 1194 amd_sdw_wake_enable(amd_manager, false); 1195 + if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) { 1196 + ret = amd_sdw_host_wake_enable(amd_manager, false); 1197 + if (ret) 1198 + return ret; 1199 + } 1218 1200 /* 1219 1201 * As per hardware programming sequence on AMD platforms, 1220 1202 * clock stop should be invoked first before powering-off ··· 1258 1220 } 1259 1221 if (amd_manager->power_mode_mask & AMD_SDW_CLK_STOP_MODE) { 1260 1222 amd_sdw_wake_enable(amd_manager, true); 1223 + if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) { 1224 + ret = amd_sdw_host_wake_enable(amd_manager, true); 1225 + if (ret) 1226 + return ret; 1227 + } 1261 1228 ret = amd_sdw_clock_stop(amd_manager); 1262 1229 if (ret) 1263 1230 return ret; 1264 1231 } else if (amd_manager->power_mode_mask & AMD_SDW_POWER_OFF_MODE) { 1265 1232 amd_sdw_wake_enable(amd_manager, true); 1233 + if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) { 1234 + ret = amd_sdw_host_wake_enable(amd_manager, true); 1235 + if (ret) 1236 + return ret; 1237 + } 1266 1238 ret = amd_sdw_clock_stop(amd_manager); 1267 1239 if (ret) 1268 1240 return ret; ··· 1313 1265 ret = amd_sdw_clock_stop_exit(amd_manager); 1314 1266 if (ret) 1315 1267 return ret; 1268 + if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) { 1269 + ret = amd_sdw_host_wake_enable(amd_manager, false); 1270 + if (ret) 1271 + return ret; 1272 + } 1316 1273 } else if (amd_manager->power_mode_mask & AMD_SDW_POWER_OFF_MODE) { 1317 1274 writel(0x00, amd_manager->acp_mmio + ACP_SW_WAKE_EN(amd_manager->instance)); 1275 + if (amd_manager->acp_rev >= ACP70_PCI_REV_ID) { 1276 + ret = amd_sdw_host_wake_enable(amd_manager, false); 1277 + if (ret) 1278 + return ret; 1279 + } 1318 1280 val = readl(amd_manager->mmio + ACP_SW_CLK_RESUME_CTRL); 1319 1281 if (val) { 1320 1282 val |= AMD_SDW_CLK_RESUME_REQ;
+2
drivers/soundwire/amd_manager.h
··· 194 194 #define AMD_SDW_CLK_RESUME_DONE 3 195 195 #define AMD_SDW_WAKE_STAT_MASK BIT(16) 196 196 #define AMD_SDW_WAKE_INTR_MASK BIT(16) 197 + #define AMD_SDW0_HOST_WAKE_INTR_MASK BIT(22) 198 + #define AMD_SDW1_HOST_WAKE_INTR_MASK BIT(23) 197 199 #define AMD_SDW_DEVICE_STATE 0x1430 198 200 #define AMD_SDW0_DEVICE_STATE_MASK GENMASK(1, 0) 199 201 #define AMD_SDW1_DEVICE_STATE_MASK GENMASK(3, 2)