Unverified Commit c206085b authored by Marek Vasut's avatar Marek Vasut Committed by Stephen Boyd
Browse files

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: default avatarBrian Masney <bmasney@redhat.com>
Reviewed-by: default avatarPeng Fan <peng.fan@nxp.com>
Signed-off-by: default avatarMarek Vasut <marex@nabladev.com>
Signed-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent d0a4d582
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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
+24 −4
Original line number Diff line number Diff line
@@ -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);