Path: blob/master/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
26517 views
/*1* Copyright 2015 Advanced Micro Devices, Inc.2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice shall be included in11* all copies or substantial portions of the Software.12*13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL16* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR17* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,18* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR19* OTHER DEALINGS IN THE SOFTWARE.20*21* Authors: AMD22*23*/2425#include <linux/irqdomain.h>26#include <linux/pci.h>27#include <linux/pm_domain.h>28#include <linux/platform_device.h>29#include <sound/designware_i2s.h>30#include <sound/pcm.h>31#include <linux/acpi.h>32#include <linux/dmi.h>3334#include "amdgpu.h"35#include "atom.h"36#include "amdgpu_acp.h"3738#include "acp_gfx_if.h"3940#define ST_JADEITE 141#define ACP_TILE_ON_MASK 0x0342#define ACP_TILE_OFF_MASK 0x0243#define ACP_TILE_ON_RETAIN_REG_MASK 0x1f44#define ACP_TILE_OFF_RETAIN_REG_MASK 0x204546#define ACP_TILE_P1_MASK 0x3e47#define ACP_TILE_P2_MASK 0x3d48#define ACP_TILE_DSP0_MASK 0x3b49#define ACP_TILE_DSP1_MASK 0x375051#define ACP_TILE_DSP2_MASK 0x2f5253#define ACP_DMA_REGS_END 0x146c054#define ACP_I2S_PLAY_REGS_START 0x1484055#define ACP_I2S_PLAY_REGS_END 0x148b456#define ACP_I2S_CAP_REGS_START 0x148b857#define ACP_I2S_CAP_REGS_END 0x1496c5859#define ACP_I2S_COMP1_CAP_REG_OFFSET 0xac60#define ACP_I2S_COMP2_CAP_REG_OFFSET 0xa861#define ACP_I2S_COMP1_PLAY_REG_OFFSET 0x6c62#define ACP_I2S_COMP2_PLAY_REG_OFFSET 0x6863#define ACP_BT_PLAY_REGS_START 0x1497064#define ACP_BT_PLAY_REGS_END 0x14a2465#define ACP_BT_COMP1_REG_OFFSET 0xac66#define ACP_BT_COMP2_REG_OFFSET 0xa86768#define mmACP_PGFSM_RETAIN_REG 0x51c969#define mmACP_PGFSM_CONFIG_REG 0x51ca70#define mmACP_PGFSM_READ_REG_0 0x51cc7172#define mmACP_MEM_SHUT_DOWN_REQ_LO 0x51f873#define mmACP_MEM_SHUT_DOWN_REQ_HI 0x51f974#define mmACP_MEM_SHUT_DOWN_STS_LO 0x51fa75#define mmACP_MEM_SHUT_DOWN_STS_HI 0x51fb7677#define mmACP_CONTROL 0x513178#define mmACP_STATUS 0x513379#define mmACP_SOFT_RESET 0x513480#define ACP_CONTROL__ClkEn_MASK 0x181#define ACP_SOFT_RESET__SoftResetAud_MASK 0x10082#define ACP_SOFT_RESET__SoftResetAudDone_MASK 0x100000083#define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF84#define ACP_SOFT_RESET_DONE_TIME_OUT_VALUE 0x000000FF8586#define ACP_TIMEOUT_LOOP 0x000000FF87#define ACP_DEVS 488#define ACP_SRC_ID 1628990static unsigned long acp_machine_id;9192enum {93ACP_TILE_P1 = 0,94ACP_TILE_P2,95ACP_TILE_DSP0,96ACP_TILE_DSP1,97ACP_TILE_DSP2,98};99100static int acp_sw_init(struct amdgpu_ip_block *ip_block)101{102struct amdgpu_device *adev = ip_block->adev;103104adev->acp.parent = adev->dev;105106adev->acp.cgs_device =107amdgpu_cgs_create_device(adev);108if (!adev->acp.cgs_device)109return -EINVAL;110111return 0;112}113114static int acp_sw_fini(struct amdgpu_ip_block *ip_block)115{116struct amdgpu_device *adev = ip_block->adev;117118if (adev->acp.cgs_device)119amdgpu_cgs_destroy_device(adev->acp.cgs_device);120121return 0;122}123124struct acp_pm_domain {125void *adev;126struct generic_pm_domain gpd;127};128129static int acp_poweroff(struct generic_pm_domain *genpd)130{131struct acp_pm_domain *apd;132struct amdgpu_device *adev;133134apd = container_of(genpd, struct acp_pm_domain, gpd);135adev = apd->adev;136/* call smu to POWER GATE ACP block137* smu will138* 1. turn off the acp clock139* 2. power off the acp tiles140* 3. check and enter ulv state141*/142amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true, 0);143return 0;144}145146static int acp_poweron(struct generic_pm_domain *genpd)147{148struct acp_pm_domain *apd;149struct amdgpu_device *adev;150151apd = container_of(genpd, struct acp_pm_domain, gpd);152adev = apd->adev;153/* call smu to UNGATE ACP block154* smu will155* 1. exit ulv156* 2. turn on acp clock157* 3. power on acp tiles158*/159amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, false, 0);160return 0;161}162163static int acp_genpd_add_device(struct device *dev, void *data)164{165struct generic_pm_domain *gpd = data;166int ret;167168ret = pm_genpd_add_device(gpd, dev);169if (ret)170dev_err(dev, "Failed to add dev to genpd %d\n", ret);171172return ret;173}174175static int acp_genpd_remove_device(struct device *dev, void *data)176{177int ret;178179ret = pm_genpd_remove_device(dev);180if (ret)181dev_err(dev, "Failed to remove dev from genpd %d\n", ret);182183/* Continue to remove */184return 0;185}186187static int acp_quirk_cb(const struct dmi_system_id *id)188{189acp_machine_id = ST_JADEITE;190return 1;191}192193static const struct dmi_system_id acp_quirk_table[] = {194{195.callback = acp_quirk_cb,196.matches = {197DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMD"),198DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Jadeite"),199}200},201{202.callback = acp_quirk_cb,203.matches = {204DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "IP3 Technology CO.,Ltd."),205DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ASN1D"),206},207},208{209.callback = acp_quirk_cb,210.matches = {211DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Standard"),212DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ASN10"),213},214},215{}216};217218/**219* acp_hw_init - start and test ACP block220*221* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.222*223*/224static int acp_hw_init(struct amdgpu_ip_block *ip_block)225{226int r;227u64 acp_base;228u32 val = 0;229u32 count = 0;230struct i2s_platform_data *i2s_pdata = NULL;231232struct amdgpu_device *adev = ip_block->adev;233234r = amd_acp_hw_init(adev->acp.cgs_device,235ip_block->version->major, ip_block->version->minor);236/* -ENODEV means board uses AZ rather than ACP */237if (r == -ENODEV) {238amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true, 0);239return 0;240} else if (r) {241return r;242}243244if (adev->rmmio_size == 0 || adev->rmmio_size < 0x5289)245return -EINVAL;246247acp_base = adev->rmmio_base;248adev->acp.acp_genpd = kzalloc(sizeof(struct acp_pm_domain), GFP_KERNEL);249if (!adev->acp.acp_genpd)250return -ENOMEM;251252adev->acp.acp_genpd->gpd.name = "ACP_AUDIO";253adev->acp.acp_genpd->gpd.power_off = acp_poweroff;254adev->acp.acp_genpd->gpd.power_on = acp_poweron;255adev->acp.acp_genpd->adev = adev;256257pm_genpd_init(&adev->acp.acp_genpd->gpd, NULL, false);258dmi_check_system(acp_quirk_table);259switch (acp_machine_id) {260case ST_JADEITE:261{262adev->acp.acp_cell = kcalloc(2, sizeof(struct mfd_cell),263GFP_KERNEL);264if (!adev->acp.acp_cell) {265r = -ENOMEM;266goto failure;267}268269adev->acp.acp_res = kcalloc(3, sizeof(struct resource), GFP_KERNEL);270if (!adev->acp.acp_res) {271r = -ENOMEM;272goto failure;273}274275i2s_pdata = kcalloc(1, sizeof(struct i2s_platform_data), GFP_KERNEL);276if (!i2s_pdata) {277r = -ENOMEM;278goto failure;279}280281i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |282DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;283i2s_pdata[0].cap = DWC_I2S_PLAY | DWC_I2S_RECORD;284i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000;285i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET;286i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET;287288adev->acp.acp_res[0].name = "acp2x_dma";289adev->acp.acp_res[0].flags = IORESOURCE_MEM;290adev->acp.acp_res[0].start = acp_base;291adev->acp.acp_res[0].end = acp_base + ACP_DMA_REGS_END;292293adev->acp.acp_res[1].name = "acp2x_dw_i2s_play_cap";294adev->acp.acp_res[1].flags = IORESOURCE_MEM;295adev->acp.acp_res[1].start = acp_base + ACP_I2S_CAP_REGS_START;296adev->acp.acp_res[1].end = acp_base + ACP_I2S_CAP_REGS_END;297298adev->acp.acp_res[2].name = "acp2x_dma_irq";299adev->acp.acp_res[2].flags = IORESOURCE_IRQ;300adev->acp.acp_res[2].start = amdgpu_irq_create_mapping(adev, 162);301adev->acp.acp_res[2].end = adev->acp.acp_res[2].start;302303adev->acp.acp_cell[0].name = "acp_audio_dma";304adev->acp.acp_cell[0].num_resources = 3;305adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0];306adev->acp.acp_cell[0].platform_data = &adev->asic_type;307adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type);308309adev->acp.acp_cell[1].name = "designware-i2s";310adev->acp.acp_cell[1].num_resources = 1;311adev->acp.acp_cell[1].resources = &adev->acp.acp_res[1];312adev->acp.acp_cell[1].platform_data = &i2s_pdata[0];313adev->acp.acp_cell[1].pdata_size = sizeof(struct i2s_platform_data);314r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, 2);315if (r)316goto failure;317r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,318acp_genpd_add_device);319if (r)320goto failure;321break;322}323default:324adev->acp.acp_cell = kcalloc(ACP_DEVS, sizeof(struct mfd_cell),325GFP_KERNEL);326327if (!adev->acp.acp_cell) {328r = -ENOMEM;329goto failure;330}331332adev->acp.acp_res = kcalloc(5, sizeof(struct resource), GFP_KERNEL);333if (!adev->acp.acp_res) {334r = -ENOMEM;335goto failure;336}337338i2s_pdata = kcalloc(3, sizeof(struct i2s_platform_data), GFP_KERNEL);339if (!i2s_pdata) {340r = -ENOMEM;341goto failure;342}343344switch (adev->asic_type) {345case CHIP_STONEY:346i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |347DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;348break;349default:350i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;351}352i2s_pdata[0].cap = DWC_I2S_PLAY;353i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000;354i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_PLAY_REG_OFFSET;355i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_PLAY_REG_OFFSET;356switch (adev->asic_type) {357case CHIP_STONEY:358i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |359DW_I2S_QUIRK_COMP_PARAM1 |360DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;361break;362default:363i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET |364DW_I2S_QUIRK_COMP_PARAM1;365}366367i2s_pdata[1].cap = DWC_I2S_RECORD;368i2s_pdata[1].snd_rates = SNDRV_PCM_RATE_8000_96000;369i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET;370i2s_pdata[1].i2s_reg_comp2 = ACP_I2S_COMP2_CAP_REG_OFFSET;371372i2s_pdata[2].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET;373switch (adev->asic_type) {374case CHIP_STONEY:375i2s_pdata[2].quirks |= DW_I2S_QUIRK_16BIT_IDX_OVERRIDE;376break;377default:378break;379}380381i2s_pdata[2].cap = DWC_I2S_PLAY | DWC_I2S_RECORD;382i2s_pdata[2].snd_rates = SNDRV_PCM_RATE_8000_96000;383i2s_pdata[2].i2s_reg_comp1 = ACP_BT_COMP1_REG_OFFSET;384i2s_pdata[2].i2s_reg_comp2 = ACP_BT_COMP2_REG_OFFSET;385386adev->acp.acp_res[0].name = "acp2x_dma";387adev->acp.acp_res[0].flags = IORESOURCE_MEM;388adev->acp.acp_res[0].start = acp_base;389adev->acp.acp_res[0].end = acp_base + ACP_DMA_REGS_END;390391adev->acp.acp_res[1].name = "acp2x_dw_i2s_play";392adev->acp.acp_res[1].flags = IORESOURCE_MEM;393adev->acp.acp_res[1].start = acp_base + ACP_I2S_PLAY_REGS_START;394adev->acp.acp_res[1].end = acp_base + ACP_I2S_PLAY_REGS_END;395396adev->acp.acp_res[2].name = "acp2x_dw_i2s_cap";397adev->acp.acp_res[2].flags = IORESOURCE_MEM;398adev->acp.acp_res[2].start = acp_base + ACP_I2S_CAP_REGS_START;399adev->acp.acp_res[2].end = acp_base + ACP_I2S_CAP_REGS_END;400401adev->acp.acp_res[3].name = "acp2x_dw_bt_i2s_play_cap";402adev->acp.acp_res[3].flags = IORESOURCE_MEM;403adev->acp.acp_res[3].start = acp_base + ACP_BT_PLAY_REGS_START;404adev->acp.acp_res[3].end = acp_base + ACP_BT_PLAY_REGS_END;405406adev->acp.acp_res[4].name = "acp2x_dma_irq";407adev->acp.acp_res[4].flags = IORESOURCE_IRQ;408adev->acp.acp_res[4].start = amdgpu_irq_create_mapping(adev, 162);409adev->acp.acp_res[4].end = adev->acp.acp_res[4].start;410411adev->acp.acp_cell[0].name = "acp_audio_dma";412adev->acp.acp_cell[0].num_resources = 5;413adev->acp.acp_cell[0].resources = &adev->acp.acp_res[0];414adev->acp.acp_cell[0].platform_data = &adev->asic_type;415adev->acp.acp_cell[0].pdata_size = sizeof(adev->asic_type);416417adev->acp.acp_cell[1].name = "designware-i2s";418adev->acp.acp_cell[1].num_resources = 1;419adev->acp.acp_cell[1].resources = &adev->acp.acp_res[1];420adev->acp.acp_cell[1].platform_data = &i2s_pdata[0];421adev->acp.acp_cell[1].pdata_size = sizeof(struct i2s_platform_data);422423adev->acp.acp_cell[2].name = "designware-i2s";424adev->acp.acp_cell[2].num_resources = 1;425adev->acp.acp_cell[2].resources = &adev->acp.acp_res[2];426adev->acp.acp_cell[2].platform_data = &i2s_pdata[1];427adev->acp.acp_cell[2].pdata_size = sizeof(struct i2s_platform_data);428429adev->acp.acp_cell[3].name = "designware-i2s";430adev->acp.acp_cell[3].num_resources = 1;431adev->acp.acp_cell[3].resources = &adev->acp.acp_res[3];432adev->acp.acp_cell[3].platform_data = &i2s_pdata[2];433adev->acp.acp_cell[3].pdata_size = sizeof(struct i2s_platform_data);434435r = mfd_add_hotplug_devices(adev->acp.parent, adev->acp.acp_cell, ACP_DEVS);436if (r)437goto failure;438439r = device_for_each_child(adev->acp.parent, &adev->acp.acp_genpd->gpd,440acp_genpd_add_device);441if (r)442goto failure;443}444445/* Assert Soft reset of ACP */446val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);447448val |= ACP_SOFT_RESET__SoftResetAud_MASK;449cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);450451count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE;452while (true) {453val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);454if (ACP_SOFT_RESET__SoftResetAudDone_MASK ==455(val & ACP_SOFT_RESET__SoftResetAudDone_MASK))456break;457if (--count == 0) {458dev_err(&adev->pdev->dev, "Failed to reset ACP\n");459r = -ETIMEDOUT;460goto failure;461}462udelay(100);463}464/* Enable clock to ACP and wait until the clock is enabled */465val = cgs_read_register(adev->acp.cgs_device, mmACP_CONTROL);466val = val | ACP_CONTROL__ClkEn_MASK;467cgs_write_register(adev->acp.cgs_device, mmACP_CONTROL, val);468469count = ACP_CLOCK_EN_TIME_OUT_VALUE;470471while (true) {472val = cgs_read_register(adev->acp.cgs_device, mmACP_STATUS);473if (val & (u32) 0x1)474break;475if (--count == 0) {476dev_err(&adev->pdev->dev, "Failed to reset ACP\n");477r = -ETIMEDOUT;478goto failure;479}480udelay(100);481}482/* Deassert the SOFT RESET flags */483val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);484val &= ~ACP_SOFT_RESET__SoftResetAud_MASK;485cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);486return 0;487488failure:489kfree(i2s_pdata);490kfree(adev->acp.acp_res);491kfree(adev->acp.acp_cell);492kfree(adev->acp.acp_genpd);493return r;494}495496/**497* acp_hw_fini - stop the hardware block498*499* @ip_block: Pointer to the amdgpu_ip_block for this hw instance.500*501*/502static int acp_hw_fini(struct amdgpu_ip_block *ip_block)503{504u32 val = 0;505u32 count = 0;506struct amdgpu_device *adev = ip_block->adev;507508/* return early if no ACP */509if (!adev->acp.acp_genpd) {510amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, false, 0);511return 0;512}513514/* Assert Soft reset of ACP */515val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);516517val |= ACP_SOFT_RESET__SoftResetAud_MASK;518cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val);519520count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE;521while (true) {522val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET);523if (ACP_SOFT_RESET__SoftResetAudDone_MASK ==524(val & ACP_SOFT_RESET__SoftResetAudDone_MASK))525break;526if (--count == 0) {527dev_err(&adev->pdev->dev, "Failed to reset ACP\n");528return -ETIMEDOUT;529}530udelay(100);531}532/* Disable ACP clock */533val = cgs_read_register(adev->acp.cgs_device, mmACP_CONTROL);534val &= ~ACP_CONTROL__ClkEn_MASK;535cgs_write_register(adev->acp.cgs_device, mmACP_CONTROL, val);536537count = ACP_CLOCK_EN_TIME_OUT_VALUE;538539while (true) {540val = cgs_read_register(adev->acp.cgs_device, mmACP_STATUS);541if (val & (u32) 0x1)542break;543if (--count == 0) {544dev_err(&adev->pdev->dev, "Failed to reset ACP\n");545return -ETIMEDOUT;546}547udelay(100);548}549550device_for_each_child(adev->acp.parent, NULL,551acp_genpd_remove_device);552553mfd_remove_devices(adev->acp.parent);554kfree(adev->acp.acp_res);555kfree(adev->acp.acp_genpd);556kfree(adev->acp.acp_cell);557558return 0;559}560561static int acp_suspend(struct amdgpu_ip_block *ip_block)562{563struct amdgpu_device *adev = ip_block->adev;564565/* power up on suspend */566if (!adev->acp.acp_cell)567amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, false, 0);568return 0;569}570571static int acp_resume(struct amdgpu_ip_block *ip_block)572{573struct amdgpu_device *adev = ip_block->adev;574575/* power down again on resume */576if (!adev->acp.acp_cell)577amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, true, 0);578return 0;579}580581static bool acp_is_idle(struct amdgpu_ip_block *ip_block)582{583return true;584}585586static int acp_set_clockgating_state(struct amdgpu_ip_block *ip_block,587enum amd_clockgating_state state)588{589return 0;590}591592static int acp_set_powergating_state(struct amdgpu_ip_block *ip_block,593enum amd_powergating_state state)594{595struct amdgpu_device *adev = ip_block->adev;596bool enable = (state == AMD_PG_STATE_GATE);597598amdgpu_dpm_set_powergating_by_smu(adev, AMD_IP_BLOCK_TYPE_ACP, enable, 0);599600return 0;601}602603static const struct amd_ip_funcs acp_ip_funcs = {604.name = "acp_ip",605.sw_init = acp_sw_init,606.sw_fini = acp_sw_fini,607.hw_init = acp_hw_init,608.hw_fini = acp_hw_fini,609.suspend = acp_suspend,610.resume = acp_resume,611.is_idle = acp_is_idle,612.set_clockgating_state = acp_set_clockgating_state,613.set_powergating_state = acp_set_powergating_state,614};615616const struct amdgpu_ip_block_version acp_ip_block = {617.type = AMD_IP_BLOCK_TYPE_ACP,618.major = 2,619.minor = 2,620.rev = 0,621.funcs = &acp_ip_funcs,622};623624625