Skip to content

Commit fe65ce8

Browse files
committed
ASoC: SOF: amd: add soundwire IO support for ACP7.0 &
Merge series from Vijendar Mukunda <[email protected]>: This patch series contains - ACP sof stack improvements - Add support for ACP7.1 platform. - Soundwire IO support for ACP7.0 & ACP7.1 platforms Link: thesofproject#5392
2 parents d85d055 + e68074c commit fe65ce8

File tree

5 files changed

+148
-19
lines changed

5 files changed

+148
-19
lines changed

sound/soc/sof/amd/Kconfig

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,14 @@ config SND_SOC_SOF_AMD_ACP63
9494
If unsure select "N".
9595

9696
config SND_SOC_SOF_AMD_ACP70
97-
tristate "SOF support for ACP7.0 platform"
97+
tristate "SOF support for ACP7.0/ACP7.1 platforms"
9898
depends on SND_SOC_SOF_PCI
9999
depends on AMD_NODE
100100
select SND_SOC_SOF_AMD_COMMON
101+
select SND_SOC_SOF_AMD_SOUNDWIRE_LINK_BASELINE
101102
help
102103
Select this option for SOF support on
103-
AMD ACP7.0 version based platforms.
104-
Say Y if you want to enable SOF on ACP7.0 based platform.
104+
AMD ACP7.0/ACP7.1 version based platforms.
105+
Say Y if you want to enable SOF on ACP7.0/ACP7.1 based platforms.
105106

106107
endif

sound/soc/sof/amd/acp-dsp-offset.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,14 @@
130130

131131
#define ACP_SW0_EN 0x3000
132132
#define ACP_SW1_EN 0x3C00
133+
#define ACP70_PME_EN 0x1400
134+
#define ACP70_EXTERNAL_INTR_CNTL1 0x1A08
135+
#define ACP70_SW0_WAKE_EN 0x1458
136+
#define ACP70_SW1_WAKE_EN 0x1460
137+
#define ACP70_SDW_HOST_WAKE_MASK 0x0C00000
138+
#define ACP70_SDW0_HOST_WAKE_STAT BIT(24)
139+
#define ACP70_SDW1_HOST_WAKE_STAT BIT(25)
140+
#define ACP70_SDW0_PME_STAT BIT(26)
141+
#define ACP70_SDW1_PME_STAT BIT(27)
142+
133143
#endif

sound/soc/sof/amd/acp.c

Lines changed: 118 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ static void init_dma_descriptor(struct acp_dev_data *adata)
5858

