Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 37c5f2c9 authored by Akshu Agrawal's avatar Akshu Agrawal Committed by Alex Deucher
Browse files

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: default avatarAkshu Agrawal <akshu.agrawal@amd.com>
Reviewed-on: https://chromium-review.googlesource.com/670207


Reviewed-by: default avatarJason Clinton <jclinton@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/676628


Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent e477e940
Loading
Loading
Loading
Loading
+124 −35
Original line number Original line Diff line number Diff line
@@ -67,6 +67,15 @@
#define mmACP_MEM_SHUT_DOWN_STS_LO		0x51fa
#define mmACP_MEM_SHUT_DOWN_STS_LO		0x51fa
#define mmACP_MEM_SHUT_DOWN_STS_HI		0x51fb
#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_TIMEOUT_LOOP			0x000000FF
#define ACP_DEVS				3
#define ACP_DEVS				3
#define ACP_SRC_ID				162
#define ACP_SRC_ID				162
@@ -260,6 +269,8 @@ static int acp_hw_init(void *handle)
{
{
	int r, i;
	int r, i;
	uint64_t acp_base;
	uint64_t acp_base;
	u32 val = 0;
	u32 count = 0;
	struct device *dev;
	struct device *dev;
	struct i2s_platform_data *i2s_pdata;
	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;
	return 0;
}
}


@@ -412,6 +463,8 @@ static int acp_hw_init(void *handle)
static int acp_hw_fini(void *handle)
static int acp_hw_fini(void *handle)
{
{
	int i, ret;
	int i, ret;
	u32 val = 0;
	u32 count = 0;
	struct device *dev;
	struct device *dev;
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;


@@ -419,6 +472,42 @@ static int acp_hw_fini(void *handle)
	if (!adev->acp.acp_cell)
	if (!adev->acp.acp_cell)
		return 0;
		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) {
	if (adev->acp.acp_genpd) {
		for (i = 0; i < ACP_DEVS ; i++) {
		for (i = 0; i < ACP_DEVS ; i++) {
			dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
			dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);