MLK-23273-1 clk: imx: Add imx8dxl clk driver

Add files for imx8dxl clk driver which is based on imx8qxp clock driver.

Signed-off-by: Teo Hall <teo.hall@nxp.com>
Reviewed-by: Anson Huang <Anson.Huang@nxp.com>
This commit is contained in:
Teo Hall 2020-02-02 16:08:31 -06:00 committed by Anson Huang
parent 468868d88d
commit 6d813b5717
5 changed files with 254 additions and 1 deletions

View File

@ -30,7 +30,8 @@ obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o clk-audiomix.o clk-hdmimix.o clk-gate-shared.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-imx8qm-acm.o
clk-imx8qxp-rsrc.o clk-imx8qm-rsrc.o clk-imx8qm-acm.o \
clk-imx8dxl-rsrc.o clk-imx8dxl-acm.o
obj-$(CONFIG_SOC_IMX1) += clk-imx1.o
obj-$(CONFIG_SOC_IMX21) += clk-imx21.o
obj-$(CONFIG_SOC_IMX25) += clk-imx25.o

View File

@ -0,0 +1,185 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2019~2020 NXP
*/
#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",
"ext_aud_mclk0",
"ext_aud_mclk1",
"esai0_rx_clk",
"esai0_rx_hf_clk",
"esai0_tx_clk",
"esai0_tx_hf_clk",
"spdif0_rx",
"sai0_rx_bclk",
"sai0_tx_bclk",
"sai1_rx_bclk",
"sai1_tx_bclk",
"sai2_rx_bclk",
"sai3_rx_bclk",
};
static const char *mclk_out_sels[] = {
"aud_rec_clk0_lpcg_clk",
"aud_rec_clk1_lpcg_clk",
"dummy",
"dummy",
"spdif0_rx",
"dummy",
"dummy",
"sai4_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 *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 imx8qxp_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_SPDIF0_RX] = imx_clk_fixed("spdif0_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_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_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_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));
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 imx8qxp_acm_match[] = {
{ .compatible = "nxp,imx8qxp-acm", },
{ /* sentinel */ }
};
static struct platform_driver imx8qxp_acm_clk_driver = {
.driver = {
.name = "imx8qxp-acm",
.of_match_table = imx8qxp_acm_match,
.suppress_bind_attrs = true,
},
.probe = imx8qxp_acm_clk_probe,
};
static int __init imx8qxp_acm_init(void)
{
return platform_driver_register(&imx8qxp_acm_clk_driver);
}
fs_initcall(imx8qxp_acm_init);

View File

@ -0,0 +1,65 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2019~2020 NXP
*/
#include <dt-bindings/firmware/imx/rsrc.h>
#include "clk-scu.h"
/* Keep sorted in the ascending order */
static u32 imx8dxl_clk_scu_rsrc_table[] = {
IMX_SC_R_SPI_0,
IMX_SC_R_SPI_1,
IMX_SC_R_SPI_2,
IMX_SC_R_SPI_3,
IMX_SC_R_UART_0,
IMX_SC_R_UART_1,
IMX_SC_R_UART_2,
IMX_SC_R_UART_3,
IMX_SC_R_I2C_0,
IMX_SC_R_I2C_1,
IMX_SC_R_I2C_2,
IMX_SC_R_I2C_3,
IMX_SC_R_ADC_0,
IMX_SC_R_FTM_0,
IMX_SC_R_FTM_1,
IMX_SC_R_CAN_0,
IMX_SC_R_LCD_0,
IMX_SC_R_LCD_0_PWM_0,
IMX_SC_R_PWM_0,
IMX_SC_R_PWM_1,
IMX_SC_R_PWM_2,
IMX_SC_R_PWM_3,
IMX_SC_R_PWM_4,
IMX_SC_R_PWM_5,
IMX_SC_R_PWM_6,
IMX_SC_R_PWM_7,
IMX_SC_R_GPT_0,
IMX_SC_R_GPT_1,
IMX_SC_R_GPT_2,
IMX_SC_R_GPT_3,
IMX_SC_R_GPT_4,
IMX_SC_R_FSPI_0,
IMX_SC_R_FSPI_1,
IMX_SC_R_SDHC_0,
IMX_SC_R_SDHC_1,
IMX_SC_R_SDHC_2,
IMX_SC_R_ENET_0,
IMX_SC_R_ENET_1,
IMX_SC_R_MLB_0,
IMX_SC_R_USB_1,
IMX_SC_R_NAND,
IMX_SC_R_M4_0_I2C,
IMX_SC_R_ELCDIF_PLL,
IMX_SC_R_AUDIO_PLL_0,
IMX_SC_R_AUDIO_PLL_1,
IMX_SC_R_AUDIO_CLK_0,
IMX_SC_R_AUDIO_CLK_1,
IMX_SC_R_A35
};
const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8dxl = {
.rsrc = imx8dxl_clk_scu_rsrc_table,
.num = ARRAY_SIZE(imx8dxl_clk_scu_rsrc_table),
};

View File

@ -71,6 +71,7 @@ static const struct of_device_id imx8qxp_match[] = {
{ .compatible = "fsl,scu-clk", },
{ .compatible = "fsl,imx8qxp-clk", &imx_clk_scu_rsrc_imx8qxp, },
{ .compatible = "fsl,imx8qm-clk", &imx_clk_scu_rsrc_imx8qm, },
{ .compatible = "fsl,imx8dxl-clk", &imx_clk_scu_rsrc_imx8dxl, },
{ /* sentinel */ }
};

View File

@ -24,6 +24,7 @@ extern struct list_head imx_scu_clks[];
extern const struct dev_pm_ops imx_clk_lpcg_scu_pm_ops;
extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qxp;
extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8qm;
extern const struct imx_clk_scu_rsrc_table imx_clk_scu_rsrc_imx8dxl;
int imx_clk_scu_init(struct device_node *np, const void *data);
struct clk_hw *imx_scu_of_clk_src_get(struct of_phandle_args *clkspec,