5959
switch (acp_data->pci_rev) {
6060
case ACP70_PCI_ID:
61+
case ACP71_PCI_ID:
6162
acp_dma_desc_base_addr = ACP70_DMA_DESC_BASE_ADDR;
6263
acp_dma_desc_max_num_dscr = ACP70_DMA_DESC_MAX_NUM_DSCR;
6364
break;
@@ -97,6 +98,7 @@ static int config_dma_channel(struct acp_dev_data *adata, unsigned int ch,
9798

9899
switch (acp_data->pci_rev) {
99100
case ACP70_PCI_ID:
101+
case ACP71_PCI_ID:
100102
acp_dma_cntl_0 = ACP70_DMA_CNTL_0;
101103
acp_dma_ch_rst_sts = ACP70_DMA_CH_RST_STS;
102104
acp_dma_dscr_err_sts_0 = ACP70_DMA_ERR_STS_0;
@@ -336,6 +338,7 @@ int acp_dma_status(struct acp_dev_data *adata, unsigned char ch)
336338

337339
switch (adata->pci_rev) {
338340
case ACP70_PCI_ID:
341+
case ACP71_PCI_ID:
339342
acp_dma_ch_sts = ACP70_DMA_CH_STS;
340343
break;
341344
default:
@@ -383,6 +386,69 @@ static int acp_memory_init(struct snd_sof_dev *sdev)
383386
return 0;
384387
}
385388

389+
static void amd_sof_handle_acp70_sdw_wake_event(struct acp_dev_data *adata)
390+
{
391+
struct amd_sdw_manager *amd_manager;
392+
393+
if (adata->acp70_sdw0_wake_event) {
394+
amd_manager = dev_get_drvdata(&adata->sdw->pdev[0]->dev);
395+
if (amd_manager)
396+
pm_request_resume(amd_manager->dev);
397+
adata->acp70_sdw0_wake_event = 0;
398+
}
399+
400+
if (adata->acp70_sdw1_wake_event) {
401+
amd_manager = dev_get_drvdata(&adata->sdw->pdev[1]->dev);
402+
if (amd_manager)
403+
pm_request_resume(amd_manager->dev);
404+
adata->acp70_sdw1_wake_event = 0;
405+
}
406+
}
407+
408+
static int amd_sof_check_and_handle_acp70_sdw_wake_irq(struct snd_sof_dev *sdev)
409+
{
410+
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
411+
struct acp_dev_data *adata = sdev->pdata->hw_pdata;
412+
u32 ext_intr_stat1;
413+
int irq_flag = 0;
414+
bool sdw_wake_irq = false;
415+
416+
ext_intr_stat1 = snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->ext_intr_stat1);
417+
if (ext_intr_stat1 & ACP70_SDW0_HOST_WAKE_STAT) {
418+
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat1,
419+
ACP70_SDW0_HOST_WAKE_STAT);
420+
adata->acp70_sdw0_wake_event = true;
421+
sdw_wake_irq = true;
422+
}
423+
424+
if (ext_intr_stat1 & ACP70_SDW1_HOST_WAKE_STAT) {
425+
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat1,
426+
ACP70_SDW1_HOST_WAKE_STAT);
427+
adata->acp70_sdw1_wake_event = true;
428+
sdw_wake_irq = true;
429+
}
430+
431+
if (ext_intr_stat1 & ACP70_SDW0_PME_STAT) {
432+
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP70_SW0_WAKE_EN, 0);
433+
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat1, ACP70_SDW0_PME_STAT);
434+
adata->acp70_sdw0_wake_event = true;
435+
sdw_wake_irq = true;
436+
}
437+
438+
if (ext_intr_stat1 & ACP70_SDW1_PME_STAT) {
439+
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP70_SW1_WAKE_EN, 0);
440+
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_stat1, ACP70_SDW1_PME_STAT);
441+
adata->acp70_sdw1_wake_event = true;
442+
sdw_wake_irq = true;
443+
}
444+
445+
if (sdw_wake_irq) {
446+
amd_sof_handle_acp70_sdw_wake_event(adata);
447+
irq_flag = 1;
448+
}
449+
return irq_flag;
450+
}
451+
386452
static irqreturn_t acp_irq_thread(int irq, void *context)
387453
{
388454
struct snd_sof_dev *sdev = context;
@@ -415,7 +481,7 @@ static irqreturn_t acp_irq_handler(int irq, void *dev_id)
415481
struct acp_dev_data *adata = sdev->pdata->hw_pdata;
416482
unsigned int base = desc->dsp_intr_base;
417483
unsigned int val;
418-
int irq_flag = 0;
484+
int irq_flag = 0, wake_irq_flag = 0;
419485

420486
val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET);
421487
if (val & ACP_DSP_TO_HOST_IRQ) {
@@ -453,8 +519,14 @@ static irqreturn_t acp_irq_handler(int irq, void *dev_id)
453519
schedule_work(&amd_manager->amd_sdw_irq_thread);
454520
irq_flag = 1;
455521
}
522+
switch (adata->pci_rev) {
523+
case ACP70_PCI_ID:
524+
case ACP71_PCI_ID:
525+
wake_irq_flag = amd_sof_check_and_handle_acp70_sdw_wake_irq(sdev);
526+
break;
527+
}
456528
}
457-
if (irq_flag)
529+
if (irq_flag || wake_irq_flag)
458530
return IRQ_HANDLED;
459531
else
460532
return IRQ_NONE;
@@ -486,6 +558,7 @@ static int acp_power_on(struct snd_sof_dev *sdev)
486558
acp_pgfsm_cntl_mask = ACP6X_PGFSM_CNTL_POWER_ON_MASK;
487559
break;
488560
case ACP70_PCI_ID:
561+
case ACP71_PCI_ID:
489562
acp_pgfsm_status_mask = ACP70_PGFSM_STATUS_MASK;
490563
acp_pgfsm_cntl_mask = ACP70_PGFSM_CNTL_POWER_ON_MASK;
491564
break;
@@ -507,7 +580,6 @@ static int acp_power_on(struct snd_sof_dev *sdev)
507580

