diff options
author | Daniel Baluta <daniel.baluta@nxp.com> | 2020-10-05 17:40:12 +0300 |
---|---|---|
committer | Daniel Baluta <daniel.baluta@nxp.com> | 2020-10-06 13:29:22 +0300 |
commit | 1714fabe712f4e0f01864dcdc0eb259d150170b8 (patch) | |
tree | 12b44ef02b9ccab0d68eb4495a80dce8fdd86cc9 /sound/soc/sof | |
parent | 271cdc141d35284e18a8b3d350867c0732a6814f (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.c | 63 |
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; } |