xref: /openbmc/linux/sound/soc/sof/amd/acp-probes.c (revision 1a74b21c)
1*1a74b21cSV sujith kumar Reddy // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2*1a74b21cSV sujith kumar Reddy //
3*1a74b21cSV sujith kumar Reddy // This file is provided under a dual BSD/GPLv2 license. When using or
4*1a74b21cSV sujith kumar Reddy // redistributing this file, you may do so under either license.
5*1a74b21cSV sujith kumar Reddy //
6*1a74b21cSV sujith kumar Reddy // Copyright(c) 2023 Advanced Micro Devices, Inc.
7*1a74b21cSV sujith kumar Reddy //
8*1a74b21cSV sujith kumar Reddy // Authors: V Sujith Kumar Reddy <Vsujithkumar.Reddy@amd.com>
9*1a74b21cSV sujith kumar Reddy 
10*1a74b21cSV sujith kumar Reddy /*
11*1a74b21cSV sujith kumar Reddy  * Probe interface for generic AMD audio ACP DSP block
12*1a74b21cSV sujith kumar Reddy  */
13*1a74b21cSV sujith kumar Reddy 
14*1a74b21cSV sujith kumar Reddy #include <linux/module.h>
15*1a74b21cSV sujith kumar Reddy #include <sound/soc.h>
16*1a74b21cSV sujith kumar Reddy #include "../sof-priv.h"
17*1a74b21cSV sujith kumar Reddy #include "../sof-client-probes.h"
18*1a74b21cSV sujith kumar Reddy #include "../sof-client.h"
19*1a74b21cSV sujith kumar Reddy #include "../ops.h"
20*1a74b21cSV sujith kumar Reddy #include "acp.h"
21*1a74b21cSV sujith kumar Reddy #include "acp-dsp-offset.h"
22*1a74b21cSV sujith kumar Reddy 
acp_probes_compr_startup(struct sof_client_dev * cdev,struct snd_compr_stream * cstream,struct snd_soc_dai * dai,u32 * stream_id)23*1a74b21cSV sujith kumar Reddy static int acp_probes_compr_startup(struct sof_client_dev *cdev,
24*1a74b21cSV sujith kumar Reddy 				    struct snd_compr_stream *cstream,
25*1a74b21cSV sujith kumar Reddy 				    struct snd_soc_dai *dai, u32 *stream_id)
26*1a74b21cSV sujith kumar Reddy {
27*1a74b21cSV sujith kumar Reddy 	struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
28*1a74b21cSV sujith kumar Reddy 	struct acp_dsp_stream *stream;
29*1a74b21cSV sujith kumar Reddy 	struct acp_dev_data *adata;
30*1a74b21cSV sujith kumar Reddy 
31*1a74b21cSV sujith kumar Reddy 	adata = sdev->pdata->hw_pdata;
32*1a74b21cSV sujith kumar Reddy 	stream = acp_dsp_stream_get(sdev, 0);
33*1a74b21cSV sujith kumar Reddy 	if (!stream)
34*1a74b21cSV sujith kumar Reddy 		return -ENODEV;
35*1a74b21cSV sujith kumar Reddy 
36*1a74b21cSV sujith kumar Reddy 	stream->cstream = cstream;
37*1a74b21cSV sujith kumar Reddy 	cstream->runtime->private_data = stream;
38*1a74b21cSV sujith kumar Reddy 
39*1a74b21cSV sujith kumar Reddy 	adata->probe_stream = stream;
40*1a74b21cSV sujith kumar Reddy 	*stream_id = stream->stream_tag;
41*1a74b21cSV sujith kumar Reddy 
42*1a74b21cSV sujith kumar Reddy 	return 0;
43*1a74b21cSV sujith kumar Reddy }
44*1a74b21cSV sujith kumar Reddy 
acp_probes_compr_shutdown(struct sof_client_dev * cdev,struct snd_compr_stream * cstream,struct snd_soc_dai * dai)45*1a74b21cSV sujith kumar Reddy static int acp_probes_compr_shutdown(struct sof_client_dev *cdev,
46*1a74b21cSV sujith kumar Reddy 				     struct snd_compr_stream *cstream,
47*1a74b21cSV sujith kumar Reddy 				     struct snd_soc_dai *dai)
48*1a74b21cSV sujith kumar Reddy {
49*1a74b21cSV sujith kumar Reddy 	struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
50*1a74b21cSV sujith kumar Reddy 	struct acp_dsp_stream *stream = cstream->runtime->private_data;
51*1a74b21cSV sujith kumar Reddy 	struct acp_dev_data *adata;
52*1a74b21cSV sujith kumar Reddy 	int ret;
53*1a74b21cSV sujith kumar Reddy 
54*1a74b21cSV sujith kumar Reddy 	ret = acp_dsp_stream_put(sdev, stream);
55*1a74b21cSV sujith kumar Reddy 	if (ret < 0) {
56*1a74b21cSV sujith kumar Reddy 		dev_err(sdev->dev, "Failed to release probe compress stream\n");
57*1a74b21cSV sujith kumar Reddy 		return ret;
58*1a74b21cSV sujith kumar Reddy 	}
59*1a74b21cSV sujith kumar Reddy 
60*1a74b21cSV sujith kumar Reddy 	adata = sdev->pdata->hw_pdata;
61*1a74b21cSV sujith kumar Reddy 	stream->cstream = NULL;
62*1a74b21cSV sujith kumar Reddy 	cstream->runtime->private_data = NULL;
63*1a74b21cSV sujith kumar Reddy 	adata->probe_stream = NULL;
64*1a74b21cSV sujith kumar Reddy 
65*1a74b21cSV sujith kumar Reddy 	return 0;
66*1a74b21cSV sujith kumar Reddy }
67*1a74b21cSV sujith kumar Reddy 
acp_probes_compr_set_params(struct sof_client_dev * cdev,struct snd_compr_stream * cstream,struct snd_compr_params * params,struct snd_soc_dai * dai)68*1a74b21cSV sujith kumar Reddy static int acp_probes_compr_set_params(struct sof_client_dev *cdev,
69*1a74b21cSV sujith kumar Reddy 				       struct snd_compr_stream *cstream,
70*1a74b21cSV sujith kumar Reddy 				       struct snd_compr_params *params,
71*1a74b21cSV sujith kumar Reddy 				       struct snd_soc_dai *dai)
72*1a74b21cSV sujith kumar Reddy {
73*1a74b21cSV sujith kumar Reddy 	struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
74*1a74b21cSV sujith kumar Reddy 	struct acp_dsp_stream *stream = cstream->runtime->private_data;
75*1a74b21cSV sujith kumar Reddy 	unsigned int buf_offset, index;
76*1a74b21cSV sujith kumar Reddy 	u32 size;
77*1a74b21cSV sujith kumar Reddy 	int ret;
78*1a74b21cSV sujith kumar Reddy 
79*1a74b21cSV sujith kumar Reddy 	stream->dmab = cstream->runtime->dma_buffer_p;
80*1a74b21cSV sujith kumar Reddy 	stream->num_pages = PFN_UP(cstream->runtime->dma_bytes);
81*1a74b21cSV sujith kumar Reddy 	size = cstream->runtime->buffer_size;
82*1a74b21cSV sujith kumar Reddy 
83*1a74b21cSV sujith kumar Reddy 	ret = acp_dsp_stream_config(sdev, stream);
84*1a74b21cSV sujith kumar Reddy 	if (ret < 0) {
85*1a74b21cSV sujith kumar Reddy 		acp_dsp_stream_put(sdev, stream);
86*1a74b21cSV sujith kumar Reddy 		return ret;
87*1a74b21cSV sujith kumar Reddy 	}
88*1a74b21cSV sujith kumar Reddy 
89*1a74b21cSV sujith kumar Reddy 	/* write buffer size of stream in scratch memory */
90*1a74b21cSV sujith kumar Reddy 
91*1a74b21cSV sujith kumar Reddy 	buf_offset = sdev->debug_box.offset +
92*1a74b21cSV sujith kumar Reddy 		     offsetof(struct scratch_reg_conf, buf_size);
93*1a74b21cSV sujith kumar Reddy 	index = stream->stream_tag - 1;
94*1a74b21cSV sujith kumar Reddy 	buf_offset = buf_offset + index * 4;
95*1a74b21cSV sujith kumar Reddy 
96*1a74b21cSV sujith kumar Reddy 	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + buf_offset, size);
97*1a74b21cSV sujith kumar Reddy 
98*1a74b21cSV sujith kumar Reddy 	return 0;
99*1a74b21cSV sujith kumar Reddy }
100*1a74b21cSV sujith kumar Reddy 
acp_probes_compr_trigger(struct sof_client_dev * cdev,struct snd_compr_stream * cstream,int cmd,struct snd_soc_dai * dai)101*1a74b21cSV sujith kumar Reddy static int acp_probes_compr_trigger(struct sof_client_dev *cdev,
102*1a74b21cSV sujith kumar Reddy 				    struct snd_compr_stream *cstream,
103*1a74b21cSV sujith kumar Reddy 				    int cmd, struct snd_soc_dai *dai)
104*1a74b21cSV sujith kumar Reddy {
105*1a74b21cSV sujith kumar Reddy 	/* Nothing to do here, as it is a mandatory callback just defined */
106*1a74b21cSV sujith kumar Reddy 	return 0;
107*1a74b21cSV sujith kumar Reddy }
108*1a74b21cSV sujith kumar Reddy 
acp_probes_compr_pointer(struct sof_client_dev * cdev,struct snd_compr_stream * cstream,struct snd_compr_tstamp * tstamp,struct snd_soc_dai * dai)109*1a74b21cSV sujith kumar Reddy static int acp_probes_compr_pointer(struct sof_client_dev *cdev,
110*1a74b21cSV sujith kumar Reddy 				    struct snd_compr_stream *cstream,
111*1a74b21cSV sujith kumar Reddy 				    struct snd_compr_tstamp *tstamp,
112*1a74b21cSV sujith kumar Reddy 				    struct snd_soc_dai *dai)
113*1a74b21cSV sujith kumar Reddy {
114*1a74b21cSV sujith kumar Reddy 	struct acp_dsp_stream *stream = cstream->runtime->private_data;
115*1a74b21cSV sujith kumar Reddy 	struct snd_soc_pcm_stream *pstream;
116*1a74b21cSV sujith kumar Reddy 
117*1a74b21cSV sujith kumar Reddy 	pstream = &dai->driver->capture;
118*1a74b21cSV sujith kumar Reddy 	tstamp->copied_total = stream->cstream_posn;
119*1a74b21cSV sujith kumar Reddy 	tstamp->sampling_rate = snd_pcm_rate_bit_to_rate(pstream->rates);
120*1a74b21cSV sujith kumar Reddy 
121*1a74b21cSV sujith kumar Reddy 	return 0;
122*1a74b21cSV sujith kumar Reddy }
123*1a74b21cSV sujith kumar Reddy 
124*1a74b21cSV sujith kumar Reddy /* SOF client implementation */
125*1a74b21cSV sujith kumar Reddy static const struct sof_probes_host_ops acp_probes_ops = {
126*1a74b21cSV sujith kumar Reddy 	.startup = acp_probes_compr_startup,
127*1a74b21cSV sujith kumar Reddy 	.shutdown = acp_probes_compr_shutdown,
128*1a74b21cSV sujith kumar Reddy 	.set_params = acp_probes_compr_set_params,
129*1a74b21cSV sujith kumar Reddy 	.trigger = acp_probes_compr_trigger,
130*1a74b21cSV sujith kumar Reddy 	.pointer = acp_probes_compr_pointer,
131*1a74b21cSV sujith kumar Reddy };
132*1a74b21cSV sujith kumar Reddy 
acp_probes_register(struct snd_sof_dev * sdev)133*1a74b21cSV sujith kumar Reddy int acp_probes_register(struct snd_sof_dev *sdev)
134*1a74b21cSV sujith kumar Reddy {
135*1a74b21cSV sujith kumar Reddy 	return sof_client_dev_register(sdev, "acp-probes", 0, &acp_probes_ops,
136*1a74b21cSV sujith kumar Reddy 				       sizeof(acp_probes_ops));
137*1a74b21cSV sujith kumar Reddy }
138*1a74b21cSV sujith kumar Reddy EXPORT_SYMBOL_NS(acp_probes_register, SND_SOC_SOF_AMD_COMMON);
139*1a74b21cSV sujith kumar Reddy 
acp_probes_unregister(struct snd_sof_dev * sdev)140*1a74b21cSV sujith kumar Reddy void acp_probes_unregister(struct snd_sof_dev *sdev)
141*1a74b21cSV sujith kumar Reddy {
142*1a74b21cSV sujith kumar Reddy 	sof_client_dev_unregister(sdev, "acp-probes", 0);
143*1a74b21cSV sujith kumar Reddy }
144*1a74b21cSV sujith kumar Reddy EXPORT_SYMBOL_NS(acp_probes_unregister, SND_SOC_SOF_AMD_COMMON);
145*1a74b21cSV sujith kumar Reddy 
146*1a74b21cSV sujith kumar Reddy MODULE_IMPORT_NS(SND_SOC_SOF_CLIENT);
147*1a74b21cSV sujith kumar Reddy 
148