508581
static int acp_reset(struct snd_sof_dev *sdev)
509582
{
510-
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
511583
unsigned int val;
512584
int ret;
513585

@@ -528,14 +600,6 @@ static int acp_reset(struct snd_sof_dev *sdev)
528600
if (ret < 0)
529601
dev_err(sdev->dev, "timeout in releasing reset\n");
530602

531-
if (desc->acp_clkmux_sel)
532-
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->acp_clkmux_sel, ACP_CLOCK_ACLK);
533-
534-
if (desc->ext_intr_enb)
535-
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_enb, 0x01);
536-
537-
if (desc->ext_intr_cntl)
538-
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_cntl, ACP_ERROR_IRQ_MASK);
539603
return ret;
540604
}
541605

@@ -566,9 +630,13 @@ static int acp_dsp_reset(struct snd_sof_dev *sdev)
566630

567631
static int acp_init(struct snd_sof_dev *sdev)
568632
{
633+
const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
634+
struct acp_dev_data *acp_data;
635+
unsigned int sdw0_wake_en, sdw1_wake_en;
569636
int ret;
570637

571638
/* power on */
639+
acp_data = sdev->pdata->hw_pdata;
572640
ret = acp_power_on(sdev);
573641
if (ret) {
574642
dev_err(sdev->dev, "ACP power on failed\n");
@@ -577,7 +645,32 @@ static int acp_init(struct snd_sof_dev *sdev)
577645

578646
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_CONTROL, 0x01);
579647
/* Reset */
580-
return acp_reset(sdev);
648+
ret = acp_reset(sdev);
649+
if (ret)
650+
return ret;
651+
652+
if (desc->acp_clkmux_sel)
653+
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->acp_clkmux_sel, ACP_CLOCK_ACLK);
654+
655+
if (desc->ext_intr_enb)
656+
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_enb, 0x01);
657+
658+
if (desc->ext_intr_cntl)
659+
snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->ext_intr_cntl, ACP_ERROR_IRQ_MASK);
660+
661+
switch (acp_data->pci_rev) {
662+
case ACP70_PCI_ID:
663+
case ACP71_PCI_ID:
664+
sdw0_wake_en = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP70_SW0_WAKE_EN);
665+
sdw1_wake_en = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP70_SW1_WAKE_EN);
666+
if (sdw0_wake_en || sdw1_wake_en)
667+
snd_sof_dsp_update_bits(sdev, ACP_DSP_BAR, ACP70_EXTERNAL_INTR_CNTL1,
668+
ACP70_SDW_HOST_WAKE_MASK, ACP70_SDW_HOST_WAKE_MASK);
669+
670+
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP70_PME_EN, 1);
671+
break;
672+
}
673+
return 0;
581674
}
582675

583676
static bool check_acp_sdw_enable_status(struct snd_sof_dev *sdev)
@@ -616,8 +709,12 @@ int amd_sof_acp_suspend(struct snd_sof_dev *sdev, u32 target_state)
616709
dev_err(sdev->dev, "ACP Reset failed\n");
617710
return ret;
618711
}
619-
if (acp_data->pci_rev == ACP70_PCI_ID)
712+
switch (acp_data->pci_rev) {
713+
case ACP70_PCI_ID:
714+
case ACP71_PCI_ID:
620715
enable = true;
716+
break;
717+
}
621718
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_CONTROL, enable);
622719

