clk: fsl-sai: Add i.MX8M support with 8 byte register offset

The i.MX8M/Mini/Nano/Plus variant of the SAI IP has control registers
shifted by +8 bytes and requires additional bus clock. Add support for
the i.MX8M variant of the IP with this register shift and additional
clock.

Reviewed-by: Brian Masney <bmasney@redhat.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Marek Vasut <marex@nabladev.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
master
Marek Vasut 2026-04-09 02:29:03 +02:00 committed by Stephen Boyd
parent d0a4d58214
commit c206085b26
No known key found for this signature in database
GPG Key ID: AD028897C6E49525
2 changed files with 25 additions and 5 deletions

View File

@ -255,7 +255,7 @@ config COMMON_CLK_FSL_FLEXSPI
config COMMON_CLK_FSL_SAI
bool "Clock driver for BCLK of Freescale SAI cores"
depends on ARCH_LAYERSCAPE || COMPILE_TEST
depends on ARCH_LAYERSCAPE || ARCH_MXC || COMPILE_TEST
help
This driver supports the Freescale SAI (Synchronous Audio Interface)
to be used as a generic clock output. Some SoCs have restrictions

View File

@ -6,6 +6,7 @@
*/
#include <linux/clk-provider.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
@ -20,6 +21,10 @@
#define CR2_DIV_SHIFT 0
#define CR2_DIV_WIDTH 8
struct fsl_sai_data {
unsigned int offset; /* Register offset */
};
struct fsl_sai_clk {
struct clk_divider div;
struct clk_gate gate;
@ -29,8 +34,10 @@ struct fsl_sai_clk {
static int fsl_sai_clk_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct fsl_sai_data *data = device_get_match_data(dev);
struct fsl_sai_clk *sai_clk;
struct clk_parent_data pdata = { .index = 0 };
struct clk *clk_bus;
void __iomem *base;
struct clk_hw *hw;
@ -42,19 +49,23 @@ static int fsl_sai_clk_probe(struct platform_device *pdev)
if (IS_ERR(base))
return PTR_ERR(base);
clk_bus = devm_clk_get_optional_enabled(dev, "bus");
if (IS_ERR(clk_bus))
return PTR_ERR(clk_bus);
spin_lock_init(&sai_clk->lock);
sai_clk->gate.reg = base + I2S_CSR;
sai_clk->gate.reg = base + data->offset + I2S_CSR;
sai_clk->gate.bit_idx = CSR_BCE_BIT;
sai_clk->gate.lock = &sai_clk->lock;
sai_clk->div.reg = base + I2S_CR2;
sai_clk->div.reg = base + data->offset + I2S_CR2;
sai_clk->div.shift = CR2_DIV_SHIFT;
sai_clk->div.width = CR2_DIV_WIDTH;
sai_clk->div.lock = &sai_clk->lock;
/* set clock direction, we are the BCLK master */
writel(CR2_BCD, base + I2S_CR2);
writel(CR2_BCD, base + data->offset + I2S_CR2);
hw = devm_clk_hw_register_composite_pdata(dev, dev->of_node->name,
&pdata, 1, NULL, NULL,
@ -69,8 +80,17 @@ static int fsl_sai_clk_probe(struct platform_device *pdev)
return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
}
static const struct fsl_sai_data fsl_sai_vf610_data = {
.offset = 0,
};
static const struct fsl_sai_data fsl_sai_imx8mq_data = {
.offset = 8,
};
static const struct of_device_id of_fsl_sai_clk_ids[] = {
{ .compatible = "fsl,vf610-sai-clock" },
{ .compatible = "fsl,vf610-sai-clock", .data = &fsl_sai_vf610_data },
{ .compatible = "fsl,imx8mq-sai-clock", .data = &fsl_sai_imx8mq_data },
{ }
};
MODULE_DEVICE_TABLE(of, of_fsl_sai_clk_ids);