0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <linux/irqdomain.h>
0027 #include <linux/pci.h>
0028 #include <linux/pm_domain.h>
0029 #include <linux/platform_device.h>
0030 #include <sound/designware_i2s.h>
0031 #include <sound/pcm.h>
0032 #include <linux/acpi.h>
0033 #include <linux/dmi.h>
0034
0035 #include "amdgpu.h"
0036 #include "atom.h"
0037 #include "amdgpu_acp.h"
0038
0039 #include "acp_gfx_if.h"
0040
0041 #define ST_JADEITE 1
0042 #define ACP_TILE_ON_MASK 0x03
0043 #define ACP_TILE_OFF_MASK 0x02
0044 #define ACP_TILE_ON_RETAIN_REG_MASK 0x1f
0045 #define ACP_TILE_OFF_RETAIN_REG_MASK 0x20
0046
0047 #define ACP_TILE_P1_MASK 0x3e
0048 #define ACP_TILE_P2_MASK 0x3d
0049 #define ACP_TILE_DSP0_MASK 0x3b
0050 #define ACP_TILE_DSP1_MASK 0x37
0051
0052 #define ACP_TILE_DSP2_MASK 0x2f
0053
0054 #define ACP_DMA_REGS_END 0x146c0
0055 #define ACP_I2S_PLAY_REGS_START 0x14840
0056 #define ACP_I2S_PLAY_REGS_END 0x148b4
0057 #define ACP_I2S_CAP_REGS_START 0x148b8
0058 #define ACP_I2S_CAP_REGS_END 0x1496c
0059
0060 #define ACP_I2S_COMP1_CAP_REG_OFFSET 0xac
0061 #define ACP_I2S_COMP2_CAP_REG_OFFSET 0xa8
0062 #define ACP_I2S_COMP1_PLAY_REG_OFFSET 0x6c
0063 #define ACP_I2S_COMP2_PLAY_REG_OFFSET 0x68
0064 #define ACP_BT_PLAY_REGS_START 0x14970
0065 #define ACP_BT_PLAY_REGS_END 0x14a24
0066 #define ACP_BT_COMP1_REG_OFFSET 0xac
0067 #define ACP_BT_COMP2_REG_OFFSET 0xa8
0068
0069 #define mmACP_PGFSM_RETAIN_REG 0x51c9
0070 #define mmACP_PGFSM_CONFIG_REG 0x51ca
0071 #define mmACP_PGFSM_READ_REG_0 0x51cc
0072
0073 #define mmACP_MEM_SHUT_DOWN_REQ_LO 0x51f8
0074 #define mmACP_MEM_SHUT_DOWN_REQ_HI 0x51f9
0075 #define mmACP_MEM_SHUT_DOWN_STS_LO 0x51fa
0076 #define mmACP_MEM_SHUT_DOWN_STS_HI 0x51fb
0077
0078 #define mmACP_CONTROL 0x5131
0079 #define mmACP_STATUS 0x5133
0080 #define mmACP_SOFT_RESET 0x5134
0081 #define ACP_CONTROL__ClkEn_MASK 0x1
0082 #define ACP_SOFT_RESET__SoftResetAud_MASK 0x100
0083 #define ACP_SOFT_RESET__SoftResetAudDone_MASK 0x1000000
0084 #define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF
0085 #define ACP_SOFT_RESET_DONE_TIME_OUT_VALUE 0x000000FF
0086
0087 #define ACP_TIMEOUT_LOOP 0x000000FF
0088 #define ACP_DEVS 4
0089 #define ACP_SRC_ID 162
0090
0091 static unsigned long acp_machine_id;
0092
0093 enum {
0094 ACP_TILE_P1 = 0,
0095 ACP_TILE_P2,
0096 ACP_TILE_DSP0,
0097 ACP_TILE_DSP1,
0098 ACP_TILE_DSP2,
0099 };
0100
0101 static int acp_sw_init(void *handle)
0102 {
0103 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0104
0105 adev->acp.parent = adev->dev;
0106
0107 adev->acp.cgs_device =
0108 amdgpu_cgs_create_device(adev);
0109 if (!adev->acp.cgs_device)
0110 return -EINVAL;
0111
0112 return 0;
0113 }
0114
0115 static int acp_sw_fini(void *handle)
0116 {
0117 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0118
0119 if (adev->acp.cgs_device)
0120 amdgpu_cgs_destroy_device(adev->acp.cgs_device);
0121
0122 return 0;
0123 }
0124
0125 struct acp_pm_domain {
0126 void *adev;
0127 struct generic_pm_domain gpd;
0128 };
0129
0130 static int acp_poweroff(struct generic_pm_domain *genpd)
0131 {
0132 struct acp_pm_domain *apd;
0133 struct amdgpu_device *adev;
0134
0135 apd = container_of(genpd, struct acp_pm_domain, gpd);
0136 adev = apd->adev;
0137
0138
0139
0140
0141
0142
0143 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true);
0144 return 0;
0145 }
0146
0147 static int acp_poweron(struct generic_pm_domain *genpd)
0148 {
0149 struct acp_pm_domain *apd;
0150 struct amdgpu_device *adev;
0151
0152 apd = container_of(genpd, struct acp_pm_domain, gpd);
0153 adev = apd->adev;
0154
0155
0156
0157
0158
0159
0160 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, false);
0161 return 0;
0162 }
0163
0164 static int acp_genpd_add_device(struct device *dev, void *data)
0165 {
0166 struct generic_pm_domain *gpd = data;
0167 int ret;
0168
0169 ret = pm_genpd_add_device(gpd, dev);
0170 if (ret)
0171 dev_err(dev, "Failed to add dev to genpd %d\n", ret);
0172
0173 return ret;
0174 }
0175
0176 static int acp_genpd_remove_device(struct device *dev, void *data)
0177 {
0178 int ret;
0179
0180 ret = pm_genpd_remove_device(dev);
0181 if (ret)
0182 dev_err(dev, "Failed to remove dev from genpd %d\n", ret);
0183
0184
0185 return 0;
0186 }
0187
0188 static int acp_quirk_cb(const struct dmi_system_id *id)
0189 {
0190 acp_machine_id = ST_JADEITE;
0191 return 1;
0192 }
0193
0194 static const struct dmi_system_id acp_quirk_table[] = {
0195 {
0196 .callback = acp_quirk_cb,
0197 .matches = {
0198 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMD"),
0199 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jadeite"),
0200 }
0201 },
0202 {
0203 .callback = acp_quirk_cb,
0204 .matches = {
0205 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "IP3 Technology CO.,Ltd."),
0206 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ASN1D"),
0207 },
0208 },
0209 {
0210 .callback = acp_quirk_cb,
0211 .matches = {
0212 DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Standard"),
0213 DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ASN10"),
0214 },
0215 },
0216 {}
0217 };
0218
0219
0220
0221
0222
0223
0224
0225 static int acp_hw_init(void *handle)
0226 {
0227 int r;
0228 u64 acp_base;
0229 u32 val = 0;
0230 u32 count = 0;
0231 struct i2s_platform_data *i2s_pdata = NULL;
0232
0233 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0234
0235 const struct amdgpu_ip_block *ip_block =
0236 amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_ACP);
0237
0238 if (!ip_block)
0239 return -EINVAL;
0240
0241 r = amd_acp_hw_init(adev->acp.cgs_device,
0242 ip_block->version->major, ip_block->version->minor);
0243
0244 if (r == -ENODEV) {
0245 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true);
0246 return 0;
0247 } else if (r) {
0248 return r;
0249 }
0250
0251 if (adev->rmmio_size == 0 || adev->rmmio_size < 0x5289)
0252 return -EINVAL;
0253
0254 acp_base = adev->rmmio_base;
0255 adev->acp.acp_genpd = kzalloc(sizeof(struct acp_pm_domain), GFP_KERNEL);
0256 if (!adev->acp.acp_genpd)
0257 return -ENOMEM;
0258
0259 adev->acp.acp_genpd->gpd.name = "ACP_AUDIO";
0260 adev->acp.acp_genpd->gpd.power_off = acp_poweroff;
0261 adev->acp.acp_genpd->gpd.power_on = acp_poweron;
0262 adev->acp.acp_genpd->adev = adev;
0263
0264 pm_genpd_init(&adev->acp.acp_genpd->gpd, NULL, false);
0265 dmi_check_system(acp_quirk_table);
0266 switch (acp_machine_id) {
0267 case ST_JADEITE:
0268 {
0269 adev->acp.acp_cell = kcalloc(2, sizeof(struct mfd_cell),
0270 GFP_KERNEL);
0271 if (!adev->acp.acp_cell) {
0272 r = -ENOMEM;
0273 goto failure;
0274 }
0275
0276 adev->acp.acp_res = kcalloc(3, sizeof(struct resource), GFP_KERNEL);
0277 if (!adev->acp.acp_res) {
0278 r = -ENOMEM;
0279 goto failure;
0280 }
0281
0282 i2s_pdata = kcalloc(1, sizeof(struct i2s_platform_data), GFP_KERNEL);
0283 if (!i2s_pdata) {
0284 r = -ENOMEM;
0285 goto failure;
0286 }
0287
0288 i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
0289 DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
0290 i2s_pdata[0].cap = DWC_I2S_PLAY | DWC_I2S_RECORD;
0291 i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000;
0292 i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET;
0293 i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET;
0294
0295 adev->acp.acp_res[0].name = "acp2x_dma";
0296 adev->acp.acp_res[0].flags = IORESOURCE_MEM;
0297 adev->acp.acp_res[0].start = acp_base;
0298 adev->acp.acp_res[0].end = acp_base + ACP_DMA_REGS_END;
0299
0300 adev->acp.acp_res[1].name = "acp2x_dw_i2s_play_cap";
0301 adev->acp.acp_res[1].flags = IORESOURCE_MEM;
0302 adev->acp.acp_res[1].start = acp_base + ACP_I2S_CAP_REGS_START;
0303 adev->acp.acp_res[1].end = acp_base + ACP_I2S_CAP_REGS_END;
0304
0305 adev->acp.acp_res[2].name = "acp2x_dma_irq";
0306 adev->acp.acp_res[2].flags = IORESOURCE_IRQ;
0307 adev->acp.acp_res[2].start = amdgpu_irq_create_mapping(adev, 162);
0308 adev->acp.acp_res[2].end = adev->acp.acp_res[2].start;
0309
0310 adev->acp.acp_cell[0].name = "acp_audio_dma";
0311 adev->acp.acp_cell[0].num_resources = 3;
0312 adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0];
0313 adev->acp.acp_cell[0].platform_data = &adev->asic_type;
0314 adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type);
0315
0316 adev->acp.acp_cell[1].name = "designware-i2s";
0317 adev->acp.acp_cell[1].num_resources = 1;
0318 adev->acp.acp_cell[1].resources = &adev->acp.acp_res[1];
0319 adev->acp.acp_cell[1].platform_data = &i2s_pdata[0];
0320 adev->acp.acp_cell[1].pdata_size = sizeof(struct i2s_platform_data);
0321 r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, 2);
0322 if (r)
0323 goto failure;
0324 r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
0325 acp_genpd_add_device);
0326 if (r)
0327 goto failure;
0328 break;
0329 }
0330 default:
0331 adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),
0332 GFP_KERNEL);
0333
0334 if (!adev->acp.acp_cell) {
0335 r = -ENOMEM;
0336 goto failure;
0337 }
0338
0339 adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);
0340 if (!adev->acp.acp_res) {
0341 r = -ENOMEM;
0342 goto failure;
0343 }
0344
0345 i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);
0346 if (!i2s_pdata) {
0347 r = -ENOMEM;
0348 goto failure;
0349 }
0350
0351 switch (adev->asic_type) {
0352 case CHIP_STONEY:
0353 i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
0354 DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
0355 break;
0356 default:
0357 i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
0358 }
0359 i2s_pdata[0].cap = DWC_I2S_PLAY;
0360 i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000;
0361 i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_PLAY_REG_OFFSET;
0362 i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_PLAY_REG_OFFSET;
0363 switch (adev->asic_type) {
0364 case CHIP_STONEY:
0365 i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
0366 DW_I2S_QUIRK_COMP_PARAM1 |
0367 DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
0368 break;
0369 default:
0370 i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |
0371 DW_I2S_QUIRK_COMP_PARAM1;
0372 }
0373
0374 i2s_pdata[1].cap = DWC_I2S_RECORD;
0375 i2s_pdata[1].snd_rates = SNDRV_PCM_RATE_8000_96000;
0376 i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET;
0377 i2s_pdata[1].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET;
0378
0379 i2s_pdata[2].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;
0380 switch (adev->asic_type) {
0381 case CHIP_STONEY:
0382 i2s_pdata[2].quirks |= DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;
0383 break;
0384 default:
0385 break;
0386 }
0387
0388 i2s_pdata[2].cap = DWC_I2S_PLAY | DWC_I2S_RECORD;
0389 i2s_pdata[2].snd_rates = SNDRV_PCM_RATE_8000_96000;
0390 i2s_pdata[2].i2s_reg_comp1 = ACP_BT_COMP1_REG_OFFSET;
0391 i2s_pdata[2].i2s_reg_comp2 = ACP_BT_COMP2_REG_OFFSET;
0392
0393 adev->acp.acp_res[0].name = "acp2x_dma";
0394 adev->acp.acp_res[0].flags = IORESOURCE_MEM;
0395 adev->acp.acp_res[0].start = acp_base;
0396 adev->acp.acp_res[0].end = acp_base + ACP_DMA_REGS_END;
0397
0398 adev->acp.acp_res[1].name = "acp2x_dw_i2s_play";
0399 adev->acp.acp_res[1].flags = IORESOURCE_MEM;
0400 adev->acp.acp_res[1].start = acp_base + ACP_I2S_PLAY_REGS_START;
0401 adev->acp.acp_res[1].end = acp_base + ACP_I2S_PLAY_REGS_END;
0402
0403 adev->acp.acp_res[2].name = "acp2x_dw_i2s_cap";
0404 adev->acp.acp_res[2].flags = IORESOURCE_MEM;
0405 adev->acp.acp_res[2].start = acp_base + ACP_I2S_CAP_REGS_START;
0406 adev->acp.acp_res[2].end = acp_base + ACP_I2S_CAP_REGS_END;
0407
0408 adev->acp.acp_res[3].name = "acp2x_dw_bt_i2s_play_cap";
0409 adev->acp.acp_res[3].flags = IORESOURCE_MEM;
0410 adev->acp.acp_res[3].start = acp_base + ACP_BT_PLAY_REGS_START;
0411 adev->acp.acp_res[3].end = acp_base + ACP_BT_PLAY_REGS_END;
0412
0413 adev->acp.acp_res[4].name = "acp2x_dma_irq";
0414 adev->acp.acp_res[4].flags = IORESOURCE_IRQ;
0415 adev->acp.acp_res[4].start = amdgpu_irq_create_mapping(adev, 162);
0416 adev->acp.acp_res[4].end = adev->acp.acp_res[4].start;
0417
0418 adev->acp.acp_cell[0].name = "acp_audio_dma";
0419 adev->acp.acp_cell[0].num_resources = 5;
0420 adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0];
0421 adev->acp.acp_cell[0].platform_data = &adev->asic_type;
0422 adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type);
0423
0424 adev->acp.acp_cell[1].name = "designware-i2s";
0425 adev->acp.acp_cell[1].num_resources = 1;
0426 adev->acp.acp_cell[1].resources = &adev->acp.acp_res[1];
0427 adev->acp.acp_cell[1].platform_data = &i2s_pdata[0];
0428 adev->acp.acp_cell[1].pdata_size = sizeof(struct i2s_platform_data);
0429
0430 adev->acp.acp_cell[2].name = "designware-i2s";
0431 adev->acp.acp_cell[2].num_resources = 1;
0432 adev->acp.acp_cell[2].resources = &adev->acp.acp_res[2];
0433 adev->acp.acp_cell[2].platform_data = &i2s_pdata[1];
0434 adev->acp.acp_cell[2].pdata_size = sizeof(struct i2s_platform_data);
0435
0436 adev->acp.acp_cell[3].name = "designware-i2s";
0437 adev->acp.acp_cell[3].num_resources = 1;
0438 adev->acp.acp_cell[3].resources = &adev->acp.acp_res[3];
0439 adev->acp.acp_cell[3].platform_data = &i2s_pdata[2];
0440 adev->acp.acp_cell[3].pdata_size = sizeof(struct i2s_platform_data);
0441
0442 r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, ACP_DEVS);
0443 if (r)
0444 goto failure;
0445
0446 r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,
0447 acp_genpd_add_device);
0448 if (r)
0449 goto failure;
0450 }
0451
0452
0453 val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);
0454
0455 val |= ACP_SOFT_RESET__SoftResetAud_MASK;
0456 cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
0457
0458 count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE;
0459 while (true) {
0460 val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);
0461 if (ACP_SOFT_RESET__SoftResetAudDone_MASK ==
0462 (val & ACP_SOFT_RESET__SoftResetAudDone_MASK))
0463 break;
0464 if (--count == 0) {
0465 dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
0466 r = -ETIMEDOUT;
0467 goto failure;
0468 }
0469 udelay(100);
0470 }
0471
0472 val = cgs_read_register(adev->acp.cgs_device, mmACP_CONTROL);
0473 val = val | ACP_CONTROL__ClkEn_MASK;
0474 cgs_write_register(adev->acp.cgs_device, mmACP_CONTROL, val);
0475
0476 count = ACP_CLOCK_EN_TIME_OUT_VALUE;
0477
0478 while (true) {
0479 val = cgs_read_register(adev->acp.cgs_device, mmACP_STATUS);
0480 if (val & (u32) 0x1)
0481 break;
0482 if (--count == 0) {
0483 dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
0484 r = -ETIMEDOUT;
0485 goto failure;
0486 }
0487 udelay(100);
0488 }
0489
0490 val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);
0491 val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;
0492 cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
0493 return 0;
0494
0495 failure:
0496 kfree(i2s_pdata);
0497 kfree(adev->acp.acp_res);
0498 kfree(adev->acp.acp_cell);
0499 kfree(adev->acp.acp_genpd);
0500 return r;
0501 }
0502
0503
0504
0505
0506
0507
0508
0509 static int acp_hw_fini(void *handle)
0510 {
0511 u32 val = 0;
0512 u32 count = 0;
0513 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0514
0515
0516 if (!adev->acp.acp_genpd) {
0517 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, false);
0518 return 0;
0519 }
0520
0521
0522 val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);
0523
0524 val |= ACP_SOFT_RESET__SoftResetAud_MASK;
0525 cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);
0526
0527 count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE;
0528 while (true) {
0529 val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);
0530 if (ACP_SOFT_RESET__SoftResetAudDone_MASK ==
0531 (val & ACP_SOFT_RESET__SoftResetAudDone_MASK))
0532 break;
0533 if (--count == 0) {
0534 dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
0535 return -ETIMEDOUT;
0536 }
0537 udelay(100);
0538 }
0539
0540 val = cgs_read_register(adev->acp.cgs_device, mmACP_CONTROL);
0541 val &= ~ACP_CONTROL__ClkEn_MASK;
0542 cgs_write_register(adev->acp.cgs_device, mmACP_CONTROL, val);
0543
0544 count = ACP_CLOCK_EN_TIME_OUT_VALUE;
0545
0546 while (true) {
0547 val = cgs_read_register(adev->acp.cgs_device, mmACP_STATUS);
0548 if (val & (u32) 0x1)
0549 break;
0550 if (--count == 0) {
0551 dev_err(&adev->pdev->dev, "Failed to reset ACP\n");
0552 return -ETIMEDOUT;
0553 }
0554 udelay(100);
0555 }
0556
0557 device_for_each_child(adev->acp.parent, NULL,
0558 acp_genpd_remove_device);
0559
0560 mfd_remove_devices(adev->acp.parent);
0561 kfree(adev->acp.acp_res);
0562 kfree(adev->acp.acp_genpd);
0563 kfree(adev->acp.acp_cell);
0564
0565 return 0;
0566 }
0567
0568 static int acp_suspend(void *handle)
0569 {
0570 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0571
0572
0573 if (!adev->acp.acp_cell)
0574 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, false);
0575 return 0;
0576 }
0577
0578 static int acp_resume(void *handle)
0579 {
0580 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0581
0582
0583 if (!adev->acp.acp_cell)
0584 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true);
0585 return 0;
0586 }
0587
0588 static int acp_early_init(void *handle)
0589 {
0590 return 0;
0591 }
0592
0593 static bool acp_is_idle(void *handle)
0594 {
0595 return true;
0596 }
0597
0598 static int acp_wait_for_idle(void *handle)
0599 {
0600 return 0;
0601 }
0602
0603 static int acp_soft_reset(void *handle)
0604 {
0605 return 0;
0606 }
0607
0608 static int acp_set_clockgating_state(void *handle,
0609 enum amd_clockgating_state state)
0610 {
0611 return 0;
0612 }
0613
0614 static int acp_set_powergating_state(void *handle,
0615 enum amd_powergating_state state)
0616 {
0617 struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0618 bool enable = (state == AMD_PG_STATE_GATE);
0619
0620 amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, enable);
0621
0622 return 0;
0623 }
0624
0625 static const struct amd_ip_funcs acp_ip_funcs = {
0626 .name = "acp_ip",
0627 .early_init = acp_early_init,
0628 .late_init = NULL,
0629 .sw_init = acp_sw_init,
0630 .sw_fini = acp_sw_fini,
0631 .hw_init = acp_hw_init,
0632 .hw_fini = acp_hw_fini,
0633 .suspend = acp_suspend,
0634 .resume = acp_resume,
0635 .is_idle = acp_is_idle,
0636 .wait_for_idle = acp_wait_for_idle,
0637 .soft_reset = acp_soft_reset,
0638 .set_clockgating_state = acp_set_clockgating_state,
0639 .set_powergating_state = acp_set_powergating_state,
0640 };
0641
0642 const struct amdgpu_ip_block_version acp_ip_block = {
0643 .type = AMD_IP_BLOCK_TYPE_ACP,
0644 .major = 2,
0645 .minor = 2,
0646 .rev = 0,
0647 .funcs = &acp_ip_funcs,
0648 };