kernel_samsung_a53x/sound/soc/samsung/vts/vts_qos.c
2024-06-15 16:02:09 -03:00

98 lines
2.8 KiB
C
Executable file

// SPDX-License-Identifier: GPL-2.0-or-later
/* sound/soc/samsung/vts/vts_qos.c
*
* ALSA SoC - Samsung VTS driver
*
* Copyright (c) 2021 Samsung Electronics Co. Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/pinctrl/consumer.h>
#include <linux/sched/clock.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/pcm_params.h>
#include <sound/tlv.h>
#include <sound/samsung/vts.h>
#include "vts.h"
#include "vts_dbg.h"
static void vts_dma_mif_control(struct device *dev, struct vts_data *vts_data, int on)
{
int mif_status;
int mif_req_out;
int mif_req_out_status;
int mif_ack_in;
int mif_on_cnt = 0;
if (on) {
mif_req_out = 0x1;
mif_ack_in = 0x0;
} else {
mif_req_out = 0x0;
mif_ack_in = 0x10;
}
mif_status = readl(vts_data->sfr_base + VTS_MIF_REQ_ACK_IN);
mif_req_out_status = readl(vts_data->sfr_base + VTS_MIF_REQ_OUT);
vts_dev_info(dev, "%s: MIF STATUS : 0x%x (0x%x), on :%d\n",
__func__, mif_status, mif_req_out_status, on);
if ((mif_status & (0x1 << 4)) == mif_ack_in) {
if (on && (mif_req_out_status == 0x1)) {
vts_dev_info(dev, "%s: Wrong REQ OUT STATUS -> Toggle\n", __func__);
writel(0x0, vts_data->sfr_base + VTS_MIF_REQ_OUT);
mdelay(5);
}
writel(mif_req_out, vts_data->sfr_base + VTS_MIF_REQ_OUT);
mif_req_out_status = readl(vts_data->sfr_base + VTS_MIF_REQ_OUT);
vts_dev_info(dev, "%s: MIF %d - 0x%x\n", __func__, on, mif_req_out_status);
while (((mif_status & (0x1 << 4)) == mif_ack_in) && mif_on_cnt <= 480) {
mif_on_cnt++;
udelay(50);
mif_status = readl(vts_data->sfr_base +
VTS_MIF_REQ_ACK_IN);
}
} else {
vts_dev_info(dev, "%s: MIF already %d\n", __func__, on);
}
vts_dev_info(dev, "%s: MIF STATUS OUT : 0x%x cnt : %d\n", __func__, mif_status, mif_on_cnt);
}
void vts_request_dram_on(struct device *dev, unsigned int id, bool on)
{
struct vts_data *data = dev_get_drvdata(dev);
struct vts_dram_request *request;
size_t len = ARRAY_SIZE(data->dram_requests);
unsigned int val = 0;
vts_dev_info(dev, "%s: (%#x, %d)\n", __func__, id, on);
for (request = data->dram_requests; request - data->dram_requests <
len && request->id && request->id != id; request++) {
}
if (request - data->dram_requests >= len) {
vts_dev_err(dev, "too many dram requests: %#x, %d\n", id, on);
return;
}
request->on = on;
request->id = id;
request->updated = local_clock();
for (request = data->dram_requests; request - data->dram_requests <
len && request->id; request++) {
if (request->on) {
val = 1;
break;
}
}
vts_dma_mif_control(dev, data, val);
}
EXPORT_SYMBOL(vts_request_dram_on);