1 1.3 riastrad /* $NetBSD: amdgpu_acp.c,v 1.3 2021/12/19 10:59:01 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /* 4 1.1 riastrad * Copyright 2015 Advanced Micro Devices, Inc. 5 1.1 riastrad * 6 1.1 riastrad * Permission is hereby granted, free of charge, to any person obtaining a 7 1.1 riastrad * copy of this software and associated documentation files (the "Software"), 8 1.1 riastrad * to deal in the Software without restriction, including without limitation 9 1.1 riastrad * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 1.1 riastrad * and/or sell copies of the Software, and to permit persons to whom the 11 1.1 riastrad * Software is furnished to do so, subject to the following conditions: 12 1.1 riastrad * 13 1.1 riastrad * The above copyright notice and this permission notice shall be included in 14 1.1 riastrad * all copies or substantial portions of the Software. 15 1.1 riastrad * 16 1.1 riastrad * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 1.1 riastrad * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 1.1 riastrad * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 1.1 riastrad * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 1.1 riastrad * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 1.1 riastrad * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 1.1 riastrad * OTHER DEALINGS IN THE SOFTWARE. 23 1.1 riastrad * 24 1.1 riastrad * Authors: AMD 25 1.1 riastrad * 26 1.1 riastrad */ 27 1.1 riastrad 28 1.1 riastrad #include <sys/cdefs.h> 29 1.3 riastrad __KERNEL_RCSID(0, "$NetBSD: amdgpu_acp.c,v 1.3 2021/12/19 10:59:01 riastradh Exp $"); 30 1.1 riastrad 31 1.1 riastrad #include <linux/irqdomain.h> 32 1.1 riastrad #include <linux/pci.h> 33 1.1 riastrad #include <linux/pm_domain.h> 34 1.1 riastrad #include <linux/platform_device.h> 35 1.1 riastrad #include <sound/designware_i2s.h> 36 1.1 riastrad #include <sound/pcm.h> 37 1.1 riastrad 38 1.1 riastrad #include "amdgpu.h" 39 1.1 riastrad #include "atom.h" 40 1.1 riastrad #include "amdgpu_acp.h" 41 1.1 riastrad 42 1.1 riastrad #include "acp_gfx_if.h" 43 1.1 riastrad 44 1.1 riastrad #define ACP_TILE_ON_MASK 0x03 45 1.1 riastrad #define ACP_TILE_OFF_MASK 0x02 46 1.1 riastrad #define ACP_TILE_ON_RETAIN_REG_MASK 0x1f 47 1.1 riastrad #define ACP_TILE_OFF_RETAIN_REG_MASK 0x20 48 1.1 riastrad 49 1.1 riastrad #define ACP_TILE_P1_MASK 0x3e 50 1.1 riastrad #define ACP_TILE_P2_MASK 0x3d 51 1.1 riastrad #define ACP_TILE_DSP0_MASK 0x3b 52 1.1 riastrad #define ACP_TILE_DSP1_MASK 0x37 53 1.1 riastrad 54 1.1 riastrad #define ACP_TILE_DSP2_MASK 0x2f 55 1.1 riastrad 56 1.1 riastrad #define ACP_DMA_REGS_END 0x146c0 57 1.1 riastrad #define ACP_I2S_PLAY_REGS_START 0x14840 58 1.1 riastrad #define ACP_I2S_PLAY_REGS_END 0x148b4 59 1.1 riastrad #define ACP_I2S_CAP_REGS_START 0x148b8 60 1.1 riastrad #define ACP_I2S_CAP_REGS_END 0x1496c 61 1.1 riastrad 62 1.1 riastrad #define ACP_I2S_COMP1_CAP_REG_OFFSET 0xac 63 1.1 riastrad #define ACP_I2S_COMP2_CAP_REG_OFFSET 0xa8 64 1.1 riastrad #define ACP_I2S_COMP1_PLAY_REG_OFFSET 0x6c 65 1.1 riastrad #define ACP_I2S_COMP2_PLAY_REG_OFFSET 0x68 66 1.1 riastrad #define ACP_BT_PLAY_REGS_START 0x14970 67 1.1 riastrad #define ACP_BT_PLAY_REGS_END 0x14a24 68 1.1 riastrad #define ACP_BT_COMP1_REG_OFFSET 0xac 69 1.1 riastrad #define ACP_BT_COMP2_REG_OFFSET 0xa8 70 1.1 riastrad 71 1.1 riastrad #define mmACP_PGFSM_RETAIN_REG 0x51c9 72 1.1 riastrad #define mmACP_PGFSM_CONFIG_REG 0x51ca 73 1.1 riastrad #define mmACP_PGFSM_READ_REG_0 0x51cc 74 1.1 riastrad 75 1.1 riastrad #define mmACP_MEM_SHUT_DOWN_REQ_LO 0x51f8 76 1.1 riastrad #define mmACP_MEM_SHUT_DOWN_REQ_HI 0x51f9 77 1.1 riastrad #define mmACP_MEM_SHUT_DOWN_STS_LO 0x51fa 78 1.1 riastrad #define mmACP_MEM_SHUT_DOWN_STS_HI 0x51fb 79 1.1 riastrad 80 1.1 riastrad #define mmACP_CONTROL 0x5131 81 1.1 riastrad #define mmACP_STATUS 0x5133 82 1.1 riastrad #define mmACP_SOFT_RESET 0x5134 83 1.1 riastrad #define ACP_CONTROL__ClkEn_MASK 0x1 84 1.1 riastrad #define ACP_SOFT_RESET__SoftResetAud_MASK 0x100 85 1.1 riastrad #define ACP_SOFT_RESET__SoftResetAudDone_MASK 0x1000000 86 1.1 riastrad #define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF 87 1.1 riastrad #define ACP_SOFT_RESET_DONE_TIME_OUT_VALUE 0x000000FF 88 1.1 riastrad 89 1.1 riastrad #define ACP_TIMEOUT_LOOP 0x000000FF 90 1.1 riastrad #define ACP_DEVS 4 91 1.1 riastrad #define ACP_SRC_ID 162 92 1.1 riastrad 93 1.1 riastrad enum { 94 1.1 riastrad ACP_TILE_P1 = 0, 95 1.1 riastrad ACP_TILE_P2, 96 1.1 riastrad ACP_TILE_DSP0, 97 1.1 riastrad ACP_TILE_DSP1, 98 1.1 riastrad ACP_TILE_DSP2, 99 1.1 riastrad }; 100 1.1 riastrad 101 1.1 riastrad static int acp_sw_init(void *handle) 102 1.1 riastrad { 103 1.1 riastrad struct amdgpu_device *adev = (struct amdgpu_device *)handle; 104 1.1 riastrad 105 1.1 riastrad adev->acp.parent = adev->dev; 106 1.1 riastrad 107 1.1 riastrad adev->acp.cgs_device = 108 1.1 riastrad amdgpu_cgs_create_device(adev); 109 1.1 riastrad if (!adev->acp.cgs_device) 110 1.1 riastrad return -EINVAL; 111 1.1 riastrad 112 1.1 riastrad return 0; 113 1.1 riastrad } 114 1.1 riastrad 115 1.1 riastrad static int acp_sw_fini(void *handle) 116 1.1 riastrad { 117 1.1 riastrad struct amdgpu_device *adev = (struct amdgpu_device *)handle; 118 1.1 riastrad 119 1.1 riastrad if (adev->acp.cgs_device) 120 1.1 riastrad amdgpu_cgs_destroy_device(adev->acp.cgs_device); 121 1.1 riastrad 122 1.1 riastrad return 0; 123 1.1 riastrad } 124 1.1 riastrad 125 1.3 riastrad #ifndef __NetBSD__ /* XXX amdgpu pm */ 126 1.3 riastrad 127 1.1 riastrad struct acp_pm_domain { 128 1.1 riastrad void *adev; 129 1.1 riastrad struct generic_pm_domain gpd; 130 1.1 riastrad }; 131 1.1 riastrad 132 1.1 riastrad static int acp_poweroff(struct generic_pm_domain *genpd) 133 1.1 riastrad { 134 1.1 riastrad struct acp_pm_domain *apd; 135 1.1 riastrad struct amdgpu_device *adev; 136 1.1 riastrad 137 1.1 riastrad apd = container_of(genpd, struct acp_pm_domain, gpd); 138 1.1 riastrad if (apd != NULL) { 139 1.1 riastrad adev = apd->adev; 140 1.1 riastrad /* call smu to POWER GATE ACP block 141 1.1 riastrad * smu will 142 1.1 riastrad * 1. turn off the acp clock 143 1.1 riastrad * 2. power off the acp tiles 144 1.1 riastrad * 3. check and enter ulv state 145 1.1 riastrad */ 146 1.1 riastrad if (adev->powerplay.pp_funcs && 147 1.1 riastrad adev->powerplay.pp_funcs->set_powergating_by_smu) 148 1.1 riastrad amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true); 149 1.1 riastrad } 150 1.1 riastrad return 0; 151 1.1 riastrad } 152 1.1 riastrad 153 1.1 riastrad static int acp_poweron(struct generic_pm_domain *genpd) 154 1.1 riastrad { 155 1.1 riastrad struct acp_pm_domain *apd; 156 1.1 riastrad struct amdgpu_device *adev; 157 1.1 riastrad 158 1.1 riastrad apd = container_of(genpd, struct acp_pm_domain, gpd); 159 1.1 riastrad if (apd != NULL) { 160 1.1 riastrad adev = apd->adev; 161 1.1 riastrad /* call smu to UNGATE ACP block 162 1.1 riastrad * smu will 163 1.1 riastrad * 1. exit ulv 164 1.1 riastrad * 2. turn on acp clock 165 1.1 riastrad * 3. power on acp tiles 166 1.1 riastrad */ 167 1.1 riastrad if (adev->powerplay.pp_funcs->set_powergating_by_smu) 168 1.1 riastrad amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, false); 169 1.1 riastrad } 170 1.1 riastrad return 0; 171 1.1 riastrad } 172 1.1 riastrad 173 1.1 riastrad static struct device *get_mfd_cell_dev(const char *device_name, int r) 174 1.1 riastrad { 175 1.1 riastrad char auto_dev_name[25]; 176 1.1 riastrad struct device *dev; 177 1.1 riastrad 178 1.1 riastrad snprintf(auto_dev_name, sizeof(auto_dev_name), 179 1.1 riastrad "%s.%d.auto", device_name, r); 180 1.1 riastrad dev = bus_find_device_by_name(&platform_bus_type, NULL, auto_dev_name); 181 1.1 riastrad dev_info(dev, "device %s added to pm domain\n", auto_dev_name); 182 1.1 riastrad 183 1.1 riastrad return dev; 184 1.1 riastrad } 185 1.1 riastrad 186 1.3 riastrad #endif 187 1.3 riastrad 188 1.1 riastrad /** 189 1.1 riastrad * acp_hw_init - start and test ACP block 190 1.1 riastrad * 191 1.1 riastrad * @adev: amdgpu_device pointer 192 1.1 riastrad * 193 1.1 riastrad */ 194 1.1 riastrad static int acp_hw_init(void *handle) 195 1.1 riastrad { 196 1.1 riastrad int r, i; 197 1.1 riastrad uint64_t acp_base; 198 1.1 riastrad u32 val = 0; 199 1.1 riastrad u32 count = 0; 200 1.1 riastrad struct device *dev; 201 1.1 riastrad struct i2s_platform_data *i2s_pdata = NULL; 202 1.1 riastrad 203 1.1 riastrad struct amdgpu_device *adev = (struct amdgpu_device *)handle; 204 1.1 riastrad 205 1.1 riastrad const struct amdgpu_ip_block *ip_block = 206 1.1 riastrad amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_ACP); 207 1.1 riastrad 208 1.1 riastrad if (!ip_block) 209 1.1 riastrad return -EINVAL; 210 1.1 riastrad 211 1.1 riastrad r = amd_acp_hw_init(adev->acp.cgs_device, 212 1.1 riastrad ip_block->version->major, ip_block->version->minor); 213 1.1 riastrad /* -ENODEV means board uses AZ rather than ACP */ 214 1.1 riastrad if (r == -ENODEV) { 215 1.1 riastrad amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true); 216 1.1 riastrad return 0; 217 1.1 riastrad } else if (r) { 218 1.1 riastrad return r; 219 1.1 riastrad } 220 1.1 riastrad 221 1.1 riastrad if (adev->rmmio_size == 0 || adev->rmmio_size < 0x5289) 222 1.1 riastrad return -EINVAL; 223 1.1 riastrad 224 1.1 riastrad acp_base = adev->rmmio_base; 225 1.1 riastrad 226 1.1 riastrad 227 1.3 riastrad #ifndef __NetBSD__ /* XXX amdgpu pm */ 228 1.1 riastrad adev->acp.acp_genpd = kzalloc(sizeof(struct acp_pm_domain), GFP_KERNEL); 229 1.1 riastrad if (adev->acp.acp_genpd == NULL) 230 1.1 riastrad return -ENOMEM; 231 1.1 riastrad 232 1.1 riastrad adev->acp.acp_genpd->gpd.name = "ACP_AUDIO"; 233 1.1 riastrad adev->acp.acp_genpd->gpd.power_off = acp_poweroff; 234 1.1 riastrad adev->acp.acp_genpd->gpd.power_on = acp_poweron; 235 1.1 riastrad 236 1.1 riastrad 237 1.1 riastrad adev->acp.acp_genpd->adev = adev; 238 1.1 riastrad 239 1.1 riastrad pm_genpd_init(&adev->acp.acp_genpd->gpd, NULL, false); 240 1.3 riastrad #endif 241 1.1 riastrad 242 1.3 riastrad #ifndef __NetBSD__ /* XXX amdgpu cell */ 243 1.1 riastrad adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell), 244 1.1 riastrad GFP_KERNEL); 245 1.1 riastrad 246 1.1 riastrad if (adev->acp.acp_cell == NULL) { 247 1.1 riastrad r = -ENOMEM; 248 1.1 riastrad goto failure; 249 1.1 riastrad } 250 1.3 riastrad #endif 251 1.1 riastrad 252 1.1 riastrad adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL); 253 1.1 riastrad if (adev->acp.acp_res == NULL) { 254 1.1 riastrad r = -ENOMEM; 255 1.1 riastrad goto failure; 256 1.1 riastrad } 257 1.1 riastrad 258 1.3 riastrad #ifdef __NetBSD__ /* XXX amdgpu sound */ 259 1.3 riastrad __USE(i2s_pdata); 260 1.3 riastrad #else 261 1.1 riastrad i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL); 262 1.1 riastrad if (i2s_pdata == NULL) { 263 1.1 riastrad r = -ENOMEM; 264 1.1 riastrad goto failure; 265 1.1 riastrad } 266 1.1 riastrad 267 1.1 riastrad switch (adev->asic_type) { 268 1.1 riastrad case CHIP_STONEY: 269 1.1 riastrad i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET | 270 1.1 riastrad DW_I2S_QUIRK_16BIT_IDX_OVERRIDE; 271 1.1 riastrad break; 272 1.1 riastrad default: 273 1.1 riastrad i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET; 274 1.1 riastrad } 275 1.1 riastrad i2s_pdata[0].cap = DWC_I2S_PLAY; 276 1.1 riastrad i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000; 277 1.1 riastrad i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_PLAY_REG_OFFSET; 278 1.1 riastrad i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_PLAY_REG_OFFSET; 279 1.1 riastrad switch (adev->asic_type) { 280 1.1 riastrad case CHIP_STONEY: 281 1.1 riastrad i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET | 282 1.1 riastrad DW_I2S_QUIRK_COMP_PARAM1 | 283 1.1 riastrad DW_I2S_QUIRK_16BIT_IDX_OVERRIDE; 284 1.1 riastrad break; 285 1.1 riastrad default: 286 1.1 riastrad i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET | 287 1.1 riastrad DW_I2S_QUIRK_COMP_PARAM1; 288 1.1 riastrad } 289 1.1 riastrad 290 1.1 riastrad i2s_pdata[1].cap = DWC_I2S_RECORD; 291 1.1 riastrad i2s_pdata[1].snd_rates = SNDRV_PCM_RATE_8000_96000; 292 1.1 riastrad i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET; 293 1.1 riastrad i2s_pdata[1].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET; 294 1.1 riastrad 295 1.1 riastrad i2s_pdata[2].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET; 296 1.1 riastrad switch (adev->asic_type) { 297 1.1 riastrad case CHIP_STONEY: 298 1.1 riastrad i2s_pdata[2].quirks |= DW_I2S_QUIRK_16BIT_IDX_OVERRIDE; 299 1.1 riastrad break; 300 1.1 riastrad default: 301 1.1 riastrad break; 302 1.1 riastrad } 303 1.1 riastrad 304 1.1 riastrad i2s_pdata[2].cap = DWC_I2S_PLAY | DWC_I2S_RECORD; 305 1.1 riastrad i2s_pdata[2].snd_rates = SNDRV_PCM_RATE_8000_96000; 306 1.1 riastrad i2s_pdata[2].i2s_reg_comp1 = ACP_BT_COMP1_REG_OFFSET; 307 1.1 riastrad i2s_pdata[2].i2s_reg_comp2 = ACP_BT_COMP2_REG_OFFSET; 308 1.3 riastrad #endif 309 1.1 riastrad 310 1.1 riastrad adev->acp.acp_res[0].name = "acp2x_dma"; 311 1.1 riastrad adev->acp.acp_res[0].flags = IORESOURCE_MEM; 312 1.1 riastrad adev->acp.acp_res[0].start = acp_base; 313 1.1 riastrad adev->acp.acp_res[0].end = acp_base + ACP_DMA_REGS_END; 314 1.1 riastrad 315 1.1 riastrad adev->acp.acp_res[1].name = "acp2x_dw_i2s_play"; 316 1.1 riastrad adev->acp.acp_res[1].flags = IORESOURCE_MEM; 317 1.1 riastrad adev->acp.acp_res[1].start = acp_base + ACP_I2S_PLAY_REGS_START; 318 1.1 riastrad adev->acp.acp_res[1].end = acp_base + ACP_I2S_PLAY_REGS_END; 319 1.1 riastrad 320 1.1 riastrad adev->acp.acp_res[2].name = "acp2x_dw_i2s_cap"; 321 1.1 riastrad adev->acp.acp_res[2].flags = IORESOURCE_MEM; 322 1.1 riastrad adev->acp.acp_res[2].start = acp_base + ACP_I2S_CAP_REGS_START; 323 1.1 riastrad adev->acp.acp_res[2].end = acp_base + ACP_I2S_CAP_REGS_END; 324 1.1 riastrad 325 1.1 riastrad adev->acp.acp_res[3].name = "acp2x_dw_bt_i2s_play_cap"; 326 1.1 riastrad adev->acp.acp_res[3].flags = IORESOURCE_MEM; 327 1.1 riastrad adev->acp.acp_res[3].start = acp_base + ACP_BT_PLAY_REGS_START; 328 1.1 riastrad adev->acp.acp_res[3].end = acp_base + ACP_BT_PLAY_REGS_END; 329 1.1 riastrad 330 1.1 riastrad adev->acp.acp_res[4].name = "acp2x_dma_irq"; 331 1.1 riastrad adev->acp.acp_res[4].flags = IORESOURCE_IRQ; 332 1.1 riastrad adev->acp.acp_res[4].start = amdgpu_irq_create_mapping(adev, 162); 333 1.1 riastrad adev->acp.acp_res[4].end = adev->acp.acp_res[4].start; 334 1.1 riastrad 335 1.3 riastrad #ifdef __NetBSD__ /* XXX amdgpu cell */ 336 1.3 riastrad __USE(dev); 337 1.3 riastrad __USE(i); 338 1.3 riastrad #else 339 1.1 riastrad adev->acp.acp_cell[0].name = "acp_audio_dma"; 340 1.1 riastrad adev->acp.acp_cell[0].num_resources = 5; 341 1.1 riastrad adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0]; 342 1.1 riastrad adev->acp.acp_cell[0].platform_data = &adev->asic_type; 343 1.1 riastrad adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type); 344 1.1 riastrad 345 1.1 riastrad adev->acp.acp_cell[1].name = "designware-i2s"; 346 1.1 riastrad adev->acp.acp_cell[1].num_resources = 1; 347 1.1 riastrad adev->acp.acp_cell[1].resources = &adev->acp.acp_res[1]; 348 1.1 riastrad adev->acp.acp_cell[1].platform_data = &i2s_pdata[0]; 349 1.1 riastrad adev->acp.acp_cell[1].pdata_size = sizeof(struct i2s_platform_data); 350 1.1 riastrad 351 1.1 riastrad adev->acp.acp_cell[2].name = "designware-i2s"; 352 1.1 riastrad adev->acp.acp_cell[2].num_resources = 1; 353 1.1 riastrad adev->acp.acp_cell[2].resources = &adev->acp.acp_res[2]; 354 1.1 riastrad adev->acp.acp_cell[2].platform_data = &i2s_pdata[1]; 355 1.1 riastrad adev->acp.acp_cell[2].pdata_size = sizeof(struct i2s_platform_data); 356 1.1 riastrad 357 1.1 riastrad adev->acp.acp_cell[3].name = "designware-i2s"; 358 1.1 riastrad adev->acp.acp_cell[3].num_resources = 1; 359 1.1 riastrad adev->acp.acp_cell[3].resources = &adev->acp.acp_res[3]; 360 1.1 riastrad adev->acp.acp_cell[3].platform_data = &i2s_pdata[2]; 361 1.1 riastrad adev->acp.acp_cell[3].pdata_size = sizeof(struct i2s_platform_data); 362 1.1 riastrad 363 1.1 riastrad r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, 364 1.1 riastrad ACP_DEVS); 365 1.1 riastrad if (r) 366 1.1 riastrad goto failure; 367 1.1 riastrad 368 1.1 riastrad for (i = 0; i < ACP_DEVS ; i++) { 369 1.1 riastrad dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); 370 1.1 riastrad r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev); 371 1.1 riastrad if (r) { 372 1.1 riastrad dev_err(dev, "Failed to add dev to genpd\n"); 373 1.1 riastrad goto failure; 374 1.1 riastrad } 375 1.1 riastrad } 376 1.3 riastrad #endif 377 1.1 riastrad 378 1.1 riastrad /* Assert Soft reset of ACP */ 379 1.1 riastrad val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); 380 1.1 riastrad 381 1.1 riastrad val |= ACP_SOFT_RESET__SoftResetAud_MASK; 382 1.1 riastrad cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); 383 1.1 riastrad 384 1.1 riastrad count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE; 385 1.1 riastrad while (true) { 386 1.1 riastrad val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); 387 1.1 riastrad if (ACP_SOFT_RESET__SoftResetAudDone_MASK == 388 1.1 riastrad (val & ACP_SOFT_RESET__SoftResetAudDone_MASK)) 389 1.1 riastrad break; 390 1.1 riastrad if (--count == 0) { 391 1.3 riastrad dev_err(pci_dev_dev(adev->pdev), "Failed to reset ACP\n"); 392 1.1 riastrad r = -ETIMEDOUT; 393 1.1 riastrad goto failure; 394 1.1 riastrad } 395 1.1 riastrad udelay(100); 396 1.1 riastrad } 397 1.1 riastrad /* Enable clock to ACP and wait until the clock is enabled */ 398 1.1 riastrad val = cgs_read_register(adev->acp.cgs_device, mmACP_CONTROL); 399 1.1 riastrad val = val | ACP_CONTROL__ClkEn_MASK; 400 1.1 riastrad cgs_write_register(adev->acp.cgs_device, mmACP_CONTROL, val); 401 1.1 riastrad 402 1.1 riastrad count = ACP_CLOCK_EN_TIME_OUT_VALUE; 403 1.1 riastrad 404 1.1 riastrad while (true) { 405 1.1 riastrad val = cgs_read_register(adev->acp.cgs_device, mmACP_STATUS); 406 1.1 riastrad if (val & (u32) 0x1) 407 1.1 riastrad break; 408 1.1 riastrad if (--count == 0) { 409 1.3 riastrad dev_err(pci_dev_dev(adev->pdev), "Failed to reset ACP\n"); 410 1.1 riastrad r = -ETIMEDOUT; 411 1.1 riastrad goto failure; 412 1.1 riastrad } 413 1.1 riastrad udelay(100); 414 1.1 riastrad } 415 1.1 riastrad /* Deassert the SOFT RESET flags */ 416 1.1 riastrad val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); 417 1.1 riastrad val &= ~ACP_SOFT_RESET__SoftResetAud_MASK; 418 1.1 riastrad cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); 419 1.1 riastrad return 0; 420 1.1 riastrad 421 1.1 riastrad failure: 422 1.1 riastrad kfree(i2s_pdata); 423 1.1 riastrad kfree(adev->acp.acp_res); 424 1.1 riastrad kfree(adev->acp.acp_cell); 425 1.1 riastrad kfree(adev->acp.acp_genpd); 426 1.1 riastrad return r; 427 1.1 riastrad } 428 1.1 riastrad 429 1.1 riastrad /** 430 1.1 riastrad * acp_hw_fini - stop the hardware block 431 1.1 riastrad * 432 1.1 riastrad * @adev: amdgpu_device pointer 433 1.1 riastrad * 434 1.1 riastrad */ 435 1.1 riastrad static int acp_hw_fini(void *handle) 436 1.1 riastrad { 437 1.1 riastrad int i, ret; 438 1.1 riastrad u32 val = 0; 439 1.1 riastrad u32 count = 0; 440 1.1 riastrad struct device *dev; 441 1.1 riastrad struct amdgpu_device *adev = (struct amdgpu_device *)handle; 442 1.1 riastrad 443 1.1 riastrad /* return early if no ACP */ 444 1.1 riastrad if (!adev->acp.acp_genpd) { 445 1.1 riastrad amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, false); 446 1.1 riastrad return 0; 447 1.1 riastrad } 448 1.1 riastrad 449 1.1 riastrad /* Assert Soft reset of ACP */ 450 1.1 riastrad val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); 451 1.1 riastrad 452 1.1 riastrad val |= ACP_SOFT_RESET__SoftResetAud_MASK; 453 1.1 riastrad cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); 454 1.1 riastrad 455 1.1 riastrad count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE; 456 1.1 riastrad while (true) { 457 1.1 riastrad val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); 458 1.1 riastrad if (ACP_SOFT_RESET__SoftResetAudDone_MASK == 459 1.1 riastrad (val & ACP_SOFT_RESET__SoftResetAudDone_MASK)) 460 1.1 riastrad break; 461 1.1 riastrad if (--count == 0) { 462 1.3 riastrad dev_err(pci_dev_dev(adev->pdev), "Failed to reset ACP\n"); 463 1.1 riastrad return -ETIMEDOUT; 464 1.1 riastrad } 465 1.1 riastrad udelay(100); 466 1.1 riastrad } 467 1.1 riastrad /* Disable ACP clock */ 468 1.1 riastrad val = cgs_read_register(adev->acp.cgs_device, mmACP_CONTROL); 469 1.1 riastrad val &= ~ACP_CONTROL__ClkEn_MASK; 470 1.1 riastrad cgs_write_register(adev->acp.cgs_device, mmACP_CONTROL, val); 471 1.1 riastrad 472 1.1 riastrad count = ACP_CLOCK_EN_TIME_OUT_VALUE; 473 1.1 riastrad 474 1.1 riastrad while (true) { 475 1.1 riastrad val = cgs_read_register(adev->acp.cgs_device, mmACP_STATUS); 476 1.1 riastrad if (val & (u32) 0x1) 477 1.1 riastrad break; 478 1.1 riastrad if (--count == 0) { 479 1.3 riastrad dev_err(pci_dev_dev(adev->pdev), "Failed to reset ACP\n"); 480 1.1 riastrad return -ETIMEDOUT; 481 1.1 riastrad } 482 1.1 riastrad udelay(100); 483 1.1 riastrad } 484 1.1 riastrad 485 1.3 riastrad #ifdef __NetBSD__ /* XXX amdgpu pm */ 486 1.3 riastrad __USE(dev); 487 1.3 riastrad __USE(i); 488 1.3 riastrad __USE(ret); 489 1.3 riastrad #else 490 1.1 riastrad for (i = 0; i < ACP_DEVS ; i++) { 491 1.1 riastrad dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); 492 1.1 riastrad ret = pm_genpd_remove_device(dev); 493 1.1 riastrad /* If removal fails, dont giveup and try rest */ 494 1.1 riastrad if (ret) 495 1.1 riastrad dev_err(dev, "remove dev from genpd failed\n"); 496 1.1 riastrad } 497 1.1 riastrad 498 1.1 riastrad mfd_remove_devices(adev->acp.parent); 499 1.3 riastrad #endif 500 1.1 riastrad kfree(adev->acp.acp_res); 501 1.1 riastrad kfree(adev->acp.acp_genpd); 502 1.1 riastrad kfree(adev->acp.acp_cell); 503 1.1 riastrad 504 1.1 riastrad return 0; 505 1.1 riastrad } 506 1.1 riastrad 507 1.1 riastrad static int acp_suspend(void *handle) 508 1.1 riastrad { 509 1.1 riastrad struct amdgpu_device *adev = (struct amdgpu_device *)handle; 510 1.1 riastrad 511 1.1 riastrad /* power up on suspend */ 512 1.1 riastrad if (!adev->acp.acp_cell) 513 1.1 riastrad amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, false); 514 1.1 riastrad return 0; 515 1.1 riastrad } 516 1.1 riastrad 517 1.1 riastrad static int acp_resume(void *handle) 518 1.1 riastrad { 519 1.1 riastrad struct amdgpu_device *adev = (struct amdgpu_device *)handle; 520 1.1 riastrad 521 1.1 riastrad /* power down again on resume */ 522 1.1 riastrad if (!adev->acp.acp_cell) 523 1.1 riastrad amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true); 524 1.1 riastrad return 0; 525 1.1 riastrad } 526 1.1 riastrad 527 1.1 riastrad static int acp_early_init(void *handle) 528 1.1 riastrad { 529 1.1 riastrad return 0; 530 1.1 riastrad } 531 1.1 riastrad 532 1.1 riastrad static bool acp_is_idle(void *handle) 533 1.1 riastrad { 534 1.1 riastrad return true; 535 1.1 riastrad } 536 1.1 riastrad 537 1.1 riastrad static int acp_wait_for_idle(void *handle) 538 1.1 riastrad { 539 1.1 riastrad return 0; 540 1.1 riastrad } 541 1.1 riastrad 542 1.1 riastrad static int acp_soft_reset(void *handle) 543 1.1 riastrad { 544 1.1 riastrad return 0; 545 1.1 riastrad } 546 1.1 riastrad 547 1.1 riastrad static int acp_set_clockgating_state(void *handle, 548 1.1 riastrad enum amd_clockgating_state state) 549 1.1 riastrad { 550 1.1 riastrad return 0; 551 1.1 riastrad } 552 1.1 riastrad 553 1.1 riastrad static int acp_set_powergating_state(void *handle, 554 1.1 riastrad enum amd_powergating_state state) 555 1.1 riastrad { 556 1.1 riastrad struct amdgpu_device *adev = (struct amdgpu_device *)handle; 557 1.1 riastrad bool enable = (state == AMD_PG_STATE_GATE); 558 1.1 riastrad 559 1.1 riastrad if (adev->powerplay.pp_funcs && 560 1.1 riastrad adev->powerplay.pp_funcs->set_powergating_by_smu) 561 1.1 riastrad amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, enable); 562 1.1 riastrad 563 1.1 riastrad return 0; 564 1.1 riastrad } 565 1.1 riastrad 566 1.1 riastrad static const struct amd_ip_funcs acp_ip_funcs = { 567 1.1 riastrad .name = "acp_ip", 568 1.1 riastrad .early_init = acp_early_init, 569 1.1 riastrad .late_init = NULL, 570 1.1 riastrad .sw_init = acp_sw_init, 571 1.1 riastrad .sw_fini = acp_sw_fini, 572 1.1 riastrad .hw_init = acp_hw_init, 573 1.1 riastrad .hw_fini = acp_hw_fini, 574 1.1 riastrad .suspend = acp_suspend, 575 1.1 riastrad .resume = acp_resume, 576 1.1 riastrad .is_idle = acp_is_idle, 577 1.1 riastrad .wait_for_idle = acp_wait_for_idle, 578 1.1 riastrad .soft_reset = acp_soft_reset, 579 1.1 riastrad .set_clockgating_state = acp_set_clockgating_state, 580 1.1 riastrad .set_powergating_state = acp_set_powergating_state, 581 1.1 riastrad }; 582 1.1 riastrad 583 1.1 riastrad const struct amdgpu_ip_block_version acp_ip_block = 584 1.1 riastrad { 585 1.1 riastrad .type = AMD_IP_BLOCK_TYPE_ACP, 586 1.1 riastrad .major = 2, 587 1.1 riastrad .minor = 2, 588 1.1 riastrad .rev = 0, 589 1.1 riastrad .funcs = &acp_ip_funcs, 590 1.1 riastrad }; 591