@@ -74,4 +74,28 @@ void imx8_dump(struct snd_sof_dev *sdev, u32 flags)
}
EXPORT_SYMBOL(imx8_dump);
+int imx8_parse_clocks(struct snd_sof_dev *sdev, struct imx_clocks *clks)
+{
+ int ret;
+
+ ret = devm_clk_bulk_get(sdev->dev, clks->num_dsp_clks, clks->dsp_clks);
+ if (ret)
+ dev_err(sdev->dev, "Failed to request DSP clocks\n");
+
+ return ret;
+}
+EXPORT_SYMBOL(imx8_parse_clocks);
+
+int imx8_enable_clocks(struct snd_sof_dev *sdev, struct imx_clocks *clks)
+{
+ return clk_bulk_prepare_enable(clks->num_dsp_clks, clks->dsp_clks);
+}
+EXPORT_SYMBOL(imx8_enable_clocks);
+
+void imx8_disable_clocks(struct snd_sof_dev *sdev, struct imx_clocks *clks)
+{
+ clk_bulk_disable_unprepare(clks->num_dsp_clks, clks->dsp_clks);
+}
+EXPORT_SYMBOL(imx8_disable_clocks);
+
MODULE_LICENSE("Dual BSD/GPL");
@@ -3,6 +3,8 @@
#ifndef __IMX_COMMON_H__
#define __IMX_COMMON_H__
+#include <linux/clk.h>
+
#define EXCEPT_MAX_HDR_SIZE 0x400
#define IMX8_STACK_DUMP_SIZE 32
@@ -13,4 +15,13 @@ void imx8_get_registers(struct snd_sof_dev *sdev,
void imx8_dump(struct snd_sof_dev *sdev, u32 flags);
+struct imx_clocks {
+ struct clk_bulk_data *dsp_clks;
+ int num_dsp_clks;
+};
+
+int imx8_parse_clocks(struct snd_sof_dev *sdev, struct imx_clocks *clks);
+int imx8_enable_clocks(struct snd_sof_dev *sdev, struct imx_clocks *clks);
+void imx8_disable_clocks(struct snd_sof_dev *sdev, struct imx_clocks *clks);
+
#endif
@@ -41,6 +41,13 @@
#define MBOX_OFFSET 0x800000
#define MBOX_SIZE 0x1000
+/* DSP clocks */
+static struct clk_bulk_data imx8_dsp_clks[] = {
+ { .id = "ipg" },
+ { .id = "ocram" },
+ { .id = "core" },
+};
+
struct imx8_priv {
struct device *dev;
struct snd_sof_dev *sdev;
@@ -57,6 +64,7 @@ struct imx8_priv {
struct device **pd_dev;
struct device_link **link;
+ struct imx_clocks *clks;
};
static int imx8_get_mailbox_offset(struct snd_sof_dev *sdev)
@@ -188,6 +196,10 @@ static int imx8_probe(struct snd_sof_dev *sdev)
if (!priv)
return -ENOMEM;
+ priv->clks = devm_kzalloc(&pdev->dev, sizeof(*priv->clks), GFP_KERNEL);
+ if (!priv->clks)
+ return -ENOMEM;
+
sdev->pdata->hw_pdata = priv;
priv->dev = sdev->dev;
priv->sdev = sdev;
@@ -300,6 +312,16 @@ static int imx8_probe(struct snd_sof_dev *sdev)
/* set default mailbox offset for FW ready message */
sdev->dsp_box.offset = MBOX_OFFSET;
+ /* init clocks info */
+ priv->clks->dsp_clks = imx8_dsp_clks;
+ priv->clks->num_dsp_clks = ARRAY_SIZE(imx8_dsp_clks);
+
+ ret = imx8_parse_clocks(sdev, priv->clks);
+ if (ret < 0)
+ goto exit_pdev_unregister;
+
+ imx8_enable_clocks(sdev, priv->clks);
+
return 0;
exit_pdev_unregister:
@@ -318,6 +340,7 @@ static int imx8_remove(struct snd_sof_dev *sdev)
struct imx8_priv *priv = sdev->pdata->hw_pdata;
int i;
+ imx8_disable_clocks(sdev, priv->clks);
platform_device_unregister(priv->ipc_dev);
for (i = 0; i < priv->num_domains; i++) {
@@ -23,6 +23,12 @@
#define MBOX_OFFSET 0x800000
#define MBOX_SIZE 0x1000
+static struct clk_bulk_data imx8m_dsp_clks[] = {
+ { .id = "ipg" },
+ { .id = "ocram" },
+ { .id = "core" },
+};
+
struct imx8m_priv {
struct device *dev;
struct snd_sof_dev *sdev;
@@ -30,6 +36,8 @@ struct imx8m_priv {
/* DSP IPC handler */
struct imx_dsp_ipc *dsp_ipc;
struct platform_device *ipc_dev;
+
+ struct imx_clocks *clks;
};
static int imx8m_get_mailbox_offset(struct snd_sof_dev *sdev)
@@ -108,6 +116,10 @@ static int imx8m_probe(struct snd_sof_dev *sdev)
if (!priv)
return -ENOMEM;
+ priv->clks = devm_kzalloc(&pdev->dev, sizeof(*priv->clks), GFP_KERNEL);
+ if (!priv->clks)
+ return -ENOMEM;
+
sdev->pdata->hw_pdata = priv;
priv->dev = sdev->dev;
priv->sdev = sdev;
@@ -175,6 +187,16 @@ static int imx8m_probe(struct snd_sof_dev *sdev)
/* set default mailbox offset for FW ready message */
sdev->dsp_box.offset = MBOX_OFFSET;
+ /* init clocks info */
+ priv->clks->dsp_clks = imx8m_dsp_clks;
+ priv->clks->num_dsp_clks = ARRAY_SIZE(imx8m_dsp_clks);
+
+ ret = imx8_parse_clocks(sdev, priv->clks);
+ if (ret < 0)
+ goto exit_pdev_unregister;
+
+ imx8_enable_clocks(sdev, priv->clks);
+
return 0;
exit_pdev_unregister:
@@ -186,6 +208,7 @@ static int imx8m_remove(struct snd_sof_dev *sdev)
{
struct imx8m_priv *priv = sdev->pdata->hw_pdata;
+ imx8_disable_clocks(sdev, priv->clks);
platform_device_unregister(priv->ipc_dev);
return 0;