Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sound/soc/sof/mediatek/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ config SND_SOC_SOF_MTK_COMMON
config SND_SOC_SOF_MT8195
tristate "SOF support for MT8195 audio DSP"
select SND_SOC_SOF_MTK_COMMON
depends on MTK_ADSP_IPC
help
This adds support for Sound Open Firmware for Mediatek platforms
using the mt8195 processors.
Expand Down
12 changes: 4 additions & 8 deletions sound/soc/sof/mediatek/adsp_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,22 @@
#ifndef __MTK_ADSP_HELPER_H__
#define __MTK_ADSP_HELPER_H__

#include <linux/firmware/mediatek/mtk-adsp-ipc.h>

/*
* Global important adsp data structure.
*/
#define DSP_MBOX_NUM 3

struct mtk_adsp_chip_info {
phys_addr_t pa_sram;
phys_addr_t pa_dram; /* adsp dram physical base */
phys_addr_t pa_shared_dram; /* adsp dram physical base */
phys_addr_t pa_cfgreg;
phys_addr_t pa_mboxreg[DSP_MBOX_NUM];
u32 sramsize;
u32 dramsize;
u32 cfgregsize;
void __iomem *va_sram; /* corresponding to pa_sram */
void __iomem *va_dram; /* corresponding to pa_dram */
void __iomem *va_cfgreg;
void __iomem *va_mboxreg[DSP_MBOX_NUM];
void __iomem *shared_sram; /* part of va_sram */
void __iomem *shared_dram; /* part of va_dram */
phys_addr_t adsp_bootup_addr;
Expand All @@ -34,10 +32,8 @@ struct mtk_adsp_chip_info {
struct adsp_priv {
struct device *dev;
struct snd_sof_dev *sdev;

/* DSP IPC handler */
struct mbox_controller *adsp_mbox;

struct mtk_adsp_ipc *dsp_ipc;
struct platform_device *ipc_dev;
struct mtk_adsp_chip_info *adsp;
struct clk **clk;
u32 (*ap2adsp_addr)(u32 addr, void *data);
Expand Down
153 changes: 147 additions & 6 deletions sound/soc/sof/mediatek/mt8195/mt8195.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <linux/delay.h>
#include <linux/firmware.h>
#include <linux/io.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
Expand All @@ -27,6 +28,99 @@
#include "mt8195.h"
#include "mt8195-clk.h"

static int mt8195_get_mailbox_offset(struct snd_sof_dev *sdev)
{
return MBOX_OFFSET;
}

static int mt8195_get_window_offset(struct snd_sof_dev *sdev, u32 id)
{
return MBOX_OFFSET;
}

static int mt8195_send_msg(struct snd_sof_dev *sdev,
struct snd_sof_ipc_msg *msg)
{
struct adsp_priv *priv = sdev->pdata->hw_pdata;

sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
msg->msg_size);

return mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_REQ, MTK_ADSP_IPC_OP_REQ);
}

static void mt8195_get_reply(struct snd_sof_dev *sdev)
{
struct snd_sof_ipc_msg *msg = sdev->msg;
struct sof_ipc_reply reply;
int ret = 0;

if (!msg) {
dev_warn(sdev->dev, "unexpected ipc interrupt\n");
return;
}

/* get reply */
sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply));
if (reply.error < 0) {
memcpy(msg->reply_data, &reply, sizeof(reply));
ret = reply.error;
} else {
/* reply has correct size? */
if (reply.hdr.size != msg->reply_size) {
dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n",
msg->reply_size, reply.hdr.size);
ret = -EINVAL;
}

/* read the message */
if (msg->reply_size > 0)
sof_mailbox_read(sdev, sdev->host_box.offset,
msg->reply_data, msg->reply_size);
}

msg->reply_error = ret;
}

static void mt8195_dsp_handle_reply(struct mtk_adsp_ipc *ipc)
{
struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc);
unsigned long flags;

spin_lock_irqsave(&priv->sdev->ipc_lock, flags);
mt8195_get_reply(priv->sdev);
snd_sof_ipc_reply(priv->sdev, 0);
spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags);
}

static void mt8195_dsp_handle_request(struct mtk_adsp_ipc *ipc)
{
struct adsp_priv *priv = mtk_adsp_ipc_get_data(ipc);
u32 p; /* panic code */
int ret;

/* Read the message from the debug box. */
sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4,
&p, sizeof(p));

/* Check to see if the message is a panic code 0x0dead*** */
if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
snd_sof_dsp_panic(priv->sdev, p);
} else {
snd_sof_ipc_msgs_rx(priv->sdev);

/* tell DSP cmd is done */
ret = mtk_adsp_ipc_send(priv->dsp_ipc, MTK_ADSP_IPC_RSP, MTK_ADSP_IPC_OP_RSP);
if (ret)
dev_err(priv->dev, "request send ipc failed");
}
}

static struct mtk_adsp_ipc_ops dsp_ops = {
.handle_reply = mt8195_dsp_handle_reply,
.handle_request = mt8195_dsp_handle_request,
};

