summaryrefslogtreecommitdiff
path: root/sound/soc/sof
diff options
context:
space:
mode:
authorDaniel Baluta <daniel.baluta@nxp.com>2020-10-05 17:40:12 +0300
committerDaniel Baluta <daniel.baluta@nxp.com>2020-10-06 13:29:22 +0300
commit1714fabe712f4e0f01864dcdc0eb259d150170b8 (patch)
tree12b44ef02b9ccab0d68eb4495a80dce8fdd86cc9 /sound/soc/sof
parent271cdc141d35284e18a8b3d350867c0732a6814f (diff)
MLK-24668-1 ASoC: SOF: imx8: Add DAI clocks handling
We no longer use FSL DAI generic driver as it is not a good direction for upstreaming. Move clock handling to SOF imx specific driver. Note that clocks handled are for DAIs used by i.MX8/i.MX8X boards, that is SAI1 and ESAI0. Reviewed-by: Paul Olaru <paul.olaru@nxp.com> Signed-off-by: Daniel Baluta <daniel.baluta@nxp.com>
Diffstat (limited to 'sound/soc/sof')
-rw-r--r--sound/soc/sof/imx/imx8.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c
index 28d5981e3aa9..7e08f1b91ded 100644
--- a/sound/soc/sof/imx/imx8.c
+++ b/sound/soc/sof/imx/imx8.c
@@ -6,6 +6,7 @@
//
// Hardware interface for audio DSP on i.MX8
+#include <linux/clk.h>
#include <linux/firmware.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
@@ -39,6 +40,15 @@
#define MBOX_OFFSET 0x800000
#define MBOX_SIZE 0x1000
+#define IMX8_DSP_CLK_NUM 9
+static const char *imx8_dsp_clks_names[IMX8_DSP_CLK_NUM] =
+{
+ /* ESAI0 clocks */
+ "esai0_core", "esai0_extal", "esai0_fsys", "esai0_spba",
+ /* SAI1 clocks */
+ "sai1_bus", "sai1_mclk0", "sai1_mclk1", "sai1_mclk2", "sai1_mclk3",
+};
+
struct imx8_priv {
struct device *dev;
struct snd_sof_dev *sdev;
@@ -56,8 +66,54 @@ struct imx8_priv {
struct device **pd_dev;
struct device_link **link;
+ struct clk *dsp_clks[IMX8_DSP_CLK_NUM];
};
+static int imx8_init_clocks(struct snd_sof_dev *sdev)
+{
+ int i;
+ struct imx8_priv *priv = (struct imx8_priv *)sdev->private;
+
+ for (i = 0; i < IMX8_DSP_CLK_NUM; i++) {
+ priv->dsp_clks[i] = devm_clk_get(priv->dev, imx8_dsp_clks_names[i]);
+ if (IS_ERR(priv->dsp_clks[i]))
+ priv->dsp_clks[i] = NULL;
+ }
+
+ return 0;
+}
+
+static int imx8_prepare_clocks(struct snd_sof_dev *sdev)
+{
+ int i, ret;
+ struct imx8_priv *priv = (struct imx8_priv *)sdev->private;
+
+ for (i = 0; i < IMX8_DSP_CLK_NUM; i++) {
+ ret = clk_prepare_enable(priv->dsp_clks[i]);
+ if (ret < 0) {
+ dev_err(priv->dev, "Failed to enable clk %s\n",
+ imx8_dsp_clks_names[i]);
+ goto err_dsp_clks;
+ }
+ }
+ return 0;
+
+err_dsp_clks:
+ while (--i >= 0)
+ clk_disable_unprepare(priv->dsp_clks[i]);
+
+ return ret;
+}
+
+static void imx8_disable_clocks(struct snd_sof_dev *sdev)
+{
+ int i;
+ struct imx8_priv *priv = (struct imx8_priv *)sdev->private;
+
+ for (i = 0; i < IMX8_DSP_CLK_NUM; i++)
+ clk_disable_unprepare(priv->dsp_clks[i]);
+}
+
static void imx8_get_reply(struct snd_sof_dev *sdev)
{
struct snd_sof_ipc_msg *msg = sdev->msg;
@@ -331,6 +387,9 @@ done_pm:
/* set default mailbox offset for FW ready message */
sdev->dsp_box.offset = MBOX_OFFSET;
+ imx8_init_clocks(sdev);
+ imx8_prepare_clocks(sdev);
+
return 0;
exit_pdev_unregister:
@@ -384,6 +443,8 @@ int imx8_resume(struct snd_sof_dev *sdev)
struct imx8_priv *priv = (struct imx8_priv *)sdev->private;
int i;
+ imx8_prepare_clocks(sdev);
+
for (i = 0; i < DSP_MU_CHAN_NUM; i++)
imx_dsp_request_channel(priv->dsp_ipc, i);
@@ -398,6 +459,8 @@ int imx8_suspend(struct snd_sof_dev *sdev)
for (i = 0; i < DSP_MU_CHAN_NUM; i++)
imx_dsp_free_channel(priv->dsp_ipc, i);
+ imx8_disable_clocks(sdev);
+
return 0;
}