diff options
author | Akshu Agrawal <akshu.agrawal@amd.com> | 2017-09-18 02:56:07 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2017-11-03 15:44:46 -0400 |
commit | 37c5f2c99adf63adf13f1ca309a1ffce25c5589a (patch) | |
tree | bcd946fc22f5eeafbf717fe30a1c323763bea586 /drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | |
parent | e477e940dad1836c6f6d23353e424665b9316b6e (diff) |
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>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 159 |
1 files 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 a52795d9b458..023bfdb3e63f 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | |||
@@ -35,41 +35,50 @@ | |||
35 | 35 | ||
36 | #include "acp_gfx_if.h" | 36 | #include "acp_gfx_if.h" |
37 | 37 | ||
38 | #define ACP_TILE_ON_MASK 0x03 | 38 | #define ACP_TILE_ON_MASK 0x03 |
39 | #define ACP_TILE_OFF_MASK 0x02 | 39 | #define ACP_TILE_OFF_MASK 0x02 |
40 | #define ACP_TILE_ON_RETAIN_REG_MASK 0x1f | 40 | #define ACP_TILE_ON_RETAIN_REG_MASK 0x1f |
41 | #define ACP_TILE_OFF_RETAIN_REG_MASK 0x20 | 41 | #define ACP_TILE_OFF_RETAIN_REG_MASK 0x20 |
42 | 42 | ||
43 | #define ACP_TILE_P1_MASK 0x3e | 43 | #define ACP_TILE_P1_MASK 0x3e |
44 | #define ACP_TILE_P2_MASK 0x3d | 44 | #define ACP_TILE_P2_MASK 0x3d |
45 | #define ACP_TILE_DSP0_MASK 0x3b | 45 | #define ACP_TILE_DSP0_MASK 0x3b |
46 | #define ACP_TILE_DSP1_MASK 0x37 | 46 | #define ACP_TILE_DSP1_MASK 0x37 |
47 | 47 | ||
48 | #define ACP_TILE_DSP2_MASK 0x2f | 48 | #define ACP_TILE_DSP2_MASK 0x2f |
49 | 49 | ||
50 | #define ACP_DMA_REGS_END 0x146c0 | 50 | #define ACP_DMA_REGS_END 0x146c0 |
51 | #define ACP_I2S_PLAY_REGS_START 0x14840 | 51 | #define ACP_I2S_PLAY_REGS_START 0x14840 |
52 | #define ACP_I2S_PLAY_REGS_END 0x148b4 | 52 | #define ACP_I2S_PLAY_REGS_END 0x148b4 |
53 | #define ACP_I2S_CAP_REGS_START 0x148b8 | 53 | #define ACP_I2S_CAP_REGS_START 0x148b8 |
54 | #define ACP_I2S_CAP_REGS_END 0x1496c | 54 | #define ACP_I2S_CAP_REGS_END 0x1496c |
55 | 55 | ||
56 | #define ACP_I2S_COMP1_CAP_REG_OFFSET 0xac | 56 | #define ACP_I2S_COMP1_CAP_REG_OFFSET 0xac |
57 | #define ACP_I2S_COMP2_CAP_REG_OFFSET 0xa8 | 57 | #define ACP_I2S_COMP2_CAP_REG_OFFSET 0xa8 |
58 | #define ACP_I2S_COMP1_PLAY_REG_OFFSET 0x6c | 58 | #define ACP_I2S_COMP1_PLAY_REG_OFFSET 0x6c |
59 | #define ACP_I2S_COMP2_PLAY_REG_OFFSET 0x68 | 59 | #define ACP_I2S_COMP2_PLAY_REG_OFFSET 0x68 |
60 | 60 | ||
61 | #define mmACP_PGFSM_RETAIN_REG 0x51c9 | 61 | #define mmACP_PGFSM_RETAIN_REG 0x51c9 |
62 | #define mmACP_PGFSM_CONFIG_REG 0x51ca | 62 | #define mmACP_PGFSM_CONFIG_REG 0x51ca |
63 | #define mmACP_PGFSM_READ_REG_0 0x51cc | 63 | #define mmACP_PGFSM_READ_REG_0 0x51cc |
64 | 64 | ||
65 | #define mmACP_MEM_SHUT_DOWN_REQ_LO 0x51f8 | 65 | #define mmACP_MEM_SHUT_DOWN_REQ_LO 0x51f8 |
66 | #define mmACP_MEM_SHUT_DOWN_REQ_HI 0x51f9 | 66 | #define mmACP_MEM_SHUT_DOWN_REQ_HI 0x51f9 |
67 | #define mmACP_MEM_SHUT_DOWN_STS_LO 0x51fa | 67 | #define mmACP_MEM_SHUT_DOWN_STS_LO 0x51fa |
68 | #define mmACP_MEM_SHUT_DOWN_STS_HI 0x51fb | 68 | #define mmACP_MEM_SHUT_DOWN_STS_HI 0x51fb |
69 | 69 | ||
70 | #define ACP_TIMEOUT_LOOP 0x000000FF | 70 | #define mmACP_CONTROL 0x5131 |
71 | #define ACP_DEVS 3 | 71 | #define mmACP_STATUS 0x5133 |
72 | #define ACP_SRC_ID 162 | 72 | #define mmACP_SOFT_RESET 0x5134 |
73 | #define ACP_CONTROL__ClkEn_MASK 0x1 | ||
74 | #define ACP_SOFT_RESET__SoftResetAud_MASK 0x100 | ||
75 | #define ACP_SOFT_RESET__SoftResetAudDone_MASK 0x1000000 | ||
76 | #define ACP_CLOCK_EN_TIME_OUT_VALUE 0x000000FF | ||
77 | #define ACP_SOFT_RESET_DONE_TIME_OUT_VALUE 0x000000FF | ||
78 | |||
79 | #define ACP_TIMEOUT_LOOP 0x000000FF | ||
80 | #define ACP_DEVS 3 | ||
81 | #define ACP_SRC_ID 162 | ||
73 | 82 | ||
74 | enum { | 83 | enum { |
75 | ACP_TILE_P1 = 0, | 84 | ACP_TILE_P1 = 0, |
@@ -260,6 +269,8 @@ static int acp_hw_init(void *handle) | |||
260 | { | 269 | { |
261 | int r, i; | 270 | int r, i; |
262 | uint64_t acp_base; | 271 | uint64_t acp_base; |
272 | u32 val = 0; | ||
273 | u32 count = 0; | ||
263 | struct device *dev; | 274 | struct device *dev; |
264 | struct i2s_platform_data *i2s_pdata; | 275 | struct i2s_platform_data *i2s_pdata; |
265 | 276 | ||
@@ -400,6 +411,46 @@ static int acp_hw_init(void *handle) | |||
400 | } | 411 | } |
401 | } | 412 | } |
402 | 413 | ||
414 | /* Assert Soft reset of ACP */ | ||
415 | val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); | ||
416 | |||
417 | val |= ACP_SOFT_RESET__SoftResetAud_MASK; | ||
418 | cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); | ||
419 | |||
420 | count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE; | ||
421 | while (true) { | ||
422 | val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); | ||
423 | if (ACP_SOFT_RESET__SoftResetAudDone_MASK == | ||
424 | (val & ACP_SOFT_RESET__SoftResetAudDone_MASK)) | ||
425 | break; | ||
426 | if (--count == 0) { | ||
427 | dev_err(&adev->pdev->dev, "Failed to reset ACP\n"); | ||
428 | return -ETIMEDOUT; | ||
429 | } | ||
430 | udelay(100); | ||
431 | } | ||
432 | /* Enable clock to ACP and wait until the clock is enabled */ | ||
433 | val = cgs_read_register(adev->acp.cgs_device, mmACP_CONTROL); | ||
434 | val = val | ACP_CONTROL__ClkEn_MASK; | ||
435 | cgs_write_register(adev->acp.cgs_device, mmACP_CONTROL, val); | ||
436 | |||
437 | count = ACP_CLOCK_EN_TIME_OUT_VALUE; | ||
438 | |||
439 | while (true) { | ||
440 | val = cgs_read_register(adev->acp.cgs_device, mmACP_STATUS); | ||
441 | if (val & (u32) 0x1) | ||
442 | break; | ||
443 | if (--count == 0) { | ||
444 | dev_err(&adev->pdev->dev, "Failed to reset ACP\n"); | ||
445 | return -ETIMEDOUT; | ||
446 | } | ||
447 | udelay(100); | ||
448 | } | ||
449 | /* Deassert the SOFT RESET flags */ | ||
450 | val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); | ||
451 | val &= ~ACP_SOFT_RESET__SoftResetAud_MASK; | ||
452 | cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); | ||
453 | |||
403 | return 0; | 454 | return 0; |
404 | } | 455 | } |
405 | 456 | ||
@@ -412,6 +463,8 @@ static int acp_hw_init(void *handle) | |||
412 | static int acp_hw_fini(void *handle) | 463 | static int acp_hw_fini(void *handle) |
413 | { | 464 | { |
414 | int i, ret; | 465 | int i, ret; |
466 | u32 val = 0; | ||
467 | u32 count = 0; | ||
415 | struct device *dev; | 468 | struct device *dev; |
416 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 469 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
417 | 470 | ||
@@ -419,6 +472,42 @@ static int acp_hw_fini(void *handle) | |||
419 | if (!adev->acp.acp_cell) | 472 | if (!adev->acp.acp_cell) |
420 | return 0; | 473 | return 0; |
421 | 474 | ||
475 | /* Assert Soft reset of ACP */ | ||
476 | val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); | ||
477 | |||
478 | val |= ACP_SOFT_RESET__SoftResetAud_MASK; | ||
479 | cgs_write_register(adev->acp.cgs_device, mmACP_SOFT_RESET, val); | ||
480 | |||
481 | count = ACP_SOFT_RESET_DONE_TIME_OUT_VALUE; | ||
482 | while (true) { | ||
483 | val = cgs_read_register(adev->acp.cgs_device, mmACP_SOFT_RESET); | ||
484 | if (ACP_SOFT_RESET__SoftResetAudDone_MASK == | ||
485 | (val & ACP_SOFT_RESET__SoftResetAudDone_MASK)) | ||
486 | break; | ||
487 | if (--count == 0) { | ||
488 | dev_err(&adev->pdev->dev, "Failed to reset ACP\n"); | ||
489 | return -ETIMEDOUT; | ||
490 | } | ||
491 | udelay(100); | ||
492 | } | ||
493 | /* Disable ACP clock */ | ||
494 | val = cgs_read_register(adev->acp.cgs_device, mmACP_CONTROL); | ||
495 | val &= ~ACP_CONTROL__ClkEn_MASK; | ||
496 | cgs_write_register(adev->acp.cgs_device, mmACP_CONTROL, val); | ||
497 | |||
498 | count = ACP_CLOCK_EN_TIME_OUT_VALUE; | ||
499 | |||
500 | while (true) { | ||
501 | val = cgs_read_register(adev->acp.cgs_device, mmACP_STATUS); | ||
502 | if (val & (u32) 0x1) | ||
503 | break; | ||
504 | if (--count == 0) { | ||
505 | dev_err(&adev->pdev->dev, "Failed to reset ACP\n"); | ||
506 | return -ETIMEDOUT; | ||
507 | } | ||
508 | udelay(100); | ||
509 | } | ||
510 | |||
422 | if (adev->acp.acp_genpd) { | 511 | if (adev->acp.acp_genpd) { |
423 | for (i = 0; i < ACP_DEVS ; i++) { | 512 | for (i = 0; i < ACP_DEVS ; i++) { |
424 | dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); | 513 | dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); |