* [PATCH v2 01/14] ASoC: amd: add Renoir ACP3x IP register header
2020-05-11 21:20 [PATCH v2 00/14] Add Renoir ACP driver Alex Deucher
@ 2020-05-11 21:20 ` Alex Deucher
2020-05-11 21:20 ` [PATCH v2 02/14] ASoC: amd: add Renoir ACP PCI driver Alex Deucher
` (12 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: Alex Deucher @ 2020-05-11 21:20 UTC (permalink / raw)
To: alsa-devel, broonie, vijendar.mukunda, tiwai
Cc: Alex Deucher, Vijendar Mukunda
From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Add register header for ACP3x IP in Renoir platform.
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
sound/soc/amd/renoir/rn_chip_offset_byte.h | 349 +++++++++++++++++++++
1 file changed, 349 insertions(+)
create mode 100644 sound/soc/amd/renoir/rn_chip_offset_byte.h
diff --git a/sound/soc/amd/renoir/rn_chip_offset_byte.h b/sound/soc/amd/renoir/rn_chip_offset_byte.h
new file mode 100644
index 000000000000..d20d967b5ff9
--- /dev/null
+++ b/sound/soc/amd/renoir/rn_chip_offset_byte.h
@@ -0,0 +1,349 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * AMD ACP 3.1 Register Documentation
+ *
+ * Copyright 2020 Advanced Micro Devices, Inc.
+ */
+
+#ifndef _rn_OFFSET_HEADER
+#define _rn_OFFSET_HEADER
+// Registers from ACP_DMA block
+
+#define ACP_DMA_CNTL_0 0x1240000
+#define ACP_DMA_CNTL_1 0x1240004
+#define ACP_DMA_CNTL_2 0x1240008
+#define ACP_DMA_CNTL_3 0x124000C
+#define ACP_DMA_CNTL_4 0x1240010
+#define ACP_DMA_CNTL_5 0x1240014
+#define ACP_DMA_CNTL_6 0x1240018
+#define ACP_DMA_CNTL_7 0x124001C
+#define ACP_DMA_DSCR_STRT_IDX_0 0x1240020
+#define ACP_DMA_DSCR_STRT_IDX_1 0x1240024
+#define ACP_DMA_DSCR_STRT_IDX_2 0x1240028
+#define ACP_DMA_DSCR_STRT_IDX_3 0x124002C
+#define ACP_DMA_DSCR_STRT_IDX_4 0x1240030
+#define ACP_DMA_DSCR_STRT_IDX_5 0x1240034
+#define ACP_DMA_DSCR_STRT_IDX_6 0x1240038
+#define ACP_DMA_DSCR_STRT_IDX_7 0x124003C
+#define ACP_DMA_DSCR_CNT_0 0x1240040
+#define ACP_DMA_DSCR_CNT_1 0x1240044
+#define ACP_DMA_DSCR_CNT_2 0x1240048
+#define ACP_DMA_DSCR_CNT_3 0x124004C
+#define ACP_DMA_DSCR_CNT_4 0x1240050
+#define ACP_DMA_DSCR_CNT_5 0x1240054
+#define ACP_DMA_DSCR_CNT_6 0x1240058
+#define ACP_DMA_DSCR_CNT_7 0x124005C
+#define ACP_DMA_PRIO_0 0x1240060
+#define ACP_DMA_PRIO_1 0x1240064
+#define ACP_DMA_PRIO_2 0x1240068
+#define ACP_DMA_PRIO_3 0x124006C
+#define ACP_DMA_PRIO_4 0x1240070
+#define ACP_DMA_PRIO_5 0x1240074
+#define ACP_DMA_PRIO_6 0x1240078
+#define ACP_DMA_PRIO_7 0x124007C
+#define ACP_DMA_CUR_DSCR_0 0x1240080
+#define ACP_DMA_CUR_DSCR_1 0x1240084
+#define ACP_DMA_CUR_DSCR_2 0x1240088
+#define ACP_DMA_CUR_DSCR_3 0x124008C
+#define ACP_DMA_CUR_DSCR_4 0x1240090
+#define ACP_DMA_CUR_DSCR_5 0x1240094
+#define ACP_DMA_CUR_DSCR_6 0x1240098
+#define ACP_DMA_CUR_DSCR_7 0x124009C
+#define ACP_DMA_CUR_TRANS_CNT_0 0x12400A0
+#define ACP_DMA_CUR_TRANS_CNT_1 0x12400A4
+#define ACP_DMA_CUR_TRANS_CNT_2 0x12400A8
+#define ACP_DMA_CUR_TRANS_CNT_3 0x12400AC
+#define ACP_DMA_CUR_TRANS_CNT_4 0x12400B0
+#define ACP_DMA_CUR_TRANS_CNT_5 0x12400B4
+#define ACP_DMA_CUR_TRANS_CNT_6 0x12400B8
+#define ACP_DMA_CUR_TRANS_CNT_7 0x12400BC
+#define ACP_DMA_ERR_STS_0 0x12400C0
+#define ACP_DMA_ERR_STS_1 0x12400C4
+#define ACP_DMA_ERR_STS_2 0x12400C8
+#define ACP_DMA_ERR_STS_3 0x12400CC
+#define ACP_DMA_ERR_STS_4 0x12400D0
+#define ACP_DMA_ERR_STS_5 0x12400D4
+#define ACP_DMA_ERR_STS_6 0x12400D8
+#define ACP_DMA_ERR_STS_7 0x12400DC
+#define ACP_DMA_DESC_BASE_ADDR 0x12400E0
+#define ACP_DMA_DESC_MAX_NUM_DSCR 0x12400E4
+#define ACP_DMA_CH_STS 0x12400E8
+#define ACP_DMA_CH_GROUP 0x12400EC
+#define ACP_DMA_CH_RST_STS 0x12400F0
+
+// Registers from ACP_AXI2AXIATU block
+
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1 0x1240C00
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_1 0x1240C04
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2 0x1240C08
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_2 0x1240C0C
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_3 0x1240C10
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_3 0x1240C14
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_4 0x1240C18
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_4 0x1240C1C
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5 0x1240C20
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_5 0x1240C24
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_6 0x1240C28
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_6 0x1240C2C
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_7 0x1240C30
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_7 0x1240C34
+#define ACPAXI2AXI_ATU_PAGE_SIZE_GRP_8 0x1240C38
+#define ACPAXI2AXI_ATU_BASE_ADDR_GRP_8 0x1240C3C
+#define ACPAXI2AXI_ATU_CTRL 0x1240C40
+
+// Registers from ACP_CLKRST block
+
+#define ACP_SOFT_RESET 0x1241000
+#define ACP_CONTROL 0x1241004
+#define ACP_STATUS 0x1241008
+#define ACP_DYNAMIC_CG_MASTER_CONTROL 0x1241010
+
+// Registers from ACP_MISC block
+
+#define ACP_EXTERNAL_INTR_ENB 0x1241800
+#define ACP_EXTERNAL_INTR_CNTL 0x1241804
+#define ACP_EXTERNAL_INTR_STAT 0x1241808
+#define ACP_PGMEM_CTRL 0x12418C0
+#define ACP_ERROR_STATUS 0x12418C4
+#define ACP_SW_I2S_ERROR_REASON 0x12418C8
+#define ACP_MEM_PG_STS 0x12418CC
+
+// Registers from ACP_PGFSM block
+
+#define ACP_I2S_PIN_CONFIG 0x1241400
+#define ACP_PAD_PULLUP_PULLDOWN_CTRL 0x1241404
+#define ACP_PAD_DRIVE_STRENGTH_CTRL 0x1241408
+#define ACP_SW_PAD_KEEPER_EN 0x124140C
+#define ACP_PGFSM_CONTROL 0x124141C
+#define ACP_PGFSM_STATUS 0x1241420
+#define ACP_CLKMUX_SEL 0x1241424
+#define ACP_DEVICE_STATE 0x1241428
+#define AZ_DEVICE_STATE 0x124142C
+#define ACP_INTR_URGENCY_TIMER 0x1241430
+#define AZ_INTR_URGENCY_TIMER 0x1241434
+
+// Registers from ACP_SCRATCH block
+
+#define ACP_SCRATCH_REG_0 0x1250000
+#define ACP_SCRATCH_REG_1 0x1250004
+#define ACP_SCRATCH_REG_2 0x1250008
+#define ACP_SCRATCH_REG_3 0x125000C
+#define ACP_SCRATCH_REG_4 0x1250010
+#define ACP_SCRATCH_REG_5 0x1250014
+#define ACP_SCRATCH_REG_6 0x1250018
+#define ACP_SCRATCH_REG_7 0x125001C
+#define ACP_SCRATCH_REG_8 0x1250020
+#define ACP_SCRATCH_REG_9 0x1250024
+#define ACP_SCRATCH_REG_10 0x1250028
+#define ACP_SCRATCH_REG_11 0x125002C
+#define ACP_SCRATCH_REG_12 0x1250030
+#define ACP_SCRATCH_REG_13 0x1250034
+#define ACP_SCRATCH_REG_14 0x1250038
+#define ACP_SCRATCH_REG_15 0x125003C
+#define ACP_SCRATCH_REG_16 0x1250040
+#define ACP_SCRATCH_REG_17 0x1250044
+#define ACP_SCRATCH_REG_18 0x1250048
+#define ACP_SCRATCH_REG_19 0x125004C
+#define ACP_SCRATCH_REG_20 0x1250050
+#define ACP_SCRATCH_REG_21 0x1250054
+#define ACP_SCRATCH_REG_22 0x1250058
+#define ACP_SCRATCH_REG_23 0x125005C
+#define ACP_SCRATCH_REG_24 0x1250060
+#define ACP_SCRATCH_REG_25 0x1250064
+#define ACP_SCRATCH_REG_26 0x1250068
+#define ACP_SCRATCH_REG_27 0x125006C
+#define ACP_SCRATCH_REG_28 0x1250070
+#define ACP_SCRATCH_REG_29 0x1250074
+#define ACP_SCRATCH_REG_30 0x1250078
+#define ACP_SCRATCH_REG_31 0x125007C
+#define ACP_SCRATCH_REG_32 0x1250080
+#define ACP_SCRATCH_REG_33 0x1250084
+#define ACP_SCRATCH_REG_34 0x1250088
+#define ACP_SCRATCH_REG_35 0x125008C
+#define ACP_SCRATCH_REG_36 0x1250090
+#define ACP_SCRATCH_REG_37 0x1250094
+#define ACP_SCRATCH_REG_38 0x1250098
+#define ACP_SCRATCH_REG_39 0x125009C
+#define ACP_SCRATCH_REG_40 0x12500A0
+#define ACP_SCRATCH_REG_41 0x12500A4
+#define ACP_SCRATCH_REG_42 0x12500A8
+#define ACP_SCRATCH_REG_43 0x12500AC
+#define ACP_SCRATCH_REG_44 0x12500B0
+#define ACP_SCRATCH_REG_45 0x12500B4
+#define ACP_SCRATCH_REG_46 0x12500B8
+#define ACP_SCRATCH_REG_47 0x12500BC
+#define ACP_SCRATCH_REG_48 0x12500C0
+#define ACP_SCRATCH_REG_49 0x12500C4
+#define ACP_SCRATCH_REG_50 0x12500C8
+#define ACP_SCRATCH_REG_51 0x12500CC
+#define ACP_SCRATCH_REG_52 0x12500D0
+#define ACP_SCRATCH_REG_53 0x12500D4
+#define ACP_SCRATCH_REG_54 0x12500D8
+#define ACP_SCRATCH_REG_55 0x12500DC
+#define ACP_SCRATCH_REG_56 0x12500E0
+#define ACP_SCRATCH_REG_57 0x12500E4
+#define ACP_SCRATCH_REG_58 0x12500E8
+#define ACP_SCRATCH_REG_59 0x12500EC
+#define ACP_SCRATCH_REG_60 0x12500F0
+#define ACP_SCRATCH_REG_61 0x12500F4
+#define ACP_SCRATCH_REG_62 0x12500F8
+#define ACP_SCRATCH_REG_63 0x12500FC
+#define ACP_SCRATCH_REG_64 0x1250100
+#define ACP_SCRATCH_REG_65 0x1250104
+#define ACP_SCRATCH_REG_66 0x1250108
+#define ACP_SCRATCH_REG_67 0x125010C
+#define ACP_SCRATCH_REG_68 0x1250110
+#define ACP_SCRATCH_REG_69 0x1250114
+#define ACP_SCRATCH_REG_70 0x1250118
+#define ACP_SCRATCH_REG_71 0x125011C
+#define ACP_SCRATCH_REG_72 0x1250120
+#define ACP_SCRATCH_REG_73 0x1250124
+#define ACP_SCRATCH_REG_74 0x1250128
+#define ACP_SCRATCH_REG_75 0x125012C
+#define ACP_SCRATCH_REG_76 0x1250130
+#define ACP_SCRATCH_REG_77 0x1250134
+#define ACP_SCRATCH_REG_78 0x1250138
+#define ACP_SCRATCH_REG_79 0x125013C
+#define ACP_SCRATCH_REG_80 0x1250140
+#define ACP_SCRATCH_REG_81 0x1250144
+#define ACP_SCRATCH_REG_82 0x1250148
+#define ACP_SCRATCH_REG_83 0x125014C
+#define ACP_SCRATCH_REG_84 0x1250150
+#define ACP_SCRATCH_REG_85 0x1250154
+#define ACP_SCRATCH_REG_86 0x1250158
+#define ACP_SCRATCH_REG_87 0x125015C
+#define ACP_SCRATCH_REG_88 0x1250160
+#define ACP_SCRATCH_REG_89 0x1250164
+#define ACP_SCRATCH_REG_90 0x1250168
+#define ACP_SCRATCH_REG_91 0x125016C
+#define ACP_SCRATCH_REG_92 0x1250170
+#define ACP_SCRATCH_REG_93 0x1250174
+#define ACP_SCRATCH_REG_94 0x1250178
+#define ACP_SCRATCH_REG_95 0x125017C
+#define ACP_SCRATCH_REG_96 0x1250180
+#define ACP_SCRATCH_REG_97 0x1250184
+#define ACP_SCRATCH_REG_98 0x1250188
+#define ACP_SCRATCH_REG_99 0x125018C
+#define ACP_SCRATCH_REG_100 0x1250190
+#define ACP_SCRATCH_REG_101 0x1250194
+#define ACP_SCRATCH_REG_102 0x1250198
+#define ACP_SCRATCH_REG_103 0x125019C
+#define ACP_SCRATCH_REG_104 0x12501A0
+#define ACP_SCRATCH_REG_105 0x12501A4
+#define ACP_SCRATCH_REG_106 0x12501A8
+#define ACP_SCRATCH_REG_107 0x12501AC
+#define ACP_SCRATCH_REG_108 0x12501B0
+#define ACP_SCRATCH_REG_109 0x12501B4
+#define ACP_SCRATCH_REG_110 0x12501B8
+#define ACP_SCRATCH_REG_111 0x12501BC
+#define ACP_SCRATCH_REG_112 0x12501C0
+#define ACP_SCRATCH_REG_113 0x12501C4
+#define ACP_SCRATCH_REG_114 0x12501C8
+#define ACP_SCRATCH_REG_115 0x12501CC
+#define ACP_SCRATCH_REG_116 0x12501D0
+#define ACP_SCRATCH_REG_117 0x12501D4
+#define ACP_SCRATCH_REG_118 0x12501D8
+#define ACP_SCRATCH_REG_119 0x12501DC
+#define ACP_SCRATCH_REG_120 0x12501E0
+#define ACP_SCRATCH_REG_121 0x12501E4
+#define ACP_SCRATCH_REG_122 0x12501E8
+#define ACP_SCRATCH_REG_123 0x12501EC
+#define ACP_SCRATCH_REG_124 0x12501F0
+#define ACP_SCRATCH_REG_125 0x12501F4
+#define ACP_SCRATCH_REG_126 0x12501F8
+#define ACP_SCRATCH_REG_127 0x12501FC
+#define ACP_SCRATCH_REG_128 0x1250200
+
+// Registers from ACP_AUDIO_BUFFERS block
+
+#define ACP_I2S_RX_RINGBUFADDR 0x1242000
+#define ACP_I2S_RX_RINGBUFSIZE 0x1242004
+#define ACP_I2S_RX_LINKPOSITIONCNTR 0x1242008
+#define ACP_I2S_RX_FIFOADDR 0x124200C
+#define ACP_I2S_RX_FIFOSIZE 0x1242010
+#define ACP_I2S_RX_DMA_SIZE 0x1242014
+#define ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH 0x1242018
+#define ACP_I2S_RX_LINEARPOSITIONCNTR_LOW 0x124201C
+#define ACP_I2S_RX_INTR_WATERMARK_SIZE 0x1242020
+#define ACP_I2S_TX_RINGBUFADDR 0x1242024
+#define ACP_I2S_TX_RINGBUFSIZE 0x1242028
+#define ACP_I2S_TX_LINKPOSITIONCNTR 0x124202C
+#define ACP_I2S_TX_FIFOADDR 0x1242030
+#define ACP_I2S_TX_FIFOSIZE 0x1242034
+#define ACP_I2S_TX_DMA_SIZE 0x1242038
+#define ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH 0x124203C
+#define ACP_I2S_TX_LINEARPOSITIONCNTR_LOW 0x1242040
+#define ACP_I2S_TX_INTR_WATERMARK_SIZE 0x1242044
+#define ACP_BT_RX_RINGBUFADDR 0x1242048
+#define ACP_BT_RX_RINGBUFSIZE 0x124204C
+#define ACP_BT_RX_LINKPOSITIONCNTR 0x1242050
+#define ACP_BT_RX_FIFOADDR 0x1242054
+#define ACP_BT_RX_FIFOSIZE 0x1242058
+#define ACP_BT_RX_DMA_SIZE 0x124205C
+#define ACP_BT_RX_LINEARPOSITIONCNTR_HIGH 0x1242060
+#define ACP_BT_RX_LINEARPOSITIONCNTR_LOW 0x1242064
+#define ACP_BT_RX_INTR_WATERMARK_SIZE 0x1242068
+#define ACP_BT_TX_RINGBUFADDR 0x124206C
+#define ACP_BT_TX_RINGBUFSIZE 0x1242070
+#define ACP_BT_TX_LINKPOSITIONCNTR 0x1242074
+#define ACP_BT_TX_FIFOADDR 0x1242078
+#define ACP_BT_TX_FIFOSIZE 0x124207C
+#define ACP_BT_TX_DMA_SIZE 0x1242080
+#define ACP_BT_TX_LINEARPOSITIONCNTR_HIGH 0x1242084
+#define ACP_BT_TX_LINEARPOSITIONCNTR_LOW 0x1242088
+#define ACP_BT_TX_INTR_WATERMARK_SIZE 0x124208C
+#define ACP_HS_RX_RINGBUFADDR 0x1242090
+#define ACP_HS_RX_RINGBUFSIZE 0x1242094
+#define ACP_HS_RX_LINKPOSITIONCNTR 0x1242098
+#define ACP_HS_RX_FIFOADDR 0x124209C
+#define ACP_HS_RX_FIFOSIZE 0x12420A0
+#define ACP_HS_RX_DMA_SIZE 0x12420A4
+#define ACP_HS_RX_LINEARPOSITIONCNTR_HIGH 0x12420A8
+#define ACP_HS_RX_LINEARPOSITIONCNTR_LOW 0x12420AC
+#define ACP_HS_RX_INTR_WATERMARK_SIZE 0x12420B0
+#define ACP_HS_TX_RINGBUFADDR 0x12420B4
+#define ACP_HS_TX_RINGBUFSIZE 0x12420B8
+#define ACP_HS_TX_LINKPOSITIONCNTR 0x12420BC
+#define ACP_HS_TX_FIFOADDR 0x12420C0
+#define ACP_HS_TX_FIFOSIZE 0x12420C4
+#define ACP_HS_TX_DMA_SIZE 0x12420C8
+#define ACP_HS_TX_LINEARPOSITIONCNTR_HIGH 0x12420CC
+#define ACP_HS_TX_LINEARPOSITIONCNTR_LOW 0x12420D0
+#define ACP_HS_TX_INTR_WATERMARK_SIZE 0x12420D4
+
+// Registers from ACP_I2S_TDM block
+
+#define ACP_I2STDM_IER 0x1242400
+#define ACP_I2STDM_IRER 0x1242404
+#define ACP_I2STDM_RXFRMT 0x1242408
+#define ACP_I2STDM_ITER 0x124240C
+#define ACP_I2STDM_TXFRMT 0x1242410
+
+// Registers from ACP_BT_TDM block
+
+#define ACP_BTTDM_IER 0x1242800
+#define ACP_BTTDM_IRER 0x1242804
+#define ACP_BTTDM_RXFRMT 0x1242808
+#define ACP_BTTDM_ITER 0x124280C
+#define ACP_BTTDM_TXFRMT 0x1242810
+
+// Registers from ACP_WOV block
+
+#define ACP_WOV_PDM_ENABLE 0x1242C04
+#define ACP_WOV_PDM_DMA_ENABLE 0x1242C08
+#define ACP_WOV_RX_RINGBUFADDR 0x1242C0C
+#define ACP_WOV_RX_RINGBUFSIZE 0x1242C10
+#define ACP_WOV_RX_LINKPOSITIONCNTR 0x1242C14
+#define ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH 0x1242C18
+#define ACP_WOV_RX_LINEARPOSITIONCNTR_LOW 0x1242C1C
+#define ACP_WOV_RX_INTR_WATERMARK_SIZE 0x1242C20
+#define ACP_WOV_PDM_FIFO_FLUSH 0x1242C24
+#define ACP_WOV_PDM_NO_OF_CHANNELS 0x1242C28
+#define ACP_WOV_PDM_DECIMATION_FACTOR 0x1242C2C
+#define ACP_WOV_PDM_VAD_CTRL 0x1242C30
+#define ACP_WOV_BUFFER_STATUS 0x1242C58
+#define ACP_WOV_MISC_CTRL 0x1242C5C
+#define ACP_WOV_CLK_CTRL 0x1242C60
+#define ACP_PDM_VAD_DYNAMIC_CLK_GATING_EN 0x1242C64
+#define ACP_WOV_ERROR_STATUS_REGISTER 0x1242C68
+#endif
--
2.25.4
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 02/14] ASoC: amd: add Renoir ACP PCI driver
2020-05-11 21:20 [PATCH v2 00/14] Add Renoir ACP driver Alex Deucher
2020-05-11 21:20 ` [PATCH v2 01/14] ASoC: amd: add Renoir ACP3x IP register header Alex Deucher
@ 2020-05-11 21:20 ` Alex Deucher
2020-05-11 21:20 ` [PATCH v2 03/14] ASoC: amd: add acp init/de-init functions Alex Deucher
` (11 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: Alex Deucher @ 2020-05-11 21:20 UTC (permalink / raw)
To: alsa-devel, broonie, vijendar.mukunda, tiwai
Cc: Alex Deucher, Vijendar Mukunda
From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
ACP is a PCI audio device.
This patch adds PCI driver to bind to this device and get
PCI resources.
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
sound/soc/amd/renoir/rn-pci-acp3x.c | 87 +++++++++++++++++++++++++++++
sound/soc/amd/renoir/rn_acp3x.h | 21 +++++++
2 files changed, 108 insertions(+)
create mode 100644 sound/soc/amd/renoir/rn-pci-acp3x.c
create mode 100644 sound/soc/amd/renoir/rn_acp3x.h
diff --git a/sound/soc/amd/renoir/rn-pci-acp3x.c b/sound/soc/amd/renoir/rn-pci-acp3x.c
new file mode 100644
index 000000000000..56b76e355cd4
--- /dev/null
+++ b/sound/soc/amd/renoir/rn-pci-acp3x.c
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// AMD Renoir ACP PCI Driver
+//
+//Copyright 2020 Advanced Micro Devices, Inc.
+
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <linux/io.h>
+
+#include "rn_acp3x.h"
+
+struct acp_dev_data {
+ void __iomem *acp_base;
+};
+
+static int snd_rn_acp_probe(struct pci_dev *pci,
+ const struct pci_device_id *pci_id)
+{
+ struct acp_dev_data *adata;
+ int ret;
+ u32 addr;
+
+ if (pci_enable_device(pci)) {
+ dev_err(&pci->dev, "pci_enable_device failed\n");
+ return -ENODEV;
+ }
+
+ ret = pci_request_regions(pci, "AMD ACP3x audio");
+ if (ret < 0) {
+ dev_err(&pci->dev, "pci_request_regions failed\n");
+ goto disable_pci;
+ }
+
+ adata = devm_kzalloc(&pci->dev, sizeof(struct acp_dev_data),
+ GFP_KERNEL);
+ if (!adata) {
+ ret = -ENOMEM;
+ goto release_regions;
+ }
+
+ addr = pci_resource_start(pci, 0);
+ adata->acp_base = devm_ioremap(&pci->dev, addr,
+ pci_resource_len(pci, 0));
+ if (!adata->acp_base) {
+ ret = -ENOMEM;
+ goto release_regions;
+ }
+ pci_set_master(pci);
+ pci_set_drvdata(pci, adata);
+ return 0;
+
+release_regions:
+ pci_release_regions(pci);
+disable_pci:
+ pci_disable_device(pci);
+
+ return ret;
+}
+
+static void snd_rn_acp_remove(struct pci_dev *pci)
+{
+ pci_disable_msi(pci);
+ pci_release_regions(pci);
+ pci_disable_device(pci);
+}
+
+static const struct pci_device_id snd_rn_acp_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP_DEVICE_ID),
+ .class = PCI_CLASS_MULTIMEDIA_OTHER << 8,
+ .class_mask = 0xffffff },
+ { 0, },
+};
+MODULE_DEVICE_TABLE(pci, snd_rn_acp_ids);
+
+static struct pci_driver rn_acp_driver = {
+ .name = KBUILD_MODNAME,
+ .id_table = snd_rn_acp_ids,
+ .probe = snd_rn_acp_probe,
+ .remove = snd_rn_acp_remove,
+};
+
+module_pci_driver(rn_acp_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("AMD ACP Renoir PCI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/amd/renoir/rn_acp3x.h b/sound/soc/amd/renoir/rn_acp3x.h
new file mode 100644
index 000000000000..da5715759646
--- /dev/null
+++ b/sound/soc/amd/renoir/rn_acp3x.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * AMD ALSA SoC PDM Driver
+ *
+ * Copyright 2020 Advanced Micro Devices, Inc.
+ */
+
+#include "rn_chip_offset_byte.h"
+
+#define ACP_PHY_BASE_ADDRESS 0x1240000
+#define ACP_DEVICE_ID 0x15E2
+
+static inline u32 rn_readl(void __iomem *base_addr)
+{
+ return readl(base_addr - ACP_PHY_BASE_ADDRESS);
+}
+
+static inline void rn_writel(u32 val, void __iomem *base_addr)
+{
+ writel(val, base_addr - ACP_PHY_BASE_ADDRESS);
+}
--
2.25.4
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 03/14] ASoC: amd: add acp init/de-init functions
2020-05-11 21:20 [PATCH v2 00/14] Add Renoir ACP driver Alex Deucher
2020-05-11 21:20 ` [PATCH v2 01/14] ASoC: amd: add Renoir ACP3x IP register header Alex Deucher
2020-05-11 21:20 ` [PATCH v2 02/14] ASoC: amd: add Renoir ACP PCI driver Alex Deucher
@ 2020-05-11 21:20 ` Alex Deucher
2020-05-11 21:20 ` [PATCH v2 04/14] ASoC: amd: create acp3x pdm platform device Alex Deucher
` (10 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: Alex Deucher @ 2020-05-11 21:20 UTC (permalink / raw)
To: alsa-devel, broonie, vijendar.mukunda, tiwai
Cc: Alex Deucher, Vijendar Mukunda
From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Add Renoir ACP PCI driver init/deinit functions.
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
sound/soc/amd/renoir/rn-pci-acp3x.c | 143 ++++++++++++++++++++++++++++
sound/soc/amd/renoir/rn_acp3x.h | 16 ++++
2 files changed, 159 insertions(+)
diff --git a/sound/soc/amd/renoir/rn-pci-acp3x.c b/sound/soc/amd/renoir/rn-pci-acp3x.c
index 56b76e355cd4..429813f6ba1c 100644
--- a/sound/soc/amd/renoir/rn-pci-acp3x.c
+++ b/sound/soc/amd/renoir/rn-pci-acp3x.c
@@ -7,13 +7,146 @@
#include <linux/pci.h>
#include <linux/module.h>
#include <linux/io.h>
+#include <linux/delay.h>
#include "rn_acp3x.h"
+static int acp_power_gating;
+module_param(acp_power_gating, int, 0644);
+MODULE_PARM_DESC(acp_power_gating, "Enable acp power gating");
+
struct acp_dev_data {
void __iomem *acp_base;
};
+static int rn_acp_power_on(void __iomem *acp_base)
+{
+ u32 val;
+ int timeout;
+
+ val = rn_readl(acp_base + ACP_PGFSM_STATUS);
+
+ if (val == 0)
+ return val;
+
+ if ((val & ACP_PGFSM_STATUS_MASK) !=
+ ACP_POWER_ON_IN_PROGRESS)
+ rn_writel(ACP_PGFSM_CNTL_POWER_ON_MASK,
+ acp_base + ACP_PGFSM_CONTROL);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = rn_readl(acp_base + ACP_PGFSM_STATUS);
+ if (!val)
+ return 0;
+ udelay(1);
+ }
+ return -ETIMEDOUT;
+}
+
+static int rn_acp_power_off(void __iomem *acp_base)
+{
+ u32 val;
+ int timeout;
+
+ rn_writel(ACP_PGFSM_CNTL_POWER_OFF_MASK,
+ acp_base + ACP_PGFSM_CONTROL);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = rn_readl(acp_base + ACP_PGFSM_STATUS);
+ if ((val & ACP_PGFSM_STATUS_MASK) == ACP_POWERED_OFF)
+ return 0;
+ udelay(1);
+ }
+ return -ETIMEDOUT;
+}
+
+static int rn_acp_reset(void __iomem *acp_base)
+{
+ u32 val;
+ int timeout;
+
+ rn_writel(1, acp_base + ACP_SOFT_RESET);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = rn_readl(acp_base + ACP_SOFT_RESET);
+ if (val & ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK)
+ break;
+ cpu_relax();
+ }
+ rn_writel(0, acp_base + ACP_SOFT_RESET);
+ timeout = 0;
+ while (++timeout < 500) {
+ val = rn_readl(acp_base + ACP_SOFT_RESET);
+ if (!val)
+ return 0;
+ cpu_relax();
+ }
+ return -ETIMEDOUT;
+}
+
+static void rn_acp_enable_interrupts(void __iomem *acp_base)
+{
+ u32 ext_intr_ctrl;
+
+ rn_writel(0x01, acp_base + ACP_EXTERNAL_INTR_ENB);
+ ext_intr_ctrl = rn_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
+ ext_intr_ctrl |= ACP_ERROR_MASK;
+ rn_writel(ext_intr_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
+}
+
+static void rn_acp_disable_interrupts(void __iomem *acp_base)
+{
+ rn_writel(ACP_EXT_INTR_STAT_CLEAR_MASK, acp_base +
+ ACP_EXTERNAL_INTR_STAT);
+ rn_writel(0x00, acp_base + ACP_EXTERNAL_INTR_ENB);
+}
+
+static int rn_acp_init(void __iomem *acp_base)
+{
+ int ret;
+
+ /* power on */
+ ret = rn_acp_power_on(acp_base);
+ if (ret) {
+ pr_err("ACP power on failed\n");
+ return ret;
+ }
+ rn_writel(0x01, acp_base + ACP_CONTROL);
+ /* Reset */
+ ret = rn_acp_reset(acp_base);
+ if (ret) {
+ pr_err("ACP reset failed\n");
+ return ret;
+ }
+ rn_writel(0x03, acp_base + ACP_CLKMUX_SEL);
+ rn_acp_enable_interrupts(acp_base);
+ return 0;
+}
+
+static int rn_acp_deinit(void __iomem *acp_base)
+{
+ int ret;
+
+ rn_acp_disable_interrupts(acp_base);
+ /* Reset */
+ ret = rn_acp_reset(acp_base);
+ if (ret) {
+ pr_err("ACP reset failed\n");
+ return ret;
+ }
+ rn_writel(0x00, acp_base + ACP_CLKMUX_SEL);
+ rn_writel(0x00, acp_base + ACP_CONTROL);
+ /* power off */
+ if (acp_power_gating) {
+ ret = rn_acp_power_off(acp_base);
+ if (ret) {
+ pr_err("ACP power off failed\n");
+ return ret;
+ }
+ }
+ return 0;
+}
+
static int snd_rn_acp_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
@@ -48,6 +181,9 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
}
pci_set_master(pci);
pci_set_drvdata(pci, adata);
+ ret = rn_acp_init(adata->acp_base);
+ if (ret)
+ goto release_regions;
return 0;
release_regions:
@@ -60,6 +196,13 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
static void snd_rn_acp_remove(struct pci_dev *pci)
{
+ struct acp_dev_data *adata;
+ int ret;
+
+ adata = pci_get_drvdata(pci);
+ ret = rn_acp_deinit(adata->acp_base);
+ if (ret)
+ dev_err(&pci->dev, "ACP de-init failed\n");
pci_disable_msi(pci);
pci_release_regions(pci);
pci_disable_device(pci);
diff --git a/sound/soc/amd/renoir/rn_acp3x.h b/sound/soc/amd/renoir/rn_acp3x.h
index da5715759646..ec2a85085163 100644
--- a/sound/soc/amd/renoir/rn_acp3x.h
+++ b/sound/soc/amd/renoir/rn_acp3x.h
@@ -9,6 +9,22 @@
#define ACP_PHY_BASE_ADDRESS 0x1240000
#define ACP_DEVICE_ID 0x15E2
+#define ACP_POWER_ON 0x00
+#define ACP_POWER_ON_IN_PROGRESS 0x01
+#define ACP_POWER_OFF 0x02
+#define ACP_POWER_OFF_IN_PROGRESS 0x03
+#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK 0x00010001
+
+#define ACP_PGFSM_CNTL_POWER_ON_MASK 0x01
+#define ACP_PGFSM_CNTL_POWER_OFF_MASK 0x00
+#define ACP_PGFSM_STATUS_MASK 0x03
+#define ACP_POWERED_ON 0x00
+#define ACP_POWER_ON_IN_PROGRESS 0x01
+#define ACP_POWERED_OFF 0x02
+#define ACP_POWER_OFF_IN_PROGRESS 0x03
+
+#define ACP_ERROR_MASK 0x20000000
+#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
static inline u32 rn_readl(void __iomem *base_addr)
{
--
2.25.4
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 04/14] ASoC: amd: create acp3x pdm platform device
2020-05-11 21:20 [PATCH v2 00/14] Add Renoir ACP driver Alex Deucher
` (2 preceding siblings ...)
2020-05-11 21:20 ` [PATCH v2 03/14] ASoC: amd: add acp init/de-init functions Alex Deucher
@ 2020-05-11 21:20 ` Alex Deucher
2020-05-11 21:20 ` [PATCH v2 05/14] ASoC: amd: add ACP3x PDM platform driver Alex Deucher
` (9 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: Alex Deucher @ 2020-05-11 21:20 UTC (permalink / raw)
To: alsa-devel, broonie, vijendar.mukunda, tiwai
Cc: Alex Deucher, Vijendar Mukunda
From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
ACP 3x IP has PDM decoder as one of IP blocks.
Create a platform device for it, so that the PDM platform driver
can be bound to this device.
Pass PCI resources like MMIO, irq to this platform device.
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
sound/soc/amd/renoir/rn-pci-acp3x.c | 61 ++++++++++++++++++++++++++++-
sound/soc/amd/renoir/rn_acp3x.h | 3 ++
2 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/sound/soc/amd/renoir/rn-pci-acp3x.c b/sound/soc/amd/renoir/rn-pci-acp3x.c
index 429813f6ba1c..362409ef0d85 100644
--- a/sound/soc/amd/renoir/rn-pci-acp3x.c
+++ b/sound/soc/amd/renoir/rn-pci-acp3x.c
@@ -8,6 +8,8 @@
#include <linux/module.h>
#include <linux/io.h>
#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
#include "rn_acp3x.h"
@@ -17,6 +19,8 @@ MODULE_PARM_DESC(acp_power_gating, "Enable acp power gating");
struct acp_dev_data {
void __iomem *acp_base;
+ struct resource *res;
+ struct platform_device *pdev;
};
static int rn_acp_power_on(void __iomem *acp_base)
@@ -151,6 +155,8 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
struct acp_dev_data *adata;
+ struct platform_device_info pdevinfo;
+ unsigned int irqflags;
int ret;
u32 addr;
@@ -172,20 +178,70 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
goto release_regions;
}
+ /* check for msi interrupt support */
+ ret = pci_enable_msi(pci);
+ if (ret)
+ /* msi is not enabled */
+ irqflags = IRQF_SHARED;
+ else
+ /* msi is enabled */
+ irqflags = 0;
+
addr = pci_resource_start(pci, 0);
adata->acp_base = devm_ioremap(&pci->dev, addr,
pci_resource_len(pci, 0));
if (!adata->acp_base) {
ret = -ENOMEM;
- goto release_regions;
+ goto disable_msi;
}
pci_set_master(pci);
pci_set_drvdata(pci, adata);
ret = rn_acp_init(adata->acp_base);
if (ret)
- goto release_regions;
+ goto disable_msi;
+
+ adata->res = devm_kzalloc(&pci->dev,
+ sizeof(struct resource) * 2,
+ GFP_KERNEL);
+ if (!adata->res) {
+ ret = -ENOMEM;
+ goto de_init;
+ }
+
+ adata->res[0].name = "acp_pdm_iomem";
+ adata->res[0].flags = IORESOURCE_MEM;
+ adata->res[0].start = addr;
+ adata->res[0].end = addr + (ACP_REG_END - ACP_REG_START);
+ adata->res[1].name = "acp_pdm_irq";
+ adata->res[1].flags = IORESOURCE_IRQ;
+ adata->res[1].start = pci->irq;
+ adata->res[1].end = pci->irq;
+
+ memset(&pdevinfo, 0, sizeof(pdevinfo));
+ pdevinfo.name = "acp_rn_pdm_dma";
+ pdevinfo.id = 0;
+ pdevinfo.parent = &pci->dev;
+ pdevinfo.num_res = 2;
+ pdevinfo.res = adata->res;
+ pdevinfo.data = &irqflags;
+ pdevinfo.size_data = sizeof(irqflags);
+
+ adata->pdev = platform_device_register_full(&pdevinfo);
+ if (IS_ERR(adata->pdev)) {
+ dev_err(&pci->dev, "cannot register %s device\n",
+ pdevinfo.name);
+ ret = PTR_ERR(adata->pdev);
+ goto unregister_devs;
+ }
return 0;
+unregister_devs:
+ platform_device_unregister(adata->pdev);
+de_init:
+ if (rn_acp_deinit(adata->acp_base))
+ dev_err(&pci->dev, "ACP de-init failed\n");
+disable_msi:
+ pci_disable_msi(pci);
release_regions:
pci_release_regions(pci);
disable_pci:
@@ -200,6 +256,7 @@ static void snd_rn_acp_remove(struct pci_dev *pci)
int ret;
adata = pci_get_drvdata(pci);
+ platform_device_unregister(adata->pdev);
ret = rn_acp_deinit(adata->acp_base);
if (ret)
dev_err(&pci->dev, "ACP de-init failed\n");
diff --git a/sound/soc/amd/renoir/rn_acp3x.h b/sound/soc/amd/renoir/rn_acp3x.h
index ec2a85085163..5e4fd99397d5 100644
--- a/sound/soc/amd/renoir/rn_acp3x.h
+++ b/sound/soc/amd/renoir/rn_acp3x.h
@@ -8,6 +8,9 @@
#include "rn_chip_offset_byte.h"
#define ACP_PHY_BASE_ADDRESS 0x1240000
+#define ACP_REG_START 0x1240000
+#define ACP_REG_END 0x1250200
+
#define ACP_DEVICE_ID 0x15E2
#define ACP_POWER_ON 0x00
#define ACP_POWER_ON_IN_PROGRESS 0x01
--
2.25.4
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 05/14] ASoC: amd: add ACP3x PDM platform driver
2020-05-11 21:20 [PATCH v2 00/14] Add Renoir ACP driver Alex Deucher
` (3 preceding siblings ...)
2020-05-11 21:20 ` [PATCH v2 04/14] ASoC: amd: create acp3x pdm platform device Alex Deucher
@ 2020-05-11 21:20 ` Alex Deucher
2020-05-11 21:20 ` [PATCH v2 06/14] ASoC: amd: irq handler changes for ACP3x PDM dma driver Alex Deucher
` (8 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: Alex Deucher @ 2020-05-11 21:20 UTC (permalink / raw)
To: alsa-devel, broonie, vijendar.mukunda, tiwai
Cc: Alex Deucher, Vijendar Mukunda
From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
PDM platform driver binds to the platform device created by
ACP3x PCI device. PDM driver registers ALSA DMA and CPU DAI
components with ASoC framework.
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
V2:
- Removed empty declaration of dai_ops
sound/soc/amd/renoir/acp3x-pdm-dma.c | 95 ++++++++++++++++++++++++++++
sound/soc/amd/renoir/rn_acp3x.h | 5 ++
2 files changed, 100 insertions(+)
create mode 100644 sound/soc/amd/renoir/acp3x-pdm-dma.c
diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c
new file mode 100644
index 000000000000..1dda8cf2edd2
--- /dev/null
+++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// AMD ALSA SoC PDM Driver
+//
+//Copyright 2020 Advanced Micro Devices, Inc.
+
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-dai.h>
+
+#include "rn_acp3x.h"
+
+#define DRV_NAME "acp_rn_pdm_dma"
+
+static struct snd_soc_dai_driver acp_pdm_dai_driver = {
+ .capture = {
+ .rates = SNDRV_PCM_RATE_48000,
+ .formats = SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ },
+};
+
+static const struct snd_soc_component_driver acp_pdm_component = {
+ .name = DRV_NAME,
+};
+
+static int acp_pdm_audio_probe(struct platform_device *pdev)
+{
+ struct resource *res;
+ struct pdm_dev_data *adata;
+ unsigned int irqflags;
+ int status;
+
+ if (!pdev->dev.platform_data) {
+ dev_err(&pdev->dev, "platform_data not retrieved\n");
+ return -ENODEV;
+ }
+ irqflags = *((unsigned int *)(pdev->dev.platform_data));
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
+ return -ENODEV;
+ }
+
+ adata = devm_kzalloc(&pdev->dev, sizeof(*adata), GFP_KERNEL);
+ if (!adata)
+ return -ENOMEM;
+
+ adata->acp_base = devm_ioremap(&pdev->dev, res->start,
+ resource_size(res));
+ if (!adata->acp_base)
+ return -ENOMEM;
+
+ adata->capture_stream = NULL;
+
+ dev_set_drvdata(&pdev->dev, adata);
+ status = devm_snd_soc_register_component(&pdev->dev,
+ &acp_pdm_component,
+ &acp_pdm_dai_driver, 1);
+ if (status) {
+ dev_err(&pdev->dev, "Fail to register acp pdm dai\n");
+
+ return -ENODEV;
+ }
+ return 0;
+}
+
+static int acp_pdm_audio_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver acp_pdm_dma_driver = {
+ .probe = acp_pdm_audio_probe,
+ .remove = acp_pdm_audio_remove,
+ .driver = {
+ .name = "acp_rn_pdm_dma",
+ },
+};
+
+module_platform_driver(acp_pdm_dma_driver);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_DESCRIPTION("AMD ACP3x Renior PDM Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/sound/soc/amd/renoir/rn_acp3x.h b/sound/soc/amd/renoir/rn_acp3x.h
index 5e4fd99397d5..0b450882c6c4 100644
--- a/sound/soc/amd/renoir/rn_acp3x.h
+++ b/sound/soc/amd/renoir/rn_acp3x.h
@@ -29,6 +29,11 @@
#define ACP_ERROR_MASK 0x20000000
#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
+struct pdm_dev_data {
+ void __iomem *acp_base;
+ struct snd_pcm_substream *capture_stream;
+};
+
static inline u32 rn_readl(void __iomem *base_addr)
{
return readl(base_addr - ACP_PHY_BASE_ADDRESS);
--
2.25.4
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 06/14] ASoC: amd: irq handler changes for ACP3x PDM dma driver
2020-05-11 21:20 [PATCH v2 00/14] Add Renoir ACP driver Alex Deucher
` (4 preceding siblings ...)
2020-05-11 21:20 ` [PATCH v2 05/14] ASoC: amd: add ACP3x PDM platform driver Alex Deucher
@ 2020-05-11 21:20 ` Alex Deucher
2020-05-11 21:20 ` [PATCH v2 07/14] ASoC: amd: add acp3x pdm driver dma ops Alex Deucher
` (7 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: Alex Deucher @ 2020-05-11 21:20 UTC (permalink / raw)
To: alsa-devel, broonie, vijendar.mukunda, tiwai
Cc: Alex Deucher, Vijendar Mukunda
From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Whenever audio data equal to the PDM watermark level
are consumed, interrupt is generated.
Acknowledge the interrupt.
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
sound/soc/amd/renoir/acp3x-pdm-dma.c | 38 ++++++++++++++++++++++++++++
sound/soc/amd/renoir/rn_acp3x.h | 2 ++
2 files changed, 40 insertions(+)
diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c
index 1dda8cf2edd2..fdac2c1e3acd 100644
--- a/sound/soc/amd/renoir/acp3x-pdm-dma.c
+++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c
@@ -16,6 +16,31 @@
#define DRV_NAME "acp_rn_pdm_dma"
+static irqreturn_t pdm_irq_handler(int irq, void *dev_id)
+{
+ struct pdm_dev_data *rn_pdm_data;
+ u16 cap_flag;
+ u32 val;
+
+ rn_pdm_data = dev_id;
+ if (!rn_pdm_data)
+ return IRQ_NONE;
+
+ cap_flag = 0;
+ val = rn_readl(rn_pdm_data->acp_base + ACP_EXTERNAL_INTR_STAT);
+ if ((val & BIT(PDM_DMA_STAT)) && rn_pdm_data->capture_stream) {
+ rn_writel(BIT(PDM_DMA_STAT), rn_pdm_data->acp_base +
+ ACP_EXTERNAL_INTR_STAT);
+ snd_pcm_period_elapsed(rn_pdm_data->capture_stream);
+ cap_flag = 1;
+ }
+
+ if (cap_flag)
+ return IRQ_HANDLED;
+ else
+ return IRQ_NONE;
+}
+
static struct snd_soc_dai_driver acp_pdm_dai_driver = {
.capture = {
.rates = SNDRV_PCM_RATE_48000,
@@ -60,6 +85,13 @@ static int acp_pdm_audio_probe(struct platform_device *pdev)
if (!adata->acp_base)
return -ENOMEM;
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n");
+ return -ENODEV;
+ }
+
+ adata->pdm_irq = res->start;
adata->capture_stream = NULL;
dev_set_drvdata(&pdev->dev, adata);
@@ -71,6 +103,12 @@ static int acp_pdm_audio_probe(struct platform_device *pdev)
return -ENODEV;
}
+ status = devm_request_irq(&pdev->dev, adata->pdm_irq, pdm_irq_handler,
+ irqflags, "ACP_PDM_IRQ", adata);
+ if (status) {
+ dev_err(&pdev->dev, "ACP PDM IRQ request failed\n");
+ return -ENODEV;
+ }
return 0;
}
diff --git a/sound/soc/amd/renoir/rn_acp3x.h b/sound/soc/amd/renoir/rn_acp3x.h
index 0b450882c6c4..1ad8a7845fda 100644
--- a/sound/soc/amd/renoir/rn_acp3x.h
+++ b/sound/soc/amd/renoir/rn_acp3x.h
@@ -28,8 +28,10 @@
#define ACP_ERROR_MASK 0x20000000
#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
+#define PDM_DMA_STAT 0x10
struct pdm_dev_data {
+ u32 pdm_irq;
void __iomem *acp_base;
struct snd_pcm_substream *capture_stream;
};
--
2.25.4
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 07/14] ASoC: amd: add acp3x pdm driver dma ops
2020-05-11 21:20 [PATCH v2 00/14] Add Renoir ACP driver Alex Deucher
` (5 preceding siblings ...)
2020-05-11 21:20 ` [PATCH v2 06/14] ASoC: amd: irq handler changes for ACP3x PDM dma driver Alex Deucher
@ 2020-05-11 21:20 ` Alex Deucher
2020-05-11 21:20 ` [PATCH v2 08/14] ASoC: amd: add ACP PDM DMA driver dai ops Alex Deucher
` (6 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: Alex Deucher @ 2020-05-11 21:20 UTC (permalink / raw)
To: alsa-devel, broonie, vijendar.mukunda, tiwai
Cc: Alex Deucher, Vijendar Mukunda
From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
This patch adds PDM driver DMA operations.
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
v2:
- Removed SNDRV_PCM_INFO_BATCH flag
sound/soc/amd/renoir/acp3x-pdm-dma.c | 195 +++++++++++++++++++++++++++
sound/soc/amd/renoir/rn_acp3x.h | 29 ++++
2 files changed, 224 insertions(+)
diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c
index fdac2c1e3acd..8bb03fa5b4a5 100644
--- a/sound/soc/amd/renoir/acp3x-pdm-dma.c
+++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c
@@ -16,6 +16,25 @@
#define DRV_NAME "acp_rn_pdm_dma"
+static const struct snd_pcm_hardware acp_pdm_hardware_capture = {
+ .info = SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
+ .formats = SNDRV_PCM_FMTBIT_S32_LE,
+ .channels_min = 2,
+ .channels_max = 2,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000,
+ .rate_max = 48000,
+ .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS * CAPTURE_MAX_PERIOD_SIZE,
+ .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
+ .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
+ .periods_min = CAPTURE_MIN_NUM_PERIODS,
+ .periods_max = CAPTURE_MAX_NUM_PERIODS,
+};
+
static irqreturn_t pdm_irq_handler(int irq, void *dev_id)
{
struct pdm_dev_data *rn_pdm_data;
@@ -41,6 +60,176 @@ static irqreturn_t pdm_irq_handler(int irq, void *dev_id)
return IRQ_NONE;
}
+static void init_pdm_ring_buffer(u32 physical_addr,
+ u32 buffer_size,
+ u32 watermark_size,
+ void __iomem *acp_base)
+{
+ rn_writel(physical_addr, acp_base + ACP_WOV_RX_RINGBUFADDR);
+ rn_writel(buffer_size, acp_base + ACP_WOV_RX_RINGBUFSIZE);
+ rn_writel(watermark_size, acp_base + ACP_WOV_RX_INTR_WATERMARK_SIZE);
+ rn_writel(0x01, acp_base + ACPAXI2AXI_ATU_CTRL);
+}
+
+static void enable_pdm_interrupts(void __iomem *acp_base)
+{
+ u32 ext_int_ctrl;
+
+ ext_int_ctrl = rn_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
+ ext_int_ctrl |= PDM_DMA_INTR_MASK;
+ rn_writel(ext_int_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
+}
+
+static void disable_pdm_interrupts(void __iomem *acp_base)
+{
+ u32 ext_int_ctrl;
+
+ ext_int_ctrl = rn_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
+ ext_int_ctrl |= ~PDM_DMA_INTR_MASK;
+ rn_writel(ext_int_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
+}
+
+static void config_acp_dma(struct pdm_stream_instance *rtd, int direction)
+{
+ u16 page_idx;
+ u32 low, high, val;
+ dma_addr_t addr;
+
+ addr = rtd->dma_addr;
+ val = 0;
+
+ /* Group Enable */
+ rn_writel(ACP_SRAM_PTE_OFFSET | BIT(31), rtd->acp_base +
+ ACPAXI2AXI_ATU_BASE_ADDR_GRP_1);
+ rn_writel(PAGE_SIZE_4K_ENABLE, rtd->acp_base +
+ ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1);
+
+ for (page_idx = 0; page_idx < rtd->num_pages; page_idx++) {
+ /* Load the low address of page int ACP SRAM through SRBM */
+ low = lower_32_bits(addr);
+ high = upper_32_bits(addr);
+
+ rn_writel(low, rtd->acp_base + ACP_SCRATCH_REG_0 + val);
+ high |= BIT(31);
+ rn_writel(high, rtd->acp_base + ACP_SCRATCH_REG_0 + val + 4);
+ val += 8;
+ addr += PAGE_SIZE;
+ }
+}
+
+static int acp_pdm_dma_open(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime;
+ struct pdm_dev_data *adata;
+ struct pdm_stream_instance *pdm_data;
+ int ret;
+
+ runtime = substream->runtime;
+ adata = dev_get_drvdata(component->dev);
+ pdm_data = kzalloc(sizeof(*pdm_data), GFP_KERNEL);
+ if (!pdm_data)
+ return -EINVAL;
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ runtime->hw = acp_pdm_hardware_capture;
+
+ ret = snd_pcm_hw_constraint_integer(runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0) {
+ dev_err(component->dev, "set integer constraint failed\n");
+ kfree(pdm_data);
+ return ret;
+ }
+
+ enable_pdm_interrupts(adata->acp_base);
+
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
+ adata->capture_stream = substream;
+
+ pdm_data->acp_base = adata->acp_base;
+ runtime->private_data = pdm_data;
+ return ret;
+}
+
+static int acp_pdm_dma_hw_params(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct pdm_stream_instance *rtd;
+ size_t size, period_bytes;
+
+ rtd = substream->runtime->private_data;
+ if (!rtd)
+ return -EINVAL;
+ size = params_buffer_bytes(params);
+ period_bytes = params_period_bytes(params);
+ rtd->dma_addr = substream->dma_buffer.addr;
+ rtd->num_pages = (PAGE_ALIGN(size) >> PAGE_SHIFT);
+ config_acp_dma(rtd, substream->stream);
+ init_pdm_ring_buffer(MEM_WINDOW_START, size, period_bytes,
+ rtd->acp_base);
+ return 0;
+}
+
+static u64 acp_pdm_get_byte_count(struct pdm_stream_instance *rtd,
+ int direction)
+{
+ union acp_pdm_dma_count byte_count;
+
+ byte_count.bcount.high =
+ rn_readl(rtd->acp_base +
+ ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH);
+ byte_count.bcount.low =
+ rn_readl(rtd->acp_base +
+ ACP_WOV_RX_LINEARPOSITIONCNTR_LOW);
+ return byte_count.bytescount;
+}
+
+static snd_pcm_uframes_t acp_pdm_dma_pointer(struct snd_soc_component *comp,
+ struct snd_pcm_substream *stream)
+{
+ struct pdm_stream_instance *rtd;
+ u32 pos, buffersize;
+ u64 bytescount;
+
+ rtd = stream->runtime->private_data;
+ buffersize = frames_to_bytes(stream->runtime,
+ stream->runtime->buffer_size);
+ bytescount = acp_pdm_get_byte_count(rtd, stream->stream);
+ if (bytescount > rtd->bytescount)
+ bytescount -= rtd->bytescount;
+ pos = do_div(bytescount, buffersize);
+ return bytes_to_frames(stream->runtime, pos);
+}
+
+static int acp_pdm_dma_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ struct device *parent = component->dev->parent;
+
+ snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
+ parent, MIN_BUFFER, MAX_BUFFER);
+ return 0;
+}
+
+static int acp_pdm_dma_mmap(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream,
+ struct vm_area_struct *vma)
+{
+ return snd_pcm_lib_default_mmap(substream, vma);
+}
+
+static int acp_pdm_dma_close(struct snd_soc_component *component,
+ struct snd_pcm_substream *substream)
+{
+ struct pdm_dev_data *adata = dev_get_drvdata(component->dev);
+
+ disable_pdm_interrupts(adata->acp_base);
+ adata->capture_stream = NULL;
+ return 0;
+}
+
static struct snd_soc_dai_driver acp_pdm_dai_driver = {
.capture = {
.rates = SNDRV_PCM_RATE_48000,
@@ -55,6 +244,12 @@ static struct snd_soc_dai_driver acp_pdm_dai_driver = {
static const struct snd_soc_component_driver acp_pdm_component = {
.name = DRV_NAME,
+ .open = acp_pdm_dma_open,
+ .close = acp_pdm_dma_close,
+ .hw_params = acp_pdm_dma_hw_params,
+ .pointer = acp_pdm_dma_pointer,
+ .mmap = acp_pdm_dma_mmap,
+ .pcm_construct = acp_pdm_dma_new,
};
static int acp_pdm_audio_probe(struct platform_device *pdev)
diff --git a/sound/soc/amd/renoir/rn_acp3x.h b/sound/soc/amd/renoir/rn_acp3x.h
index 1ad8a7845fda..3536d24374f3 100644
--- a/sound/soc/amd/renoir/rn_acp3x.h
+++ b/sound/soc/amd/renoir/rn_acp3x.h
@@ -29,13 +29,42 @@
#define ACP_ERROR_MASK 0x20000000
#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF
#define PDM_DMA_STAT 0x10
+#define PDM_DMA_INTR_MASK 0x10000
+#define ACP_ERROR_STAT 29
+#define ACP_SRAM_PTE_OFFSET 0x02050000
+#define PAGE_SIZE_4K_ENABLE 0x2
+#define MEM_WINDOW_START 0x4000000
+
+#define CAPTURE_MIN_NUM_PERIODS 4
+#define CAPTURE_MAX_NUM_PERIODS 4
+#define CAPTURE_MAX_PERIOD_SIZE 8192
+#define CAPTURE_MIN_PERIOD_SIZE 4096
+
+#define MAX_BUFFER (CAPTURE_MAX_PERIOD_SIZE * CAPTURE_MAX_NUM_PERIODS)
+#define MIN_BUFFER MAX_BUFFER
struct pdm_dev_data {
u32 pdm_irq;
void __iomem *acp_base;
struct snd_pcm_substream *capture_stream;
};
+struct pdm_stream_instance {
+ u16 num_pages;
+ u16 channels;
+ dma_addr_t dma_addr;
+ u64 bytescount;
+ void __iomem *acp_base;
+};
+
+union acp_pdm_dma_count {
+ struct {
+ u32 low;
+ u32 high;
+ } bcount;
+ u64 bytescount;
+};
+
static inline u32 rn_readl(void __iomem *base_addr)
{
return readl(base_addr - ACP_PHY_BASE_ADDRESS);
--
2.25.4
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 08/14] ASoC: amd: add ACP PDM DMA driver dai ops
2020-05-11 21:20 [PATCH v2 00/14] Add Renoir ACP driver Alex Deucher
` (6 preceding siblings ...)
2020-05-11 21:20 ` [PATCH v2 07/14] ASoC: amd: add acp3x pdm driver dma ops Alex Deucher
@ 2020-05-11 21:20 ` Alex Deucher
2020-05-11 22:12 ` Pierre-Louis Bossart
2020-05-11 21:20 ` [PATCH v2 09/14] ASoC: amd: add Renoir ACP PCI driver PM ops Alex Deucher
` (5 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: Alex Deucher @ 2020-05-11 21:20 UTC (permalink / raw)
To: alsa-devel, broonie, vijendar.mukunda, tiwai
Cc: Alex Deucher, Vijendar Mukunda
From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
This patch adds ACP3x PDM DMA driver DAI operations.
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
v2:
- Defined Macros for delay and counter and corrected dma stop sequence.
sound/soc/amd/renoir/acp3x-pdm-dma.c | 149 +++++++++++++++++++++++++++
sound/soc/amd/renoir/rn_acp3x.h | 9 ++
2 files changed, 158 insertions(+)
diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c
index 8bb03fa5b4a5..fd19b17f553e 100644
--- a/sound/soc/amd/renoir/acp3x-pdm-dma.c
+++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c
@@ -71,6 +71,27 @@ static void init_pdm_ring_buffer(u32 physical_addr,
rn_writel(0x01, acp_base + ACPAXI2AXI_ATU_CTRL);
}
+static void config_pdm_stream_params(unsigned int ch_mask,
+ void __iomem *acp_base)
+{
+ rn_writel(ch_mask, acp_base + ACP_WOV_PDM_NO_OF_CHANNELS);
+ rn_writel(PDM_DECIMATION_FACTOR, acp_base +
+ ACP_WOV_PDM_DECIMATION_FACTOR);
+}
+
+static void enable_pdm_clock(void __iomem *acp_base)
+{
+ u32 pdm_clk_enable, pdm_ctrl;
+
+ pdm_clk_enable = ACP_PDM_CLK_FREQ_MASK;
+ pdm_ctrl = 0x00;
+
+ rn_writel(pdm_clk_enable, acp_base + ACP_WOV_CLK_CTRL);
+ pdm_ctrl = rn_readl(acp_base + ACP_WOV_MISC_CTRL);
+ pdm_ctrl |= ACP_WOV_MISC_CTRL_MASK;
+ rn_writel(pdm_ctrl, acp_base + ACP_WOV_MISC_CTRL);
+}
+
static void enable_pdm_interrupts(void __iomem *acp_base)
{
u32 ext_int_ctrl;
@@ -89,6 +110,77 @@ static void disable_pdm_interrupts(void __iomem *acp_base)
rn_writel(ext_int_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
}
+static bool check_pdm_dma_status(void __iomem *acp_base)
+{
+ bool pdm_dma_status;
+ u32 pdm_enable, pdm_dma_enable;
+
+ pdm_dma_status = false;
+ pdm_enable = rn_readl(acp_base + ACP_WOV_PDM_ENABLE);
+ pdm_dma_enable = rn_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ if ((pdm_enable & ACP_PDM_ENABLE) && (pdm_dma_enable &
+ ACP_PDM_DMA_EN_STATUS))
+ pdm_dma_status = true;
+ return pdm_dma_status;
+}
+
+static int start_pdm_dma(void __iomem *acp_base)
+{
+ u32 pdm_enable;
+ u32 pdm_dma_enable;
+ int timeout;
+
+ pdm_enable = 0x01;
+ pdm_dma_enable = 0x01;
+
+ enable_pdm_clock(acp_base);
+ rn_writel(pdm_enable, acp_base + ACP_WOV_PDM_ENABLE);
+ rn_writel(pdm_dma_enable, acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ pdm_dma_enable = 0x00;
+ timeout = 0;
+ while (++timeout < ACP_COUNTER) {
+ pdm_dma_enable = rn_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ if ((pdm_dma_enable & 0x02) == ACP_PDM_DMA_EN_STATUS)
+ return 0;
+ udelay(DELAY_US);
+ }
+ return -ETIMEDOUT;
+}
+
+static int stop_pdm_dma(void __iomem *acp_base)
+{
+ u32 pdm_enable, pdm_dma_enable, pdm_fifo_flush;
+ int timeout;
+
+ pdm_enable = 0x00;
+ pdm_dma_enable = 0x00;
+ pdm_fifo_flush = 0x00;
+
+ pdm_enable = rn_readl(acp_base + ACP_WOV_PDM_ENABLE);
+ pdm_dma_enable = rn_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ if (pdm_dma_enable & 0x01) {
+ pdm_dma_enable = 0x02;
+ rn_writel(pdm_dma_enable, acp_base + ACP_WOV_PDM_DMA_ENABLE);
+ pdm_dma_enable = 0x00;
+ timeout = 0;
+ while (++timeout < ACP_COUNTER) {
+ pdm_dma_enable = rn_readl(acp_base +
+ ACP_WOV_PDM_DMA_ENABLE);
+ if ((pdm_dma_enable & 0x02) == 0x00)
+ break;
+ udelay(DELAY_US);
+ }
+ if (timeout == ACP_COUNTER)
+ return -ETIMEDOUT;
+ }
+ if (pdm_enable == ACP_PDM_ENABLE) {
+ pdm_enable = ACP_PDM_DISABLE;
+ rn_writel(pdm_enable, acp_base + ACP_WOV_PDM_ENABLE);
+ }
+ rn_writel(0x01, acp_base + ACP_WOV_PDM_FIFO_FLUSH);
+ return 0;
+}
+
static void config_acp_dma(struct pdm_stream_instance *rtd, int direction)
{
u16 page_idx;
@@ -230,6 +322,62 @@ static int acp_pdm_dma_close(struct snd_soc_component *component,
return 0;
}
+static int acp_pdm_dai_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct pdm_stream_instance *rtd;
+ unsigned int ch_mask;
+
+ rtd = substream->runtime->private_data;
+ switch (params_channels(params)) {
+ case TWO_CH:
+ default:
+ ch_mask = 0x00;
+ break;
+ }
+ config_pdm_stream_params(ch_mask, rtd->acp_base);
+ return 0;
+}
+
+static int acp_pdm_dai_trigger(struct snd_pcm_substream *substream,
+ int cmd, struct snd_soc_dai *dai)
+{
+ struct pdm_stream_instance *rtd;
+ int ret;
+ bool pdm_status;
+
+ rtd = substream->runtime->private_data;
+ ret = 0;
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ rtd->bytescount = acp_pdm_get_byte_count(rtd,
+ substream->stream);
+ pdm_status = check_pdm_dma_status(rtd->acp_base);
+ if (!pdm_status)
+ ret = start_pdm_dma(rtd->acp_base);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ pdm_status = check_pdm_dma_status(rtd->acp_base);
+ if (pdm_status)
+ ret = stop_pdm_dma(rtd->acp_base);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static struct snd_soc_dai_ops acp_pdm_dai_ops = {
+ .hw_params = acp_pdm_dai_hw_params,
+ .trigger = acp_pdm_dai_trigger,
+};
+
static struct snd_soc_dai_driver acp_pdm_dai_driver = {
.capture = {
.rates = SNDRV_PCM_RATE_48000,
@@ -240,6 +388,7 @@ static struct snd_soc_dai_driver acp_pdm_dai_driver = {
.rate_min = 48000,
.rate_max = 48000,
},
+ .ops = &acp_pdm_dai_ops,
};
static const struct snd_soc_component_driver acp_pdm_component = {
diff --git a/sound/soc/amd/renoir/rn_acp3x.h b/sound/soc/amd/renoir/rn_acp3x.h
index 3536d24374f3..a4f654cf2df0 100644
--- a/sound/soc/amd/renoir/rn_acp3x.h
+++ b/sound/soc/amd/renoir/rn_acp3x.h
@@ -31,6 +31,15 @@
#define PDM_DMA_STAT 0x10
#define PDM_DMA_INTR_MASK 0x10000
#define ACP_ERROR_STAT 29
+#define PDM_DECIMATION_FACTOR 0x2
+#define ACP_PDM_CLK_FREQ_MASK 0x07
+#define ACP_WOV_MISC_CTRL_MASK 0x10
+#define ACP_PDM_ENABLE 0x01
+#define ACP_PDM_DISABLE 0x00
+#define ACP_PDM_DMA_EN_STATUS 0x02
+#define TWO_CH 0x02
+#define DELAY_US 5
+#define ACP_COUNTER 20000
#define ACP_SRAM_PTE_OFFSET 0x02050000
#define PAGE_SIZE_4K_ENABLE 0x2
--
2.25.4
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH v2 08/14] ASoC: amd: add ACP PDM DMA driver dai ops
2020-05-11 21:20 ` [PATCH v2 08/14] ASoC: amd: add ACP PDM DMA driver dai ops Alex Deucher
@ 2020-05-11 22:12 ` Pierre-Louis Bossart
2020-05-12 16:15 ` Mukunda, Vijendar
0 siblings, 1 reply; 25+ messages in thread
From: Pierre-Louis Bossart @ 2020-05-11 22:12 UTC (permalink / raw)
To: Alex Deucher, alsa-devel, broonie, vijendar.mukunda, tiwai; +Cc: Alex Deucher
> +static int start_pdm_dma(void __iomem *acp_base)
> +{
> + u32 pdm_enable;
> + u32 pdm_dma_enable;
> + int timeout;
> +
> + pdm_enable = 0x01;
> + pdm_dma_enable = 0x01;
> +
> + enable_pdm_clock(acp_base);
> + rn_writel(pdm_enable, acp_base + ACP_WOV_PDM_ENABLE);
> + rn_writel(pdm_dma_enable, acp_base + ACP_WOV_PDM_DMA_ENABLE);
> + pdm_dma_enable = 0x00;
> + timeout = 0;
> + while (++timeout < ACP_COUNTER) {
> + pdm_dma_enable = rn_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
> + if ((pdm_dma_enable & 0x02) == ACP_PDM_DMA_EN_STATUS)
> + return 0;
> + udelay(DELAY_US);
> + }
> + return -ETIMEDOUT;
> +}
> +
> +static int stop_pdm_dma(void __iomem *acp_base)
> +{
> + u32 pdm_enable, pdm_dma_enable, pdm_fifo_flush;
> + int timeout;
> +
> + pdm_enable = 0x00;
> + pdm_dma_enable = 0x00;
> + pdm_fifo_flush = 0x00;
> +
> + pdm_enable = rn_readl(acp_base + ACP_WOV_PDM_ENABLE);
> + pdm_dma_enable = rn_readl(acp_base + ACP_WOV_PDM_DMA_ENABLE);
> + if (pdm_dma_enable & 0x01) {
> + pdm_dma_enable = 0x02;
> + rn_writel(pdm_dma_enable, acp_base + ACP_WOV_PDM_DMA_ENABLE);
> + pdm_dma_enable = 0x00;
> + timeout = 0;
> + while (++timeout < ACP_COUNTER) {
> + pdm_dma_enable = rn_readl(acp_base +
> + ACP_WOV_PDM_DMA_ENABLE);
> + if ((pdm_dma_enable & 0x02) == 0x00)
> + break;
> + udelay(DELAY_US);
> + }
> + if (timeout == ACP_COUNTER)
if you reach this point, timeout is by construction equal to ACP_COUNTER
so this test is useless
You could also use a helper where you check if the value is
ACP_PDM_DMA_EN_STATUS or zero so that you don't copy the same logic twice.
^ permalink raw reply [flat|nested] 25+ messages in thread
* RE: [PATCH v2 08/14] ASoC: amd: add ACP PDM DMA driver dai ops
2020-05-11 22:12 ` Pierre-Louis Bossart
@ 2020-05-12 16:15 ` Mukunda, Vijendar
0 siblings, 0 replies; 25+ messages in thread
From: Mukunda, Vijendar @ 2020-05-12 16:15 UTC (permalink / raw)
To: Pierre-Louis Bossart, Alex Deucher, alsa-devel, broonie, tiwai
Cc: Deucher, Alexander
> -----Original Message-----
> From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Sent: Tuesday, May 12, 2020 3:42 AM
> To: Alex Deucher <alexdeucher@gmail.com>; alsa-devel@alsa-project.org;
> broonie@kernel.org; Mukunda, Vijendar <Vijendar.Mukunda@amd.com>;
> tiwai@suse.de
> Cc: Deucher, Alexander <Alexander.Deucher@amd.com>
> Subject: Re: [PATCH v2 08/14] ASoC: amd: add ACP PDM DMA driver dai ops
>
>
>
>
> > +static int start_pdm_dma(void __iomem *acp_base)
> > +{
> > + u32 pdm_enable;
> > + u32 pdm_dma_enable;
> > + int timeout;
> > +
> > + pdm_enable = 0x01;
> > + pdm_dma_enable = 0x01;
> > +
> > + enable_pdm_clock(acp_base);
> > + rn_writel(pdm_enable, acp_base + ACP_WOV_PDM_ENABLE);
> > + rn_writel(pdm_dma_enable, acp_base +
> ACP_WOV_PDM_DMA_ENABLE);
> > + pdm_dma_enable = 0x00;
> > + timeout = 0;
> > + while (++timeout < ACP_COUNTER) {
> > + pdm_dma_enable = rn_readl(acp_base +
> ACP_WOV_PDM_DMA_ENABLE);
> > + if ((pdm_dma_enable & 0x02) ==
> ACP_PDM_DMA_EN_STATUS)
> > + return 0;
> > + udelay(DELAY_US);
> > + }
> > + return -ETIMEDOUT;
> > +}
> > +
> > +static int stop_pdm_dma(void __iomem *acp_base)
> > +{
> > + u32 pdm_enable, pdm_dma_enable, pdm_fifo_flush;
> > + int timeout;
> > +
> > + pdm_enable = 0x00;
> > + pdm_dma_enable = 0x00;
> > + pdm_fifo_flush = 0x00;
> > +
> > + pdm_enable = rn_readl(acp_base + ACP_WOV_PDM_ENABLE);
> > + pdm_dma_enable = rn_readl(acp_base +
> ACP_WOV_PDM_DMA_ENABLE);
> > + if (pdm_dma_enable & 0x01) {
> > + pdm_dma_enable = 0x02;
> > + rn_writel(pdm_dma_enable, acp_base +
> ACP_WOV_PDM_DMA_ENABLE);
> > + pdm_dma_enable = 0x00;
> > + timeout = 0;
> > + while (++timeout < ACP_COUNTER) {
> > + pdm_dma_enable = rn_readl(acp_base +
> > +
> ACP_WOV_PDM_DMA_ENABLE);
> > + if ((pdm_dma_enable & 0x02) == 0x00)
> > + break;
> > + udelay(DELAY_US);
> > + }
> > + if (timeout == ACP_COUNTER)
>
> if you reach this point, timeout is by construction equal to ACP_COUNTER
> so this test is useless
Here we are checking current dma status.
If DMA enable status bit is set to zero , it will exit the while loop.
It will continue rest of the registers programming to disable PDM
decoder and flushing fifo.
When this condition "if ((pdm_dma_enable & 0x02) == 0x00)" is true,
"timeout" counter won't be exhausted i.e it won't cross ACP_COUNTER
value.
We have to return time out error only when DMA enable status bit is
not cleared and timeout reached max value i.e ACP_COUNTER. i.e
This check " if (timeout == ACP_COUNTER) " required to know the while
loop exit condition.
>
> You could also use a helper where you check if the value is
> ACP_PDM_DMA_EN_STATUS or zero so that you don't copy the same logic
> twice.
I believe it's only a single register check, still its hold to be good.
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 09/14] ASoC: amd: add Renoir ACP PCI driver PM ops
2020-05-11 21:20 [PATCH v2 00/14] Add Renoir ACP driver Alex Deucher
` (7 preceding siblings ...)
2020-05-11 21:20 ` [PATCH v2 08/14] ASoC: amd: add ACP PDM DMA driver dai ops Alex Deucher
@ 2020-05-11 21:20 ` Alex Deucher
2020-05-11 22:28 ` Pierre-Louis Bossart
2020-05-11 21:20 ` [PATCH v2 10/14] ASoC: amd: add ACP PDM DMA driver pm ops Alex Deucher
` (4 subsequent siblings)
13 siblings, 1 reply; 25+ messages in thread
From: Alex Deucher @ 2020-05-11 21:20 UTC (permalink / raw)
To: alsa-devel, broonie, vijendar.mukunda, tiwai
Cc: Alex Deucher, Vijendar Mukunda
From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Add Renoir ACP Pci driver pm ops.
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
v2:
- Changed PCI driver pm runtime sequence
sound/soc/amd/renoir/rn-pci-acp3x.c | 48 +++++++++++++++++++++++++++++
sound/soc/amd/renoir/rn_acp3x.h | 2 ++
2 files changed, 50 insertions(+)
diff --git a/sound/soc/amd/renoir/rn-pci-acp3x.c b/sound/soc/amd/renoir/rn-pci-acp3x.c
index 362409ef0d85..14651df9b5c8 100644
--- a/sound/soc/amd/renoir/rn-pci-acp3x.c
+++ b/sound/soc/amd/renoir/rn-pci-acp3x.c
@@ -10,6 +10,7 @@
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
#include "rn_acp3x.h"
@@ -233,6 +234,11 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
ret = PTR_ERR(adata->pdev);
goto unregister_devs;
}
+ pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
+ pm_runtime_use_autosuspend(&pci->dev);
+ pm_runtime_allow(&pci->dev);
+ pm_runtime_mark_last_busy(&pci->dev);
+ pm_runtime_put_autosuspend(&pci->dev);
return 0;
unregister_devs:
@@ -250,6 +256,42 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
return ret;
}
+static int snd_rn_acp_suspend(struct device *dev)
+{
+ int ret;
+ struct acp_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ ret = rn_acp_deinit(adata->acp_base);
+ if (ret)
+ dev_err(dev, "ACP de-init failed\n");
+ else
+ dev_dbg(dev, "ACP de-initialized\n");
+
+ return 0;
+}
+
+static int snd_rn_acp_resume(struct device *dev)
+{
+ int ret;
+ struct acp_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ ret = rn_acp_init(adata->acp_base);
+ if (ret) {
+ dev_err(dev, "ACP init failed\n");
+ return ret;
+ }
+ return 0;
+}
+
+static const struct dev_pm_ops rn_acp_pm = {
+ .runtime_suspend = snd_rn_acp_suspend,
+ .runtime_resume = snd_rn_acp_resume,
+ .suspend = snd_rn_acp_suspend,
+ .resume = snd_rn_acp_resume,
+};
+
static void snd_rn_acp_remove(struct pci_dev *pci)
{
struct acp_dev_data *adata;
@@ -260,6 +302,9 @@ static void snd_rn_acp_remove(struct pci_dev *pci)
ret = rn_acp_deinit(adata->acp_base);
if (ret)
dev_err(&pci->dev, "ACP de-init failed\n");
+ pm_runtime_put_noidle(&pci->dev);
+ pm_runtime_get_sync(&pci->dev);
+ pm_runtime_forbid(&pci->dev);
pci_disable_msi(pci);
pci_release_regions(pci);
pci_disable_device(pci);
@@ -278,6 +323,9 @@ static struct pci_driver rn_acp_driver = {
.id_table = snd_rn_acp_ids,
.probe = snd_rn_acp_probe,
.remove = snd_rn_acp_remove,
+ .driver = {
+ .pm = &rn_acp_pm,
+ }
};
module_pci_driver(rn_acp_driver);
diff --git a/sound/soc/amd/renoir/rn_acp3x.h b/sound/soc/amd/renoir/rn_acp3x.h
index a4f654cf2df0..6e1888167fb3 100644
--- a/sound/soc/amd/renoir/rn_acp3x.h
+++ b/sound/soc/amd/renoir/rn_acp3x.h
@@ -40,6 +40,8 @@
#define TWO_CH 0x02
#define DELAY_US 5
#define ACP_COUNTER 20000
+/* time in ms for runtime suspend delay */
+#define ACP_SUSPEND_DELAY_MS 2000
#define ACP_SRAM_PTE_OFFSET 0x02050000
#define PAGE_SIZE_4K_ENABLE 0x2
--
2.25.4
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH v2 09/14] ASoC: amd: add Renoir ACP PCI driver PM ops
2020-05-11 21:20 ` [PATCH v2 09/14] ASoC: amd: add Renoir ACP PCI driver PM ops Alex Deucher
@ 2020-05-11 22:28 ` Pierre-Louis Bossart
2020-05-12 13:46 ` Alex Deucher
0 siblings, 1 reply; 25+ messages in thread
From: Pierre-Louis Bossart @ 2020-05-11 22:28 UTC (permalink / raw)
To: Alex Deucher, alsa-devel, broonie, vijendar.mukunda, tiwai; +Cc: Alex Deucher
> @@ -233,6 +234,11 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
> ret = PTR_ERR(adata->pdev);
> goto unregister_devs;
> }
> + pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
> + pm_runtime_use_autosuspend(&pci->dev);
> + pm_runtime_allow(&pci->dev);
> + pm_runtime_mark_last_busy(&pci->dev);
> + pm_runtime_put_autosuspend(&pci->dev);
usually there is a pm_runtime_put_noidle() here?
[...]
> static void snd_rn_acp_remove(struct pci_dev *pci)
> {
> struct acp_dev_data *adata;
> @@ -260,6 +302,9 @@ static void snd_rn_acp_remove(struct pci_dev *pci)
> ret = rn_acp_deinit(adata->acp_base);
> if (ret)
> dev_err(&pci->dev, "ACP de-init failed\n");
> + pm_runtime_put_noidle(&pci->dev);
> + pm_runtime_get_sync(&pci->dev);
> + pm_runtime_forbid(&pci->dev);
doing a put_noidle() followed by a get_sync() and immediately forbid()
is very odd at best.
Isn't the recommendation to call get_noresume() here?
> pci_disable_msi(pci);
> pci_release_regions(pci);
> pci_disable_device(pci);
> @@ -278,6 +323,9 @@ static struct pci_driver rn_acp_driver = {
> .id_table = snd_rn_acp_ids,
> .probe = snd_rn_acp_probe,
> .remove = snd_rn_acp_remove,
> + .driver = {
> + .pm = &rn_acp_pm,
> + }
> };
>
> module_pci_driver(rn_acp_driver);
> diff --git a/sound/soc/amd/renoir/rn_acp3x.h b/sound/soc/amd/renoir/rn_acp3x.h
> index a4f654cf2df0..6e1888167fb3 100644
> --- a/sound/soc/amd/renoir/rn_acp3x.h
> +++ b/sound/soc/amd/renoir/rn_acp3x.h
> @@ -40,6 +40,8 @@
> #define TWO_CH 0x02
> #define DELAY_US 5
> #define ACP_COUNTER 20000
> +/* time in ms for runtime suspend delay */
> +#define ACP_SUSPEND_DELAY_MS 2000
>
> #define ACP_SRAM_PTE_OFFSET 0x02050000
> #define PAGE_SIZE_4K_ENABLE 0x2
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v2 09/14] ASoC: amd: add Renoir ACP PCI driver PM ops
2020-05-11 22:28 ` Pierre-Louis Bossart
@ 2020-05-12 13:46 ` Alex Deucher
2020-05-12 15:16 ` Pierre-Louis Bossart
0 siblings, 1 reply; 25+ messages in thread
From: Alex Deucher @ 2020-05-12 13:46 UTC (permalink / raw)
To: Pierre-Louis Bossart
Cc: Takashi Iwai, Alex Deucher, alsa-devel, Mark Brown, Vijendar Mukunda
On Mon, May 11, 2020 at 6:37 PM Pierre-Louis Bossart
<pierre-louis.bossart@linux.intel.com> wrote:
>
>
> > @@ -233,6 +234,11 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
> > ret = PTR_ERR(adata->pdev);
> > goto unregister_devs;
> > }
> > + pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
> > + pm_runtime_use_autosuspend(&pci->dev);
> > + pm_runtime_allow(&pci->dev);
> > + pm_runtime_mark_last_busy(&pci->dev);
> > + pm_runtime_put_autosuspend(&pci->dev);
>
> usually there is a pm_runtime_put_noidle() here?
I'm not sure.
>
> [...]
>
> > static void snd_rn_acp_remove(struct pci_dev *pci)
> > {
> > struct acp_dev_data *adata;
> > @@ -260,6 +302,9 @@ static void snd_rn_acp_remove(struct pci_dev *pci)
> > ret = rn_acp_deinit(adata->acp_base);
> > if (ret)
> > dev_err(&pci->dev, "ACP de-init failed\n");
> > + pm_runtime_put_noidle(&pci->dev);
> > + pm_runtime_get_sync(&pci->dev);
> > + pm_runtime_forbid(&pci->dev);
>
> doing a put_noidle() followed by a get_sync() and immediately forbid()
> is very odd at best.
> Isn't the recommendation to call get_noresume() here?
>
I'm not sure here either. Is there some definitive documentation on
what exact sequences are supposed to be used in drivers? A quick
browse through drivers that implement runtime pm seems to show a lot
of variation. This sequence works. I'm not sure if it's optimal or
not.
Alex
>
>
> > pci_disable_msi(pci);
> > pci_release_regions(pci);
> > pci_disable_device(pci);
> > @@ -278,6 +323,9 @@ static struct pci_driver rn_acp_driver = {
> > .id_table = snd_rn_acp_ids,
> > .probe = snd_rn_acp_probe,
> > .remove = snd_rn_acp_remove,
> > + .driver = {
> > + .pm = &rn_acp_pm,
> > + }
> > };
> >
> > module_pci_driver(rn_acp_driver);
> > diff --git a/sound/soc/amd/renoir/rn_acp3x.h b/sound/soc/amd/renoir/rn_acp3x.h
> > index a4f654cf2df0..6e1888167fb3 100644
> > --- a/sound/soc/amd/renoir/rn_acp3x.h
> > +++ b/sound/soc/amd/renoir/rn_acp3x.h
> > @@ -40,6 +40,8 @@
> > #define TWO_CH 0x02
> > #define DELAY_US 5
> > #define ACP_COUNTER 20000
> > +/* time in ms for runtime suspend delay */
> > +#define ACP_SUSPEND_DELAY_MS 2000
> >
> > #define ACP_SRAM_PTE_OFFSET 0x02050000
> > #define PAGE_SIZE_4K_ENABLE 0x2
> >
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v2 09/14] ASoC: amd: add Renoir ACP PCI driver PM ops
2020-05-12 13:46 ` Alex Deucher
@ 2020-05-12 15:16 ` Pierre-Louis Bossart
2020-05-12 19:54 ` Mukunda, Vijendar
0 siblings, 1 reply; 25+ messages in thread
From: Pierre-Louis Bossart @ 2020-05-12 15:16 UTC (permalink / raw)
To: Alex Deucher
Cc: Takashi Iwai, Alex Deucher, alsa-devel, Mark Brown, Vijendar Mukunda
On 5/12/20 8:46 AM, Alex Deucher wrote:
> On Mon, May 11, 2020 at 6:37 PM Pierre-Louis Bossart
> <pierre-louis.bossart@linux.intel.com> wrote:
>>
>>
>>> @@ -233,6 +234,11 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
>>> ret = PTR_ERR(adata->pdev);
>>> goto unregister_devs;
>>> }
>>> + pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
>>> + pm_runtime_use_autosuspend(&pci->dev);
>>> + pm_runtime_allow(&pci->dev);
>>> + pm_runtime_mark_last_busy(&pci->dev);
>>> + pm_runtime_put_autosuspend(&pci->dev);
>>
>> usually there is a pm_runtime_put_noidle() here?
>
> I'm not sure.
>
>>
>> [...]
>>
>>> static void snd_rn_acp_remove(struct pci_dev *pci)
>>> {
>>> struct acp_dev_data *adata;
>>> @@ -260,6 +302,9 @@ static void snd_rn_acp_remove(struct pci_dev *pci)
>>> ret = rn_acp_deinit(adata->acp_base);
>>> if (ret)
>>> dev_err(&pci->dev, "ACP de-init failed\n");
>>> + pm_runtime_put_noidle(&pci->dev);
>>> + pm_runtime_get_sync(&pci->dev);
>>> + pm_runtime_forbid(&pci->dev);
>>
>> doing a put_noidle() followed by a get_sync() and immediately forbid()
>> is very odd at best.
>> Isn't the recommendation to call get_noresume() here?
>>
>
> I'm not sure here either. Is there some definitive documentation on
> what exact sequences are supposed to be used in drivers? A quick
> browse through drivers that implement runtime pm seems to show a lot
> of variation. This sequence works. I'm not sure if it's optimal or
> not.
We based our sequence on the comments in drivers/pci/pci-driver.c
/*
* Unbound PCI devices are always put in D0, regardless of
* runtime PM status. During probe, the device is set to
* active and the usage count is incremented. If the driver
* supports runtime PM, it should call pm_runtime_put_noidle(),
* or any other runtime PM helper function decrementing the usage
* count, in its probe routine and pm_runtime_get_noresume() in
* its remove routine.
*/
^ permalink raw reply [flat|nested] 25+ messages in thread
* RE: [PATCH v2 09/14] ASoC: amd: add Renoir ACP PCI driver PM ops
2020-05-12 15:16 ` Pierre-Louis Bossart
@ 2020-05-12 19:54 ` Mukunda, Vijendar
2020-05-12 20:36 ` Pierre-Louis Bossart
0 siblings, 1 reply; 25+ messages in thread
From: Mukunda, Vijendar @ 2020-05-12 19:54 UTC (permalink / raw)
To: Pierre-Louis Bossart, Alex Deucher
Cc: Takashi Iwai, Deucher, Alexander, alsa-devel, Mark Brown
> -----Original Message-----
> From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Sent: Tuesday, May 12, 2020 8:46 PM
> To: Alex Deucher <alexdeucher@gmail.com>
> Cc: Takashi Iwai <tiwai@suse.de>; Deucher, Alexander
> <Alexander.Deucher@amd.com>; alsa-devel@alsa-project.org; Mark Brown
> <broonie@kernel.org>; Mukunda, Vijendar <Vijendar.Mukunda@amd.com>
> Subject: Re: [PATCH v2 09/14] ASoC: amd: add Renoir ACP PCI driver PM ops
>
>
>
> On 5/12/20 8:46 AM, Alex Deucher wrote:
> > On Mon, May 11, 2020 at 6:37 PM Pierre-Louis Bossart
> > <pierre-louis.bossart@linux.intel.com> wrote:
> >>
> >>
> >>> @@ -233,6 +234,11 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
> >>> ret = PTR_ERR(adata->pdev);
> >>> goto unregister_devs;
> >>> }
> >>> + pm_runtime_set_autosuspend_delay(&pci->dev,
> ACP_SUSPEND_DELAY_MS);
> >>> + pm_runtime_use_autosuspend(&pci->dev);
> >>> + pm_runtime_allow(&pci->dev);
> >>> + pm_runtime_mark_last_busy(&pci->dev);
> >>> + pm_runtime_put_autosuspend(&pci->dev);
> >>
> >> usually there is a pm_runtime_put_noidle() here?
> >
> > I'm not sure.
> >
> >>
> >> [...]
> >>
> >>> static void snd_rn_acp_remove(struct pci_dev *pci)
> >>> {
> >>> struct acp_dev_data *adata;
> >>> @@ -260,6 +302,9 @@ static void snd_rn_acp_remove(struct pci_dev
> *pci)
> >>> ret = rn_acp_deinit(adata->acp_base);
> >>> if (ret)
> >>> dev_err(&pci->dev, "ACP de-init failed\n");
> >>> + pm_runtime_put_noidle(&pci->dev);
> >>> + pm_runtime_get_sync(&pci->dev);
> >>> + pm_runtime_forbid(&pci->dev);
> >>
> >> doing a put_noidle() followed by a get_sync() and immediately forbid()
> >> is very odd at best.
> >> Isn't the recommendation to call get_noresume() here?
> >>
> >
> > I'm not sure here either. Is there some definitive documentation on
> > what exact sequences are supposed to be used in drivers? A quick
> > browse through drivers that implement runtime pm seems to show a lot
> > of variation. This sequence works. I'm not sure if it's optimal or
> > not.
>
> We based our sequence on the comments in drivers/pci/pci-driver.c
>
> /*
> * Unbound PCI devices are always put in D0, regardless of
> * runtime PM status. During probe, the device is set to
> * active and the usage count is incremented. If the driver
> * supports runtime PM, it should call pm_runtime_put_noidle(),
> * or any other runtime PM helper function decrementing the usage
> * count, in its probe routine and pm_runtime_get_noresume() in
> * its remove routine.
> */
If I understood correctly, below should be the correct sequence rite ?
acp pci driver probe sequence:
pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(&pci->dev);
pm_runtime_put_noidle(&pci->dev);
pm_runtime_allow(&pci->dev);
acp pci driver remove sequence:
pm_runtime_get_noresume(&pci->dev);
pm_runtime_disable(&pci->dev);
I have still have a doubt.
Do we need to call pm_runtime_disable() explicitly in this case ?
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH v2 09/14] ASoC: amd: add Renoir ACP PCI driver PM ops
2020-05-12 19:54 ` Mukunda, Vijendar
@ 2020-05-12 20:36 ` Pierre-Louis Bossart
2020-05-13 17:44 ` Mukunda, Vijendar
0 siblings, 1 reply; 25+ messages in thread
From: Pierre-Louis Bossart @ 2020-05-12 20:36 UTC (permalink / raw)
To: Mukunda, Vijendar, Alex Deucher
Cc: Takashi Iwai, Deucher, Alexander, alsa-devel, Mark Brown
>>>>> + pm_runtime_set_autosuspend_delay(&pci->dev,
>> ACP_SUSPEND_DELAY_MS);
>>>>> + pm_runtime_use_autosuspend(&pci->dev);
>>>>> + pm_runtime_allow(&pci->dev);
>>>>> + pm_runtime_mark_last_busy(&pci->dev);
>>>>> + pm_runtime_put_autosuspend(&pci->dev);
>>>>
>>>> usually there is a pm_runtime_put_noidle() here?
>>>
>>> I'm not sure.
>>>
>>>>
>>>> [...]
>>>>
>>>>> static void snd_rn_acp_remove(struct pci_dev *pci)
>>>>> {
>>>>> struct acp_dev_data *adata;
>>>>> @@ -260,6 +302,9 @@ static void snd_rn_acp_remove(struct pci_dev
>> *pci)
>>>>> ret = rn_acp_deinit(adata->acp_base);
>>>>> if (ret)
>>>>> dev_err(&pci->dev, "ACP de-init failed\n");
>>>>> + pm_runtime_put_noidle(&pci->dev);
>>>>> + pm_runtime_get_sync(&pci->dev);
>>>>> + pm_runtime_forbid(&pci->dev);
>>>>
>>>> doing a put_noidle() followed by a get_sync() and immediately forbid()
>>>> is very odd at best.
>>>> Isn't the recommendation to call get_noresume() here?
>>>>
>>>
>>> I'm not sure here either. Is there some definitive documentation on
>>> what exact sequences are supposed to be used in drivers? A quick
>>> browse through drivers that implement runtime pm seems to show a lot
>>> of variation. This sequence works. I'm not sure if it's optimal or
>>> not.
>>
>> We based our sequence on the comments in drivers/pci/pci-driver.c
>>
>> /*
>> * Unbound PCI devices are always put in D0, regardless of
>> * runtime PM status. During probe, the device is set to
>> * active and the usage count is incremented. If the driver
>> * supports runtime PM, it should call pm_runtime_put_noidle(),
>> * or any other runtime PM helper function decrementing the usage
>> * count, in its probe routine and pm_runtime_get_noresume() in
>> * its remove routine.
>> */
>
> If I understood correctly, below should be the correct sequence rite ?
>
> acp pci driver probe sequence:
>
> pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
> pm_runtime_use_autosuspend(&pci->dev);
> pm_runtime_put_noidle(&pci->dev);
> pm_runtime_allow(&pci->dev);
sounds about right. We added an extra pm_runtime_mark_last_busy() to
make sure the information is updated, but that's probably on the
paranoid side.
>
> acp pci driver remove sequence:
>
> pm_runtime_get_noresume(&pci->dev);
> pm_runtime_disable(&pci->dev);
>
> I have still have a doubt.
> Do we need to call pm_runtime_disable() explicitly in this case ?
we don't call pm_runtime_disable().
^ permalink raw reply [flat|nested] 25+ messages in thread
* RE: [PATCH v2 09/14] ASoC: amd: add Renoir ACP PCI driver PM ops
2020-05-12 20:36 ` Pierre-Louis Bossart
@ 2020-05-13 17:44 ` Mukunda, Vijendar
0 siblings, 0 replies; 25+ messages in thread
From: Mukunda, Vijendar @ 2020-05-13 17:44 UTC (permalink / raw)
To: Pierre-Louis Bossart, Alex Deucher
Cc: Takashi Iwai, Deucher, Alexander, alsa-devel, Mark Brown
[AMD Official Use Only - Internal Distribution Only]
> -----Original Message-----
> From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Sent: Wednesday, May 13, 2020 2:06 AM
> To: Mukunda, Vijendar <Vijendar.Mukunda@amd.com>; Alex Deucher
> <alexdeucher@gmail.com>
> Cc: Takashi Iwai <tiwai@suse.de>; Deucher, Alexander
> <Alexander.Deucher@amd.com>; alsa-devel@alsa-project.org; Mark Brown
> <broonie@kernel.org>
> Subject: Re: [PATCH v2 09/14] ASoC: amd: add Renoir ACP PCI driver PM ops
>
>
>
> >>>>> + pm_runtime_set_autosuspend_delay(&pci->dev,
> >> ACP_SUSPEND_DELAY_MS);
> >>>>> + pm_runtime_use_autosuspend(&pci->dev);
> >>>>> + pm_runtime_allow(&pci->dev);
> >>>>> + pm_runtime_mark_last_busy(&pci->dev);
> >>>>> + pm_runtime_put_autosuspend(&pci->dev);
> >>>>
> >>>> usually there is a pm_runtime_put_noidle() here?
> >>>
> >>> I'm not sure.
> >>>
> >>>>
> >>>> [...]
> >>>>
> >>>>> static void snd_rn_acp_remove(struct pci_dev *pci)
> >>>>> {
> >>>>> struct acp_dev_data *adata;
> >>>>> @@ -260,6 +302,9 @@ static void snd_rn_acp_remove(struct pci_dev
> >> *pci)
> >>>>> ret = rn_acp_deinit(adata->acp_base);
> >>>>> if (ret)
> >>>>> dev_err(&pci->dev, "ACP de-init failed\n");
> >>>>> + pm_runtime_put_noidle(&pci->dev);
> >>>>> + pm_runtime_get_sync(&pci->dev);
> >>>>> + pm_runtime_forbid(&pci->dev);
> >>>>
> >>>> doing a put_noidle() followed by a get_sync() and immediately forbid()
> >>>> is very odd at best.
> >>>> Isn't the recommendation to call get_noresume() here?
> >>>>
> >>>
> >>> I'm not sure here either. Is there some definitive documentation on
> >>> what exact sequences are supposed to be used in drivers? A quick
> >>> browse through drivers that implement runtime pm seems to show a lot
> >>> of variation. This sequence works. I'm not sure if it's optimal or
> >>> not.
> >>
> >> We based our sequence on the comments in drivers/pci/pci-driver.c
> >>
> >> /*
> >> * Unbound PCI devices are always put in D0, regardless of
> >> * runtime PM status. During probe, the device is set to
> >> * active and the usage count is incremented. If the driver
> >> * supports runtime PM, it should call pm_runtime_put_noidle(),
> >> * or any other runtime PM helper function decrementing the usage
> >> * count, in its probe routine and pm_runtime_get_noresume() in
> >> * its remove routine.
> >> */
> >
> > If I understood correctly, below should be the correct sequence rite ?
> >
> > acp pci driver probe sequence:
> >
> > pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
> > pm_runtime_use_autosuspend(&pci->dev);
> > pm_runtime_put_noidle(&pci->dev);
> > pm_runtime_allow(&pci->dev);
>
> sounds about right. We added an extra pm_runtime_mark_last_busy() to
> make sure the information is updated, but that's probably on the
> paranoid side.
> >
> > acp pci driver remove sequence:
> >
> > pm_runtime_get_noresume(&pci->dev);
> > pm_runtime_disable(&pci->dev);
> >
> > I have still have a doubt.
> > Do we need to call pm_runtime_disable() explicitly in this case ?
>
> we don't call pm_runtime_disable().
I see in one of the PCI driver implementation, in driver remove sequence
pm_runtime_forbid( ) API is called before pm_runtime_get_noresume () call.
I believe , It's safe to call pm_runtime_forbid() which will prevent device to
be power managed at runtime in remove sequence.
Correct me, if my understanding is wrong .
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 10/14] ASoC: amd: add ACP PDM DMA driver pm ops
2020-05-11 21:20 [PATCH v2 00/14] Add Renoir ACP driver Alex Deucher
` (8 preceding siblings ...)
2020-05-11 21:20 ` [PATCH v2 09/14] ASoC: amd: add Renoir ACP PCI driver PM ops Alex Deucher
@ 2020-05-11 21:20 ` Alex Deucher
2020-05-11 21:20 ` [PATCH v2 11/14] ASoC: amd: enable Renoir acp3x drivers build Alex Deucher
` (3 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: Alex Deucher @ 2020-05-11 21:20 UTC (permalink / raw)
To: alsa-devel, broonie, vijendar.mukunda, tiwai
Cc: Alex Deucher, Vijendar Mukunda
From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Add ACP PDM DMA driver pm ops.
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
sound/soc/amd/renoir/acp3x-pdm-dma.c | 53 ++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c
index fd19b17f553e..942010021319 100644
--- a/sound/soc/amd/renoir/acp3x-pdm-dma.c
+++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c
@@ -8,6 +8,7 @@
#include <linux/module.h>
#include <linux/err.h>
#include <linux/io.h>
+#include <linux/pm_runtime.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dai.h>
@@ -453,19 +454,71 @@ static int acp_pdm_audio_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "ACP PDM IRQ request failed\n");
return -ENODEV;
}
+ pm_runtime_set_autosuspend_delay(&pdev->dev, ACP_SUSPEND_DELAY_MS);
+ pm_runtime_use_autosuspend(&pdev->dev);
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_allow(&pdev->dev);
return 0;
}
static int acp_pdm_audio_remove(struct platform_device *pdev)
{
+ pm_runtime_disable(&pdev->dev);
return 0;
}
+static int acp_pdm_resume(struct device *dev)
+{
+ struct pdm_dev_data *adata;
+ struct snd_pcm_runtime *runtime;
+ struct pdm_stream_instance *rtd;
+ u32 period_bytes, buffer_len;
+
+ adata = dev_get_drvdata(dev);
+ if (adata->capture_stream && adata->capture_stream->runtime) {
+ runtime = adata->capture_stream->runtime;
+ rtd = runtime->private_data;
+ period_bytes = frames_to_bytes(runtime, runtime->period_size);
+ buffer_len = frames_to_bytes(runtime, runtime->buffer_size);
+ config_acp_dma(rtd, SNDRV_PCM_STREAM_CAPTURE);
+ init_pdm_ring_buffer(MEM_WINDOW_START, buffer_len, period_bytes,
+ adata->acp_base);
+ }
+ enable_pdm_interrupts(adata->acp_base);
+ return 0;
+}
+
+static int acp_pdm_runtime_suspend(struct device *dev)
+{
+ struct pdm_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ disable_pdm_interrupts(adata->acp_base);
+
+ return 0;
+}
+
+static int acp_pdm_runtime_resume(struct device *dev)
+{
+ struct pdm_dev_data *adata;
+
+ adata = dev_get_drvdata(dev);
+ enable_pdm_interrupts(adata->acp_base);
+ return 0;
+}
+
+static const struct dev_pm_ops acp_pdm_pm_ops = {
+ .runtime_suspend = acp_pdm_runtime_suspend,
+ .runtime_resume = acp_pdm_runtime_resume,
+ .resume = acp_pdm_resume,
+};
+
static struct platform_driver acp_pdm_dma_driver = {
.probe = acp_pdm_audio_probe,
.remove = acp_pdm_audio_remove,
.driver = {
.name = "acp_rn_pdm_dma",
+ .pm = &acp_pdm_pm_ops,
},
};
--
2.25.4
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 11/14] ASoC: amd: enable Renoir acp3x drivers build
2020-05-11 21:20 [PATCH v2 00/14] Add Renoir ACP driver Alex Deucher
` (9 preceding siblings ...)
2020-05-11 21:20 ` [PATCH v2 10/14] ASoC: amd: add ACP PDM DMA driver pm ops Alex Deucher
@ 2020-05-11 21:20 ` Alex Deucher
2020-05-11 21:20 ` [PATCH v2 12/14] ASoC: amd: create platform devices for Renoir Alex Deucher
` (2 subsequent siblings)
13 siblings, 0 replies; 25+ messages in thread
From: Alex Deucher @ 2020-05-11 21:20 UTC (permalink / raw)
To: alsa-devel, broonie, vijendar.mukunda, tiwai
Cc: Alex Deucher, Vijendar Mukunda
From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Renoir ACP3x drivers can be built by selecting necessary
kernel config option.
The patch enables build support of the same.
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
sound/soc/amd/Kconfig | 6 ++++++
sound/soc/amd/Makefile | 1 +
sound/soc/amd/renoir/Makefile | 6 ++++++
3 files changed, 13 insertions(+)
create mode 100644 sound/soc/amd/renoir/Makefile
diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig
index bce4cee5cb54..5f57a47382b4 100644
--- a/sound/soc/amd/Kconfig
+++ b/sound/soc/amd/Kconfig
@@ -36,3 +36,9 @@ config SND_SOC_AMD_RV_RT5682_MACH
depends on SND_SOC_AMD_ACP3x && I2C && CROS_EC
help
This option enables machine driver for RT5682 and MAX9835.
+
+config SND_SOC_AMD_RENOIR
+ tristate "AMD Audio Coprocessor - Renoir support"
+ depends on X86 && PCI
+ help
+ This option enables ACP support for Renoir platform
diff --git a/sound/soc/amd/Makefile b/sound/soc/amd/Makefile
index e6f3d9b469f3..e6df2f72a2a1 100644
--- a/sound/soc/amd/Makefile
+++ b/sound/soc/amd/Makefile
@@ -9,3 +9,4 @@ obj-$(CONFIG_SND_SOC_AMD_CZ_DA7219MX98357_MACH) += snd-soc-acp-da7219mx98357-mac
obj-$(CONFIG_SND_SOC_AMD_CZ_RT5645_MACH) += snd-soc-acp-rt5645-mach.o
obj-$(CONFIG_SND_SOC_AMD_ACP3x) += raven/
obj-$(CONFIG_SND_SOC_AMD_RV_RT5682_MACH) += snd-soc-acp-rt5682-mach.o
+obj-$(CONFIG_SND_SOC_AMD_RENOIR) += renoir/
diff --git a/sound/soc/amd/renoir/Makefile b/sound/soc/amd/renoir/Makefile
new file mode 100644
index 000000000000..43100515c7db
--- /dev/null
+++ b/sound/soc/amd/renoir/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Renoir platform Support
+snd-rn-pci-acp3x-objs := rn-pci-acp3x.o
+snd-acp3x-pdm-dma-objs := acp3x-pdm-dma.o
+obj-$(CONFIG_SND_SOC_AMD_RENOIR) += snd-rn-pci-acp3x.o
+obj-$(CONFIG_SND_SOC_AMD_RENOIR) += snd-acp3x-pdm-dma.o
--
2.25.4
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 12/14] ASoC: amd: create platform devices for Renoir
2020-05-11 21:20 [PATCH v2 00/14] Add Renoir ACP driver Alex Deucher
` (10 preceding siblings ...)
2020-05-11 21:20 ` [PATCH v2 11/14] ASoC: amd: enable Renoir acp3x drivers build Alex Deucher
@ 2020-05-11 21:20 ` Alex Deucher
2020-05-11 21:20 ` [PATCH v2 13/14] ASoC: amd: RN machine driver using dmic Alex Deucher
2020-05-11 21:20 ` [PATCH v2 14/14] ASoC: amd: enable build for RN machine driver Alex Deucher
13 siblings, 0 replies; 25+ messages in thread
From: Alex Deucher @ 2020-05-11 21:20 UTC (permalink / raw)
To: alsa-devel, broonie, vijendar.mukunda, tiwai
Cc: Alex Deucher, Vijendar Mukunda
From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Create platform devices for generic dmic codec driver and
machine driver.
These platform devices required for creation of sound card.
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
sound/soc/amd/renoir/rn-pci-acp3x.c | 51 ++++++++++++++++++-----------
sound/soc/amd/renoir/rn_acp3x.h | 1 +
2 files changed, 32 insertions(+), 20 deletions(-)
diff --git a/sound/soc/amd/renoir/rn-pci-acp3x.c b/sound/soc/amd/renoir/rn-pci-acp3x.c
index 14651df9b5c8..8ae0d75103ff 100644
--- a/sound/soc/amd/renoir/rn-pci-acp3x.c
+++ b/sound/soc/amd/renoir/rn-pci-acp3x.c
@@ -21,7 +21,7 @@ MODULE_PARM_DESC(acp_power_gating, "Enable acp power gating");
struct acp_dev_data {
void __iomem *acp_base;
struct resource *res;
- struct platform_device *pdev;
+ struct platform_device *pdev[ACP_DEVS];
};
static int rn_acp_power_on(void __iomem *acp_base)
@@ -156,9 +156,9 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
const struct pci_device_id *pci_id)
{
struct acp_dev_data *adata;
- struct platform_device_info pdevinfo;
+ struct platform_device_info pdevinfo[ACP_DEVS];
unsigned int irqflags;
- int ret;
+ int ret, index;
u32 addr;
if (pci_enable_device(pci)) {
@@ -219,20 +219,29 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
adata->res[1].end = pci->irq;
memset(&pdevinfo, 0, sizeof(pdevinfo));
- pdevinfo.name = "acp_rn_pdm_dma";
- pdevinfo.id = 0;
- pdevinfo.parent = &pci->dev;
- pdevinfo.num_res = 2;
- pdevinfo.res = adata->res;
- pdevinfo.data = &irqflags;
- pdevinfo.size_data = sizeof(irqflags);
-
- adata->pdev = platform_device_register_full(&pdevinfo);
- if (IS_ERR(adata->pdev)) {
- dev_err(&pci->dev, "cannot register %s device\n",
- pdevinfo.name);
- ret = PTR_ERR(adata->pdev);
- goto unregister_devs;
+ pdevinfo[0].name = "acp_rn_pdm_dma";
+ pdevinfo[0].id = 0;
+ pdevinfo[0].parent = &pci->dev;
+ pdevinfo[0].num_res = 2;
+ pdevinfo[0].res = adata->res;
+ pdevinfo[0].data = &irqflags;
+ pdevinfo[0].size_data = sizeof(irqflags);
+
+ pdevinfo[1].name = "dmic-codec";
+ pdevinfo[1].id = 0;
+ pdevinfo[1].parent = &pci->dev;
+ pdevinfo[2].name = "acp_pdm_mach";
+ pdevinfo[2].id = 0;
+ pdevinfo[2].parent = &pci->dev;
+ for (index = 0; index < ACP_DEVS; index++) {
+ adata->pdev[index] =
+ platform_device_register_full(&pdevinfo[index]);
+ if (IS_ERR(adata->pdev[index])) {
+ dev_err(&pci->dev, "cannot register %s device\n",
+ pdevinfo[index].name);
+ ret = PTR_ERR(adata->pdev[index]);
+ goto unregister_devs;
+ }
}
pm_runtime_set_autosuspend_delay(&pci->dev, ACP_SUSPEND_DELAY_MS);
pm_runtime_use_autosuspend(&pci->dev);
@@ -242,7 +251,8 @@ static int snd_rn_acp_probe(struct pci_dev *pci,
return 0;
unregister_devs:
- platform_device_unregister(adata->pdev);
+ for (index = 0; index < ACP_DEVS; index++)
+ platform_device_unregister(adata->pdev[index]);
de_init:
if (rn_acp_deinit(adata->acp_base))
dev_err(&pci->dev, "ACP de-init failed\n");
@@ -295,10 +305,11 @@ static const struct dev_pm_ops rn_acp_pm = {
static void snd_rn_acp_remove(struct pci_dev *pci)
{
struct acp_dev_data *adata;
- int ret;
+ int ret, index;
adata = pci_get_drvdata(pci);
- platform_device_unregister(adata->pdev);
+ for (index = 0; index < ACP_DEVS; index++)
+ platform_device_unregister(adata->pdev[index]);
ret = rn_acp_deinit(adata->acp_base);
if (ret)
dev_err(&pci->dev, "ACP de-init failed\n");
diff --git a/sound/soc/amd/renoir/rn_acp3x.h b/sound/soc/amd/renoir/rn_acp3x.h
index 6e1888167fb3..75228e306e0b 100644
--- a/sound/soc/amd/renoir/rn_acp3x.h
+++ b/sound/soc/amd/renoir/rn_acp3x.h
@@ -7,6 +7,7 @@
#include "rn_chip_offset_byte.h"
+#define ACP_DEVS 3
#define ACP_PHY_BASE_ADDRESS 0x1240000
#define ACP_REG_START 0x1240000
#define ACP_REG_END 0x1250200
--
2.25.4
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH v2 13/14] ASoC: amd: RN machine driver using dmic
2020-05-11 21:20 [PATCH v2 00/14] Add Renoir ACP driver Alex Deucher
` (11 preceding siblings ...)
2020-05-11 21:20 ` [PATCH v2 12/14] ASoC: amd: create platform devices for Renoir Alex Deucher
@ 2020-05-11 21:20 ` Alex Deucher
2020-05-11 22:37 ` Pierre-Louis Bossart
2020-05-11 21:20 ` [PATCH v2 14/14] ASoC: amd: enable build for RN machine driver Alex Deucher
13 siblings, 1 reply; 25+ messages in thread
From: Alex Deucher @ 2020-05-11 21:20 UTC (permalink / raw)
To: alsa-devel, broonie, vijendar.mukunda, tiwai
Cc: Alex Deucher, Vijendar Mukunda
From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
This patch adds Renoir Machine driver for dmic support.
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
v2:
- Removed redundant code
sound/soc/amd/renoir/acp3x-rn.c | 106 ++++++++++++++++++++++++++++++++
1 file changed, 106 insertions(+)
create mode 100644 sound/soc/amd/renoir/acp3x-rn.c
diff --git a/sound/soc/amd/renoir/acp3x-rn.c b/sound/soc/amd/renoir/acp3x-rn.c
new file mode 100644
index 000000000000..069714035e95
--- /dev/null
+++ b/sound/soc/amd/renoir/acp3x-rn.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Machine driver for AMD Renoir platform using DMIC
+//
+//Copyright 2020 Advanced Micro Devices, Inc.
+
+#include <sound/soc.h>
+#include <sound/soc-dapm.h>
+#include <linux/module.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+#include <linux/io.h>
+
+#include "rn_acp3x.h"
+
+#define DRV_NAME "acp_pdm_mach"
+
+static int acp_pdm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ return 0;
+}
+
+static struct snd_soc_ops acp_pdm_ops = {
+ .hw_params = acp_pdm_hw_params,
+};
+
+static int acp_init(struct snd_soc_pcm_runtime *rtd)
+{
+ return 0;
+}
+
+SND_SOC_DAILINK_DEF(acp_pdm,
+ DAILINK_COMP_ARRAY(COMP_CPU("acp_rn_pdm_dma.0")));
+
+SND_SOC_DAILINK_DEF(dmic_codec,
+ DAILINK_COMP_ARRAY(COMP_CODEC("dmic-codec.0",
+ "dmic-hifi")));
+
+SND_SOC_DAILINK_DEF(platform,
+ DAILINK_COMP_ARRAY(COMP_PLATFORM("acp_rn_pdm_dma.0")));
+
+static struct snd_soc_dai_link acp_dai_pdm[] = {
+ {
+ .name = "acp3x-dmic-capture",
+ .stream_name = "DMIC capture",
+ .ops = &acp_pdm_ops,
+ .init = acp_init,
+ .capture_only = 1,
+ SND_SOC_DAILINK_REG(acp_pdm, dmic_codec, platform),
+ },
+};
+
+static struct snd_soc_card acp_card = {
+ .name = "acp",
+ .owner = THIS_MODULE,
+ .dai_link = acp_dai_pdm,
+ .num_links = 1,
+};
+
+static int acp_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct acp_pdm *machine = NULL;
+ struct snd_soc_card *card;
+
+ card = &acp_card;
+ acp_card.dev = &pdev->dev;
+
+ platform_set_drvdata(pdev, card);
+ snd_soc_card_set_drvdata(card, machine);
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "snd_soc_register_card(%s) failed: %d\n",
+ acp_card.name, ret);
+ return ret;
+ }
+ return 0;
+}
+
+static struct platform_driver acp_mach_driver = {
+ .driver = {
+ .name = "acp_pdm_mach",
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = acp_probe,
+};
+
+static int __init acp_audio_init(void)
+{
+ platform_driver_register(&acp_mach_driver);
+ return 0;
+}
+
+static void __exit acp_audio_exit(void)
+{
+ platform_driver_unregister(&acp_mach_driver);
+}
+
+module_init(acp_audio_init);
+module_exit(acp_audio_exit);
+
+MODULE_AUTHOR("Vijendar.Mukunda@amd.com");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
--
2.25.4
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH v2 13/14] ASoC: amd: RN machine driver using dmic
2020-05-11 21:20 ` [PATCH v2 13/14] ASoC: amd: RN machine driver using dmic Alex Deucher
@ 2020-05-11 22:37 ` Pierre-Louis Bossart
2020-05-12 14:22 ` Mukunda, Vijendar
0 siblings, 1 reply; 25+ messages in thread
From: Pierre-Louis Bossart @ 2020-05-11 22:37 UTC (permalink / raw)
To: Alex Deucher, alsa-devel, broonie, vijendar.mukunda, tiwai; +Cc: Alex Deucher
> +static int acp_pdm_hw_params(struct snd_pcm_substream *substream,
> + struct snd_pcm_hw_params *hw_params)
> +{
> + return 0;
> +}
is this needed?
> +
> +static struct snd_soc_ops acp_pdm_ops = {
> + .hw_params = acp_pdm_hw_params,
> +};
> +
> +static int acp_init(struct snd_soc_pcm_runtime *rtd)
> +{
> + return 0;
> +}
is this needed?
> +static struct platform_driver acp_mach_driver = {
> + .driver = {
> + .name = "acp_pdm_mach",
> + .pm = &snd_soc_pm_ops,
> + },
> + .probe = acp_probe,
> +};
> +
> +static int __init acp_audio_init(void)
> +{
> + platform_driver_register(&acp_mach_driver);
> + return 0;
> +}
> +
> +static void __exit acp_audio_exit(void)
> +{
> + platform_driver_unregister(&acp_mach_driver);
> +}
> +
> +module_init(acp_audio_init);
> +module_exit(acp_audio_exit);
use module_platform_driver() - was already feedback on v1...
^ permalink raw reply [flat|nested] 25+ messages in thread
* RE: [PATCH v2 13/14] ASoC: amd: RN machine driver using dmic
2020-05-11 22:37 ` Pierre-Louis Bossart
@ 2020-05-12 14:22 ` Mukunda, Vijendar
0 siblings, 0 replies; 25+ messages in thread
From: Mukunda, Vijendar @ 2020-05-12 14:22 UTC (permalink / raw)
To: Pierre-Louis Bossart, Alex Deucher, alsa-devel, broonie, tiwai
Cc: Deucher, Alexander
> -----Original Message-----
> From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
> Sent: Tuesday, May 12, 2020 4:07 AM
> To: Alex Deucher <alexdeucher@gmail.com>; alsa-devel@alsa-project.org;
> broonie@kernel.org; Mukunda, Vijendar <Vijendar.Mukunda@amd.com>;
> tiwai@suse.de
> Cc: Deucher, Alexander <Alexander.Deucher@amd.com>
> Subject: Re: [PATCH v2 13/14] ASoC: amd: RN machine driver using dmic
>
>
>
>
> > +static int acp_pdm_hw_params(struct snd_pcm_substream *substream,
> > + struct snd_pcm_hw_params *hw_params)
> > +{
> > + return 0;
> > +}
>
> is this needed?
Will remove it.
>
> > +
> > +static struct snd_soc_ops acp_pdm_ops = {
> > + .hw_params = acp_pdm_hw_params,
> > +};
> > +
> > +static int acp_init(struct snd_soc_pcm_runtime *rtd)
> > +{
> > + return 0;
> > +}
>
> is this needed?
Will remove it.
>
>
> > +static struct platform_driver acp_mach_driver = {
> > + .driver = {
> > + .name = "acp_pdm_mach",
> > + .pm = &snd_soc_pm_ops,
> > + },
> > + .probe = acp_probe,
> > +};
> > +
> > +static int __init acp_audio_init(void)
> > +{
> > + platform_driver_register(&acp_mach_driver);
> > + return 0;
> > +}
> > +
> > +static void __exit acp_audio_exit(void)
> > +{
> > + platform_driver_unregister(&acp_mach_driver);
> > +}
> > +
> > +module_init(acp_audio_init);
> > +module_exit(acp_audio_exit);
>
> use module_platform_driver() - was already feedback on v1...
Sorry, I have over looked it. Will fix it.
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH v2 14/14] ASoC: amd: enable build for RN machine driver
2020-05-11 21:20 [PATCH v2 00/14] Add Renoir ACP driver Alex Deucher
` (12 preceding siblings ...)
2020-05-11 21:20 ` [PATCH v2 13/14] ASoC: amd: RN machine driver using dmic Alex Deucher
@ 2020-05-11 21:20 ` Alex Deucher
13 siblings, 0 replies; 25+ messages in thread
From: Alex Deucher @ 2020-05-11 21:20 UTC (permalink / raw)
To: alsa-devel, broonie, vijendar.mukunda, tiwai
Cc: Alex Deucher, Vijendar Mukunda
From: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
This patch enables build for RN machine driver.
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
---
sound/soc/amd/Kconfig | 7 +++++++
sound/soc/amd/renoir/Makefile | 1 +
2 files changed, 8 insertions(+)
diff --git a/sound/soc/amd/Kconfig b/sound/soc/amd/Kconfig
index 5f57a47382b4..77ffdb41bee5 100644
--- a/sound/soc/amd/Kconfig
+++ b/sound/soc/amd/Kconfig
@@ -42,3 +42,10 @@ config SND_SOC_AMD_RENOIR
depends on X86 && PCI
help
This option enables ACP support for Renoir platform
+
+config SND_SOC_AMD_RENOIR_MACH
+ tristate "AMD Renoir support for DMIC"
+ select SND_SOC_DMIC
+ depends on SND_SOC_AMD_RENOIR
+ help
+ This option enables machine driver for DMIC
diff --git a/sound/soc/amd/renoir/Makefile b/sound/soc/amd/renoir/Makefile
index 43100515c7db..e4371932a55a 100644
--- a/sound/soc/amd/renoir/Makefile
+++ b/sound/soc/amd/renoir/Makefile
@@ -4,3 +4,4 @@ snd-rn-pci-acp3x-objs := rn-pci-acp3x.o
snd-acp3x-pdm-dma-objs := acp3x-pdm-dma.o
obj-$(CONFIG_SND_SOC_AMD_RENOIR) += snd-rn-pci-acp3x.o
obj-$(CONFIG_SND_SOC_AMD_RENOIR) += snd-acp3x-pdm-dma.o
+obj-$(CONFIG_SND_SOC_AMD_RENOIR_MACH) += acp3x-rn.o
--
2.25.4
^ permalink raw reply related [flat|nested] 25+ messages in thread