diff options
author | Shengjiu Wang <shengjiu.wang@nxp.com> | 2019-08-23 16:29:33 +0800 |
---|---|---|
committer | Dong Aisheng <aisheng.dong@nxp.com> | 2019-11-25 16:28:40 +0800 |
commit | 3ff06a66248c54143dcf43342c7e8bf96887f00b (patch) | |
tree | c3123037db600e35be1a64bb8c91ddcd75036fc3 | |
parent | e72f2ac0f37050512b0a77d93d8e8aad3a87b01f (diff) |
clk: imx8qm: add audio acm clocks
add audio acm clocks
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
-rw-r--r-- | drivers/clk/imx/Makefile | 2 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx8qm-acm.c | 216 | ||||
-rw-r--r-- | drivers/clk/imx/clk-imx8qxp-acm.c | 7 | ||||
-rw-r--r-- | include/dt-bindings/clock/imx8-clock.h | 16 |
4 files changed, 234 insertions, 7 deletions
diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index 90436588a873..1140f1c1a116 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -29,7 +29,7 @@ obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o clk-imx8qxp-acm.o \ - clk-imx8qxp-rsrc.o clk-imx8qm-rsrc.o + clk-imx8qxp-rsrc.o clk-imx8qm-rsrc.o clk-imx8qm-acm.o obj-$(CONFIG_SOC_IMX1) += clk-imx1.o obj-$(CONFIG_SOC_IMX21) += clk-imx21.o obj-$(CONFIG_SOC_IMX25) += clk-imx25.o diff --git a/drivers/clk/imx/clk-imx8qm-acm.c b/drivers/clk/imx/clk-imx8qm-acm.c new file mode 100644 index 000000000000..ebb153d4614f --- /dev/null +++ b/drivers/clk/imx/clk-imx8qm-acm.c @@ -0,0 +1,216 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 NXP + * Dong Aisheng <aisheng.dong@nxp.com> + */ + +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_device.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/pm_domain.h> + +#include "clk.h" +#include "clk-scu.h" + +#include <dt-bindings/clock/imx8-clock.h> + +static const char *aud_clk_sels[] = { + "aud_rec_clk0_lpcg_clk", + "aud_rec_clk1_lpcg_clk", + "mlb_clk", + "hdmi_rx_mclk", + "ext_aud_mclk0", + "ext_aud_mclk1", + "esai0_rx_clk", + "esai0_rx_hf_clk", + "esai0_tx_clk", + "esai0_tx_hf_clk", + "esai1_rx_clk", + "esai1_rx_hf_clk", + "esai1_tx_clk", + "esai1_tx_hf_clk", + "spdif0_rx", + "spdif1_rx", + "sai0_rx_bclk", + "sai0_tx_bclk", + "sai1_rx_bclk", + "sai1_tx_bclk", + "sai2_rx_bclk", + "sai3_rx_bclk", + "sai4_rx_bclk", +}; + +static const char *mclk_out_sels[] = { + "aud_rec_clk0_lpcg_clk", + "aud_rec_clk1_lpcg_clk", + "mlb_clk", + "hdmi_rx_mclk", + "spdif0_rx", + "spdif1_rx", + "sai4_rx_bclk", + "sai6_rx_bclk", +}; + +static const char *sai_mclk_sels[] = { + "aud_pll_div_clk0_lpcg_clk", + "aud_pll_div_clk1_lpcg_clk", + "acm_aud_clk0_sel", + "acm_aud_clk1_sel", +}; + +static const char *asrc_mux_clk_sels[] = { + "sai4_rx_bclk", + "sai5_tx_bclk", + "dummy", + "mlb_clk", +}; + +static const char *esai_mclk_sels[] = { + "aud_pll_div_clk0_lpcg_clk", + "aud_pll_div_clk1_lpcg_clk", + "acm_aud_clk0_sel", + "acm_aud_clk1_sel", +}; + +static const char *spdif_mclk_sels[] = { + "aud_pll_div_clk0_lpcg_clk", + "aud_pll_div_clk1_lpcg_clk", + "acm_aud_clk0_sel", + "acm_aud_clk1_sel", +}; + +static const char *mqs_mclk_sels[] = { + "aud_pll_div_clk0_lpcg_clk", + "aud_pll_div_clk1_lpcg_clk", + "acm_aud_clk0_sel", + "acm_aud_clk1_sel", +}; + +static int imx8qm_acm_clk_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct clk_onecell_data *clk_data; + struct resource *res; + struct clk **clks; + void __iomem *base; + int num_domains; + int i; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap(dev, res->start, resource_size(res)); + if (!base) + return -ENOMEM; + + clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->clks = kcalloc(IMX_ADMA_ACM_CLK_END, + sizeof(*clk_data->clks), GFP_KERNEL); + if (!clk_data->clks) + return -ENOMEM; + + clk_data->clk_num = IMX_ADMA_ACM_CLK_END; + + clks = clk_data->clks; + + num_domains = of_count_phandle_with_args(dev->of_node, "power-domains", + "#power-domain-cells"); + for (i = 0; i < num_domains; i++) { + struct device *pd_dev; + struct device_link *link; + + pd_dev = dev_pm_domain_attach_by_id(&pdev->dev, i); + if (IS_ERR(pd_dev)) + return PTR_ERR(pd_dev); + + link = device_link_add(&pdev->dev, pd_dev, + DL_FLAG_STATELESS | + DL_FLAG_PM_RUNTIME | + DL_FLAG_RPM_ACTIVE); + if (IS_ERR(link)) + return PTR_ERR(link); + } + + clks[IMX_ADMA_EXT_AUD_MCLK0] = imx_clk_fixed("ext_aud_mclk0", 0); + clks[IMX_ADMA_EXT_AUD_MCLK1] = imx_clk_fixed("ext_aud_mclk1", 0); + clks[IMX_ADMA_ESAI0_RX_CLK] = imx_clk_fixed("esai0_rx_clk", 0); + clks[IMX_ADMA_ESAI0_RX_HF_CLK] = imx_clk_fixed("esai0_rx_hf_clk", 0); + clks[IMX_ADMA_ESAI0_TX_CLK] = imx_clk_fixed("esai0_tx_clk", 0); + clks[IMX_ADMA_ESAI0_TX_HF_CLK] = imx_clk_fixed("esai0_tx_hf_clk", 0); + clks[IMX_ADMA_ESAI1_RX_CLK] = imx_clk_fixed("esai1_rx_clk", 0); + clks[IMX_ADMA_ESAI1_RX_HF_CLK] = imx_clk_fixed("esai1_rx_hf_clk", 0); + clks[IMX_ADMA_ESAI1_TX_CLK] = imx_clk_fixed("esai1_tx_clk", 0); + clks[IMX_ADMA_ESAI1_TX_HF_CLK] = imx_clk_fixed("esai1_tx_hf_clk", 0); + clks[IMX_ADMA_SPDIF0_RX] = imx_clk_fixed("spdif0_rx", 0); + clks[IMX_ADMA_SPDIF1_RX] = imx_clk_fixed("spdif1_rx", 0); + clks[IMX_ADMA_SAI0_RX_BCLK] = imx_clk_fixed("sai0_rx_bclk", 0); + clks[IMX_ADMA_SAI0_TX_BCLK] = imx_clk_fixed("sai0_tx_bclk", 0); + clks[IMX_ADMA_SAI1_RX_BCLK] = imx_clk_fixed("sai1_rx_bclk", 0); + clks[IMX_ADMA_SAI1_TX_BCLK] = imx_clk_fixed("sai1_tx_bclk", 0); + clks[IMX_ADMA_SAI2_RX_BCLK] = imx_clk_fixed("sai2_rx_bclk", 0); + clks[IMX_ADMA_SAI3_RX_BCLK] = imx_clk_fixed("sai3_rx_bclk", 0); + clks[IMX_ADMA_SAI4_RX_BCLK] = imx_clk_fixed("sai4_rx_bclk", 0); + clks[IMX_ADMA_SAI5_TX_BCLK] = imx_clk_fixed("sai5_tx_bclk", 0); + clks[IMX_ADMA_SAI6_RX_BCLK] = imx_clk_fixed("sai6_rx_bclk", 0); + clks[IMX_ADMA_HDMI_RX_MCLK] = imx_clk_fixed("hdmi_rx_mclk", 0); + clks[IMX_ADMA_MLB_CLK] = imx_clk_fixed("mlb_clk", 0); + + + clks[IMX_ADMA_ACM_AUD_CLK0_SEL] = imx_clk_mux("acm_aud_clk0_sel", base+0x000000, 0, 5, aud_clk_sels, ARRAY_SIZE(aud_clk_sels)); + clks[IMX_ADMA_ACM_AUD_CLK1_CLK] = imx_clk_mux("acm_aud_clk1_sel", base+0x010000, 0, 5, aud_clk_sels, ARRAY_SIZE(aud_clk_sels)); + + clks[IMX_ADMA_ACM_MCLKOUT0_SEL] = imx_clk_mux("acm_mclkout0_sel", base+0x020000, 0, 3, mclk_out_sels, ARRAY_SIZE(mclk_out_sels)); + clks[IMX_ADMA_ACM_MCLKOUT1_SEL] = imx_clk_mux("acm_mclkout1_sel", base+0x030000, 0, 3, mclk_out_sels, ARRAY_SIZE(mclk_out_sels)); + + clks[IMX_ADMA_ACM_ASRC0_MUX_CLK_SEL] = imx_clk_mux("acm_asrc0_mclk_sel", base+0x040000, 0, 2, asrc_mux_clk_sels, ARRAY_SIZE(asrc_mux_clk_sels)); + + clks[IMX_ADMA_ACM_ESAI0_MCLK_SEL] = imx_clk_mux("acm_esai0_mclk_sel", base+0x060000, 0, 2, esai_mclk_sels, ARRAY_SIZE(esai_mclk_sels)); + clks[IMX_ADMA_ACM_ESAI1_MCLK_SEL] = imx_clk_mux("acm_esai1_mclk_sel", base+0x070000, 0, 2, esai_mclk_sels, ARRAY_SIZE(esai_mclk_sels)); + clks[IMX_ADMA_ACM_SAI0_MCLK_SEL] = imx_clk_mux("acm_sai0_mclk_sel", base+0x0E0000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels)); + clks[IMX_ADMA_ACM_SAI1_MCLK_SEL] = imx_clk_mux("acm_sai1_mclk_sel", base+0x0F0000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels)); + clks[IMX_ADMA_ACM_SAI2_MCLK_SEL] = imx_clk_mux("acm_sai2_mclk_sel", base+0x100000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels)); + clks[IMX_ADMA_ACM_SAI3_MCLK_SEL] = imx_clk_mux("acm_sai3_mclk_sel", base+0x110000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels)); + clks[IMX_ADMA_ACM_SAI4_MCLK_SEL] = imx_clk_mux("acm_sai4_mclk_sel", base+0x120000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels)); + clks[IMX_ADMA_ACM_SAI5_MCLK_SEL] = imx_clk_mux("acm_sai5_mclk_sel", base+0x130000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels)); + clks[IMX_ADMA_ACM_SAI6_MCLK_SEL] = imx_clk_mux("acm_sai6_mclk_sel", base+0x140000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels)); + clks[IMX_ADMA_ACM_SAI7_MCLK_SEL] = imx_clk_mux("acm_sai7_mclk_sel", base+0x150000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels)); + + clks[IMX_ADMA_ACM_SPDIF0_TX_CLK_SEL] = imx_clk_mux("acm_spdif0_mclk_sel", base+0x1A0000, 0, 2, spdif_mclk_sels, ARRAY_SIZE(spdif_mclk_sels)); + clks[IMX_ADMA_ACM_SPDIF1_TX_CLK_SEL] = imx_clk_mux("acm_spdif1_mclk_sel", base+0x1B0000, 0, 2, spdif_mclk_sels, ARRAY_SIZE(spdif_mclk_sels)); + clks[IMX_ADMA_ACM_MQS_TX_CLK_SEL] = imx_clk_mux("acm_mqs_mclk_sel", base+0x1C0000, 0, 2, mqs_mclk_sels, ARRAY_SIZE(mqs_mclk_sels)); + + for (i = 0; i < clk_data->clk_num; i++) { + if (IS_ERR(clks[i])) + pr_warn("i.MX clk %u: register failed with %ld\n", + i, PTR_ERR(clks[i])); + } + + return of_clk_add_provider(np, of_clk_src_onecell_get, clk_data); +} + +static const struct of_device_id imx8qm_acm_match[] = { + { .compatible = "nxp,imx8qm-acm", }, + { /* sentinel */ } +}; + +static struct platform_driver imx8qm_acm_clk_driver = { + .driver = { + .name = "imx8qm-acm", + .of_match_table = imx8qm_acm_match, + .suppress_bind_attrs = true, + }, + .probe = imx8qm_acm_clk_probe, +}; + +static int __init imx8qm_acm_init(void) +{ + return platform_driver_register(&imx8qm_acm_clk_driver); +} +fs_initcall(imx8qm_acm_init); diff --git a/drivers/clk/imx/clk-imx8qxp-acm.c b/drivers/clk/imx/clk-imx8qxp-acm.c index ea58e1f4c172..4497865f72cc 100644 --- a/drivers/clk/imx/clk-imx8qxp-acm.c +++ b/drivers/clk/imx/clk-imx8qxp-acm.c @@ -145,16 +145,13 @@ static int imx8qxp_acm_clk_probe(struct platform_device *pdev) clks[IMX_ADMA_ACM_MCLKOUT0_SEL] = imx_clk_mux("acm_mclkout0_sel", base+0x020000, 0, 3, mclk_out_sels, ARRAY_SIZE(mclk_out_sels)); clks[IMX_ADMA_ACM_MCLKOUT1_SEL] = imx_clk_mux("acm_mclkout1_sel", base+0x030000, 0, 3, mclk_out_sels, ARRAY_SIZE(mclk_out_sels)); - clks[IMX_ADMA_ACM_ASRC0_MUX_CLK_SEL] = imx_clk_mux("acm_asrc0_mclk_sel", base+0x040000, 0, 2, NULL, 0); - clks[IMX_ADMA_ACM_ASRC1_MUX_CLK_SEL] = imx_clk_mux("acm_asrc1_mclk_sel", base+0x050000, 0, 2, NULL, 0); - clks[IMX_ADMA_ACM_ESAI0_MCLK_SEL] = imx_clk_mux("acm_esai0_mclk_sel", base+0x060000, 0, 2, esai_mclk_sels, ARRAY_SIZE(esai_mclk_sels)); clks[IMX_ADMA_ACM_SAI0_MCLK_SEL] = imx_clk_mux("acm_sai0_mclk_sel", base+0x0E0000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels)); clks[IMX_ADMA_ACM_SAI1_MCLK_SEL] = imx_clk_mux("acm_sai1_mclk_sel", base+0x0F0000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels)); clks[IMX_ADMA_ACM_SAI2_MCLK_SEL] = imx_clk_mux("acm_sai2_mclk_sel", base+0x100000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels)); clks[IMX_ADMA_ACM_SAI3_MCLK_SEL] = imx_clk_mux("acm_sai3_mclk_sel", base+0x110000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels)); -// clks[IMX_ADMA_ACM_SAI4_MCLK_SEL] = imx_clk_mux("acm_sai4_mclk_sel", base+0x140000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels)); -// clks[IMX_ADMA_ACM_SAI5_MCLK_SEL] = imx_clk_mux("acm_sai5_mclk_sel", base+0x150000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels)); + clks[IMX_ADMA_ACM_SAI4_MCLK_SEL] = imx_clk_mux("acm_sai4_mclk_sel", base+0x140000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels)); + clks[IMX_ADMA_ACM_SAI5_MCLK_SEL] = imx_clk_mux("acm_sai5_mclk_sel", base+0x150000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels)); clks[IMX_ADMA_ACM_SPDIF0_TX_CLK_SEL] = imx_clk_mux("acm_spdif0_mclk_sel", base+0x1A0000, 0, 2, spdif_mclk_sels, ARRAY_SIZE(spdif_mclk_sels)); clks[IMX_ADMA_ACM_MQS_TX_CLK_SEL] = imx_clk_mux("acm_mqs_mclk_sel", base+0x1C0000, 0, 2, mqs_mclk_sels, ARRAY_SIZE(mqs_mclk_sels)); diff --git a/include/dt-bindings/clock/imx8-clock.h b/include/dt-bindings/clock/imx8-clock.h index c9cecb47aefb..d7d2a8f3d49e 100644 --- a/include/dt-bindings/clock/imx8-clock.h +++ b/include/dt-bindings/clock/imx8-clock.h @@ -45,7 +45,21 @@ #define IMX_ADMA_SAI2_RX_BCLK 34 #define IMX_ADMA_SAI3_RX_BCLK 35 #define IMX_ADMA_SAI4_RX_BCLK 36 +#define IMX_ADMA_SAI5_TX_BCLK 37 +#define IMX_ADMA_SAI6_RX_BCLK 38 +#define IMX_ADMA_HDMI_RX_MCLK 39 +#define IMX_ADMA_MLB_CLK 40 +#define IMX_ADMA_SPDIF1_RX 41 +#define IMX_ADMA_ESAI1_RX_CLK 42 +#define IMX_ADMA_ESAI1_RX_HF_CLK 43 +#define IMX_ADMA_ESAI1_TX_CLK 44 +#define IMX_ADMA_ESAI1_TX_HF_CLK 45 -#define IMX_ADMA_ACM_CLK_END 37 +#define IMX_ADMA_ACM_ESAI1_MCLK_SEL 46 +#define IMX_ADMA_ACM_SAI6_MCLK_SEL 47 +#define IMX_ADMA_ACM_SAI7_MCLK_SEL 48 +#define IMX_ADMA_ACM_SPDIF1_TX_CLK_SEL 49 + +#define IMX_ADMA_ACM_CLK_END 50 #endif /* __DT_BINDINGS_CLOCK_IMX_H */ |