static int platform_parse_resource(struct platform_device *pdev, void *data)
{
struct resource *mmio;
Expand Down Expand Up @@ -257,14 +351,33 @@ static int mt8195_dsp_probe(struct snd_sof_dev *sdev)
goto err_adsp_sram_power_off;
}

priv->ipc_dev = platform_device_register_data(&pdev->dev, "mtk-adsp-ipc",
PLATFORM_DEVID_NONE,
pdev, sizeof(*pdev));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is the platform_device_unregister() done?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I miss this part, will fix this. thanks.

if (IS_ERR(priv->ipc_dev)) {
ret = PTR_ERR(priv->ipc_dev);
dev_err(sdev->dev, "failed to register mtk-adsp-ipc device\n");
goto err_adsp_sram_power_off;
}

priv->dsp_ipc = dev_get_drvdata(&priv->ipc_dev->dev);
if (!priv->dsp_ipc) {
ret = -EPROBE_DEFER;
dev_err(sdev->dev, "failed to get drvdata\n");
goto exit_pdev_unregister;
}

mtk_adsp_ipc_set_data(priv->dsp_ipc, priv);
priv->dsp_ipc->ops = &dsp_ops;

sdev->bar[SOF_FW_BLK_TYPE_IRAM] = devm_ioremap(sdev->dev,
priv->adsp->pa_sram,
priv->adsp->sramsize);
if (!sdev->bar[SOF_FW_BLK_TYPE_IRAM]) {
dev_err(sdev->dev, "failed to ioremap base %pa size %#x\n",
&priv->adsp->pa_sram, priv->adsp->sramsize);
ret = -EINVAL;
goto err_adsp_sram_power_off;
goto exit_pdev_unregister;
}

sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap_wc(sdev->dev,
Expand All @@ -274,26 +387,28 @@ static int mt8195_dsp_probe(struct snd_sof_dev *sdev)
dev_err(sdev->dev, "failed to ioremap base %pa size %#x\n",
&priv->adsp->pa_dram, priv->adsp->dramsize);
ret = -EINVAL;
goto err_adsp_sram_power_off;
goto exit_pdev_unregister;
}
priv->adsp->va_dram = sdev->bar[SOF_FW_BLK_TYPE_SRAM];

ret = adsp_shared_base_ioremap(pdev, priv->adsp);
if (ret) {
dev_err(sdev->dev, "adsp_shared_base_ioremap fail!\n");
goto err_adsp_sram_power_off;
goto exit_pdev_unregister;
}

sdev->bar[DSP_REG_BAR] = priv->adsp->va_cfgreg;
sdev->bar[DSP_MBOX0_BAR] = priv->adsp->va_mboxreg[0];
sdev->bar[DSP_MBOX1_BAR] = priv->adsp->va_mboxreg[1];
sdev->bar[DSP_MBOX2_BAR] = priv->adsp->va_mboxreg[2];

sdev->mmio_bar = SOF_FW_BLK_TYPE_SRAM;
sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM;

/* set default mailbox offset for FW ready message */
sdev->dsp_box.offset = mt8195_get_mailbox_offset(sdev);

return 0;

exit_pdev_unregister:
platform_device_unregister(priv->ipc_dev);
err_adsp_sram_power_off:
adsp_sram_power_on(&pdev->dev, false);
exit_clk_disable:
Expand All @@ -305,7 +420,9 @@ static int mt8195_dsp_probe(struct snd_sof_dev *sdev)
static int mt8195_dsp_remove(struct snd_sof_dev *sdev)
{
struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev);
struct adsp_priv *priv = sdev->pdata->hw_pdata;

platform_device_unregister(priv->ipc_dev);
adsp_sram_power_on(&pdev->dev, false);
adsp_clock_off(sdev);

Expand Down Expand Up @@ -356,6 +473,21 @@ static int mt8195_get_bar_index(struct snd_sof_dev *sdev, u32 type)
return type;
}

static int mt8195_ipc_msg_data(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream,
void *p, size_t sz)
{
sof_mailbox_read(sdev, sdev->dsp_box.offset, p, sz);
return 0;
}

static int mt8195_ipc_pcm_params(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream,
const struct sof_ipc_pcm_params_reply *reply)
{
return 0;
}

static struct snd_soc_dai_driver mt8195_dai[] = {
{
.name = "SOF_DL2",
Expand Down Expand Up @@ -406,6 +538,15 @@ static const struct snd_sof_dsp_ops sof_mt8195_ops = {
.write64 = sof_io_write64,
.read64 = sof_io_read64,

/* ipc */
.send_msg = mt8195_send_msg,
.fw_ready = sof_fw_ready,
.get_mailbox_offset = mt8195_get_mailbox_offset,
.get_window_offset = mt8195_get_window_offset,

.ipc_msg_data = mt8195_ipc_msg_data,
.ipc_pcm_params = mt8195_ipc_pcm_params,

/* misc */
.get_bar_index = mt8195_get_bar_index,

Expand Down