diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2144-drm-amd-amdgpu-Enabling-ACP-clock-in-hw_init-v2.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2144-drm-amd-amdgpu-Enabling-ACP-clock-in-hw_init-v2.patch | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2144-drm-amd-amdgpu-Enabling-ACP-clock-in-hw_init-v2.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2144-drm-amd-amdgpu-Enabling-ACP-clock-in-hw_init-v2.patch new file mode 100644 index 00000000..fe5bcad7 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71/2144-drm-amd-amdgpu-Enabling-ACP-clock-in-hw_init-v2.patch @@ -0,0 +1,231 @@ +From 5c629ed5ca09acf371f19e2aac2f34bbe7692cdf Mon Sep 17 00:00:00 2001 +From: Akshu Agrawal <akshu.agrawal@amd.com> +Date: Mon, 18 Sep 2017 12:26:07 +0530 +Subject: [PATCH 2144/4131] drm/amd/amdgpu: Enabling ACP clock in hw_init (v2) + +Enabling of ACP in hw_init does away with requirement of order +of probe on designware_i2s and acp dma driver. designware_i2s +reads i2s registers and this use to fail if acp dma driver was not probed +prior to it. + +BUG=:b:62103837 +TEST=modprobe snd-soc-acp-pcm +modprobe snd-soc-acp-rt5645-mach +aplay -l +**** List of PLAYBACK Hardware Devices **** +card 0: acprt5650 [acprt5650], device 0: RT5645_AIF1 rt5645-aif1-0 [] + Subdevices: 1/1 + Subdevice #0: subdevice #0 + +v2: use proper device in dev_err to fix warnings (Alex) + +Signed-off-by: Akshu Agrawal <akshu.agrawal@amd.com> +Reviewed-on: https://chromium-review.googlesource.com/670207 +Reviewed-by: Jason Clinton <jclinton@chromium.org> +Reviewed-on: https://chromium-review.googlesource.com/676628 +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 159 +++++++++++++++++++++++++------- + 1 file changed, 124 insertions(+), 35 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +index ebca223..08eb67d 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +@@ -35,41 +35,50 @@ + + #include "acp_gfx_if.h" + +-#define ACP_TILE_ON_MASK 0x03 +-#define ACP_TILE_OFF_MASK 0x02 +-#define ACP_TILE_ON_RETAIN_REG_MASK 0x1f +-#define ACP_TILE_OFF_RETAIN_REG_MASK 0x20 +- +-#define ACP_TILE_P1_MASK 0x3e +-#define ACP_TILE_P2_MASK 0x3d +-#define ACP_TILE_DSP0_MASK 0x3b +-#define ACP_TILE_DSP1_MASK 0x37 +- +-#define ACP_TILE_DSP2_MASK 0x2f +- +-#define ACP_DMA_REGS_END 0x146c0 +-#define ACP_I2S_PLAY_REGS_START 0x14840 +-#define ACP_I2S_PLAY_REGS_END 0x148b4 +-#define ACP_I2S_CAP_REGS_START 0x148b8 +-#define ACP_I2S_CAP_REGS_END 0x1496c +- +-#define ACP_I2S_COMP1_CAP_REG_OFFSET 0xac +-#define ACP_I2S_COMP2_CAP_REG_OFFSET 0xa8 +-#define ACP_I2S_COMP1_PLAY_REG_OFFSET 0x6c +-#define ACP_I2S_COMP2_PLAY_REG_OFFSET 0x68 +- +-#define mmACP_PGFSM_RETAIN_REG 0x51c9 +-#define mmACP_PGFSM_CONFIG_REG 0x51ca +-#define mmACP_PGFSM_READ_REG_0 0x51cc +- +-#define mmACP_MEM_SHUT_DOWN_REQ_LO 0x51f8 +-#define mmACP_MEM_SHUT_DOWN_REQ_HI 0x51f9 +-#define mmACP_MEM_SHUT_DOWN_STS_LO 0x51fa +-#define mmACP_MEM_SHUT_DOWN_STS_HI 0x51fb +- +-#define ACP_TIMEOUT_LOOP 0x000000FF +-#define ACP_DEVS 3 +-#define ACP_SRC_ID 162 ++#define ACP_TILE_ON_MASK 0x03 ++#define ACP_TILE_OFF_MASK 0x02 ++#define ACP_TILE_ON_RETAIN_REG_MASK 0x1f ++#define ACP_TILE_OFF_RETAIN_REG_MASK 0x20 ++ ++#define ACP_TILE_P1_MASK 0x3e ++#define ACP_TILE_P2_MASK 0x3d ++#define ACP_TILE_DSP0_MASK 0x3b ++#define ACP_TILE_DSP1_MASK 0x37 ++ ++#define ACP_TILE_DSP2_MASK 0x2f ++ ++#define ACP_DMA_REGS_END 0x146c0 ++#define ACP_I2S_PLAY_REGS_START 0x14840 ++#define ACP_I2S_PLAY_REGS_END 0x148b4 ++#define ACP_I2S_CAP_REGS_START 0x148b8 ++#define ACP_I2S_CAP_REGS_END 0x1496c ++ ++#define ACP_I2S_COMP1_CAP_REG_OFFSET 0xac ++#define ACP_I2S_COMP2_CAP_REG_OFFSET 0xa8 ++#define ACP_I2S_COMP1_PLAY_REG_OFFSET 0x6c ++#define ACP_I2S_COMP2_PLAY_REG_OFFSET 0x68 ++ ++#define mmACP_PGFSM_RETAIN_REG 0x51c9 ++#define mmACP_PGFSM_CONFIG_REG 0x51ca ++#define mmACP_PGFSM_READ_REG_0 0x51cc ++ ++#define mmACP_MEM_SHUT_DOWN_REQ_LO 0x51f8 ++#define mmACP_MEM_SHUT_DOWN_REQ_HI 0x51f9 ++#define mmACP_MEM_SHUT_DOWN_STS_LO 0x51fa ++#define mmACP_MEM_SHUT_DOWN_STS_HI 0x51fb ++ ++#define mmACP_CONTROL 0x5131 ++#define mmACP_STATUS 0x5133 ++#define mmACP_SOFT_RESET 0x5134 ++#define ACP_CONTROL__ClkEn_MASK 0x1 ++#define ACP_SOFT_RESET__SoftResetAud_MASK 0x100 ++#define ACP_SOFT_RESET__SoftResetAudDone_MASK 0x1000000 ++#define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF ++#define ACP_SOFT_RESET_DONE_TIME_OUT_VALUE 0x000000FF ++ ++#define ACP_TIMEOUT_LOOP 0x000000FF ++#define ACP_DEVS 3 ++#define ACP_SRC_ID 162 + + enum { + ACP_TILE_P1 = 0, +@@ -260,6 +269,8 @@ static int acp_hw_init(void *handle) + { + int r, i; + uint64_t acp_base; ++ u32 val = 0; ++ u32 count = 0; + struct device *dev; + struct i2s_platform_data *i2s_pdata; + +@@ -401,6 +412,46 @@ static int acp_hw_init(void *handle) + } + } + } ++ ++ /* Assert Soft reset of ACP */ ++ val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); ++ ++ val |= ACP_SOFT_RESET__SoftResetAud_MASK; ++ cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); ++ ++ count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE; ++ while (true) { ++ val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); ++ if (ACP_SOFT_RESET__SoftResetAudDone_MASK == ++ (val & ACP_SOFT_RESET__SoftResetAudDone_MASK)) ++ break; ++ if (--count == 0) { ++ dev_err(&adev->pdev->dev, "Failed to reset ACP\n"); ++ return -ETIMEDOUT; ++ } ++ udelay(100); ++ } ++ /* Enable clock to ACP and wait until the clock is enabled */ ++ val = cgs_read_register(adev->acp.cgs_device, mmACP_CONTROL); ++ val = val | ACP_CONTROL__ClkEn_MASK; ++ cgs_write_register(adev->acp.cgs_device, mmACP_CONTROL, val); ++ ++ count = ACP_CLOCK_EN_TIME_OUT_VALUE; ++ ++ while (true) { ++ val = cgs_read_register(adev->acp.cgs_device, mmACP_STATUS); ++ if (val & (u32) 0x1) ++ break; ++ if (--count == 0) { ++ dev_err(&adev->pdev->dev, "Failed to reset ACP\n"); ++ return -ETIMEDOUT; ++ } ++ udelay(100); ++ } ++ /* Deassert the SOFT RESET flags */ ++ val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); ++ val &= ~ACP_SOFT_RESET__SoftResetAud_MASK; ++ cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); + + return 0; + } +@@ -414,6 +465,8 @@ static int acp_hw_init(void *handle) + static int acp_hw_fini(void *handle) + { + int i, ret; ++ u32 val = 0; ++ u32 count = 0; + struct device *dev; + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + +@@ -421,6 +474,42 @@ static int acp_hw_fini(void *handle) + if (!adev->acp.acp_cell) + return 0; + ++ /* Assert Soft reset of ACP */ ++ val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); ++ ++ val |= ACP_SOFT_RESET__SoftResetAud_MASK; ++ cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); ++ ++ count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE; ++ while (true) { ++ val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); ++ if (ACP_SOFT_RESET__SoftResetAudDone_MASK == ++ (val & ACP_SOFT_RESET__SoftResetAudDone_MASK)) ++ break; ++ if (--count == 0) { ++ dev_err(&adev->pdev->dev, "Failed to reset ACP\n"); ++ return -ETIMEDOUT; ++ } ++ udelay(100); ++ } ++ /* Disable ACP clock */ ++ val = cgs_read_register(adev->acp.cgs_device, mmACP_CONTROL); ++ val &= ~ACP_CONTROL__ClkEn_MASK; ++ cgs_write_register(adev->acp.cgs_device, mmACP_CONTROL, val); ++ ++ count = ACP_CLOCK_EN_TIME_OUT_VALUE; ++ ++ while (true) { ++ val = cgs_read_register(adev->acp.cgs_device, mmACP_STATUS); ++ if (val & (u32) 0x1) ++ break; ++ if (--count == 0) { ++ dev_err(&adev->pdev->dev, "Failed to reset ACP\n"); ++ return -ETIMEDOUT; ++ } ++ udelay(100); ++ } ++ + if (adev->acp.acp_genpd) { + for (i = 0; i < ACP_DEVS ; i++) { + dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); +-- +2.7.4 + |