summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Liao <rogerliao@google.com>2021-10-13 21:09:02 +0800
committerRoger Liao <rogerliao@google.com>2021-10-13 23:03:47 +0800
commit21348712f59126e9a56232b3f263ee29e4b6ea52 (patch)
tree8124bea1324fcbcecb6ac1aa46f4b914a3ca1deb
parent07596de8fb03884e88855660209e4089ca95cd01 (diff)
parentdbd0e2ffed6c4db9d1a6ef650a6c38954ea9ac29 (diff)
downloadaoc-21348712f59126e9a56232b3f263ee29e4b6ea52.tar.gz
Merge android12-gs-pixel-5.10-sc-qpr1 into android12-gs-pixel-5.10-sc-qpr2
Change-Id: I503b99dba6ae14ec020d9b209921805251293c75 Signed-off-by: Roger Liao <rogerliao@google.com>
-rw-r--r--alsa/aoc_alsa_pcm.c15
-rw-r--r--aoc.c62
-rw-r--r--aoc.h2
-rw-r--r--aoc_control_dev.c54
4 files changed, 113 insertions, 20 deletions
diff --git a/alsa/aoc_alsa_pcm.c b/alsa/aoc_alsa_pcm.c
index 908f908..5cbd12f 100644
--- a/alsa/aoc_alsa_pcm.c
+++ b/alsa/aoc_alsa_pcm.c
@@ -607,16 +607,23 @@ static int snd_aoc_pcm_mmap(struct snd_soc_component *component,
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct aoc_alsa_stream *alsa_stream = runtime->private_data;
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
size_t ring_size;
int err;
phys_addr_t aoc_ring_base;
+ aoc_direction dir;
+
+ dir = ((alsa_stream->substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+ AOC_DOWN : AOC_UP);
- if (alsa_stream->substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ /* return the heap base address for MMAP playback and capture */
+ if (is_aaudio_mmaped_service(rtd->dai_link->name)) {
aoc_ring_base =
- aoc_service_ring_base_phys_addr(alsa_stream->dev, AOC_DOWN, &ring_size);
- else
+ aoc_get_heap_base_phys_addr(alsa_stream->dev, dir, &ring_size);
+ } else {
aoc_ring_base =
- aoc_service_ring_base_phys_addr(alsa_stream->dev, AOC_UP, &ring_size);
+ aoc_service_ring_base_phys_addr(alsa_stream->dev, dir, &ring_size);
+ }
alsa_stream->vma = vma;
diff --git a/aoc.c b/aoc.c
index 0983597..88624f2 100644
--- a/aoc.c
+++ b/aoc.c
@@ -903,6 +903,36 @@ phys_addr_t aoc_service_ring_base_phys_addr(struct aoc_service_dev *dev, aoc_dir
}
EXPORT_SYMBOL_GPL(aoc_service_ring_base_phys_addr);
+phys_addr_t aoc_get_heap_base_phys_addr(struct aoc_service_dev *dev, aoc_direction dir,
+ size_t *out_size)
+{
+ const struct device *parent;
+ struct aoc_prvdata *prvdata;
+ aoc_service *service;
+ phys_addr_t audio_heap_base;
+
+ if (!dev)
+ return -EINVAL;
+
+ parent = dev->dev.parent;
+ prvdata = dev_get_drvdata(parent);
+
+ service = service_at_index(prvdata, dev->service_index);
+
+ if (out_size)
+ *out_size = aoc_service_ring_size(service, dir);
+
+ if (dir == AOC_DOWN)
+ audio_heap_base = prvdata->audio_playback_heap_base;
+ else
+ audio_heap_base = prvdata->audio_capture_heap_base;
+
+ pr_debug("Get heap address(phy):%llx\n", audio_heap_base);
+
+ return audio_heap_base;
+}
+EXPORT_SYMBOL_GPL(aoc_get_heap_base_phys_addr);
+
bool aoc_service_flush_read_data(struct aoc_service_dev *dev)
{
const struct device *parent;
@@ -2121,26 +2151,26 @@ static void aoc_take_offline(struct aoc_prvdata *prvdata)
int rc;
/* check if devices/services are ready */
- if (aoc_state == AOC_STATE_OFFLINE || !prvdata->services)
- return;
-
- pr_notice("taking aoc offline\n");
- aoc_state = AOC_STATE_OFFLINE;
+ if (aoc_state == AOC_STATE_ONLINE) {
+ pr_notice("taking aoc offline\n");
+ aoc_state = AOC_STATE_OFFLINE;
- bus_for_each_dev(&aoc_bus_type, NULL, NULL, aoc_remove_device);
+ bus_for_each_dev(&aoc_bus_type, NULL, NULL, aoc_remove_device);
- if (aoc_control)
- aoc_control->magic = 0;
+ if (aoc_control)
+ aoc_control->magic = 0;
- devm_kfree(prvdata->dev, prvdata->services);
- prvdata->services = NULL;
- prvdata->total_services = 0;
+ if (prvdata->services) {
+ devm_kfree(prvdata->dev, prvdata->services);
+ prvdata->services = NULL;
+ prvdata->total_services = 0;
+ }
- /* wakeup AOC before calling GSA */
- aoc_req_assert(prvdata, true);
- rc = aoc_req_wait(prvdata, true);
- if (rc) {
- dev_err(prvdata->dev, "timed out waiting for aoc_ack\n");
+ /* wakeup AOC before calling GSA */
+ aoc_req_assert(prvdata, true);
+ rc = aoc_req_wait(prvdata, true);
+ if (rc)
+ dev_err(prvdata->dev, "timed out waiting for aoc_ack\n");
}
/* TODO: GSA_AOC_SHUTDOWN needs to be 4, but the current header defines
diff --git a/aoc.h b/aoc.h
index 506e7df..cfcf011 100644
--- a/aoc.h
+++ b/aoc.h
@@ -41,6 +41,8 @@ struct aoc_service_dev {
phys_addr_t aoc_service_ring_base_phys_addr(struct aoc_service_dev *dev, aoc_direction dir,
size_t *out_size);
+phys_addr_t aoc_get_heap_base_phys_addr(struct aoc_service_dev *dev, aoc_direction dir,
+ size_t *out_size);
ssize_t aoc_service_read(struct aoc_service_dev *dev, uint8_t *buffer,
size_t count, bool block);
ssize_t aoc_service_read_timeout(struct aoc_service_dev *dev, uint8_t *buffer,
diff --git a/aoc_control_dev.c b/aoc_control_dev.c
index d932b9e..130110b 100644
--- a/aoc_control_dev.c
+++ b/aoc_control_dev.c
@@ -174,6 +174,59 @@ static ssize_t memory_exception_show(struct device *dev,
static DEVICE_ATTR_RO(memory_exception);
+static ssize_t memory_votes_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct stats_prvdata *prvdata = dev_get_drvdata(dev);
+ struct CMD_GET_MEMORY_VOTES_DATA_COUNT get_count_cmd;
+ struct CMD_GET_MEMORY_VOTES_DATA get_data_cmd;
+ u32 total_count;
+ u32 i;
+ u32 bytes_written;
+ int ret;
+
+ AocCmdHdrSet(&get_count_cmd.parent, CMD_GET_MEMORY_VOTES_DATA_COUNT_ID,
+ sizeof(get_count_cmd));
+
+ ret = read_attribute(prvdata, &get_count_cmd, sizeof(get_count_cmd),
+ &get_count_cmd, sizeof(get_count_cmd));
+
+ if (ret < 0)
+ return ret;
+
+ total_count = get_count_cmd.num_of_clients;
+
+ bytes_written = 0;
+
+ for (i = 0; i < total_count; i++) {
+
+ AocCmdHdrSet(&get_data_cmd.parent, CMD_GET_MEMORY_VOTES_DATA_ID, sizeof(get_data_cmd));
+ get_data_cmd.app_id = i;
+ get_data_cmd.valid = false;
+
+ ret = read_attribute(prvdata, &get_data_cmd, sizeof(get_data_cmd),
+ &get_data_cmd, sizeof(get_data_cmd));
+
+ if (ret < 0)
+ return ret;
+
+ if (get_data_cmd.valid) {
+ bytes_written += scnprintf(buf + bytes_written, PAGE_SIZE - bytes_written,
+ "App %hhu, votes Curr/Tot/ON %5u / %5u / %5u Last %10llu us, Dur %10llu us\n",
+ get_data_cmd.app_id,
+ get_data_cmd.votes,
+ get_data_cmd.total_votes,
+ get_data_cmd.on_votes,
+ get_data_cmd.last_on_time_ns / 1000ULL,
+ get_data_cmd.total_time_us);
+ }
+ }
+
+ return bytes_written;
+}
+
+static DEVICE_ATTR_RO(memory_votes);
+
static ssize_t read_timed_stat(struct device *dev, char *buf, int index)
{
struct stats_prvdata *prvdata = dev_get_drvdata(dev);
@@ -358,6 +411,7 @@ static struct attribute *aoc_stats_attrs[] = {
&dev_attr_logging_wakeup.attr,
&dev_attr_hotword_wakeup.attr,
&dev_attr_memory_exception.attr,
+ &dev_attr_memory_votes.attr,
NULL
};