diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | 72 |
1 files changed, 46 insertions, 26 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c index 06879d1dcabd..a52795d9b458 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c | |||
@@ -285,19 +285,20 @@ static int acp_hw_init(void *handle) | |||
285 | return 0; | 285 | return 0; |
286 | else if (r) | 286 | else if (r) |
287 | return r; | 287 | return r; |
288 | if (adev->asic_type != CHIP_STONEY) { | ||
289 | adev->acp.acp_genpd = kzalloc(sizeof(struct acp_pm_domain), GFP_KERNEL); | ||
290 | if (adev->acp.acp_genpd == NULL) | ||
291 | return -ENOMEM; | ||
288 | 292 | ||
289 | adev->acp.acp_genpd = kzalloc(sizeof(struct acp_pm_domain), GFP_KERNEL); | 293 | adev->acp.acp_genpd->gpd.name = "ACP_AUDIO"; |
290 | if (adev->acp.acp_genpd == NULL) | 294 | adev->acp.acp_genpd->gpd.power_off = acp_poweroff; |
291 | return -ENOMEM; | 295 | adev->acp.acp_genpd->gpd.power_on = acp_poweron; |
292 | |||
293 | adev->acp.acp_genpd->gpd.name = "ACP_AUDIO"; | ||
294 | adev->acp.acp_genpd->gpd.power_off = acp_poweroff; | ||
295 | adev->acp.acp_genpd->gpd.power_on = acp_poweron; | ||
296 | 296 | ||
297 | 297 | ||
298 | adev->acp.acp_genpd->cgs_dev = adev->acp.cgs_device; | 298 | adev->acp.acp_genpd->cgs_dev = adev->acp.cgs_device; |
299 | 299 | ||
300 | pm_genpd_init(&adev->acp.acp_genpd->gpd, NULL, false); | 300 | pm_genpd_init(&adev->acp.acp_genpd->gpd, NULL, false); |
301 | } | ||
301 | 302 | ||
302 | adev->acp.acp_cell = kzalloc(sizeof(struct mfd_cell) * ACP_DEVS, | 303 | adev->acp.acp_cell = kzalloc(sizeof(struct mfd_cell) * ACP_DEVS, |
303 | GFP_KERNEL); | 304 | GFP_KERNEL); |
@@ -319,14 +320,29 @@ static int acp_hw_init(void *handle) | |||
319 | return -ENOMEM; | 320 | return -ENOMEM; |
320 | } | 321 | } |
321 | 322 | ||
322 | i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET; | 323 | switch (adev->asic_type) { |
324 | case CHIP_STONEY: | ||
325 | i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET | | ||
326 | DW_I2S_QUIRK_16BIT_IDX_OVERRIDE; | ||
327 | break; | ||
328 | default: | ||
329 | i2s_pdata[0].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET; | ||
330 | } | ||
323 | i2s_pdata[0].cap = DWC_I2S_PLAY; | 331 | i2s_pdata[0].cap = DWC_I2S_PLAY; |
324 | i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000; | 332 | i2s_pdata[0].snd_rates = SNDRV_PCM_RATE_8000_96000; |
325 | i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_PLAY_REG_OFFSET; | 333 | i2s_pdata[0].i2s_reg_comp1 = ACP_I2S_COMP1_PLAY_REG_OFFSET; |
326 | i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_PLAY_REG_OFFSET; | 334 | i2s_pdata[0].i2s_reg_comp2 = ACP_I2S_COMP2_PLAY_REG_OFFSET; |
335 | switch (adev->asic_type) { | ||
336 | case CHIP_STONEY: | ||
337 | i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET | | ||
338 | DW_I2S_QUIRK_COMP_PARAM1 | | ||
339 | DW_I2S_QUIRK_16BIT_IDX_OVERRIDE; | ||
340 | break; | ||
341 | default: | ||
342 | i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET | | ||
343 | DW_I2S_QUIRK_COMP_PARAM1; | ||
344 | } | ||
327 | 345 | ||
328 | i2s_pdata[1].quirks = DW_I2S_QUIRK_COMP_REG_OFFSET | | ||
329 | DW_I2S_QUIRK_COMP_PARAM1; | ||
330 | i2s_pdata[1].cap = DWC_I2S_RECORD; | 346 | i2s_pdata[1].cap = DWC_I2S_RECORD; |
331 | i2s_pdata[1].snd_rates = SNDRV_PCM_RATE_8000_96000; | 347 | i2s_pdata[1].snd_rates = SNDRV_PCM_RATE_8000_96000; |
332 | i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET; | 348 | i2s_pdata[1].i2s_reg_comp1 = ACP_I2S_COMP1_CAP_REG_OFFSET; |
@@ -373,12 +389,14 @@ static int acp_hw_init(void *handle) | |||
373 | if (r) | 389 | if (r) |
374 | return r; | 390 | return r; |
375 | 391 | ||
376 | for (i = 0; i < ACP_DEVS ; i++) { | 392 | if (adev->asic_type != CHIP_STONEY) { |
377 | dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); | 393 | for (i = 0; i < ACP_DEVS ; i++) { |
378 | r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev); | 394 | dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); |
379 | if (r) { | 395 | r = pm_genpd_add_device(&adev->acp.acp_genpd->gpd, dev); |
380 | dev_err(dev, "Failed to add dev to genpd\n"); | 396 | if (r) { |
381 | return r; | 397 | dev_err(dev, "Failed to add dev to genpd\n"); |
398 | return r; | ||
399 | } | ||
382 | } | 400 | } |
383 | } | 401 | } |
384 | 402 | ||
@@ -398,20 +416,22 @@ static int acp_hw_fini(void *handle) | |||
398 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; | 416 | struct amdgpu_device *adev = (struct amdgpu_device *)handle; |
399 | 417 | ||
400 | /* return early if no ACP */ | 418 | /* return early if no ACP */ |
401 | if (!adev->acp.acp_genpd) | 419 | if (!adev->acp.acp_cell) |
402 | return 0; | 420 | return 0; |
403 | 421 | ||
404 | for (i = 0; i < ACP_DEVS ; i++) { | 422 | if (adev->acp.acp_genpd) { |
405 | dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); | 423 | for (i = 0; i < ACP_DEVS ; i++) { |
406 | ret = pm_genpd_remove_device(&adev->acp.acp_genpd->gpd, dev); | 424 | dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i); |
407 | /* If removal fails, dont giveup and try rest */ | 425 | ret = pm_genpd_remove_device(&adev->acp.acp_genpd->gpd, dev); |
408 | if (ret) | 426 | /* If removal fails, dont giveup and try rest */ |
409 | dev_err(dev, "remove dev from genpd failed\n"); | 427 | if (ret) |
428 | dev_err(dev, "remove dev from genpd failed\n"); | ||
429 | } | ||
430 | kfree(adev->acp.acp_genpd); | ||
410 | } | 431 | } |
411 | 432 | ||
412 | mfd_remove_devices(adev->acp.parent); | 433 | mfd_remove_devices(adev->acp.parent); |
413 | kfree(adev->acp.acp_res); | 434 | kfree(adev->acp.acp_res); |
414 | kfree(adev->acp.acp_genpd); | ||
415 | kfree(adev->acp.acp_cell); | 435 | kfree(adev->acp.acp_cell); |
416 | 436 | ||
417 | return 0; | 437 | return 0; |