623720
return 0;
@@ -637,9 +734,15 @@ int amd_sof_acp_resume(struct snd_sof_dev *sdev)
637734
return ret;
638735
}
639736
return acp_memory_init(sdev);
640-
} else {
641-
return acp_dsp_reset(sdev);
642737
}
738+
switch (acp_data->pci_rev) {
739+
case ACP70_PCI_ID:
740+
case ACP71_PCI_ID:
741+
snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP70_PME_EN, 1);
742+
break;
743+
}
744+
745+
return acp_dsp_reset(sdev);
643746
}
644747
EXPORT_SYMBOL_NS(amd_sof_acp_resume, "SND_SOC_SOF_AMD_COMMON");
645748

sound/soc/sof/amd/acp.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474
#define ACP_RMB_PCI_ID 0x6F
7575
#define ACP63_PCI_ID 0x63
7676
#define ACP70_PCI_ID 0x70
77+
#define ACP71_PCI_ID 0x71
7778

7879
#define HOST_BRIDGE_CZN 0x1630
7980
#define HOST_BRIDGE_VGH 0x1645
@@ -109,9 +110,11 @@
109110
#define ACP_SDW0_IRQ_MASK BIT(21)
110111
#define ACP_SDW1_IRQ_MASK BIT(2)
111112
#define SDW_ACPI_ADDR_ACP63 5
113+
#define SDW_ACPI_ADDR_ACP70 SDW_ACPI_ADDR_ACP63
112114
#define ACP_DEFAULT_SRAM_LENGTH 0x00080000
113115
#define ACP_SRAM_PAGE_COUNT 128
114116
#define ACP6X_SDW_MAX_MANAGER_COUNT 2
117+
#define ACP70_SDW_MAX_MANAGER_COUNT ACP6X_SDW_MAX_MANAGER_COUNT
115118

116119
enum clock_source {
117120
ACP_CLOCK_96M = 0,
@@ -260,6 +263,10 @@ struct acp_dev_data {
260263
bool is_dram_in_use;
261264
bool is_sram_in_use;
262265
bool sdw_en_stat;
266+
/* acp70_sdw0_wake_event flag set to true when wake irq asserted for SW0 instance */
267+
bool acp70_sdw0_wake_event;
268+
/* acp70_sdw1_wake_event flag set to true when wake irq asserted for SW1 instance */
269+
bool acp70_sdw1_wake_event;
263270
unsigned int pci_rev;
264271
};
265272

sound/soc/sof/amd/pci-acp70.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,15 @@ static const struct sof_amd_acp_desc acp70_chip_info = {
3333
.ext_intr_cntl = ACP70_EXTERNAL_INTR_CNTL,
3434
.ext_intr_stat = ACP70_EXT_INTR_STAT,
3535
.ext_intr_stat1 = ACP70_EXT_INTR_STAT1,
36+
.acp_error_stat = ACP70_ERROR_STATUS,
3637
.dsp_intr_base = ACP70_DSP_SW_INTR_BASE,
3738
.acp_sw0_i2s_err_reason = ACP7X_SW0_I2S_ERROR_REASON,
3839
.sram_pte_offset = ACP70_SRAM_PTE_OFFSET,
3940
.hw_semaphore_offset = ACP70_AXI2DAGB_SEM_0,
4041
.fusion_dsp_offset = ACP70_DSP_FUSION_RUNSTALL,
4142
.probe_reg_offset = ACP70_FUTURE_REG_ACLK_0,
43+
.sdw_max_link_count = ACP70_SDW_MAX_MANAGER_COUNT,
44+
.sdw_acpi_dev_addr = SDW_ACPI_ADDR_ACP70,
4245
.reg_start_addr = ACP70_REG_START,
4346
.reg_end_addr = ACP70_REG_END,
4447
};
@@ -70,8 +73,13 @@ static int acp70_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_
7073
{
7174
unsigned int flag;
7275

73-
if (pci->revision != ACP70_PCI_ID)
76+
switch (pci->revision) {
77+
case ACP70_PCI_ID:
78+
case ACP71_PCI_ID:
79+
break;
80+
default:
7481
return -ENODEV;
82+
}
7583

7684
flag = snd_amd_acp_find_config(pci);
7785
if (flag != FLAG_AMD_SOF && flag != FLAG_AMD_SOF_ONLY_DMIC)

0 commit comments

Comments
 (0)