forked from Minki/linux
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=🅱️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>
This commit is contained in:
parent
e477e940da
commit
37c5f2c99a
@ -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_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_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_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_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 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_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_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 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;
|
||||
|
||||
@ -400,6 +411,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;
|
||||
}
|
||||
|
||||
@ -412,6 +463,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;
|
||||
|
||||
@ -419,6 +472,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);
|
||||
|
Loading…
Reference in New Issue
Block a user