diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index a84c5573cabeae1ede83c2e597e8d310bc98d307..b7cb91fadab4f6106c618434681586d0241ed3cc 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -71,7 +71,7 @@ obj-$(CONFIG_ARCH_DAVINCI) += davinci/ obj-$(CONFIG_H8300) += h8300/ obj-$(CONFIG_ARCH_HISI) += hisilicon/ obj-y += imgtec/ -obj-$(CONFIG_ARCH_MXC) += imx/ +obj-y += imx/ obj-$(CONFIG_MACH_INGENIC) += ingenic/ obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ obj-$(CONFIG_MACH_LOONGSON32) += loongson1/ diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index c8342350bc81e55c3abb7c6f2a23628592cbdbcf..a66d4d5f485db0a641bf350045a27d260034a8f2 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -31,3 +31,5 @@ obj-$(CONFIG_SOC_IMX6UL) += clk-imx6ul.o obj-$(CONFIG_SOC_IMX7D) += clk-imx7d.o obj-$(CONFIG_SOC_IMX7ULP) += clk-imx7ulp.o clk-composite-7ulp.o obj-$(CONFIG_SOC_VF610) += clk-vf610.o + +obj-$(CONFIG_ARCH_FSL_IMX8QXP) += clk.o clk-imx8qxp.o clk-imx8.o clk-divider-scu.o clk-gate-scu.o clk-mux-scu.o diff --git a/drivers/clk/imx/clk-divider-scu.c b/drivers/clk/imx/clk-divider-scu.c new file mode 100644 index 0000000000000000000000000000000000000000..b8ad05050ec09863b8751e955ef73c06cb49b41a --- /dev/null +++ b/drivers/clk/imx/clk-divider-scu.c @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/jiffies.h> +#include <linux/slab.h> +#include <soc/imx8/sc/sci.h> + +#include "clk-imx8.h" + +struct clk_divider_scu { + struct clk_divider div; + sc_rsrc_t rsrc_id; + sc_pm_clk_t clk_type; +}; + +struct clk_divider3_scu { + struct clk_divider div; + sc_rsrc_t rsrc_id; + sc_ctrl_t gpr_id; +}; + +static inline struct clk_divider3_scu *to_clk_divider3_scu(struct clk_hw *hw) +{ + struct clk_divider *div = container_of(hw, struct clk_divider, hw); + + return container_of(div, struct clk_divider3_scu, div); +} + +static inline struct clk_divider_scu *to_clk_divider_scu(struct clk_hw *hw) +{ + struct clk_divider *div = container_of(hw, struct clk_divider, hw); + + return container_of(div, struct clk_divider_scu, div); +} + +static unsigned long clk_divider_scu_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_divider_scu *clk = to_clk_divider_scu(hw); + sc_err_t sci_err; + sc_pm_clock_rate_t rate = 0; + + if (!ccm_ipc_handle) + return 0; + + sci_err = sc_pm_get_clock_rate(ccm_ipc_handle, clk->rsrc_id, + clk->clk_type, &rate); + + return sci_err ? 0 : rate; +} + +static long clk_divider_scu_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + /* TODO */ + *prate = rate; + + return rate; +} + +static int clk_divider_scu_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_divider_scu *clk = to_clk_divider_scu(hw); + sc_err_t sci_err; + + if (!ccm_ipc_handle) { + return -EAGAIN; + } + + sci_err = sc_pm_set_clock_rate(ccm_ipc_handle, clk->rsrc_id, + clk->clk_type, (sc_pm_clock_rate_t *)&rate); + + return sci_err ? -EINVAL : 0; +} + +static struct clk_ops clk_divider_scu_ops = { + .recalc_rate = clk_divider_scu_recalc_rate, + .round_rate = clk_divider_scu_round_rate, + .set_rate = clk_divider_scu_set_rate, +}; + +struct clk *imx_clk_divider_scu(const char *name, + sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type) +{ + struct clk_divider_scu *div_clk; + struct clk *clk; + struct clk_init_data init; + + if (!imx8_clk_is_resource_owned(rsrc_id)) { + pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id); + return ERR_PTR(-ENODEV); + } + + div_clk = kzalloc(sizeof(*div_clk), GFP_KERNEL); + if (!div_clk) + return ERR_PTR(-ENOMEM); + + div_clk->rsrc_id = rsrc_id; + div_clk->clk_type = clk_type; + + init.name = name; + init.ops = &clk_divider_scu_ops; + init.flags = CLK_GET_RATE_NOCACHE; + init.num_parents = 0; + div_clk->div.hw.init = &init; + + clk = clk_register(NULL, &div_clk->div.hw); + if (IS_ERR(clk)) + kfree(div_clk); + + return clk; +} + +struct clk *imx_clk_divider2_scu(const char *name, const char *parent_name, + sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type) +{ + struct clk_divider_scu *div_clk; + struct clk *clk; + struct clk_init_data init; + + if (!imx8_clk_is_resource_owned(rsrc_id)) { + pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id); + return ERR_PTR(-ENODEV); + } + + div_clk = kzalloc(sizeof(*div_clk), GFP_KERNEL); + if (!div_clk) + return ERR_PTR(-ENOMEM); + + div_clk->rsrc_id = rsrc_id; + div_clk->clk_type = clk_type; + + init.name = name; + init.ops = &clk_divider_scu_ops; + init.flags = CLK_GET_RATE_NOCACHE; + init.parent_names = parent_name ? &parent_name : NULL; + init.num_parents = parent_name ? 1 : 0; + div_clk->div.hw.init = &init; + + clk = clk_register(NULL, &div_clk->div.hw); + if (IS_ERR(clk)) + kfree(div_clk); + + return clk; +} + +static unsigned long clk_divider3_scu_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_divider3_scu *clk = to_clk_divider3_scu(hw); + uint32_t val; + sc_err_t sci_err; + sc_pm_clock_rate_t rate = 0; + + if (!ccm_ipc_handle) + return 0; + + sci_err = sc_misc_get_control(ccm_ipc_handle, clk->rsrc_id, + clk->gpr_id, &val); + + rate = (val) ? parent_rate / 2 : parent_rate; + + return sci_err ? 0 : rate; +} + +static long clk_divider3_scu_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + if (rate < *prate) + rate = *prate / 2; + else + rate = *prate; + + return rate; +} + +static int clk_divider3_scu_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_divider3_scu *clk = to_clk_divider3_scu(hw); + uint32_t val; + sc_err_t sci_err; + + if (!ccm_ipc_handle) { + return -EAGAIN; + } + + val = (rate < parent_rate) ? 1 : 0; + sci_err = sc_misc_set_control(ccm_ipc_handle, clk->rsrc_id, + clk->gpr_id, val); + + return sci_err ? -EINVAL : 0; +} + +static struct clk_ops clk_divider3_scu_ops = { + .recalc_rate = clk_divider3_scu_recalc_rate, + .round_rate = clk_divider3_scu_round_rate, + .set_rate = clk_divider3_scu_set_rate, +}; + +struct clk *imx_clk_divider3_scu(const char *name, const char *parent_name, + sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id) +{ + struct clk_divider3_scu *div; + struct clk *clk; + struct clk_init_data init; + + if (!imx8_clk_is_resource_owned(rsrc_id)) { + pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id); + return ERR_PTR(-ENODEV); + } + + div = kzalloc(sizeof(struct clk_divider3_scu), GFP_KERNEL); + if (!div) + return ERR_PTR(-ENOMEM); + + div->rsrc_id = rsrc_id; + div->gpr_id = gpr_id; + + init.name = name; + init.ops = &clk_divider3_scu_ops; + init.flags = 0; + init.parent_names = parent_name ? &parent_name : NULL; + init.num_parents = parent_name ? 1 : 0; + + div->div.hw.init = &init; + + clk = clk_register(NULL, &div->div.hw); + if (IS_ERR(clk)) + kfree(div); + + return clk; +} diff --git a/drivers/clk/imx/clk-gate-scu.c b/drivers/clk/imx/clk-gate-scu.c new file mode 100644 index 0000000000000000000000000000000000000000..abcda5f9a9529c7dc4d558b9e5ef710d7564bf56 --- /dev/null +++ b/drivers/clk/imx/clk-gate-scu.c @@ -0,0 +1,448 @@ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pm_domain.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <soc/imx8/sc/sci.h> + +#include "clk-imx8.h" + +/* + * DOC: basic gatable clock which can gate and ungate it's ouput + * + * Traits of this clock: + * prepare - clk_(un)prepare only ensures parent is (un)prepared + * enable - clk_enable and clk_disable are functional & control gating + * rate - inherits rate from parent. No clk_set_rate support + * parent - fixed parent. No clk_set_parent support + */ + +#define CLK_GATE_SCU_HW_SW_EN (BIT(0) | BIT(1)) +#define CLK_GATE_SCU_SW_EN BIT(1) + +struct clk_gate_scu { + struct clk_hw hw; + void __iomem *reg; + u8 bit_idx; + bool hw_gate; + u8 flags; + spinlock_t *lock; + sc_rsrc_t rsrc_id; + sc_pm_clk_t clk_type; +}; + +struct clk_gate2_scu { + struct clk_hw hw; + void __iomem *reg; + u8 bit_idx; + u8 flags; + spinlock_t *lock; + char *pd_name; + struct generic_pm_domain *pd; +}; + +struct clk_gate3_scu { + struct clk_hw hw; + spinlock_t *lock; + sc_rsrc_t rsrc_id; + sc_ctrl_t gpr_id; + bool invert; +}; + +#define to_clk_gate_scu(_hw) container_of(_hw, struct clk_gate_scu, hw) +#define to_clk_gate2_scu(_hw) container_of(_hw, struct clk_gate2_scu, hw) +#define to_clk_gate3_scu(_hw) container_of(_hw, struct clk_gate3_scu, hw) + +/* Write to the LPCG bits. */ +static int clk_gate_scu_enable(struct clk_hw *hw) +{ + struct clk_gate_scu *gate = to_clk_gate_scu(hw); + u32 reg; + + if (!ccm_ipc_handle) + return -1; + + if (gate->reg) { + reg = readl(gate->reg); + if (gate->hw_gate) + reg |= (CLK_GATE_SCU_HW_SW_EN << gate->bit_idx); + else + reg |= (CLK_GATE_SCU_SW_EN << gate->bit_idx); + writel(reg, gate->reg); + } + + return 0; +} + +/* Write to the LPCG bits. */ +static void clk_gate_scu_disable(struct clk_hw *hw) +{ + struct clk_gate_scu *gate = to_clk_gate_scu(hw); + u32 reg; + + if (!ccm_ipc_handle) + return; + + if (gate->reg) { + reg = readl(gate->reg); + if (gate->hw_gate) + reg &= ~(CLK_GATE_SCU_HW_SW_EN << gate->bit_idx); + else + reg &= ~(CLK_GATE_SCU_SW_EN << gate->bit_idx); + writel(reg, gate->reg); + } +} + +static int clk_gate_scu_prepare(struct clk_hw *hw) +{ + struct clk_gate_scu *gate = to_clk_gate_scu(hw); + sc_err_t sci_err = SC_ERR_NONE; + + if (!ccm_ipc_handle) + return -1; + + /* Enable the clock at the DSC slice level */ + sci_err = sc_pm_clock_enable(ccm_ipc_handle, gate->rsrc_id, + gate->clk_type, true, gate->hw_gate); + + if (sci_err != SC_ERR_NONE) + return -EINVAL; + + return 0; +} + +static void clk_gate_scu_unprepare(struct clk_hw *hw) +{ + struct clk_gate_scu *gate = to_clk_gate_scu(hw); + sc_err_t sci_err; + + if (!ccm_ipc_handle) + return; + + sci_err = sc_pm_clock_enable(ccm_ipc_handle, gate->rsrc_id, + gate->clk_type, false, false); + if (sci_err) + pr_err("clk gate scu unprepare clk fail!\n"); +} + +static unsigned long clk_gate_scu_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_gate_scu *clk = to_clk_gate_scu(hw); + sc_err_t sci_err; + sc_pm_clock_rate_t rate = 0; + + if (!ccm_ipc_handle) + return 0; + + sci_err = sc_pm_get_clock_rate(ccm_ipc_handle, clk->rsrc_id, + clk->clk_type, &rate); + + return sci_err ? 0 : rate; +} + +static struct clk_ops clk_gate_scu_ops = { + .prepare = clk_gate_scu_prepare, + .unprepare = clk_gate_scu_unprepare, + .enable = clk_gate_scu_enable, + .disable = clk_gate_scu_disable, + .recalc_rate = clk_gate_scu_recalc_rate, +}; + +struct clk *clk_register_gate_scu(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + u8 clk_gate_scu_flags, spinlock_t *lock, + sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type, + void __iomem *reg, u8 bit_idx, bool hw_gate) +{ + struct clk_gate_scu *gate; + struct clk *clk; + struct clk_init_data init; + + if (!imx8_clk_is_resource_owned(rsrc_id)) { + pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id); + return ERR_PTR(-ENODEV); + } + + gate = kzalloc(sizeof(struct clk_gate_scu), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + /* struct clk_gate_scu assignments */ + gate->flags = clk_gate_scu_flags; + gate->lock = lock; + gate->rsrc_id = rsrc_id; + gate->clk_type = clk_type; + if (reg != NULL) + gate->reg = ioremap((phys_addr_t)reg, SZ_64K); + else + gate->reg = NULL; + gate->bit_idx = bit_idx; + gate->hw_gate = hw_gate; + + init.name = name; + init.ops = &clk_gate_scu_ops; + init.flags = flags; + init.parent_names = parent_name ? &parent_name : NULL; + init.num_parents = parent_name ? 1 : 0; + + gate->hw.init = &init; + + clk = clk_register(dev, &gate->hw); + if (IS_ERR(clk)) { + iounmap(gate->reg); + kfree(gate); + } + + return clk; +} + +/* Get the power domain associated with the clock from the device tree. */ +static void populate_gate_pd(struct clk_gate2_scu *clk) +{ + struct device_node *np; + struct of_phandle_args pd_args; + + np = of_find_node_by_name(NULL, clk->pd_name); + if (np) { + pd_args.np = np; + pd_args.args_count = 0; + clk->pd = genpd_get_from_provider(&pd_args); + if (IS_ERR(clk->pd)) + pr_warn("%s: failed to get pd\n", __func__); + } +} + +/* Write to the LPCG bits. */ +static int clk_gate2_scu_enable(struct clk_hw *hw) +{ + struct clk_gate2_scu *gate = to_clk_gate2_scu(hw); + u32 reg; + + if (!ccm_ipc_handle) + return -1; + + if (gate->pd == NULL && gate->pd_name) + populate_gate_pd(gate); + + if (IS_ERR_OR_NULL(gate->pd)) + return -1; + + if (gate->pd->status != GPD_STATE_ACTIVE) + return -1; + + if (gate->reg) { + reg = readl(gate->reg); + reg |= (0x2 << gate->bit_idx); + writel(reg, gate->reg); + } + + return 0; +} + +/* Write to the LPCG bits. */ +static void clk_gate2_scu_disable(struct clk_hw *hw) +{ + struct clk_gate2_scu *gate = to_clk_gate2_scu(hw); + u32 reg; + + if (!ccm_ipc_handle) + return; + + if (gate->pd == NULL && gate->pd_name) + populate_gate_pd(gate); + + if (IS_ERR_OR_NULL(gate->pd)) + return; + + if (gate->pd->status != GPD_STATE_ACTIVE) + return; + + if (gate->reg) { + reg = readl(gate->reg); + reg &= ~(0x2 << gate->bit_idx); + writel(reg, gate->reg); + } +} + +static int clk_gate2_scu_is_enabled(struct clk_hw *hw) +{ + struct clk_gate2_scu *gate = to_clk_gate2_scu(hw); + u32 val; + + if (gate->pd == NULL && gate->pd_name) + populate_gate_pd(gate); + + if (IS_ERR_OR_NULL(gate->pd)) + return 0; + + if (gate->pd->status != GPD_STATE_ACTIVE) + return 0; + + if (gate->reg) { + val = readl(gate->reg); + + if (((val >> gate->bit_idx) & 2) == 2) + return 1; + } + return 0; +} + + +static struct clk_ops clk_gate2_scu_ops = { + .enable = clk_gate2_scu_enable, + .disable = clk_gate2_scu_disable, + .is_enabled = clk_gate2_scu_is_enabled, +}; + +struct clk *clk_register_gate2_scu(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u8 bit_idx, + u8 clk_gate_flags, spinlock_t *lock, const char *pd_name) +{ + struct clk_gate2_scu *gate; + struct clk *clk; + struct clk_init_data init; + + gate = kzalloc(sizeof(struct clk_gate2_scu), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + /* struct clk_gate_scu assignments */ + gate->flags = clk_gate_flags; + gate->lock = lock; + if (reg != NULL) + gate->reg = ioremap((phys_addr_t)reg, SZ_64K); + else + gate->reg = NULL; + gate->bit_idx = bit_idx; + gate->pd = NULL; + gate->pd_name = NULL; + if (pd_name) { + gate->pd_name = kzalloc(strlen(pd_name) + 1, GFP_KERNEL); + strcpy(gate->pd_name, pd_name); + } + + init.name = name; + init.ops = &clk_gate2_scu_ops; + init.flags = flags; + init.parent_names = parent_name ? &parent_name : NULL; + init.num_parents = parent_name ? 1 : 0; + + gate->hw.init = &init; + + clk = clk_register(dev, &gate->hw); + if (IS_ERR(clk)) { + iounmap(gate->reg); + kfree(gate->pd_name); + kfree(gate); + } + + return clk; +} + +static int clk_gate3_scu_prepare(struct clk_hw *hw) +{ + struct clk_gate3_scu *gate = to_clk_gate3_scu(hw); + uint32_t val; + + if (!ccm_ipc_handle) + return -1; + + val = (gate->invert) ? 0 : 1; + + return sc_misc_set_control(ccm_ipc_handle, + gate->rsrc_id, gate->gpr_id, val); +} + +/* Write to the LPCG bits. */ +static void clk_gate3_scu_unprepare(struct clk_hw *hw) +{ + struct clk_gate3_scu *gate = to_clk_gate3_scu(hw); + uint32_t val; + + if (!ccm_ipc_handle) + return; + + val = (gate->invert) ? 1 : 0; + sc_misc_set_control(ccm_ipc_handle, gate->rsrc_id, gate->gpr_id, val); +} + +static int clk_gate3_scu_is_prepared(struct clk_hw *hw) +{ + struct clk_gate3_scu *gate = to_clk_gate3_scu(hw); + uint32_t val; + + if (!ccm_ipc_handle) + return -1; + + sc_misc_get_control(ccm_ipc_handle, gate->rsrc_id, gate->gpr_id, &val); + val &= 1; + + if (gate->invert) + return 1 - val; + + return val; +} + +static struct clk_ops clk_gate3_scu_ops = { + .prepare = clk_gate3_scu_prepare, + .unprepare = clk_gate3_scu_unprepare, + .is_prepared = clk_gate3_scu_is_prepared, +}; + +struct clk *clk_register_gate3_scu(struct device *dev, const char *name, + const char *parent_name, spinlock_t *lock, + sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id, bool invert_flag) +{ + struct clk_gate3_scu *gate; + struct clk *clk; + struct clk_init_data init; + + if (!imx8_clk_is_resource_owned(rsrc_id)) { + pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id); + return ERR_PTR(-ENODEV); + } + + gate = kzalloc(sizeof(struct clk_gate_scu), GFP_KERNEL); + if (!gate) + return ERR_PTR(-ENOMEM); + + /* struct clk_gate_scu assignments */ + gate->lock = lock; + gate->rsrc_id = rsrc_id; + gate->gpr_id = gpr_id; + gate->invert = invert_flag; + + init.name = name; + init.ops = &clk_gate3_scu_ops; + init.flags = 0; + init.parent_names = parent_name ? &parent_name : NULL; + init.num_parents = parent_name ? 1 : 0; + + gate->hw.init = &init; + + clk = clk_register(dev, &gate->hw); + if (IS_ERR(clk)) + kfree(gate); + + return clk; +} diff --git a/drivers/clk/imx/clk-imx8.c b/drivers/clk/imx/clk-imx8.c new file mode 100644 index 0000000000000000000000000000000000000000..fb5896a09b79d92afc675d6b33fb5598bd4d28d7 --- /dev/null +++ b/drivers/clk/imx/clk-imx8.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/errno.h> +#include <soc/imx8/sc/sci.h> + +#include "clk-imx8.h" + +sc_ipc_t ccm_ipc_handle; + +int imx8_clk_mu_init(void) +{ + uint32_t mu_id; + sc_err_t sciErr; + + printk("MU and Power domains initialized\n"); + + sciErr = sc_ipc_getMuID(&mu_id); + if (sciErr != SC_ERR_NONE) { + pr_info("Cannot obtain MU ID\n"); + return -EPROBE_DEFER; + } + + sciErr = sc_ipc_open(&ccm_ipc_handle, mu_id); + + if (sciErr != SC_ERR_NONE) { + pr_info("Cannot open MU channel to SCU\n"); + return -EPROBE_DEFER; + } + + return 0; +} + +bool imx8_clk_is_resource_owned(sc_rsrc_t rsrc) +{ + /* + * A-core resources are special. SCFW reports they are not "owned" by + * current partition but linux can still adjust them for cpufreq. + * + * So force this to return false when running as a VM guest and always + * true otherwise. + */ + if (rsrc == SC_R_A53 || rsrc == SC_R_A72 || rsrc == SC_R_A35) { + if (xen_domain() && !xen_initial_domain()) + return false; + return true; + } + + if (!ccm_ipc_handle) { + pr_warn("%s: no ipc handle!\n", __func__); + /* should have handled -EPROBE_DEFER from clk_mu_init earlier. */ + return false; + } + + return sc_rm_is_resource_owned(ccm_ipc_handle, rsrc); +} diff --git a/drivers/clk/imx/clk-imx8.h b/drivers/clk/imx/clk-imx8.h new file mode 100644 index 0000000000000000000000000000000000000000..05552b44b507f8d1f64c893fbd53857891708ddc --- /dev/null +++ b/drivers/clk/imx/clk-imx8.h @@ -0,0 +1,130 @@ +#ifndef __IMX8_CLK_H +#define __IMX8_CLK_H + +#include <linux/spinlock.h> +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <soc/imx8/sc/sci.h> + +extern spinlock_t imx_ccm_lock; +extern sc_ipc_t ccm_ipc_handle; + +int imx8_clk_mu_init(void); +bool imx8_clk_is_resource_owned(sc_rsrc_t rsrc); + +struct clk *imx_clk_divider_scu(const char *name, + sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type); + +struct clk *imx_clk_divider2_scu(const char *name, const char *parent_name, + sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type); + +struct clk *imx_clk_divider3_scu(const char *name, const char *parent_name, + sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id); + +struct clk *clk_register_gate_scu(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + u8 clk_gate_scu_flags, spinlock_t *lock, + sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type, + void __iomem *reg, u8 bit_idx, bool hw_gate); + +struct clk *clk_register_gate2_scu(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u8 bit_idx, + u8 clk_gate_flags, spinlock_t *lock, const char *pd_name); + +struct clk *clk_register_mux_scu(struct device *dev, const char *name, + const char **parent_names, u8 num_parents, unsigned long flags, + void __iomem *reg, u8 shift, u8 width, + u8 clk_mux_flags, spinlock_t *lock, + const char *pd_name); + +struct clk *clk_register_gate3_scu(struct device *dev, const char *name, + const char *parent_name, spinlock_t *lock, + sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id, bool invert_flag); + +struct clk *clk_register_mux_gpr_scu(struct device *dev, const char *name, + const char **parents, int num_parents, spinlock_t *lock, + sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id); + +struct clk *clk_register_mux2_scu(struct device *dev, const char *name, + const char **parents, int num_parents, unsigned long flags, + sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type); + +static inline struct clk *imx_clk_fixed(const char *name, int rate) +{ + return clk_register_fixed_rate(NULL, name, NULL, 0, rate); +} + +static inline struct clk *imx_clk_gate_scu(const char *name, const char *parent, + sc_rsrc_t rsrc_id, sc_pm_clk_t clk_type, + void __iomem *reg, u8 bit_idx, bool hw_gate) +{ + return clk_register_gate_scu(NULL, name, parent, + CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE, 0, + &imx_ccm_lock, rsrc_id, clk_type, reg, + bit_idx, hw_gate); +} + +static inline struct clk *imx_clk_gate2_scu(const char *name, const char *parent, + void __iomem *reg, u8 bit_idx, const char *pd_name) +{ + return clk_register_gate2_scu(NULL, name, parent, 0, reg, + bit_idx, 0, &imx_ccm_lock, pd_name); +} + +static inline struct clk *imx_clk_gate3_scu(const char *name, const char *parent, + sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id, bool invert_flag) +{ + return clk_register_gate3_scu(NULL, name, parent, + &imx_ccm_lock, rsrc_id, gpr_id, invert_flag); +} + +static inline struct clk *imx_clk_mux_gpr_scu(const char *name, const char **parents, + int num_parents, sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id) +{ + return clk_register_mux_gpr_scu(NULL, name, parents, num_parents, + &imx_ccm_lock, rsrc_id, gpr_id); +} + +static inline struct clk *imx_clk_mux2_scu(const char *name, + const char **parents, int num_parents, sc_rsrc_t rsrc_id, + sc_pm_clk_t clk_type) +{ + return clk_register_mux2_scu(NULL, name, parents, num_parents, + CLK_SET_RATE_NO_REPARENT, rsrc_id, + clk_type); +} + +static inline void imx_clk_set_rate(struct clk *clk, unsigned long rate) +{ + int ret = clk_set_rate(clk, rate); + + if (ret) + pr_err("failed to set rate of clk %s to %ld: %d\n", + __clk_get_name(clk), rate, ret); +} + +static inline struct clk *imx_clk_gate(const char *name, const char *parent, + void __iomem *reg, u8 shift) +{ + return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg, + shift, 0, &imx_ccm_lock); +} + +static inline struct clk *imx_clk_fixed_factor(const char *name, + const char *parent, unsigned int mult, unsigned int div) +{ + return clk_register_fixed_factor(NULL, name, parent, + CLK_SET_RATE_PARENT, mult, div); +} + +static inline struct clk *imx_clk_mux_scu(const char *name, void __iomem *reg, + u8 shift, u8 width, const char **parents, int num_parents, const char *pd_name) +{ + return clk_register_mux_scu(NULL, name, parents, num_parents, + CLK_SET_RATE_NO_REPARENT, reg, shift, + width, 0, &imx_ccm_lock, pd_name); +} + + +#endif diff --git a/drivers/clk/imx/clk-imx8qxp.c b/drivers/clk/imx/clk-imx8qxp.c new file mode 100644 index 0000000000000000000000000000000000000000..4c109eb277dbfb7ff050f984945c5007bd900811 --- /dev/null +++ b/drivers/clk/imx/clk-imx8qxp.c @@ -0,0 +1,736 @@ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <dt-bindings/clock/imx8qxp-clock.h> +#include <dt-bindings/soc/imx8_pd.h> +#include <linux/clk.h> +#include <linux/clkdev.h> +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_irq.h> +#include <linux/types.h> +#include <linux/platform_device.h> +#include <linux/pm_domain.h> + +#include <soc/imx8/imx8qxp/lpcg.h> +#include <soc/imx8/sc/sci.h> +#include "clk-imx8.h" + +#define STR_VALUE(arg) #arg +#define FUNCTION_NAME(name) STR_VALUE(name) + +static const char *aud_clk_sels[] = { + "aud_acm_aud_rec_clk0_clk", + "aud_acm_aud_rec_clk1_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_acm_aud_rec_clk0_clk", + "aud_acm_aud_rec_clk1_clk", + "dummy", + "dummy", + "spdif0_rx", + "dummy", + "dummy", + "sai4_rx_bclk", +}; + +static const char *sai_mclk_sels[] = { + "aud_acm_aud_pll_clk0_clk", + "aud_acm_aud_pll_clk1_clk", + "acm_aud_clk0_clk", + "acm_aud_clk1_clk", +}; + +static const char *esai_mclk_sels[] = { + "aud_acm_aud_pll_clk0_clk", + "aud_acm_aud_pll_clk1_clk", + "acm_aud_clk0_clk", + "acm_aud_clk1_clk", +}; + +static const char *spdif_mclk_sels[] = { + "aud_acm_aud_pll_clk0_clk", + "aud_acm_aud_pll_clk1_clk", + "acm_aud_clk0_clk", + "acm_aud_clk1_clk", +}; + +static const char *mqs_mclk_sels[] = { + "aud_acm_aud_pll_clk0_clk", + "aud_acm_aud_pll_clk1_clk", + "acm_aud_clk0_clk", + "acm_aud_clk1_clk", +}; + +static const char *mipi0_sels[] = { + "dummy", + "mipi0_pll_clk", + "mipi0_pll_div2_clk", + "dummy", + "mipi0_lvds_bypass_clk", +}; + +static const char *mipi1_sels[] = { + "dummy", + "mipi1_pll_clk", + "mipi1_pll_div2_clk", + "dummy", + "mipi1_lvds_bypass_clk", +}; + +static const char *sdhc0_sels[] = { + "dummy", + "conn_pll0_clk", + "conn_pll1_clk", + "dummy", + "dummy", +}; + +static const char *sdhc1_sels[] = { + "dummy", + "conn_pll0_clk", + "conn_pll1_clk", + "dummy", + "dummy", +}; + +static const char *sdhc2_sels[] = { + "dummy", + "conn_pll0_clk", + "conn_pll1_clk", + "dummy", + "dummy", +}; + +static const char *pll0_sels[] = { + "dummy", + "parallel_pll_clk", + "dummy", + "dummy", + "dummy", +}; + +static const char *lcd_pxl_sels[] = { + "dummy", + "dummy", + "dummy", + "dummy", + "lcd_pxl_bypass_div", +}; + +static const char *lcd_sels[] = { + "dummy", + "dummy", + "dummy", + "dummy", + "elcdif_pll", +}; + +static struct clk *clks[IMX8QXP_CLK_END]; +static struct clk_onecell_data clk_data; + +static const char *enet_sels[] = { "enet_25MHz", "enet_125MHz", }; +static const char *enet0_rmii_tx_sels[] = { "enet0_ref_div", "dummy", }; +static const char *enet1_rmii_tx_sels[] = { "enet1_ref_div", "dummy", }; + +static int imx8qxp_clk_probe(struct platform_device *pdev) +{ + struct device_node *ccm_node = pdev->dev.of_node; + struct device_node *np_acm; + void __iomem *base_acm; + int i, ret; + + ret = imx8_clk_mu_init(); + if (ret) + return ret; + + pr_info("***** imx8qxp_clocks_init *****\n"); + + /* Fixed clocks */ + clks[IMX8QXP_CLK_DUMMY] = imx_clk_fixed("dummy", 0); + clks[IMX8QXP_24MHZ] = imx_clk_fixed("xtal_24MHz", SC_24MHZ); + clks[IMX8QXP_GPT_3M] = imx_clk_fixed("gpt_3m", 3000000); + clks[IMX8QXP_32KHZ] = imx_clk_fixed("xtal_32KHz", SC_32KHZ); + + /* ARM core */ + clks[IMX8QXP_A35_DIV] = imx_clk_divider_scu("a35_div", SC_R_A35, SC_PM_CLK_CPU); + + /* User Defined PLLs dividers */ + clks[IMX8QXP_AUD_PLL0_DIV] = imx_clk_divider_scu("audio_pll0_div", SC_R_AUDIO_PLL_0, SC_PM_CLK_PLL); + clks[IMX8QXP_AUD_PLL1_DIV] = imx_clk_divider_scu("audio_pll1_div", SC_R_AUDIO_PLL_1, SC_PM_CLK_PLL); + clks[IMX8QXP_ELCDIF_PLL_DIV] = imx_clk_divider_scu("elcdif_pll_div", SC_R_ELCDIF_PLL, SC_PM_CLK_PLL); + + /* User Defined PLLs clocks */ + clks[IMX8QXP_AUD_PLL0] = imx_clk_gate_scu("audio_pll0_clk", "audio_pll0_div", SC_R_AUDIO_PLL_0, SC_PM_CLK_PLL, NULL, 0, 0); + clks[IMX8QXP_AUD_PLL1] = imx_clk_gate_scu("audio_pll1_clk", "audio_pll1_div", SC_R_AUDIO_PLL_1, SC_PM_CLK_PLL, NULL, 0, 0); + clks[IMX8QXP_ELCDIF_PLL] = imx_clk_gate_scu("elcdif_pll", "elcdif_pll_div", SC_R_ELCDIF_PLL, SC_PM_CLK_PLL, NULL, 0, 0); + + clks[IMX8QXP_IPG_DMA_CLK_ROOT] = imx_clk_fixed("ipg_dma_clk_root", SC_120MHZ); + clks[IMX8QXP_IPG_AUD_CLK_ROOT] = imx_clk_fixed("ipg_aud_clk_root", SC_150MHZ); + clks[IMX8QXP_AXI_CONN_CLK_ROOT] = imx_clk_fixed("axi_conn_clk_root", SC_333MHZ); + clks[IMX8QXP_AHB_CONN_CLK_ROOT] = imx_clk_fixed("ahb_conn_clk_root", SC_166MHZ); + clks[IMX8QXP_IPG_CONN_CLK_ROOT] = imx_clk_fixed("ipg_conn_clk_root", SC_83MHZ); + clks[IMX8QXP_DC_AXI_EXT_CLK] = imx_clk_fixed("axi_ext_dc_clk_root", SC_800MHZ); + clks[IMX8QXP_DC_AXI_INT_CLK] = imx_clk_fixed("axi_int_dc_clk_root", SC_400MHZ); + clks[IMX8QXP_DC_CFG_CLK] = imx_clk_fixed("cfg_dc_clk_root", SC_100MHZ); + clks[IMX8QXP_MIPI_IPG_CLK] = imx_clk_fixed("ipg_mipi_clk_root", SC_120MHZ); + clks[IMX8QXP_IMG_AXI_CLK] = imx_clk_fixed("axi_img_clk_root", SC_400MHZ); + clks[IMX8QXP_IMG_IPG_CLK] = imx_clk_fixed("ipg_img_clk_root", SC_200MHZ); + clks[IMX8QXP_IMG_PXL_CLK] = imx_clk_fixed("pxl_img_clk_root", SC_600MHZ); + clks[IMX8QXP_HSIO_AXI_CLK] = imx_clk_fixed("axi_hsio_clk_root", SC_400MHZ); + clks[IMX8QXP_HSIO_PER_CLK] = imx_clk_fixed("per_hsio_clk_root", SC_133MHZ); + clks[IMX8QXP_CM40_IPG_CLK] = imx_clk_fixed("ipg_cm40_clk_root", SC_132MHZ); + clks[IMX8QXP_MIPI0_DSI_PLL_CLK] = imx_clk_fixed("mipi0_pll_clk", SC_864MHZ); + clks[IMX8QXP_MIPI0_DSI_PLL_DIV2_CLK] = imx_clk_fixed("mipi0_pll_div2_clk", SC_432MHZ); + clks[IMX8QXP_MIPI1_DSI_PLL_CLK] = imx_clk_fixed("mipi1_pll_clk", SC_864MHZ); + clks[IMX8QXP_MIPI1_DSI_PLL_DIV2_CLK] = imx_clk_fixed("mipi1_pll_div2_clk", SC_432MHZ); + clks[IMX8QXP_CONN_PLL0_CLK] = imx_clk_fixed("conn_pll0_clk", SC_792MHZ); + clks[IMX8QXP_CONN_PLL1_CLK] = imx_clk_fixed("conn_pll1_clk", SC_1000MHZ); + + clks[IMX8QXP_UART0_DIV] = imx_clk_divider_scu("uart0_div", SC_R_UART_0, SC_PM_CLK_PER); + clks[IMX8QXP_UART0_IPG_CLK] = imx_clk_gate2_scu("uart0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPUART_0_LPCG), 16, FUNCTION_NAME(PD_DMA_UART0)); + clks[IMX8QXP_UART0_CLK] = imx_clk_gate_scu("uart0_clk", "uart0_div", SC_R_UART_0, SC_PM_CLK_PER, (void __iomem *)(LPUART_0_LPCG), 0, 0); + + clks[IMX8QXP_GPU0_CORE_DIV] = imx_clk_divider_scu("gpu_core0_div", SC_R_GPU_0_PID0, SC_PM_CLK_PER); + clks[IMX8QXP_GPU0_SHADER_DIV] = imx_clk_divider_scu("gpu_shader0_div", SC_R_GPU_0_PID0, SC_PM_CLK_MISC); + clks[IMX8QXP_GPU0_CORE_CLK] = imx_clk_gate_scu("gpu_core0_clk", "gpu_core0_div", SC_R_GPU_0_PID0, SC_PM_CLK_PER, NULL, 0, 0); + clks[IMX8QXP_GPU0_SHADER_CLK] = imx_clk_gate_scu("gpu_shader0_clk", "gpu_shader0_div", SC_R_GPU_0_PID0, SC_PM_CLK_MISC, NULL, 0, 0); + + /* LSIO SS */ + clks[IMX8QXP_LSIO_MEM_CLK] = imx_clk_fixed("lsio_mem_clk_root", SC_100MHZ); + clks[IMX8QXP_LSIO_BUS_CLK] = imx_clk_fixed("lsio_bus_clk_root", SC_200MHZ); + + clks[IMX8QXP_LSIO_PWM0_DIV] = imx_clk_divider_scu("pwm_0_div", SC_R_PWM_0, SC_PM_CLK_PER); + clks[IMX8QXP_LSIO_PWM0_IPG_S_CLK] = imx_clk_gate_scu("pwm_0_ipg_s_clk", "pwm_0_div", SC_R_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 0x10, 0); + clks[IMX8QXP_LSIO_PWM0_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_0_ipg_slv_clk", "pwm_0_ipg_s_clk", SC_R_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 0x14, 0); + clks[IMX8QXP_LSIO_PWM0_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_0_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_0_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_0)); + clks[IMX8QXP_LSIO_PWM0_HF_CLK] = imx_clk_gate_scu("pwm_0_hf_clk", "pwm_0_ipg_slv_clk", SC_R_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 4, 0); + clks[IMX8QXP_LSIO_PWM0_CLK] = imx_clk_gate_scu("pwm_0_clk", "pwm_0_ipg_slv_clk", SC_R_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_0_LPCG), 0, 0); + clks[IMX8QXP_LSIO_PWM1_DIV] = imx_clk_divider_scu("pwm_1_div", SC_R_PWM_1, SC_PM_CLK_PER); + clks[IMX8QXP_LSIO_PWM1_IPG_S_CLK] = imx_clk_gate_scu("pwm_1_ipg_s_clk", "pwm_1_div", SC_R_PWM_1, SC_PM_CLK_PER, (void __iomem *)(PWM_1_LPCG), 0x10, 0); + clks[IMX8QXP_LSIO_PWM1_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_1_ipg_slv_clk", "pwm_1_ipg_s_clk", SC_R_PWM_1, SC_PM_CLK_PER, (void __iomem *)(PWM_1_LPCG), 0x14, 0); + clks[IMX8QXP_LSIO_PWM1_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_1_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_1_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_1)); + clks[IMX8QXP_LSIO_PWM1_HF_CLK] = imx_clk_gate_scu("pwm_1_hf_clk", "pwm_1_ipg_slv_clk", SC_R_PWM_1, SC_PM_CLK_PER, (void __iomem *)(PWM_1_LPCG), 4, 0); + clks[IMX8QXP_LSIO_PWM1_CLK] = imx_clk_gate_scu("pwm_1_clk", "pwm_1_ipg_slv_clk", SC_R_PWM_1, SC_PM_CLK_PER, (void __iomem *)(PWM_1_LPCG), 0, 0); + clks[IMX8QXP_LSIO_PWM2_DIV] = imx_clk_divider_scu("pwm_2_div", SC_R_PWM_2, SC_PM_CLK_PER); + clks[IMX8QXP_LSIO_PWM2_IPG_S_CLK] = imx_clk_gate_scu("pwm_2_ipg_s_clk", "pwm_2_div", SC_R_PWM_2, SC_PM_CLK_PER, (void __iomem *)(PWM_2_LPCG), 0x10, 0); + clks[IMX8QXP_LSIO_PWM2_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_2_ipg_slv_clk", "pwm_2_ipg_s_clk", SC_R_PWM_2, SC_PM_CLK_PER, (void __iomem *)(PWM_2_LPCG), 0x14, 0); + clks[IMX8QXP_LSIO_PWM2_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_2_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_2_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_2)); + clks[IMX8QXP_LSIO_PWM2_HF_CLK] = imx_clk_gate_scu("pwm_2_hf_clk", "pwm_2_ipg_slv_clk", SC_R_PWM_2, SC_PM_CLK_PER, (void __iomem *)(PWM_2_LPCG), 4, 0); + clks[IMX8QXP_LSIO_PWM2_CLK] = imx_clk_gate_scu("pwm_2_clk", "pwm_2_ipg_slv_clk", SC_R_PWM_2, SC_PM_CLK_PER, (void __iomem *)(PWM_2_LPCG), 0, 0); + clks[IMX8QXP_LSIO_PWM3_DIV] = imx_clk_divider_scu("pwm_3_div", SC_R_PWM_3, SC_PM_CLK_PER); + clks[IMX8QXP_LSIO_PWM3_IPG_S_CLK] = imx_clk_gate_scu("pwm_3_ipg_s_clk", "pwm_3_div", SC_R_PWM_3, SC_PM_CLK_PER, (void __iomem *)(PWM_3_LPCG), 0x10, 0); + clks[IMX8QXP_LSIO_PWM3_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_3_ipg_slv_clk", "pwm_3_ipg_s_clk", SC_R_PWM_3, SC_PM_CLK_PER, (void __iomem *)(PWM_3_LPCG), 0x14, 0); + clks[IMX8QXP_LSIO_PWM3_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_3_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_3_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_3)); + clks[IMX8QXP_LSIO_PWM3_HF_CLK] = imx_clk_gate_scu("pwm_3_hf_clk", "pwm_3_ipg_slv_clk", SC_R_PWM_3, SC_PM_CLK_PER, (void __iomem *)(PWM_3_LPCG), 4, 0); + clks[IMX8QXP_LSIO_PWM3_CLK] = imx_clk_gate_scu("pwm_3_clk", "pwm_3_ipg_slv_clk", SC_R_PWM_3, SC_PM_CLK_PER, (void __iomem *)(PWM_3_LPCG), 0, 0); + clks[IMX8QXP_LSIO_PWM4_DIV] = imx_clk_divider_scu("pwm_4_div", SC_R_PWM_4, SC_PM_CLK_PER); + clks[IMX8QXP_LSIO_PWM4_IPG_S_CLK] = imx_clk_gate_scu("pwm_4_ipg_s_clk", "pwm_4_div", SC_R_PWM_4, SC_PM_CLK_PER, (void __iomem *)(PWM_4_LPCG), 0x10, 0); + clks[IMX8QXP_LSIO_PWM4_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_4_ipg_slv_clk", "pwm_4_ipg_s_clk", SC_R_PWM_4, SC_PM_CLK_PER, (void __iomem *)(PWM_4_LPCG), 0x14, 0); + clks[IMX8QXP_LSIO_PWM4_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_4_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_4_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_4)); + clks[IMX8QXP_LSIO_PWM4_HF_CLK] = imx_clk_gate_scu("pwm_4_hf_clk", "pwm_4_ipg_slv_clk", SC_R_PWM_4, SC_PM_CLK_PER, (void __iomem *)(PWM_4_LPCG), 4, 0); + clks[IMX8QXP_LSIO_PWM4_CLK] = imx_clk_gate_scu("pwm_4_clk", "pwm_4_ipg_slv_clk", SC_R_PWM_4, SC_PM_CLK_PER, (void __iomem *)(PWM_4_LPCG), 0, 0); + clks[IMX8QXP_LSIO_PWM5_DIV] = imx_clk_divider_scu("pwm_5_div", SC_R_PWM_5, SC_PM_CLK_PER); + clks[IMX8QXP_LSIO_PWM5_IPG_S_CLK] = imx_clk_gate_scu("pwm_5_ipg_s_clk", "pwm_5_div", SC_R_PWM_5, SC_PM_CLK_PER, (void __iomem *)(PWM_5_LPCG), 0x10, 0); + clks[IMX8QXP_LSIO_PWM5_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_5_ipg_slv_clk", "pwm_5_ipg_s_clk", SC_R_PWM_5, SC_PM_CLK_PER, (void __iomem *)(PWM_5_LPCG), 0x14, 0); + clks[IMX8QXP_LSIO_PWM5_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_5_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_5_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_5)); + clks[IMX8QXP_LSIO_PWM5_HF_CLK] = imx_clk_gate_scu("pwm_5_hf_clk", "pwm_5_ipg_slv_clk", SC_R_PWM_5, SC_PM_CLK_PER, (void __iomem *)(PWM_5_LPCG), 4, 0); + clks[IMX8QXP_LSIO_PWM5_CLK] = imx_clk_gate_scu("pwm_5_clk", "pwm_5_ipg_slv_clk", SC_R_PWM_5, SC_PM_CLK_PER, (void __iomem *)(PWM_5_LPCG), 0, 0); + clks[IMX8QXP_LSIO_PWM6_DIV] = imx_clk_divider_scu("pwm_6_div", SC_R_PWM_6, SC_PM_CLK_PER); + clks[IMX8QXP_LSIO_PWM6_IPG_S_CLK] = imx_clk_gate_scu("pwm_6_ipg_s_clk", "pwm_6_div", SC_R_PWM_6, SC_PM_CLK_PER, (void __iomem *)(PWM_6_LPCG), 0x10, 0); + clks[IMX8QXP_LSIO_PWM6_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_6_ipg_slv_clk", "pwm_6_ipg_s_clk", SC_R_PWM_6, SC_PM_CLK_PER, (void __iomem *)(PWM_6_LPCG), 0x14, 0); + clks[IMX8QXP_LSIO_PWM6_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_6_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_6_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_6)); + clks[IMX8QXP_LSIO_PWM6_HF_CLK] = imx_clk_gate_scu("pwm_6_hf_clk", "pwm_6_ipg_slv_clk", SC_R_PWM_6, SC_PM_CLK_PER, (void __iomem *)(PWM_6_LPCG), 4, 0); + clks[IMX8QXP_LSIO_PWM6_CLK] = imx_clk_gate_scu("pwm_6_clk", "pwm_6_ipg_slv_clk", SC_R_PWM_6, SC_PM_CLK_PER, (void __iomem *)(PWM_6_LPCG), 0, 0); + clks[IMX8QXP_LSIO_PWM7_DIV] = imx_clk_divider_scu("pwm_7_div", SC_R_PWM_7, SC_PM_CLK_PER); + clks[IMX8QXP_LSIO_PWM7_IPG_S_CLK] = imx_clk_gate_scu("pwm_7_ipg_s_clk", "pwm_7_div", SC_R_PWM_7, SC_PM_CLK_PER, (void __iomem *)(PWM_7_LPCG), 0x10, 0); + clks[IMX8QXP_LSIO_PWM7_IPG_SLV_CLK] = imx_clk_gate_scu("pwm_7_ipg_slv_clk", "pwm_7_ipg_s_clk", SC_R_PWM_7, SC_PM_CLK_PER, (void __iomem *)(PWM_7_LPCG), 0x14, 0); + clks[IMX8QXP_LSIO_PWM7_IPG_MSTR_CLK] = imx_clk_gate2_scu("pwm_7_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(PWM_7_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_PWM_7)); + clks[IMX8QXP_LSIO_PWM7_HF_CLK] = imx_clk_gate_scu("pwm_7_hf_clk", "pwm_7_ipg_slv_clk", SC_R_PWM_7, SC_PM_CLK_PER, (void __iomem *)(PWM_7_LPCG), 4, 0); + clks[IMX8QXP_LSIO_PWM7_CLK] = imx_clk_gate_scu("pwm_7_clk", "pwm_7_ipg_slv_clk", SC_R_PWM_7, SC_PM_CLK_PER, (void __iomem *)(PWM_7_LPCG), 0, 0); + clks[IMX8QXP_LSIO_GPT0_DIV] = imx_clk_divider_scu("gpt_0_div", SC_R_GPT_4, SC_PM_CLK_PER); + clks[IMX8QXP_LSIO_GPT0_IPG_S_CLK] = imx_clk_gate_scu("gpt_0_ipg_s_clk", "gpt_0_div", SC_R_GPT_0, SC_PM_CLK_PER, (void __iomem *)(GPT_0_LPCG), 0x10, 0); + clks[IMX8QXP_LSIO_GPT0_IPG_SLV_CLK] = imx_clk_gate_scu("gpt_0_ipg_slv_clk", "gpt_0_ipg_s_clk", SC_R_GPT_0, SC_PM_CLK_PER, (void __iomem *)(GPT_0_LPCG), 0x14, 0); + clks[IMX8QXP_LSIO_GPT0_CLK] = imx_clk_gate_scu("gpt_0_clk", "gpt_0_ipg_slv_clk", SC_R_GPT_0, SC_PM_CLK_PER, (void __iomem *)(GPT_0_LPCG), 0, 0); + clks[IMX8QXP_LSIO_GPT0_IPG_MSTR_CLK] = imx_clk_gate2_scu("gpt_0_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_0_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_GPT_0)); + clks[IMX8QXP_LSIO_GPT0_HF_CLK] = imx_clk_gate_scu("gpt_0_hf_clk", "gpt_0_ipg_slv_clk", SC_R_GPT_0, SC_PM_CLK_PER, (void __iomem *)(GPT_0_LPCG), 4, 0); + clks[IMX8QXP_LSIO_GPT1_DIV] = imx_clk_divider_scu("gpt_1_div", SC_R_GPT_4, SC_PM_CLK_PER); + clks[IMX8QXP_LSIO_GPT1_IPG_S_CLK] = imx_clk_gate_scu("gpt_1_ipg_s_clk", "gpt_1_div", SC_R_GPT_1, SC_PM_CLK_PER, (void __iomem *)(GPT_1_LPCG), 0x10, 0); + clks[IMX8QXP_LSIO_GPT1_IPG_SLV_CLK] = imx_clk_gate_scu("gpt_1_ipg_slv_clk", "gpt_1_ipg_s_clk", SC_R_GPT_1, SC_PM_CLK_PER, (void __iomem *)(GPT_1_LPCG), 0x14, 0); + clks[IMX8QXP_LSIO_GPT1_CLK] = imx_clk_gate_scu("gpt_1_clk", "gpt_1_ipg_slv_clk", SC_R_GPT_1, SC_PM_CLK_PER, (void __iomem *)(GPT_1_LPCG), 0, 0); + clks[IMX8QXP_LSIO_GPT1_HF_CLK] = imx_clk_gate_scu("gpt_1_hf_clk", "gpt_1_ipg_slv_clk", SC_R_GPT_1, SC_PM_CLK_PER, (void __iomem *)(GPT_1_LPCG), 4, 0); + clks[IMX8QXP_LSIO_GPT1_IPG_MSTR_CLK] = imx_clk_gate2_scu("gpt_1_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_1_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_GPT_1)); + clks[IMX8QXP_LSIO_GPT2_DIV] = imx_clk_divider_scu("gpt_2_div", SC_R_GPT_4, SC_PM_CLK_PER); + clks[IMX8QXP_LSIO_GPT2_IPG_S_CLK] = imx_clk_gate_scu("gpt_2_ipg_s_clk", "gpt_2_div", SC_R_GPT_2, SC_PM_CLK_PER, (void __iomem *)(GPT_2_LPCG), 0x10, 0); + clks[IMX8QXP_LSIO_GPT2_IPG_SLV_CLK] = imx_clk_gate_scu("gpt_2_ipg_slv_clk", "gpt_2_ipg_s_clk", SC_R_GPT_2, SC_PM_CLK_PER, (void __iomem *)(GPT_2_LPCG), 0x14, 0); + clks[IMX8QXP_LSIO_GPT2_CLK] = imx_clk_gate_scu("gpt_2_clk", "gpt_2_ipg_slv_clk", SC_R_GPT_2, SC_PM_CLK_PER, (void __iomem *)(GPT_2_LPCG), 0, 0); + clks[IMX8QXP_LSIO_GPT2_HF_CLK] = imx_clk_gate_scu("gpt_2_hf_clk", "gpt_2_ipg_slv_clk", SC_R_GPT_2, SC_PM_CLK_PER, (void __iomem *)(GPT_2_LPCG), 4, 0); + clks[IMX8QXP_LSIO_GPT2_IPG_MSTR_CLK] = imx_clk_gate2_scu("gpt_2_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_2_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_GPT_2)); + clks[IMX8QXP_LSIO_GPT3_DIV] = imx_clk_divider_scu("gpt_3_div", SC_R_GPT_4, SC_PM_CLK_PER); + clks[IMX8QXP_LSIO_GPT3_IPG_S_CLK] = imx_clk_gate_scu("gpt_3_ipg_s_clk", "gpt_3_div", SC_R_GPT_3, SC_PM_CLK_PER, (void __iomem *)(GPT_3_LPCG), 0x10, 0); + clks[IMX8QXP_LSIO_GPT3_IPG_SLV_CLK] = imx_clk_gate_scu("gpt_3_ipg_slv_clk", "gpt_3_ipg_s_clk", SC_R_GPT_3, SC_PM_CLK_PER, (void __iomem *)(GPT_3_LPCG), 0x14, 0); + clks[IMX8QXP_LSIO_GPT3_CLK] = imx_clk_gate_scu("gpt_3_clk", "gpt_3_ipg_slv_clk", SC_R_GPT_3, SC_PM_CLK_PER, (void __iomem *)(GPT_3_LPCG), 0, 0); + clks[IMX8QXP_LSIO_GPT3_HF_CLK] = imx_clk_gate_scu("gpt_3_hf_clk", "gpt_3_ipg_slv_clk", SC_R_GPT_3, SC_PM_CLK_PER, (void __iomem *)(GPT_3_LPCG), 4, 0); + clks[IMX8QXP_LSIO_GPT3_IPG_MSTR_CLK] = imx_clk_gate2_scu("gpt_3_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_3_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_GPT_3)); + clks[IMX8QXP_LSIO_GPT4_DIV] = imx_clk_divider_scu("gpt_4_div", SC_R_GPT_4, SC_PM_CLK_PER); + clks[IMX8QXP_LSIO_GPT4_IPG_S_CLK] = imx_clk_gate_scu("gpt_4_ipg_s_clk", "gpt_4_div", SC_R_GPT_4, SC_PM_CLK_PER, (void __iomem *)(GPT_4_LPCG), 0x10, 0); + clks[IMX8QXP_LSIO_GPT4_IPG_SLV_CLK] = imx_clk_gate_scu("gpt_4_ipg_slv_clk", "gpt_4_ipg_s_clk", SC_R_GPT_4, SC_PM_CLK_PER, (void __iomem *)(GPT_4_LPCG), 0x14, 0); + clks[IMX8QXP_LSIO_GPT4_CLK] = imx_clk_gate_scu("gpt_4_clk", "gpt_4_ipg_slv_clk", SC_R_GPT_4, SC_PM_CLK_PER, (void __iomem *)(GPT_4_LPCG), 0, 0); + clks[IMX8QXP_LSIO_GPT4_HF_CLK] = imx_clk_gate_scu("gpt_4_hf_clk", "gpt_4_ipg_slv_clk", SC_R_GPT_4, SC_PM_CLK_PER, (void __iomem *)(GPT_4_LPCG), 4, 0); + clks[IMX8QXP_LSIO_GPT4_IPG_MSTR_CLK] = imx_clk_gate2_scu("gpt_4_ipg_mstr_clk", "lsio_bus_clk_root", (void __iomem *)(GPT_4_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_GPT_4)); + clks[IMX8QXP_LSIO_FSPI0_DIV] = imx_clk_divider_scu("fspi_0_div", SC_R_FSPI_0, SC_PM_CLK_PER); + clks[IMX8QXP_LSIO_FSPI0_HCLK] = imx_clk_gate2_scu("fspi0_hclk_clk", "lsio_mem_clk_root", (void __iomem *)(FSPI_0_LPCG), 0x10, FUNCTION_NAME(PD_LSIO_FSPI_0)); + clks[IMX8QXP_LSIO_FSPI0_IPG_S_CLK] = imx_clk_gate2_scu("fspi0_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(FSPI_0_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_FSPI_0)); + clks[IMX8QXP_LSIO_FSPI0_IPG_CLK] = imx_clk_gate2_scu("fspi0_ipg_clk", "fspi0_ipg_s_clk", (void __iomem *)(FSPI_0_LPCG), 0x14, FUNCTION_NAME(PD_LSIO_FSPI_0)); + clks[IMX8QXP_LSIO_FSPI0_CLK] = imx_clk_gate_scu("fspi_0_clk", "fspi_0_div", SC_R_FSPI_0, SC_PM_CLK_PER, (void __iomem *)(FSPI_0_LPCG), 0, 0); + clks[IMX8QXP_LSIO_FSPI1_DIV] = imx_clk_divider_scu("fspi_1_div", SC_R_FSPI_1, SC_PM_CLK_PER); + clks[IMX8QXP_LSIO_FSPI1_HCLK] = imx_clk_gate2_scu("fspi1_hclk_clk", "lsio_mem_clk_root", (void __iomem *)(FSPI_1_LPCG), 0x10, FUNCTION_NAME(PD_LSIO_FSPI_1)); + clks[IMX8QXP_LSIO_FSPI1_IPG_S_CLK] = imx_clk_gate2_scu("fspi1_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(FSPI_1_LPCG), 0x18, FUNCTION_NAME(PD_LSIO_FSPI_1)); + clks[IMX8QXP_LSIO_FSPI1_IPG_CLK] = imx_clk_gate2_scu("fspi1_ipg_clk", "fspi1_ipg_s_clk", (void __iomem *)(FSPI_1_LPCG), 0x14, FUNCTION_NAME(PD_LSIO_FSPI_1)); + clks[IMX8QXP_LSIO_FSPI1_CLK] = imx_clk_gate_scu("fspi_1_clk", "fspi_1_div", SC_R_FSPI_1, SC_PM_CLK_PER, (void __iomem *)(FSPI_1_LPCG), 0, 0); + clks[IMX8QXP_LSIO_MU5A_IPG_S_CLK] = imx_clk_gate2_scu("mu5_a_ipg_s_clk", "lsio_bus_clk_root", (void __iomem *)(MU_5A_LPCG), 0x10, FUNCTION_NAME(PD_LSIO_MU5A)); + clks[IMX8QXP_LSIO_MU5A_IPG_CLK] = imx_clk_gate2_scu("mu5_a_ipg_clk", "mu5_a_ipg_s_clk", (void __iomem *)(MU_5A_LPCG), 0x0, FUNCTION_NAME(PD_LSIO_MU5A)); + /* ADMA SS */ + clks[IMX8QXP_UART1_IPG_CLK] = imx_clk_gate2_scu("uart1_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPUART_1_LPCG), 16, FUNCTION_NAME(PD_DMA_UART1)); + clks[IMX8QXP_UART2_IPG_CLK] = imx_clk_gate2_scu("uart2_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPUART_2_LPCG), 16, FUNCTION_NAME(PD_DMA_UART2)); + clks[IMX8QXP_UART3_IPG_CLK] = imx_clk_gate2_scu("uart3_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPUART_3_LPCG), 16, FUNCTION_NAME(PD_DMA_UART3)); + clks[IMX8QXP_UART1_DIV] = imx_clk_divider_scu("uart1_div", SC_R_UART_1, SC_PM_CLK_PER); + clks[IMX8QXP_UART2_DIV] = imx_clk_divider_scu("uart2_div", SC_R_UART_2, SC_PM_CLK_PER); + clks[IMX8QXP_UART3_DIV] = imx_clk_divider_scu("uart3_div", SC_R_UART_3, SC_PM_CLK_PER); + clks[IMX8QXP_UART1_CLK] = imx_clk_gate_scu("uart1_clk", "uart1_div", SC_R_UART_1, SC_PM_CLK_PER, (void __iomem *)(LPUART_1_LPCG), 0, 0); + clks[IMX8QXP_UART2_CLK] = imx_clk_gate_scu("uart2_clk", "uart2_div", SC_R_UART_2, SC_PM_CLK_PER, (void __iomem *)(LPUART_2_LPCG), 0, 0); + clks[IMX8QXP_UART3_CLK] = imx_clk_gate_scu("uart3_clk", "uart3_div", SC_R_UART_3, SC_PM_CLK_PER, (void __iomem *)(LPUART_3_LPCG), 0, 0); + clks[IMX8QXP_SPI0_IPG_CLK] = imx_clk_gate2_scu("spi0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPSPI_0_LPCG), 16, FUNCTION_NAME(PD_DMA_SPI_0)); + clks[IMX8QXP_SPI1_IPG_CLK] = imx_clk_gate2_scu("spi1_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPSPI_1_LPCG), 16, FUNCTION_NAME(PD_DMA_SPI_1)); + clks[IMX8QXP_SPI2_IPG_CLK] = imx_clk_gate2_scu("spi2_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPSPI_2_LPCG), 16, FUNCTION_NAME(PD_DMA_SPI_2)); + clks[IMX8QXP_SPI3_IPG_CLK] = imx_clk_gate2_scu("spi3_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPSPI_3_LPCG), 16, FUNCTION_NAME(PD_DMA_SPI_3)); + clks[IMX8QXP_SPI0_DIV] = imx_clk_divider_scu("spi0_div", SC_R_SPI_0, SC_PM_CLK_PER); + clks[IMX8QXP_SPI1_DIV] = imx_clk_divider_scu("spi1_div", SC_R_SPI_1, SC_PM_CLK_PER); + clks[IMX8QXP_SPI2_DIV] = imx_clk_divider_scu("spi2_div", SC_R_SPI_2, SC_PM_CLK_PER); + clks[IMX8QXP_SPI3_DIV] = imx_clk_divider_scu("spi3_div", SC_R_SPI_3, SC_PM_CLK_PER); + clks[IMX8QXP_SPI0_CLK] = imx_clk_gate_scu("spi0_clk", "spi0_div", SC_R_SPI_0, SC_PM_CLK_PER, (void __iomem *)(LPSPI_0_LPCG), 0, 0); + clks[IMX8QXP_SPI1_CLK] = imx_clk_gate_scu("spi1_clk", "spi1_div", SC_R_SPI_1, SC_PM_CLK_PER, (void __iomem *)(LPSPI_1_LPCG), 0, 0); + clks[IMX8QXP_SPI2_CLK] = imx_clk_gate_scu("spi2_clk", "spi2_div", SC_R_SPI_2, SC_PM_CLK_PER, (void __iomem *)(LPSPI_2_LPCG), 0, 0); + clks[IMX8QXP_SPI3_CLK] = imx_clk_gate_scu("spi3_clk", "spi3_div", SC_R_SPI_3, SC_PM_CLK_PER, (void __iomem *)(LPSPI_3_LPCG), 0, 0); + clks[IMX8QXP_CAN0_IPG_CHI_CLK] = imx_clk_gate2_scu("can0_ipg_chi_clk", "ipg_dma_clk_root", (void __iomem *)(FLEX_CAN_0_LPCG), 20, FUNCTION_NAME(PD_DMA_CAN_0)); + clks[IMX8QXP_CAN0_IPG_CLK] = imx_clk_gate2_scu("can0_ipg_clk", "can0_ipg_chi_clk", (void __iomem *)(FLEX_CAN_0_LPCG), 16, FUNCTION_NAME(PD_DMA_CAN_0)); + clks[IMX8QXP_CAN1_IPG_CHI_CLK] = imx_clk_gate2_scu("can1_ipg_chi_clk", "ipg_dma_clk_root", (void __iomem *)(FLEX_CAN_1_LPCG), 20, FUNCTION_NAME(PD_DMA_CAN_1)); + clks[IMX8QXP_CAN1_IPG_CLK] = imx_clk_gate2_scu("can1_ipg_clk", "can1_ipg_chi_clk", (void __iomem *)(FLEX_CAN_1_LPCG), 16, FUNCTION_NAME(PD_DMA_CAN_1)); + clks[IMX8QXP_CAN2_IPG_CHI_CLK] = imx_clk_gate2_scu("can2_ipg_chi_clk", "ipg_dma_clk_root", (void __iomem *)(FLEX_CAN_2_LPCG), 20, FUNCTION_NAME(PD_DMA_CAN_2)); + clks[IMX8QXP_CAN2_IPG_CLK] = imx_clk_gate2_scu("can2_ipg_clk", "can2_ipg_chi_clk", (void __iomem *)(FLEX_CAN_2_LPCG), 16, FUNCTION_NAME(PD_DMA_CAN_2)); + clks[IMX8QXP_CAN0_DIV] = imx_clk_divider_scu("can0_div", SC_R_CAN_0, SC_PM_CLK_PER); + clks[IMX8QXP_CAN1_DIV] = imx_clk_divider_scu("can1_div", SC_R_CAN_1, SC_PM_CLK_PER); + clks[IMX8QXP_CAN2_DIV] = imx_clk_divider_scu("can2_div", SC_R_CAN_2, SC_PM_CLK_PER); + clks[IMX8QXP_CAN0_CLK] = imx_clk_gate_scu("can0_clk", "can0_div", SC_R_CAN_0, SC_PM_CLK_PER, (void __iomem *)(FLEX_CAN_0_LPCG), 0, 0); + clks[IMX8QXP_CAN1_CLK] = imx_clk_gate_scu("can1_clk", "can1_div", SC_R_CAN_1, SC_PM_CLK_PER, (void __iomem *)(FLEX_CAN_1_LPCG), 0, 0); + clks[IMX8QXP_CAN2_CLK] = imx_clk_gate_scu("can2_clk", "can2_div", SC_R_CAN_2, SC_PM_CLK_PER, (void __iomem *)(FLEX_CAN_2_LPCG), 0, 0); + clks[IMX8QXP_I2C0_IPG_CLK] = imx_clk_gate2_scu("i2c0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPI2C_0_LPCG), 16, FUNCTION_NAME(PD_DMA_I2C_0)); + clks[IMX8QXP_I2C1_IPG_CLK] = imx_clk_gate2_scu("i2c1_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPI2C_1_LPCG), 16, FUNCTION_NAME(PD_DMA_I2C_1)); + clks[IMX8QXP_I2C2_IPG_CLK] = imx_clk_gate2_scu("i2c2_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPI2C_2_LPCG), 16, FUNCTION_NAME(PD_DMA_I2C_2)); + clks[IMX8QXP_I2C3_IPG_CLK] = imx_clk_gate2_scu("i2c3_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LPI2C_3_LPCG), 16, FUNCTION_NAME(PD_DMA_I2C_3)); + clks[IMX8QXP_I2C0_DIV] = imx_clk_divider_scu("i2c0_div", SC_R_I2C_0, SC_PM_CLK_PER); + clks[IMX8QXP_I2C1_DIV] = imx_clk_divider_scu("i2c1_div", SC_R_I2C_1, SC_PM_CLK_PER); + clks[IMX8QXP_I2C2_DIV] = imx_clk_divider_scu("i2c2_div", SC_R_I2C_2, SC_PM_CLK_PER); + clks[IMX8QXP_I2C3_DIV] = imx_clk_divider_scu("i2c3_div", SC_R_I2C_3, SC_PM_CLK_PER); + clks[IMX8QXP_I2C0_CLK] = imx_clk_gate_scu("i2c0_clk", "i2c0_div", SC_R_I2C_0, SC_PM_CLK_PER, (void __iomem *)(LPI2C_0_LPCG), 0, 0); + clks[IMX8QXP_I2C1_CLK] = imx_clk_gate_scu("i2c1_clk", "i2c1_div", SC_R_I2C_1, SC_PM_CLK_PER, (void __iomem *)(LPI2C_1_LPCG), 0, 0); + clks[IMX8QXP_I2C2_CLK] = imx_clk_gate_scu("i2c2_clk", "i2c2_div", SC_R_I2C_2, SC_PM_CLK_PER, (void __iomem *)(LPI2C_2_LPCG), 0, 0); + clks[IMX8QXP_I2C3_CLK] = imx_clk_gate_scu("i2c3_clk", "i2c3_div", SC_R_I2C_3, SC_PM_CLK_PER, (void __iomem *)(LPI2C_3_LPCG), 0, 0); + clks[IMX8QXP_FTM0_IPG_CLK] = imx_clk_gate2_scu("ftm0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(FTM_0_LPCG), 16, FUNCTION_NAME(PD_DMA_FTM_0)); + clks[IMX8QXP_FTM1_IPG_CLK] = imx_clk_gate2_scu("ftm1_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(FTM_1_LPCG), 16, FUNCTION_NAME(PD_DMA_FTM_1)); + clks[IMX8QXP_FTM0_DIV] = imx_clk_divider_scu("ftm0_div", SC_R_FTM_0, SC_PM_CLK_PER); + clks[IMX8QXP_FTM1_DIV] = imx_clk_divider_scu("ftm1_div", SC_R_FTM_1, SC_PM_CLK_PER); + clks[IMX8QXP_FTM0_CLK] = imx_clk_gate_scu("ftm0_clk", "ftm0_div", SC_R_FTM_0, SC_PM_CLK_PER, (void __iomem *)(FTM_0_LPCG), 0, 0); + clks[IMX8QXP_FTM1_CLK] = imx_clk_gate_scu("ftm1_clk", "ftm1_div", SC_R_FTM_1, SC_PM_CLK_PER, (void __iomem *)(FTM_1_LPCG), 0, 0); + clks[IMX8QXP_ADC0_IPG_CLK] = imx_clk_gate2_scu("adc0_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(ADC_0_LPCG), 16, FUNCTION_NAME(PD_DMA_ADC_0)); + clks[IMX8QXP_ADC0_DIV] = imx_clk_divider_scu("adc0_div", SC_R_ADC_0, SC_PM_CLK_PER); + clks[IMX8QXP_ADC0_CLK] = imx_clk_gate_scu("adc0_clk", "adc0_div", SC_R_ADC_0, SC_PM_CLK_PER, (void __iomem *)(ADC_0_LPCG), 0, 0); + clks[IMX8QXP_PWM_IPG_CLK] = imx_clk_gate2_scu("pwm_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(PWM_LPCG), 16, FUNCTION_NAME(PD_DMA_PWM_0)); + clks[IMX8QXP_PWM_DIV] = imx_clk_divider_scu("pwm_div", SC_R_LCD_0_PWM_0, SC_PM_CLK_PER); + clks[IMX8QXP_PWM_CLK] = imx_clk_gate_scu("pwm_clk", "pwm_div", SC_R_LCD_0_PWM_0, SC_PM_CLK_PER, (void __iomem *)(PWM_LPCG), 0, 0); + clks[IMX8QXP_LCD_IPG_CLK] = imx_clk_gate2_scu("lcd_ipg_clk", "ipg_dma_clk_root", (void __iomem *)(LCD_LPCG), 16, FUNCTION_NAME(PD_DMA_LCD_0)); + + clks[IMX8QXP_LCD_PXL_BYPASS_DIV] = imx_clk_divider_scu("lcd_pxl_bypass_div", SC_R_LCD_0, SC_PM_CLK_BYPASS); + clks[IMX8QXP_LCD_PXL_SEL] = imx_clk_mux2_scu("lcd_pxl_sel", lcd_pxl_sels, ARRAY_SIZE(lcd_pxl_sels), SC_R_LCD_0, SC_PM_CLK_MISC0); + clks[IMX8QXP_LCD_PXL_DIV] = imx_clk_divider2_scu("lcd_pxl_div", "lcd_pxl_sel", SC_R_LCD_0, SC_PM_CLK_MISC0); + clks[IMX8QXP_LCD_PXL_CLK] = imx_clk_gate_scu("lcd_pxl_clk", "lcd_pxl_div", SC_R_LCD_0, SC_PM_CLK_MISC0, NULL, 0, 0); + clks[IMX8QXP_LCD_SEL] = imx_clk_mux2_scu("lcd_sel", lcd_sels, ARRAY_SIZE(lcd_sels), SC_R_LCD_0, SC_PM_CLK_PER); + clks[IMX8QXP_LCD_DIV] = imx_clk_divider2_scu("lcd_div", "lcd_sel", SC_R_LCD_0, SC_PM_CLK_PER); + clks[IMX8QXP_LCD_CLK] = imx_clk_gate_scu("lcd_clk", "lcd_div", SC_R_LCD_0, SC_PM_CLK_PER, (void __iomem *)(LCD_LPCG), 0, 0); + + /* Connectivity */ + clks[IMX8QXP_SDHC0_IPG_CLK] = imx_clk_gate2_scu("sdhc0_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(USDHC_0_LPCG), 16, FUNCTION_NAME(PD_CONN_SDHC_0)); + clks[IMX8QXP_SDHC1_IPG_CLK] = imx_clk_gate2_scu("sdhc1_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(USDHC_1_LPCG), 16, FUNCTION_NAME(PD_CONN_SDHC_1)); + clks[IMX8QXP_SDHC2_IPG_CLK] = imx_clk_gate2_scu("sdhc2_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(USDHC_2_LPCG), 16, FUNCTION_NAME(PD_CONN_SDHC_2)); + clks[IMX8QXP_SDHC0_SEL] = imx_clk_mux2_scu("sdhc0_sel", sdhc0_sels, ARRAY_SIZE(sdhc0_sels), SC_R_SDHC_0, SC_PM_CLK_PER); + clks[IMX8QXP_SDHC1_SEL] = imx_clk_mux2_scu("sdhc1_sel", sdhc1_sels, ARRAY_SIZE(sdhc1_sels), SC_R_SDHC_1, SC_PM_CLK_PER); + clks[IMX8QXP_SDHC2_SEL] = imx_clk_mux2_scu("sdhc2_sel", sdhc2_sels, ARRAY_SIZE(sdhc2_sels), SC_R_SDHC_2, SC_PM_CLK_PER); + clks[IMX8QXP_SDHC0_DIV] = imx_clk_divider2_scu("sdhc0_div", "sdhc0_sel", SC_R_SDHC_0, SC_PM_CLK_PER); + clks[IMX8QXP_SDHC1_DIV] = imx_clk_divider2_scu("sdhc1_div", "sdhc1_sel", SC_R_SDHC_1, SC_PM_CLK_PER); + clks[IMX8QXP_SDHC2_DIV] = imx_clk_divider2_scu("sdhc2_div", "sdhc2_sel", SC_R_SDHC_2, SC_PM_CLK_PER); + clks[IMX8QXP_SDHC0_CLK] = imx_clk_gate_scu("sdhc0_clk", "sdhc0_div", SC_R_SDHC_0, SC_PM_CLK_PER, (void __iomem *)(USDHC_0_LPCG), 0, 0); + clks[IMX8QXP_SDHC1_CLK] = imx_clk_gate_scu("sdhc1_clk", "sdhc1_div", SC_R_SDHC_1, SC_PM_CLK_PER, (void __iomem *)(USDHC_1_LPCG), 0, 0); + clks[IMX8QXP_SDHC2_CLK] = imx_clk_gate_scu("sdhc2_clk", "sdhc2_div", SC_R_SDHC_2, SC_PM_CLK_PER, (void __iomem *)(USDHC_2_LPCG), 0, 0); + clks[IMX8QXP_ENET0_ROOT_DIV] = imx_clk_divider_scu("enet0_root_div", SC_R_ENET_0, SC_PM_CLK_PER); + clks[IMX8QXP_ENET0_REF_DIV] = imx_clk_divider3_scu("enet0_ref_div", "enet0_root_clk", SC_R_ENET_0, SC_C_CLKDIV); + clks[IMX8QXP_ENET1_REF_DIV] = imx_clk_divider3_scu("enet1_ref_div", "enet1_root_clk", SC_R_ENET_1, SC_C_CLKDIV); + clks[IMX8QXP_ENET0_BYPASS_DIV] = imx_clk_divider_scu("enet0_bypass_div", SC_R_ENET_0, SC_PM_CLK_BYPASS); + clks[IMX8QXP_ENET0_RGMII_DIV] = imx_clk_divider_scu("enet0_rgmii_div", SC_R_ENET_0, SC_PM_CLK_MISC0); + clks[IMX8QXP_ENET1_ROOT_DIV] = imx_clk_divider_scu("enet1_root_div", SC_R_ENET_1, SC_PM_CLK_PER); + clks[IMX8QXP_ENET1_BYPASS_DIV] = imx_clk_divider_scu("enet1_bypass_div", SC_R_ENET_1, SC_PM_CLK_BYPASS); + clks[IMX8QXP_ENET1_RGMII_DIV] = imx_clk_divider_scu("enet1_rgmii_div", SC_R_ENET_1, SC_PM_CLK_MISC0); + clks[IMX8QXP_ENET0_AHB_CLK] = imx_clk_gate2_scu("enet0_ahb_clk", "axi_conn_clk_root", (void __iomem *)(ENET_0_LPCG), 8, FUNCTION_NAME(PD_CONN_ENET_0)); + clks[IMX8QXP_ENET0_IPG_S_CLK] = imx_clk_gate2_scu("enet0_ipg_s_clk", "ipg_conn_clk_root", (void __iomem *)(ENET_0_LPCG), 20, FUNCTION_NAME(PD_CONN_ENET_0)); + clks[IMX8QXP_ENET0_IPG_CLK] = imx_clk_gate2_scu("enet0_ipg_clk", "enet0_ipg_s_clk", (void __iomem *)(ENET_0_LPCG), 16, FUNCTION_NAME(PD_CONN_ENET_0)); + clks[IMX8QXP_ENET1_AHB_CLK] = imx_clk_gate2_scu("enet1_ahb_clk", "axi_conn_clk_root", (void __iomem *)(ENET_1_LPCG), 8, FUNCTION_NAME(PD_CONN_ENET_1)); + clks[IMX8QXP_ENET1_IPG_S_CLK] = imx_clk_gate2_scu("enet1_ipg_s_clk", "ipg_conn_clk_root", (void __iomem *)(ENET_1_LPCG), 20, FUNCTION_NAME(PD_CONN_ENET_1)); + clks[IMX8QXP_ENET1_IPG_CLK] = imx_clk_gate2_scu("enet1_ipg_clk", "enet1_ipg_s_clk", (void __iomem *)(ENET_1_LPCG), 16, FUNCTION_NAME(PD_CONN_ENET_1)); + clks[IMX8QXP_ENET0_ROOT_CLK] = imx_clk_gate_scu("enet0_root_clk", "enet0_root_div", SC_R_ENET_0, SC_PM_CLK_PER, NULL, 0, 0); + clks[IMX8QXP_ENET1_ROOT_CLK] = imx_clk_gate_scu("enet1_root_clk", "enet1_root_div", SC_R_ENET_1, SC_PM_CLK_PER, NULL, 0, 0); + clks[IMX8QXP_ENET0_TX_CLK] = imx_clk_gate2_scu("enet0_tx_2x_clk", "enet0_root_clk", (void __iomem *)(ENET_0_LPCG), 4, FUNCTION_NAME(PD_CONN_ENET_0)); + clks[IMX8QXP_ENET1_TX_CLK] = imx_clk_gate2_scu("enet1_tx_2x_clk", "enet1_root_clk", (void __iomem *)(ENET_1_LPCG), 4, FUNCTION_NAME(PD_CONN_ENET_1)); + clks[IMX8QXP_ENET0_PTP_CLK] = imx_clk_gate2_scu("enet0_ptp_clk", "enet0_root_clk", (void __iomem *)(ENET_0_LPCG), 0, FUNCTION_NAME(PD_CONN_ENET_0)); + clks[IMX8QXP_ENET1_PTP_CLK] = imx_clk_gate2_scu("enet1_ptp_clk", "enet1_root_clk", (void __iomem *)(ENET_1_LPCG), 0, FUNCTION_NAME(PD_CONN_ENET_1)); + clks[IMX8QXP_ENET0_REF_25MHZ_125MHZ_SEL] = imx_clk_mux_gpr_scu("enet0_ref_25_125_sel", enet_sels, ARRAY_SIZE(enet_sels), SC_R_ENET_0, SC_C_SEL_125); + clks[IMX8QXP_ENET1_REF_25MHZ_125MHZ_SEL] = imx_clk_mux_gpr_scu("enet1_ref_25_125_sel", enet_sels, ARRAY_SIZE(enet_sels), SC_R_ENET_1, SC_C_SEL_125); + clks[IMX8QXP_ENET0_RMII_TX_SEL] = imx_clk_mux_gpr_scu("enet0_rmii_tx_sel", enet0_rmii_tx_sels, ARRAY_SIZE(enet0_rmii_tx_sels), SC_R_ENET_0, SC_C_TXCLK); + clks[IMX8QXP_ENET1_RMII_TX_SEL] = imx_clk_mux_gpr_scu("enet1_rmii_tx_sel", enet1_rmii_tx_sels, ARRAY_SIZE(enet1_rmii_tx_sels), SC_R_ENET_1, SC_C_TXCLK); + clks[IMX8QXP_ENET0_RGMII_TX_CLK] = imx_clk_gate2_scu("enet0_rgmii_tx_clk", "enet0_rmii_tx_sel", (void __iomem *)(ENET_0_LPCG), 12, FUNCTION_NAME(PD_CONN_ENET_0)); + clks[IMX8QXP_ENET1_RGMII_TX_CLK] = imx_clk_gate2_scu("enet1_rgmii_tx_clk", "enet1_rmii_tx_sel", (void __iomem *)(ENET_1_LPCG), 12, FUNCTION_NAME(PD_CONN_ENET_1)); + clks[IMX8QXP_ENET0_RMII_RX_CLK] = imx_clk_gate2_scu("enet0_rgmii_rx_clk", "enet0_rgmii_div", (void __iomem *)(ENET_0_LPCG + 0x4), 0, FUNCTION_NAME(PD_CONN_ENET_0)); + clks[IMX8QXP_ENET1_RMII_RX_CLK] = imx_clk_gate2_scu("enet1_rgmii_rx_clk", "enet1_rgmii_div", (void __iomem *)(ENET_1_LPCG + 0x4), 0, FUNCTION_NAME(PD_CONN_ENET_1)); + clks[IMX8QXP_ENET0_REF_25MHZ_125MHZ_CLK] = imx_clk_gate3_scu("enet0_ref_25_125_clk", "enet0_ref_25_125_sel", SC_R_ENET_0, SC_C_DISABLE_125, true); + clks[IMX8QXP_ENET1_REF_25MHZ_125MHZ_CLK] = imx_clk_gate3_scu("enet1_ref_25_125_clk", "enet1_ref_25_125_sel", SC_R_ENET_1, SC_C_DISABLE_125, true); + clks[IMX8QXP_ENET0_REF_50MHZ_CLK] = imx_clk_gate3_scu("enet0_ref_50_clk", NULL, SC_R_ENET_0, SC_C_DISABLE_50, true); + clks[IMX8QXP_ENET1_REF_50MHZ_CLK] = imx_clk_gate3_scu("enet1_ref_50_clk", NULL, SC_R_ENET_1, SC_C_DISABLE_50, true); + clks[IMX8QXP_GPMI_BCH_IO_DIV] = imx_clk_divider_scu("gpmi_io_div", SC_R_NAND, SC_PM_CLK_MST_BUS); + clks[IMX8QXP_GPMI_BCH_DIV] = imx_clk_divider_scu("gpmi_bch_div", SC_R_NAND, SC_PM_CLK_PER); + clks[IMX8QXP_GPMI_APB_CLK] = imx_clk_gate2_scu("gpmi_apb_clk", "axi_conn_clk_root", (void __iomem *)(NAND_LPCG), 16, FUNCTION_NAME(PD_CONN_NAND)); + clks[IMX8QXP_GPMI_APB_BCH_CLK] = imx_clk_gate2_scu("gpmi_apb_bch_clk", "axi_conn_clk_root", (void __iomem *)(NAND_LPCG), 20, FUNCTION_NAME(PD_CONN_NAND)); + clks[IMX8QXP_GPMI_BCH_IO_CLK] = imx_clk_gate_scu("gpmi_io_clk", "gpmi_io_div", SC_R_NAND, SC_PM_CLK_MST_BUS, (void __iomem *)(NAND_LPCG), 4, 0); + clks[IMX8QXP_GPMI_BCH_CLK] = imx_clk_gate_scu("gpmi_bch_clk", "gpmi_bch_div", SC_R_NAND, SC_PM_CLK_PER, (void __iomem *)(NAND_LPCG), 0, 0); + clks[IMX8QXP_APBHDMA_CLK] = imx_clk_gate2_scu("gpmi_clk", "axi_conn_clk_root", (void __iomem *)(NAND_LPCG + 0x4), 16, FUNCTION_NAME(PD_CONN_NAND)); + clks[IMX8QXP_USB3_ACLK_DIV] = imx_clk_divider_scu("usb3_aclk_div", SC_R_USB_2, SC_PM_CLK_PER); + clks[IMX8QXP_USB3_BUS_DIV] = imx_clk_divider_scu("usb3_bus_div", SC_R_USB_2, SC_PM_CLK_MST_BUS); + clks[IMX8QXP_USB3_LPM_DIV] = imx_clk_divider_scu("usb3_lpm_div", SC_R_USB_2, SC_PM_CLK_MISC); + clks[IMX8QXP_USB2_OH_AHB_CLK] = imx_clk_gate2_scu("usboh3", "ahb_conn_clk_root", (void __iomem *)(USB_2_LPCG), 24, FUNCTION_NAME(PD_CONN_USB_0)); + clks[IMX8QXP_USB2_OH_IPG_S_CLK] = imx_clk_gate2_scu("usboh3_ipg_s", "ipg_conn_clk_root", (void __iomem *)(USB_2_LPCG), 16, FUNCTION_NAME(PD_CONN_USB_0)); + clks[IMX8QXP_USB2_OH_IPG_S_PL301_CLK] = imx_clk_gate2_scu("usboh3_ipg_pl301_s", "ipg_conn_clk_root", (void __iomem *)(USB_2_LPCG), 20, FUNCTION_NAME(PD_CONN_USB_0)); + clks[IMX8QXP_USB2_PHY_IPG_CLK] = imx_clk_gate2_scu("usboh3_phy_clk", "ipg_conn_clk_root", (void __iomem *)(USB_2_LPCG), 28, FUNCTION_NAME(PD_CONN_USB_0)); + clks[IMX8QXP_USB3_IPG_CLK] = imx_clk_gate2_scu("usb3_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(USB_3_LPCG), 16, FUNCTION_NAME(PD_CONN_USB_2)); + clks[IMX8QXP_USB3_CORE_PCLK] = imx_clk_gate2_scu("usb3_core_clk", "ipg_conn_clk_root", (void __iomem *)(USB_3_LPCG), 20, FUNCTION_NAME(PD_CONN_USB_2)); + clks[IMX8QXP_USB3_PHY_CLK] = imx_clk_gate2_scu("usb3_phy_clk", "usb3_ipg_clk", (void __iomem *)(USB_3_LPCG), 24, FUNCTION_NAME(PD_CONN_USB_2_PHY)); + clks[IMX8QXP_USB3_ACLK] = imx_clk_gate_scu("usb3_aclk", "usb3_aclk_div", SC_R_USB_2, SC_PM_CLK_PER, (void __iomem *)(USB_3_LPCG), 28, 0); + clks[IMX8QXP_USB3_BUS_CLK] = imx_clk_gate_scu("usb3_bus_clk", "usb3_bus_div", SC_R_USB_2, SC_PM_CLK_MST_BUS, (void __iomem *)(USB_3_LPCG), 0, 0); + clks[IMX8QXP_USB3_LPM_CLK] = imx_clk_gate_scu("usb3_lpm_clk", "usb3_lpm_div", SC_R_USB_2, SC_PM_CLK_MISC, (void __iomem *)(USB_3_LPCG), 4, 0); + clks[IMX8QXP_EDMA_CLK] = imx_clk_gate2_scu("edma_clk", "axi_conn_clk_root", (void __iomem *)(EDMA_LPCG), 0, FUNCTION_NAME(PD_CONN_DMA_4_CH0)); + clks[IMX8QXP_EDMA_IPG_CLK] = imx_clk_gate2_scu("edma_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(EDMA_LPCG), 16, FUNCTION_NAME(PD_CONN_DMA_4_CH0)); + clks[IMX8QXP_MLB_HCLK] = imx_clk_gate2_scu("mlb_hclk", "axi_conn_clk_root", (void __iomem *)(MLB_LPCG), 20, FUNCTION_NAME(PD_CONN_MLB_0)); + clks[IMX8QXP_MLB_CLK] = imx_clk_gate2_scu("mlb_clk", "mlb_hclk", (void __iomem *)(MLB_LPCG), 0, FUNCTION_NAME(PD_CONN_MLB_0)); + clks[IMX8QXP_MLB_IPG_CLK] = imx_clk_gate2_scu("mlb_ipg_clk", "ipg_conn_clk_root", (void __iomem *)(MLB_LPCG), 16, FUNCTION_NAME(PD_CONN_MLB_0)); + + /* Display controller - DC0 SS */ + clks[IMX8QXP_DC0_PLL0_DIV] = imx_clk_divider_scu("dc0_pll0_div", SC_R_DC_0_PLL_0, SC_PM_CLK_PLL); + clks[IMX8QXP_DC0_PLL1_DIV] = imx_clk_divider_scu("dc0_pll1_div", SC_R_DC_0_PLL_1, SC_PM_CLK_PLL); + clks[IMX8QXP_DC0_PLL0_CLK] = imx_clk_gate_scu("dc0_pll0_clk", "dc0_pll0_div", SC_R_DC_0_PLL_0, SC_PM_CLK_PLL, NULL, 0, 0); + clks[IMX8QXP_DC0_PLL1_CLK] = imx_clk_gate_scu("dc0_pll1_clk", "dc0_pll1_div", SC_R_DC_0_PLL_1, SC_PM_CLK_PLL, NULL, 0, 0); + clks[IMX8QXP_DC0_DISP0_DIV] = imx_clk_divider_scu("dc0_disp0_div", SC_R_DC_0, SC_PM_CLK_MISC0); + clks[IMX8QXP_DC0_DISP1_DIV] = imx_clk_divider_scu("dc0_disp1_div", SC_R_DC_0, SC_PM_CLK_MISC1); + clks[IMX8QXP_DC0_DISP0_CLK] = imx_clk_gate_scu("dc0_disp0_clk", "dc0_disp0_div", SC_R_DC_0, SC_PM_CLK_MISC0, (void __iomem *)(DC_0_LPCG), 0, 0); + clks[IMX8QXP_DC0_DISP1_CLK] = imx_clk_gate_scu("dc0_disp1_clk", "dc0_disp1_div", SC_R_DC_0, SC_PM_CLK_MISC1, (void __iomem *)(DC_0_LPCG), 4, 0); + clks[IMX8QXP_DC0_BYPASS_0_DIV] = imx_clk_divider_scu("dc0_bypass0_div", SC_R_DC_0_VIDEO0, SC_PM_CLK_BYPASS); + clks[IMX8QXP_DC0_BYPASS_1_DIV] = imx_clk_divider_scu("dc0_bypass1_div", SC_R_DC_0_VIDEO1, SC_PM_CLK_BYPASS); + clks[IMX8QXP_DC0_PRG0_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg0_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x20), 0, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG0_APB_CLK] = imx_clk_gate2_scu("dc0_prg0_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x20), 16, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG1_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg1_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x24), 0, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG1_APB_CLK] = imx_clk_gate2_scu("dc0_prg1_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x24), 16, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG2_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg2_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x28), 0, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG2_APB_CLK] = imx_clk_gate2_scu("dc0_prg2_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x28), 16, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG3_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg3_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x34), 0, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG3_APB_CLK] = imx_clk_gate2_scu("dc0_prg3_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x34), 16, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG4_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg4_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x38), 0, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG4_APB_CLK] = imx_clk_gate2_scu("dc0_prg4_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x38), 16, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG5_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg5_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x3c), 0, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG5_APB_CLK] = imx_clk_gate2_scu("dc0_prg5_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x3c), 16, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG6_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg6_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x40), 0, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG6_APB_CLK] = imx_clk_gate2_scu("dc0_prg6_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x40), 16, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG7_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg7_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x44), 0, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG7_APB_CLK] = imx_clk_gate2_scu("dc0_prg7_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x44), 16, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG8_RTRAM_CLK] = imx_clk_gate2_scu("dc0_prg8_rtram_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x48), 0, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_PRG8_APB_CLK] = imx_clk_gate2_scu("dc0_prg8_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x48), 16, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_DPR0_APB_CLK] = imx_clk_gate2_scu("dc0_dpr0_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x18), 16, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_DPR0_B_CLK] = imx_clk_gate2_scu("dc0_dpr0_b_clk", "axi_ext_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x18), 20, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_RTRAM0_CLK] = imx_clk_gate2_scu("dc0_rtrm0_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x1C), 0, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_DPR1_APB_CLK] = imx_clk_gate2_scu("dc0_dpr1_apb_clk", "cfg_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x2C), 16, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_DPR1_B_CLK] = imx_clk_gate2_scu("dc0_dpr1_b_clk", "axi_ext_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x2C), 20, FUNCTION_NAME(PD_DC_0)); + clks[IMX8QXP_DC0_RTRAM1_CLK] = imx_clk_gate2_scu("dc0_rtrm1_clk", "axi_int_dc_clk_root", (void __iomem *)(DC_0_LPCG + 0x30), 0, FUNCTION_NAME(PD_DC_0)); + + /* Display interface - MIPI-LVDS SS */ + clks[IMX8QXP_MIPI0_BYPASS_CLK] = imx_clk_divider_scu("mipi0_bypass_clk", SC_R_MIPI_0, SC_PM_CLK_BYPASS); + clks[IMX8QXP_MIPI0_PIXEL_DIV] = imx_clk_divider_scu("mipi0_pixel_div", SC_R_MIPI_0, SC_PM_CLK_PER); + clks[IMX8QXP_MIPI0_PIXEL_CLK] = imx_clk_gate_scu("mipi0_pixel_clk", "mipi0_pixel_div", SC_R_MIPI_0, SC_PM_CLK_PER, NULL, 0, 0); + clks[IMX8QXP_MIPI0_LVDS_PIXEL_DIV] = imx_clk_divider_scu("mipi0_lvds_pixel_div", SC_R_LVDS_0, SC_PM_CLK_MISC2); + clks[IMX8QXP_MIPI0_LVDS_PIXEL_CLK] = imx_clk_gate_scu("mipi0_lvds_pixel_clk", "mipi0_lvds_pixel_div", SC_R_LVDS_0, SC_PM_CLK_MISC2, NULL, 0, 0); + clks[IMX8QXP_MIPI0_LVDS_BYPASS_CLK] = imx_clk_divider_scu("mipi0_lvds_bypass_clk", SC_R_LVDS_0, SC_PM_CLK_BYPASS); + clks[IMX8QXP_MIPI0_LVDS_PHY_DIV] = imx_clk_divider_scu("mipi0_lvds_phy_div", SC_R_LVDS_0, SC_PM_CLK_MISC3); + clks[IMX8QXP_MIPI0_LVDS_PHY_CLK] = imx_clk_gate_scu("mipi0_lvds_phy_clk", "mipi0_lvds_phy_div", SC_R_LVDS_0, SC_PM_CLK_MISC3, NULL, 0, 0); + clks[IMX8QXP_MIPI0_DSI_TX_ESC_SEL] = imx_clk_mux2_scu("mipi0_dsi_tx_esc_sel", mipi0_sels, ARRAY_SIZE(mipi0_sels), SC_R_MIPI_0, SC_PM_CLK_MST_BUS); + clks[IMX8QXP_MIPI0_DSI_TX_ESC_DIV] = imx_clk_divider2_scu("mipi0_dsi_tx_esc_div", "mipi0_dsi_tx_esc_sel", SC_R_MIPI_0, SC_PM_CLK_MST_BUS); + clks[IMX8QXP_MIPI0_DSI_TX_ESC_CLK] = imx_clk_gate_scu("mipi0_dsi_tx_esc_clk", "mipi0_dsi_tx_esc_div", SC_R_MIPI_0, SC_PM_CLK_MST_BUS, NULL, 0, 0); + clks[IMX8QXP_MIPI0_DSI_RX_ESC_SEL] = imx_clk_mux2_scu("mipi0_dsi_rx_esc_sel", mipi0_sels, ARRAY_SIZE(mipi0_sels), SC_R_MIPI_0, SC_PM_CLK_SLV_BUS); + clks[IMX8QXP_MIPI0_DSI_RX_ESC_DIV] = imx_clk_divider2_scu("mipi0_dsi_rx_esc_div", "mipi0_dsi_rx_esc_sel", SC_R_MIPI_0, SC_PM_CLK_SLV_BUS); + clks[IMX8QXP_MIPI0_DSI_RX_ESC_CLK] = imx_clk_gate_scu("mipi0_dsi_rx_esc_clk", "mipi0_dsi_rx_esc_div", SC_R_MIPI_0, SC_PM_CLK_SLV_BUS, NULL, 0, 0); + clks[IMX8QXP_MIPI0_DSI_PHY_SEL] = imx_clk_mux2_scu("mipi0_dsi_phy_sel", mipi0_sels, ARRAY_SIZE(mipi0_sels), SC_R_MIPI_0, SC_PM_CLK_PHY); + clks[IMX8QXP_MIPI0_DSI_PHY_DIV] = imx_clk_divider2_scu("mipi0_dsi_phy_div", "mipi0_dsi_phy_sel", SC_R_MIPI_0, SC_PM_CLK_PHY); + clks[IMX8QXP_MIPI0_DSI_PHY_CLK] = imx_clk_gate_scu("mipi0_dsi_phy_clk", "mipi0_dsi_phy_div", SC_R_MIPI_0, SC_PM_CLK_PHY, NULL, 0, 0); + clks[IMX8QXP_MIPI0_I2C0_DIV] = imx_clk_divider_scu("mipi0_i2c0_div", SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2); + clks[IMX8QXP_MIPI0_I2C1_DIV] = imx_clk_divider_scu("mipi0_i2c1_div", SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2); + clks[IMX8QXP_MIPI0_I2C0_CLK] = imx_clk_gate_scu("mipi0_i2c0_clk", "mipi0_i2c0_div", SC_R_MIPI_0_I2C_0, SC_PM_CLK_MISC2, (void __iomem *)(DI_MIPI0_LPCG + 0x10), 0, 0); + clks[IMX8QXP_MIPI0_I2C1_CLK] = imx_clk_gate_scu("mipi0_i2c1_clk", "mipi0_i2c1_div", SC_R_MIPI_0_I2C_1, SC_PM_CLK_MISC2, (void __iomem *)(DI_MIPI0_LPCG + 0x14), 0, 0); + clks[IMX8QXP_MIPI0_I2C0_IPG_CLK] = imx_clk_gate2_scu("mipi0_i2c0_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0x10), 16, FUNCTION_NAME(PD_MIPI_0_DSI_I2C0)); + clks[IMX8QXP_MIPI0_I2C1_IPG_CLK] = imx_clk_gate2_scu("mipi0_i2c1_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0x14), 16, FUNCTION_NAME(PD_MIPI_0_DSI_I2C1)); + clks[IMX8QXP_MIPI0_PWM_IPG_CLK] = imx_clk_gate2_scu("mipi0_pwm_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0xC), 16, FUNCTION_NAME(PD_MIPI_0_DSI_PWM0)); + clks[IMX8QXP_MIPI0_PWM_32K_CLK] = imx_clk_gate2_scu("mipi0_pwm_32K_clk", "xtal_32KHz", (void __iomem *)(DI_MIPI0_LPCG + 0xC), 4, FUNCTION_NAME(PD_MIPI_0_DSI_PWM0)); + clks[IMX8QXP_MIPI0_PWM_DIV] = imx_clk_divider_scu("mipi0_pwm_div", SC_R_MIPI_0_PWM_0, SC_PM_CLK_PER); + clks[IMX8QXP_MIPI0_PWM_CLK] = imx_clk_gate_scu("mipi0_pwm_clk", "mipi0_pwm_div", SC_R_MIPI_0_PWM_0, SC_PM_CLK_PER, (void __iomem *)(DI_MIPI0_LPCG + 0xC), 0, 0); + clks[IMX8QXP_MIPI0_GPIO_IPG_CLK] = imx_clk_gate2_scu("mipi0_gpio_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0x8), 16, FUNCTION_NAME(PD_MIPI_0_GPIO_0)); + clks[IMX8QXP_MIPI0_LIS_IPG_CLK] = imx_clk_gate2_scu("mipi0_lis_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI0_LPCG + 0x0), 16, FUNCTION_NAME(PD_MIPI_0_DSI)); + clks[IMX8QXP_MIPI1_BYPASS_CLK] = imx_clk_divider_scu("mipi1_bypass_clk", SC_R_MIPI_1, SC_PM_CLK_BYPASS); + clks[IMX8QXP_MIPI1_PIXEL_DIV] = imx_clk_divider_scu("mipi1_pixel_div", SC_R_MIPI_1, SC_PM_CLK_PER); + clks[IMX8QXP_MIPI1_PIXEL_CLK] = imx_clk_gate_scu("mipi1_pixel_clk", "mipi1_pixel_div", SC_R_MIPI_1, SC_PM_CLK_PER, NULL, 0, 0); + clks[IMX8QXP_MIPI1_LVDS_PIXEL_DIV] = imx_clk_divider_scu("mipi1_lvds_pixel_div", SC_R_LVDS_1, SC_PM_CLK_MISC2); + clks[IMX8QXP_MIPI1_LVDS_PIXEL_CLK] = imx_clk_gate_scu("mipi1_lvds_pixel_clk", "mipi1_lvds_pixel_div", SC_R_LVDS_1, SC_PM_CLK_MISC2, NULL, 0, 0); + clks[IMX8QXP_MIPI1_LVDS_BYPASS_CLK] = imx_clk_divider_scu("mipi1_lvds_bypass_clk", SC_R_LVDS_1, SC_PM_CLK_BYPASS); + clks[IMX8QXP_MIPI1_LVDS_PHY_DIV] = imx_clk_divider_scu("mipi1_lvds_phy_div", SC_R_LVDS_1, SC_PM_CLK_MISC3); + clks[IMX8QXP_MIPI1_LVDS_PHY_CLK] = imx_clk_gate_scu("mipi1_lvds_phy_clk", "mipi1_lvds_phy_div", SC_R_LVDS_1, SC_PM_CLK_MISC3, NULL, 0, 0); + clks[IMX8QXP_MIPI1_DSI_TX_ESC_SEL] = imx_clk_mux2_scu("mipi1_dsi_tx_esc_sel", mipi1_sels, ARRAY_SIZE(mipi1_sels), SC_R_MIPI_1, SC_PM_CLK_MST_BUS); + clks[IMX8QXP_MIPI1_DSI_TX_ESC_DIV] = imx_clk_divider2_scu("mipi1_dsi_tx_esc_div", "mipi1_dsi_tx_esc_sel", SC_R_MIPI_1, SC_PM_CLK_MST_BUS); + clks[IMX8QXP_MIPI1_DSI_TX_ESC_CLK] = imx_clk_gate_scu("mipi1_dsi_tx_esc_clk", "mipi1_dsi_tx_esc_div", SC_R_MIPI_1, SC_PM_CLK_MST_BUS, NULL, 0, 0); + clks[IMX8QXP_MIPI1_DSI_RX_ESC_SEL] = imx_clk_mux2_scu("mipi1_dsi_rx_esc_sel", mipi1_sels, ARRAY_SIZE(mipi1_sels), SC_R_MIPI_1, SC_PM_CLK_SLV_BUS); + clks[IMX8QXP_MIPI1_DSI_RX_ESC_DIV] = imx_clk_divider2_scu("mipi1_dsi_rx_esc_div", "mipi1_dsi_rx_esc_sel", SC_R_MIPI_1, SC_PM_CLK_SLV_BUS); + clks[IMX8QXP_MIPI1_DSI_RX_ESC_CLK] = imx_clk_gate_scu("mipi1_dsi_rx_esc_clk", "mipi1_dsi_rx_esc_div", SC_R_MIPI_1, SC_PM_CLK_SLV_BUS, NULL, 0, 0); + + clks[IMX8QXP_MIPI1_I2C0_DIV] = imx_clk_divider_scu("mipi1_i2c0_div", SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2); + clks[IMX8QXP_MIPI1_I2C1_DIV] = imx_clk_divider_scu("mipi1_i2c1_div", SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2); + clks[IMX8QXP_MIPI1_I2C0_CLK] = imx_clk_gate_scu("mipi1_i2c0_clk", "mipi1_i2c0_div", SC_R_MIPI_1_I2C_0, SC_PM_CLK_MISC2, (void __iomem *)(DI_MIPI1_LPCG + 0x10), 0, 0); + clks[IMX8QXP_MIPI1_I2C1_CLK] = imx_clk_gate_scu("mipi1_i2c1_clk", "mipi1_i2c1_div", SC_R_MIPI_1_I2C_1, SC_PM_CLK_MISC2, (void __iomem *)(DI_MIPI1_LPCG + 0x14), 0, 0); + clks[IMX8QXP_MIPI1_I2C0_IPG_CLK] = imx_clk_gate2_scu("mipi1_i2c0_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI1_LPCG + 0x10), 16, FUNCTION_NAME(PD_MIPI_1_DSI_I2C0)); + clks[IMX8QXP_MIPI1_I2C1_IPG_CLK] = imx_clk_gate2_scu("mipi1_i2c1_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI1_LPCG + 0x14), 16, FUNCTION_NAME(PD_MIPI_1_DSI_I2C1)); + clks[IMX8QXP_MIPI1_PWM_IPG_CLK] = imx_clk_gate2_scu("mipi1_pwm_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI1_LPCG + 0xC), 16, FUNCTION_NAME(PD_MIPI_1_DSI_PWM0)); + clks[IMX8QXP_MIPI1_PWM_32K_CLK] = imx_clk_gate2_scu("mipi1_pwm_32K_clk", "xtal_32KHz", (void __iomem *)(DI_MIPI1_LPCG + 0xC), 4, FUNCTION_NAME(PD_MIPI_1_DSI_PWM0)); + clks[IMX8QXP_MIPI1_PWM_DIV] = imx_clk_divider_scu("mipi1_pwm_div", SC_R_MIPI_1_PWM_0, SC_PM_CLK_PER); + clks[IMX8QXP_MIPI1_PWM_CLK] = imx_clk_gate_scu("mipi1_pwm_clk", "mipi1_pwm_div", SC_R_MIPI_1_PWM_0, SC_PM_CLK_PER, (void __iomem *)(DI_MIPI1_LPCG + 0xC), 0, 0); + clks[IMX8QXP_MIPI1_GPIO_IPG_CLK] = imx_clk_gate2_scu("mipi1_gpio_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI1_LPCG + 0x8), 16, FUNCTION_NAME(PD_MIPI_1_GPIO_0)); + clks[IMX8QXP_MIPI1_LIS_IPG_CLK] = imx_clk_gate2_scu("mipi1_lis_ipg_clk", "ipg_mipi_clk_root", (void __iomem *)(DI_MIPI1_LPCG + 0x0), 16, FUNCTION_NAME(PD_MIPI_1_DSI)); + + /* Imaging SS */ + clks[IMX8QXP_IMG_JPEG_ENC_IPG_CLK] = imx_clk_gate2_scu("img_jpeg_enc_ipg_clk", "ipg_img_clk_root", (void __iomem *)(IMG_JPEG_ENC_LPCG), 16, FUNCTION_NAME(PD_IMAGING_JPEG_ENC)); + clks[IMX8QXP_IMG_JPEG_ENC_CLK] = imx_clk_gate2_scu("img_jpeg_enc_clk", "img_jpeg_enc_ipg_clk", (void __iomem *)(IMG_JPEG_ENC_LPCG), 0, FUNCTION_NAME(PD_IMAGING_JPEG_ENC)); + clks[IMX8QXP_IMG_JPEG_DEC_IPG_CLK] = imx_clk_gate2_scu("img_jpeg_dec_ipg_clk", "ipg_img_clk_root", (void __iomem *)(IMG_JPEG_DEC_LPCG), 16, FUNCTION_NAME(PD_IMAGING_JPEG_DEC)); + clks[IMX8QXP_IMG_JPEG_DEC_CLK] = imx_clk_gate2_scu("img_jpeg_dec_clk", "img_jpeg_dec_ipg_clk", (void __iomem *)(IMG_JPEG_DEC_LPCG), 0, FUNCTION_NAME(PD_IMAGING_JPEG_DEC)); + clks[IMX8QXP_IMG_PXL_LINK_DC0_CLK] = imx_clk_gate2_scu("img_pxl_link_dc0_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_DC0_LPCG), 0, FUNCTION_NAME(PD_IMAGING)); + clks[IMX8QXP_IMG_PXL_LINK_DC1_CLK] = imx_clk_gate2_scu("img_pxl_link_dc1_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_DC1_LPCG), 0, FUNCTION_NAME(PD_IMAGING)); + clks[IMX8QXP_IMG_PXL_LINK_CSI0_CLK] = imx_clk_gate2_scu("img_pxl_link_csi0_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_CSI0_LPCG), 0, FUNCTION_NAME(PD_IMAGING)); + clks[IMX8QXP_IMG_PXL_LINK_CSI1_CLK] = imx_clk_gate2_scu("img_pxl_link_csi1_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_CSI1_LPCG), 0, FUNCTION_NAME(PD_IMAGING)); + clks[IMX8QXP_IMG_PXL_LINK_HDMI_IN_CLK] = imx_clk_gate2_scu("img_pxl_link_hdmi_in_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PXL_LINK_HDMI_LPCG), 0, FUNCTION_NAME(PD_HDMI_RX)); + clks[IMX8QXP_IMG_PDMA_0_CLK] = imx_clk_gate2_scu("img_pdma0_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_0_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA0)); + clks[IMX8QXP_IMG_PDMA_1_CLK] = imx_clk_gate2_scu("img_pdma1_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_1_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA1)); + clks[IMX8QXP_IMG_PDMA_2_CLK] = imx_clk_gate2_scu("img_pdma2_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_2_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA2)); + clks[IMX8QXP_IMG_PDMA_3_CLK] = imx_clk_gate2_scu("img_pdma3_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_3_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA3)); + clks[IMX8QXP_IMG_PDMA_4_CLK] = imx_clk_gate2_scu("img_pdma4_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_4_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA4)); + clks[IMX8QXP_IMG_PDMA_5_CLK] = imx_clk_gate2_scu("img_pdma5_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_5_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA5)); + clks[IMX8QXP_IMG_PDMA_6_CLK] = imx_clk_gate2_scu("img_pdma6_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_6_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA6)); + clks[IMX8QXP_IMG_PDMA_7_CLK] = imx_clk_gate2_scu("img_pdma7_clk", "pxl_img_clk_root", (void __iomem *)(IMG_PDMA_7_LPCG), 0, FUNCTION_NAME(PD_IMAGING_PDMA7)); + + /* MIPI CSI SS */ + clks[IMX8QXP_CSI0_I2C0_DIV] = imx_clk_divider_scu("mipi_csi0_i2c0_div", SC_R_CSI_0_I2C_0, SC_PM_CLK_PER); + clks[IMX8QXP_CSI0_PWM0_DIV] = imx_clk_divider_scu("mipi_csi0_pwm0_div", SC_R_CSI_0_PWM_0, SC_PM_CLK_PER); + clks[IMX8QXP_CSI0_CORE_DIV] = imx_clk_divider_scu("mipi_csi0_core_div", SC_R_CSI_0, SC_PM_CLK_PER); + clks[IMX8QXP_CSI0_ESC_DIV] = imx_clk_divider_scu("mipi_csi0_esc_div", SC_R_CSI_0, SC_PM_CLK_MISC); + clks[IMX8QXP_CSI0_I2C0_IPG_CLK] = imx_clk_gate2_scu("mipi_csi0_i2c0_ipg_s", "ipg_mipi_csi_clk_root", (void __iomem *)(MIPI_CSI_0_LPCG + 0x14), 16, FUNCTION_NAME(PD_MIPI_CSI0_I2C0)); + clks[IMX8QXP_CSI0_I2C0_CLK] = imx_clk_gate_scu("mipi_csi0_i2c0_clk", "mipi_csi0_i2c0_div", SC_R_CSI_0_I2C_0, SC_PM_CLK_PER, (void __iomem *)(MIPI_CSI_0_LPCG + 0x14), 0, 0); + clks[IMX8QXP_CSI0_PWM0_IPG_CLK] = imx_clk_gate2_scu("mipi_csi0_pwm0_ipg_s", "ipg_mipi_csi_clk_root", (void __iomem *)(MIPI_CSI_0_LPCG + 0x10), 16, FUNCTION_NAME(PD_MIPI_CSI0_PWM)); + clks[IMX8QXP_CSI0_PWM0_CLK] = imx_clk_gate_scu("mipi_csi0_pwm0_clk", "mipi_csi0_pwm0_div", SC_R_CSI_0_PWM_0, SC_PM_CLK_PER, (void __iomem *)(MIPI_CSI_0_LPCG + 0x10), 0, 0); + clks[IMX8QXP_CSI0_CORE_CLK] = imx_clk_gate_scu("mipi_csi0_core_clk", "mipi_csi0_core_div", SC_R_CSI_0, SC_PM_CLK_PER, (void __iomem *)(MIPI_CSI_0_LPCG + 0x18), 16, 0); + clks[IMX8QXP_CSI0_ESC_CLK] = imx_clk_gate_scu("mipi_csi0_esc_clk", "mipi_csi0_esc_div", SC_R_CSI_0, SC_PM_CLK_MISC, (void __iomem *)(MIPI_CSI_0_LPCG + 0x1C), 16, 0); + + /* Parallel CSI */ + clks[IMX8QXP_PARALLEL_CSI_CLK_DPLL] = imx_clk_divider_scu("parallel_pll_clk", SC_R_PI_0_PLL, SC_PM_CLK_PLL); + clks[IMX8QXP_PARALLEL_CSI_CLK_SEL] = imx_clk_mux2_scu("pll0_sel", pll0_sels, ARRAY_SIZE(pll0_sels), SC_R_PI_0, SC_PM_CLK_PER); + clks[IMX8QXP_PARALLEL_CSI_PER_CLK_DIV] = imx_clk_divider2_scu("parallel_per_clk", "pll0_sel", SC_R_PI_0, SC_PM_CLK_PER); + clks[IMX8QXP_PARALLEL_CSI_MCLK_DIV] = imx_clk_divider_scu("parallel_csi_mclk_div", SC_R_PI_0, SC_PM_CLK_MISC0); + clks[IMX8QXP_PARALLEL_CSI_PIXEL_CLK] = imx_clk_gate_scu("parallel_pixel_clk", "parallel_per_clk", SC_R_PI_0, SC_PM_CLK_PER, (void __iomem *)(PARALLEL_CSI_LPCG + 0x18), 0, 0); + clks[IMX8QXP_PARALLEL_CSI_IPG_CLK] = imx_clk_gate_scu("parallel_ipg_clk", "parallel_per_clk", SC_R_PI_0, SC_PM_CLK_PER, (void __iomem *)(PARALLEL_CSI_LPCG + 0x4), 16, 0); + clks[IMX8QXP_PARALLEL_CSI_MISC0_CLK] = imx_clk_gate_scu("parallel_csi_mclk", "parallel_csi_mclk_div", SC_R_PI_0, SC_PM_CLK_MISC0, (void __iomem *)(PARALLEL_CSI_LPCG + 0x1C), 0, 0); + + + /* HSIO SS */ + clks[IMX8QXP_HSIO_PCIE_MSTR_AXI_CLK] = imx_clk_gate2_scu("hsio_pcie_mstr_axi_clk", "axi_hsio_clk_root", (void __iomem *)(HSIO_PCIE_X1_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_B)); + clks[IMX8QXP_HSIO_PCIE_SLV_AXI_CLK] = imx_clk_gate2_scu("hsio_pcie_slv_axi_clk", "axi_hsio_clk_root", (void __iomem *)(HSIO_PCIE_X1_LPCG), 20, FUNCTION_NAME(PD_HSIO_PCIE_B)); + clks[IMX8QXP_HSIO_PCIE_DBI_AXI_CLK] = imx_clk_gate2_scu("hsio_pcie_dbi_axi_clk", "axi_hsio_clk_root", (void __iomem *)(HSIO_PCIE_X1_LPCG), 24, FUNCTION_NAME(PD_HSIO_PCIE_B)); + clks[IMX8QXP_HSIO_PCIE_X1_PER_CLK] = imx_clk_gate2_scu("hsio_pcie_x1_per_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_PCIE_X1_CRR3_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_B)); + clks[IMX8QXP_HSIO_PHY_X1_PER_CLK] = imx_clk_gate2_scu("hsio_phy_x1_per_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_PHY_X1_CRR1_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_B)); + clks[IMX8QXP_HSIO_MISC_PER_CLK] = imx_clk_gate2_scu("hsio_misc_per_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_MISC_LPCG), 16, FUNCTION_NAME(PD_HSIO)); + clks[IMX8QXP_HSIO_PHY_X1_APB_CLK] = imx_clk_gate2_scu("hsio_phy_x1_apb_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_PHY_X1_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_B)); + clks[IMX8QXP_HSIO_GPIO_CLK] = imx_clk_gate2_scu("hsio_gpio_clk", "per_hsio_clk_root", (void __iomem *)(HSIO_GPIO_LPCG), 16, FUNCTION_NAME(PD_HSIO_PCIE_B)); + clks[IMX8QXP_HSIO_PHY_X1_PCLK] = imx_clk_gate2_scu("hsio_phy_x1_pclk", "dummy", (void __iomem *)(HSIO_PHY_X1_LPCG), 0, FUNCTION_NAME(PD_HSIO_PCIE_B)); + + /* CM40 */ + clks[IMX8QXP_CM40_I2C_DIV] = imx_clk_divider_scu("cm40_i2c_div", SC_R_M4_0_I2C, SC_PM_CLK_PER); + clks[IMX8QXP_CM40_I2C_CLK] = imx_clk_gate_scu("cm40_i2c_clk", "cm40_i2c_div", SC_R_M4_0_I2C, SC_PM_CLK_PER, (void __iomem *)(CM40_I2C_LPCG), 0, 0); + clks[IMX8QXP_CM40_I2C_IPG_CLK] = imx_clk_gate2_scu("cm40_i2c_ipg_clk", "ipg_cm40_clk_root", (void __iomem *)(CM40_I2C_LPCG), 16, FUNCTION_NAME(PD_CM40_I2C)); + + /* Audio */ + clks[IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV] = imx_clk_divider2_scu("aud_acm_aud_pll_clk0_div", "audio_pll0_clk", SC_R_AUDIO_PLL_0, SC_PM_CLK_MISC0); + clks[IMX8QXP_AUD_ACM_AUD_PLL_CLK1_DIV] = imx_clk_divider2_scu("aud_acm_aud_pll_clk1_div", "audio_pll1_clk", SC_R_AUDIO_PLL_1, SC_PM_CLK_MISC0); + clks[IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV] = imx_clk_divider2_scu("aud_acm_aud_rec_clk0_div", "audio_pll0_clk", SC_R_AUDIO_PLL_0, SC_PM_CLK_MISC1); + clks[IMX8QXP_AUD_ACM_AUD_REC_CLK1_DIV] = imx_clk_divider2_scu("aud_acm_aud_rec_clk1_div", "audio_pll1_clk", SC_R_AUDIO_PLL_1, SC_PM_CLK_MISC1); + clks[IMX8QXP_AUD_ACM_AUD_PLL_CLK0_CLK] = imx_clk_gate_scu("aud_acm_aud_pll_clk0_clk", "aud_acm_aud_pll_clk0_div", SC_R_AUDIO_PLL_0, SC_PM_CLK_MISC0, (void __iomem *)(AUD_PLL_CLK0_LPCG), 0, 0); + clks[IMX8QXP_AUD_ACM_AUD_PLL_CLK1_CLK] = imx_clk_gate_scu("aud_acm_aud_pll_clk1_clk", "aud_acm_aud_pll_clk1_div", SC_R_AUDIO_PLL_1, SC_PM_CLK_MISC0, (void __iomem *)(AUD_PLL_CLK1_LPCG), 0, 0); + clks[IMX8QXP_AUD_ACM_AUD_REC_CLK0_CLK] = imx_clk_gate_scu("aud_acm_aud_rec_clk0_clk", "aud_acm_aud_rec_clk0_div", SC_R_AUDIO_PLL_0, SC_PM_CLK_MISC1, (void __iomem *)(AUD_REC_CLK0_LPCG), 0, 0); + clks[IMX8QXP_AUD_ACM_AUD_REC_CLK1_CLK] = imx_clk_gate_scu("aud_acm_aud_rec_clk1_clk", "aud_acm_aud_rec_clk1_div", SC_R_AUDIO_PLL_1, SC_PM_CLK_MISC1, (void __iomem *)(AUD_REC_CLK1_LPCG), 0, 0); + + /* VPU */ + clks[IMX8QXP_VPU_ENC_CLK] = imx_clk_gate_scu("vpu_enc_clk", "dummy", SC_R_VPU_ENC_0, SC_PM_CLK_PER, NULL, 0, 0); + clks[IMX8QXP_VPU_DEC_CLK] = imx_clk_gate_scu("vpu_dec_clk", "dummy", SC_R_VPU_DEC_0, SC_PM_CLK_PER, NULL, 0, 0); + + np_acm = of_find_compatible_node(NULL, NULL, "nxp,imx8qm-acm"); + if (np_acm) { + base_acm = of_iomap(np_acm, 0); + WARN_ON(!base_acm); + + clks[IMX8QXP_EXT_AUD_MCLK0] = imx_clk_fixed("ext_aud_mclk0", 0); + clks[IMX8QXP_EXT_AUD_MCLK1] = imx_clk_fixed("ext_aud_mclk1", 0); + clks[IMX8QXP_ESAI0_RX_CLK] = imx_clk_fixed("esai0_rx_clk", 0); + clks[IMX8QXP_ESAI0_RX_HF_CLK] = imx_clk_fixed("esai0_rx_hf_clk", 0); + clks[IMX8QXP_ESAI0_TX_CLK] = imx_clk_fixed("esai0_tx_clk", 0); + clks[IMX8QXP_ESAI0_TX_HF_CLK] = imx_clk_fixed("esai0_tx_hf_clk", 0); + clks[IMX8QXP_SPDIF0_RX] = imx_clk_fixed("spdif0_rx", 0); + clks[IMX8QXP_SAI0_RX_BCLK] = imx_clk_fixed("sai0_rx_bclk", 0); + clks[IMX8QXP_SAI0_TX_BCLK] = imx_clk_fixed("sai0_tx_bclk", 0); + clks[IMX8QXP_SAI1_RX_BCLK] = imx_clk_fixed("sai1_rx_bclk", 0); + clks[IMX8QXP_SAI1_TX_BCLK] = imx_clk_fixed("sai1_tx_bclk", 0); + clks[IMX8QXP_SAI2_RX_BCLK] = imx_clk_fixed("sai2_rx_bclk", 0); + clks[IMX8QXP_SAI3_RX_BCLK] = imx_clk_fixed("sai3_rx_bclk", 0); + clks[IMX8QXP_SAI4_RX_BCLK] = imx_clk_fixed("sai4_rx_bclk", 0); + + clks[IMX8QXP_ACM_AUD_CLK0_SEL] = imx_clk_mux_scu("acm_aud_clk0_sel", base_acm+0x000000, 0, 5, aud_clk_sels, ARRAY_SIZE(aud_clk_sels), FUNCTION_NAME(PD_AUD_AUDIO_CLK_0)); + clks[IMX8QXP_ACM_AUD_CLK0_CLK] = imx_clk_gate_scu("acm_aud_clk0_clk", "acm_aud_clk0_sel", SC_R_AUDIO_CLK_0, SC_PM_CLK_SLV_BUS, NULL, 0, 0); + clks[IMX8QXP_ACM_AUD_CLK1_SEL] = imx_clk_mux_scu("acm_aud_clk1_sel", base_acm+0x010000, 0, 5, aud_clk_sels, ARRAY_SIZE(aud_clk_sels), FUNCTION_NAME(PD_AUD_AUDIO_CLK_1)); + clks[IMX8QXP_ACM_AUD_CLK1_CLK] = imx_clk_gate_scu("acm_aud_clk1_clk", "acm_aud_clk1_sel", SC_R_AUDIO_CLK_1, SC_PM_CLK_SLV_BUS, NULL, 0, 0); + clks[IMX8QXP_ACM_MCLKOUT0_SEL] = imx_clk_mux_scu("acm_mclkout0_sel", base_acm+0x020000, 0, 3, mclk_out_sels, ARRAY_SIZE(mclk_out_sels), FUNCTION_NAME(PD_AUD_MCLK_OUT_0)); + clks[IMX8QXP_ACM_MCLKOUT1_SEL] = imx_clk_mux_scu("acm_mclkout1_sel", base_acm+0x030000, 0, 3, mclk_out_sels, ARRAY_SIZE(mclk_out_sels), FUNCTION_NAME(PD_AUD_MCLK_OUT_1)); + clks[IMX8QXP_ACM_ASRC0_MUX_CLK_SEL] = imx_clk_mux_scu("acm_asrc0_mclk_sel", base_acm+0x040000, 0, 2, NULL, 0, FUNCTION_NAME(PD_AUD_ASRC_0)); + clks[IMX8QXP_ACM_ASRC0_MUX_CLK_CLK] = imx_clk_gate_scu("aud_asrc0_mux_clk", "acm_asrc0_mclk_sel", SC_R_ASRC_0, SC_PM_CLK_PER, NULL, 0, 0); + clks[IMX8QXP_ACM_ASRC1_MUX_CLK_SEL] = imx_clk_mux_scu("acm_asrc1_mclk_sel", base_acm+0x050000, 0, 2, NULL, 0, FUNCTION_NAME(PD_AUD_ASRC_1)); + clks[IMX8QXP_ACM_ASRC1_MUX_CLK_CLK] = imx_clk_gate_scu("aud_asrc1_mux_clk", "acm_asrc1_mclk_sel", SC_R_ASRC_1, SC_PM_CLK_PER, NULL, 0, 0); + clks[IMX8QXP_ACM_ESAI0_MCLK_SEL] = imx_clk_mux_scu("acm_esai0_mclk_sel", base_acm+0x060000, 0, 2, esai_mclk_sels, ARRAY_SIZE(esai_mclk_sels), FUNCTION_NAME(PD_AUD_ESAI_0)); + clks[IMX8QXP_ACM_SAI0_MCLK_SEL] = imx_clk_mux_scu("acm_sai0_mclk_sel", base_acm+0x0E0000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_0)); + clks[IMX8QXP_ACM_SAI1_MCLK_SEL] = imx_clk_mux_scu("acm_sai1_mclk_sel", base_acm+0x0F0000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_1)); + clks[IMX8QXP_ACM_SAI2_MCLK_SEL] = imx_clk_mux_scu("acm_sai2_mclk_sel", base_acm+0x100000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_2)); + clks[IMX8QXP_ACM_SAI3_MCLK_SEL] = imx_clk_mux_scu("acm_sai3_mclk_sel", base_acm+0x110000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_3)); + clks[IMX8QXP_ACM_SAI4_MCLK_SEL] = imx_clk_mux_scu("acm_sai4_mclk_sel", base_acm+0x140000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_4)); + clks[IMX8QXP_ACM_SAI5_MCLK_SEL] = imx_clk_mux_scu("acm_sai5_mclk_sel", base_acm+0x150000, 0, 2, sai_mclk_sels, ARRAY_SIZE(sai_mclk_sels), FUNCTION_NAME(PD_AUD_SAI_5)); + clks[IMX8QXP_ACM_SPDIF0_TX_CLK_SEL] = imx_clk_mux_scu("acm_spdif0_mclk_sel", base_acm+0x1A0000, 0, 2, spdif_mclk_sels, ARRAY_SIZE(spdif_mclk_sels), FUNCTION_NAME(PD_AUD_SPDIF_0)); + clks[IMX8QXP_ACM_MQS_TX_CLK_SEL] = imx_clk_mux_scu("acm_mqs_mclk_sel", base_acm+0x1C0000, 0, 2, mqs_mclk_sels, ARRAY_SIZE(mqs_mclk_sels), FUNCTION_NAME(PD_AUD_MQS_0)); + + clks[IMX8QXP_AUD_AMIX_IPG] = imx_clk_gate2_scu("aud_amix_ipg_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_AMIX_LPCG), 0, FUNCTION_NAME(PD_AUD_AMIX)); + clks[IMX8QXP_AUD_ESAI_0_IPG] = imx_clk_gate2_scu("aud_esai0_ipg_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_ESAI_0_LPCG), 16, FUNCTION_NAME(PD_AUD_ESAI_0)); + clks[IMX8QXP_AUD_ESAI_0_EXTAL_IPG] = imx_clk_gate2_scu("aud_esai0_extal_clk", "acm_esai0_mclk_sel", (void __iomem *)(AUD_ESAI_0_LPCG), 0, FUNCTION_NAME(PD_AUD_ESAI_0)); + clks[IMX8QXP_AUD_SAI_0_IPG] = imx_clk_gate2_scu("aud_sai0_ipg_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_SAI_0_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_0)); + clks[IMX8QXP_AUD_SAI_0_MCLK] = imx_clk_gate2_scu("aud_sai0_mclk_clk", "acm_sai0_mclk_sel", (void __iomem *)(AUD_SAI_0_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_0)); + clks[IMX8QXP_AUD_SAI_1_IPG] = imx_clk_gate2_scu("aud_sai1_ipg_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_SAI_1_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_1)); + clks[IMX8QXP_AUD_SAI_1_MCLK] = imx_clk_gate2_scu("aud_sai1_mclk_clk", "acm_sai1_mclk_sel", (void __iomem *)(AUD_SAI_1_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_1)); + clks[IMX8QXP_AUD_SAI_2_IPG] = imx_clk_gate2_scu("aud_sai2_ipg_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_SAI_2_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_2)); + clks[IMX8QXP_AUD_SAI_2_MCLK] = imx_clk_gate2_scu("aud_sai2_mclk_clk", "acm_sai2_mclk_sel", (void __iomem *)(AUD_SAI_2_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_2)); + clks[IMX8QXP_AUD_SAI_3_IPG] = imx_clk_gate2_scu("aud_sai3_ipg_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_SAI_3_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_3)); + clks[IMX8QXP_AUD_SAI_3_MCLK] = imx_clk_gate2_scu("aud_sai3_mclk_clk", "acm_sai3_mclk_sel", (void __iomem *)(AUD_SAI_3_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_3)); + clks[IMX8QXP_AUD_SAI_4_IPG] = imx_clk_gate2_scu("aud_sai4_ipg_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_SAI_4_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_4)); + clks[IMX8QXP_AUD_SAI_4_MCLK] = imx_clk_gate2_scu("aud_sai4_mclk_clk", "acm_sai4_mclk_sel", (void __iomem *)(AUD_SAI_4_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_4)); + clks[IMX8QXP_AUD_SAI_5_IPG] = imx_clk_gate2_scu("aud_sai5_ipg_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_SAI_5_LPCG), 16, FUNCTION_NAME(PD_AUD_SAI_5)); + clks[IMX8QXP_AUD_SAI_5_MCLK] = imx_clk_gate2_scu("aud_sai5_mclk_clk", "acm_sai5_mclk_sel", (void __iomem *)(AUD_SAI_5_LPCG), 0, FUNCTION_NAME(PD_AUD_SAI_5)); + clks[IMX8QXP_AUD_MQS_IPG] = imx_clk_gate2_scu("aud_mqs_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_MQS_LPCG), 16, FUNCTION_NAME(PD_AUD_MQS_0)); + clks[IMX8QXP_AUD_MQS_HMCLK] = imx_clk_gate2_scu("aud_mqs_hm_clk", "acm_mqs_mclk_sel", (void __iomem *)(AUD_MQS_LPCG), 0, FUNCTION_NAME(PD_AUD_MQS_0)); + clks[IMX8QXP_AUD_GPT5_IPG] = imx_clk_gate2_scu("aud_gpt5_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_5_LPCG), 16, FUNCTION_NAME(PD_AUD_GPT_5)); + clks[IMX8QXP_AUD_GPT5_CLKIN] = imx_clk_gate2_scu("aud_gpt5_clkin", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_5_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_5)); + clks[IMX8QXP_AUD_GPT6_IPG] = imx_clk_gate2_scu("aud_gpt6_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_6_LPCG), 16, FUNCTION_NAME(PD_AUD_GPT_6)); + clks[IMX8QXP_AUD_GPT6_CLKIN] = imx_clk_gate2_scu("aud_gpt6_clkin", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_6_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_6)); + clks[IMX8QXP_AUD_GPT7_IPG] = imx_clk_gate2_scu("aud_gpt7_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_7_LPCG), 16, FUNCTION_NAME(PD_AUD_GPT_7)); + clks[IMX8QXP_AUD_GPT7_CLKIN] = imx_clk_gate2_scu("aud_gpt7_clkin", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_7_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_7)); + clks[IMX8QXP_AUD_GPT8_IPG] = imx_clk_gate2_scu("aud_gpt8_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_8_LPCG), 16, FUNCTION_NAME(PD_AUD_GPT_8)); + clks[IMX8QXP_AUD_GPT8_CLKIN] = imx_clk_gate2_scu("aud_gpt8_clkin", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_8_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_8)); + clks[IMX8QXP_AUD_GPT9_IPG] = imx_clk_gate2_scu("aud_gpt9_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_9_LPCG), 16, FUNCTION_NAME(PD_AUD_GPT_9)); + clks[IMX8QXP_AUD_GPT9_CLKIN] = imx_clk_gate2_scu("aud_gpt9_clkin", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_9_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_9)); + clks[IMX8QXP_AUD_GPT10_IPG] = imx_clk_gate2_scu("aud_gpt10_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_10_LPCG), 16, FUNCTION_NAME(PD_AUD_GPT_10)); + clks[IMX8QXP_AUD_GPT10_CLKIN] = imx_clk_gate2_scu("aud_gpt10_clkin", "ipg_aud_clk_root", (void __iomem *)(AUD_GPT_10_LPCG), 0, FUNCTION_NAME(PD_AUD_GPT_10)); + clks[IMX8QXP_AUD_MCLKOUT0] = imx_clk_gate2_scu("aud_mclkout0", "acm_mclkout0_sel", (void __iomem *)(AUD_MCLKOUT0_LPCG), 0, FUNCTION_NAME(PD_AUD_MCLK_OUT_0)); + clks[IMX8QXP_AUD_MCLKOUT1] = imx_clk_gate2_scu("aud_mclkout1", "acm_mclkout1_sel", (void __iomem *)(AUD_MCLKOUT1_LPCG), 0, FUNCTION_NAME(PD_AUD_MCLK_OUT_1)); + clks[IMX8QXP_AUD_SPDIF_0_GCLKW] = imx_clk_gate2_scu("spdif0_gclkw", "ipg_aud_clk_root", (void __iomem *)(AUD_SPDIF_0_LPCG), 16, FUNCTION_NAME(PD_AUD_SPDIF_0)); + clks[IMX8QXP_AUD_SPDIF_0_TX_CLK] = imx_clk_gate2_scu("spdif0_tx_clk", "acm_spdif0_mclk_sel", (void __iomem *)(AUD_SPDIF_0_LPCG), 0, FUNCTION_NAME(PD_AUD_SPDIF_0)); + clks[IMX8QXP_AUD_ASRC_0_IPG] = imx_clk_gate2_scu("aud_asrc0_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_ASRC_0_LPCG), 16, FUNCTION_NAME(PD_AUD_ASRC_0)); + clks[IMX8QXP_AUD_ASRC_1_IPG] = imx_clk_gate2_scu("aud_asrc1_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_ASRC_1_LPCG), 16, FUNCTION_NAME(PD_AUD_ASRC_1)); + clks[IMX8QXP_AUD_DSP_ADB_ACLK] = imx_clk_gate2_scu("aud_dsp_adb_aclk", "ipg_aud_clk_root", (void __iomem *)(AUD_DSP_LPCG), 16, FUNCTION_NAME(PD_AUD_DSP)); + clks[IMX8QXP_AUD_DSP_IPG] = imx_clk_gate2_scu("aud_dsp_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_DSP_LPCG), 20, FUNCTION_NAME(PD_AUD_DSP)); + clks[IMX8QXP_AUD_DSP_CORE_CLK] = imx_clk_gate2_scu("aud_dsp_core_clk", "ipg_aud_clk_root", (void __iomem *)(AUD_DSP_LPCG), 28, FUNCTION_NAME(PD_AUD_DSP)); + clks[IMX8QXP_AUD_OCRAM_IPG] = imx_clk_gate2_scu("aud_ocram_ipg", "ipg_aud_clk_root", (void __iomem *)(AUD_OCRAM_LPCG), 16, FUNCTION_NAME(PD_AUD_OCRAM)); + }; + + for (i = 0; i < ARRAY_SIZE(clks); i++) + if (IS_ERR(clks[i]) && PTR_ERR(clks[i]) != -ENODEV) + pr_err("i.MX8QXP clk %d: register failed with %ld\n", + i, PTR_ERR(clks[i])); + + clk_data.clks = clks; + clk_data.clk_num = ARRAY_SIZE(clks); + of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data); + + return 0; +} + +static const struct of_device_id imx8qxp_match[] = { + { .compatible = "fsl,imx8qxp-clk", }, + { /* sentinel value */ } +}; + +static struct platform_driver imx8qxp_clk_driver = { + .driver = { + .name = "imx8qxp-clk", + .of_match_table = imx8qxp_match, + }, + .probe = imx8qxp_clk_probe, +}; + +static int __init imx8qxp_clk_init(void) +{ + return platform_driver_register(&imx8qxp_clk_driver); +} +core_initcall(imx8qxp_clk_init); diff --git a/drivers/clk/imx/clk-mux-scu.c b/drivers/clk/imx/clk-mux-scu.c new file mode 100644 index 0000000000000000000000000000000000000000..ac1c8bc385bd18bd5e3d39c65d9b01b64375217f --- /dev/null +++ b/drivers/clk/imx/clk-mux-scu.c @@ -0,0 +1,445 @@ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017 NXP + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/clk.h> +#include <linux/clk-provider.h> +#include <linux/err.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/pm_domain.h> +#include <linux/slab.h> +#include <linux/string.h> +#include <soc/imx8/sc/sci.h> + +#include "clk-imx8.h" + +/* + * DOC: basic adjustable multiplexer clock that cannot gate + * + * Traits of this clock: + * prepare - clk_prepare only ensures that parents are prepared + * enable - clk_enable only ensures that parents are enabled + * rate - rate is only affected by parent switching. No clk_set_rate support + * parent - parent is adjustable through clk_set_parent + */ + +struct clk_mux_scu { + struct clk_hw hw; + void __iomem *reg; + u32 *table; + u32 mask; + u8 shift; + u8 flags; + u32 val; + bool update; + spinlock_t *lock; + char *pd_name; + struct generic_pm_domain *pd; +}; + +struct clk_mux_gpr_scu { + struct clk_hw hw; + sc_rsrc_t rsrc_id; + sc_ctrl_t gpr_id; +}; + +struct clk_mux2_scu { + struct clk_hw hw; + sc_rsrc_t rsrc_id; + sc_pm_clk_t clk_type; +}; + +#define to_clk_mux_scu(_hw) container_of(_hw, struct clk_mux_scu, hw) +#define to_clk_mux_gpr_scu(_hw) container_of(_hw, struct clk_mux_gpr_scu, hw) +#define to_clk_mux2_scu(_hw) container_of(_hw, struct clk_mux2_scu, hw) + +/* Get the power domain associated with the clock from the device tree. */ +static void populate_mux_pd(struct clk_mux_scu *clk) +{ + struct device_node *np; + struct of_phandle_args pd_args; + + np = of_find_node_by_name(NULL, clk->pd_name); + if (np) { + pd_args.np = np; + pd_args.args_count = 0; + clk->pd = genpd_get_from_provider(&pd_args); + if (IS_ERR(clk->pd)) + pr_warn("%s: failed to get pd\n", __func__); + } +} + +static int check_mux_pd(struct clk_mux_scu *mux) +{ + if (!ccm_ipc_handle) + return -1; + + if (mux->pd == NULL && mux->pd_name) + populate_mux_pd(mux); + + if (IS_ERR_OR_NULL(mux->pd)) + return -1; + + if (mux->pd->status != GPD_STATE_ACTIVE) + return -1; + + return 0; +} + +static u8 clk_mux_get_parent_scu(struct clk_hw *hw) +{ + struct clk_mux_scu *mux = to_clk_mux_scu(hw); + int num_parents = clk_hw_get_num_parents(hw); + u32 val; + + /* + * FIXME need a mux-specific flag to determine if val is bitwise or numeric + * e.g. sys_clkin_ck's clksel field is 3 bits wide, but ranges from 0x1 + * to 0x7 (index starts at one) + * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so + * val = 0x4 really means "bit 2, index starts at bit 0" + */ + val = mux->val >> mux->shift; + val &= mux->mask; + + if (mux->table) { + int i; + + for (i = 0; i < num_parents; i++) + if (mux->table[i] == val) + return i; + return -EINVAL; + } + + if (val && (mux->flags & CLK_MUX_INDEX_BIT)) + val = ffs(val) - 1; + + if (val && (mux->flags & CLK_MUX_INDEX_ONE)) + val--; + + if (val >= num_parents) + return -EINVAL; + + return val; +} + +static int clk_mux_prepare_scu(struct clk_hw *hw) +{ + struct clk_mux_scu *mux = to_clk_mux_scu(hw); + unsigned long flags = 0; + int ret; + + ret = check_mux_pd(mux); + if (ret) + return ret; + + if (mux->lock) + spin_lock_irqsave(mux->lock, flags); + + if (mux->update) { + clk_writel(mux->val, mux->reg); + mux->update = 0; + } + + if (mux->lock) + spin_unlock_irqrestore(mux->lock, flags); + + return 0; +} + +static int clk_mux_set_parent_scu(struct clk_hw *hw, u8 index) +{ + struct clk_mux_scu *mux = to_clk_mux_scu(hw); + unsigned long flags = 0; + int ret; + + ret = check_mux_pd(mux); + + if (mux->table) { + index = mux->table[index]; + } else { + if (mux->flags & CLK_MUX_INDEX_BIT) + index = 1 << index; + if (mux->flags & CLK_MUX_INDEX_ONE) + index++; + } + + if (mux->lock) + spin_lock_irqsave(mux->lock, flags); + + if (mux->flags & CLK_MUX_HIWORD_MASK) { + mux->val = mux->mask << (mux->shift + 16); + } else { + mux->val &= ~(mux->mask << mux->shift); + } + mux->val |= index << mux->shift; + mux->update = (ret != 0); + + if (ret == 0) + clk_writel(mux->val, mux->reg); + + if (mux->lock) + spin_unlock_irqrestore(mux->lock, flags); + + return 0; +} + +const struct clk_ops clk_mux_scu_ops = { + .prepare = clk_mux_prepare_scu, + .get_parent = clk_mux_get_parent_scu, + .set_parent = clk_mux_set_parent_scu, + .determine_rate = __clk_mux_determine_rate, +}; + +const struct clk_ops clk_mux_ro_scu_ops = { + .get_parent = clk_mux_get_parent_scu, +}; + +struct clk *clk_register_mux_table_scu(struct device *dev, const char *name, + const char **parent_names, u8 num_parents, unsigned long flags, + void __iomem *reg, u8 shift, u32 mask, + u8 clk_mux_flags, u32 *table, spinlock_t *lock, + const char *pd_name) +{ + struct clk_mux_scu *mux; + struct clk *clk; + struct clk_init_data init; + u8 width = 0; + + if (clk_mux_flags & CLK_MUX_HIWORD_MASK) { + width = fls(mask) - ffs(mask) + 1; + if (width + shift > 16) { + pr_err("mux value exceeds LOWORD field\n"); + return ERR_PTR(-EINVAL); + } + } + + /* allocate the mux */ + mux = kzalloc(sizeof(struct clk_mux_scu), GFP_KERNEL); + if (!mux) { + pr_err("%s: could not allocate mux clk\n", __func__); + return ERR_PTR(-ENOMEM); + } + + init.name = name; + if (clk_mux_flags & CLK_MUX_READ_ONLY) + init.ops = &clk_mux_ro_scu_ops; + else + init.ops = &clk_mux_scu_ops; + init.flags = flags | CLK_IS_BASIC; + init.parent_names = parent_names; + init.num_parents = num_parents; + + /* struct clk_mux_scu assignments */ + mux->reg = reg; + mux->shift = shift; + mux->mask = mask; + mux->flags = clk_mux_flags; + mux->lock = lock; + mux->table = table; + mux->hw.init = &init; + mux->pd_name = NULL; + if (pd_name) { + mux->pd_name = kzalloc(strlen(pd_name) + 1, GFP_KERNEL); + strcpy(mux->pd_name, pd_name); + } + + clk = clk_register(dev, &mux->hw); + + if (IS_ERR(clk)) { + kfree(mux->pd_name); + kfree(mux); + } + + return clk; +} + +struct clk *clk_register_mux_scu(struct device *dev, const char *name, + const char **parent_names, u8 num_parents, unsigned long flags, + void __iomem *reg, u8 shift, u8 width, + u8 clk_mux_flags, spinlock_t *lock, + const char *pd_name) +{ + u32 mask = BIT(width) - 1; + + return clk_register_mux_table_scu(dev, name, parent_names, num_parents, + flags, reg, shift, mask, clk_mux_flags, + NULL, lock, pd_name); +} + +void clk_unregister_mux_scu(struct clk *clk) +{ + struct clk_mux_scu *mux; + struct clk_hw *hw; + + hw = __clk_get_hw(clk); + if (!hw) + return; + + mux = to_clk_mux_scu(hw); + + clk_unregister(clk); + kfree(mux); +} + +static u8 clk_mux_gpr_scu_get_parent(struct clk_hw *hw) +{ + struct clk_mux_gpr_scu *gpr_mux = to_clk_mux_gpr_scu(hw); + u32 val = 0; + + if (!ccm_ipc_handle) + return 0; + + sc_misc_get_control(ccm_ipc_handle, + gpr_mux->rsrc_id, gpr_mux->gpr_id, &val); + + return (u8)val; +} + +static int clk_mux_gpr_scu_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_mux_gpr_scu *gpr_mux = to_clk_mux_gpr_scu(hw); + + if (!ccm_ipc_handle) + return -1; + + sc_misc_set_control(ccm_ipc_handle, + gpr_mux->rsrc_id, gpr_mux->gpr_id, index); + + return 0; +} + +static const struct clk_ops clk_mux_gpr_scu_ops = { + .get_parent = clk_mux_gpr_scu_get_parent, + .set_parent = clk_mux_gpr_scu_set_parent, +}; + +struct clk *clk_register_mux_gpr_scu(struct device *dev, const char *name, + const char **parents, int num_parents, spinlock_t *lock, + sc_rsrc_t rsrc_id, sc_ctrl_t gpr_id) +{ + struct clk_mux_gpr_scu *gpr_scu_mux; + struct clk *clk; + struct clk_init_data init; + + if (!imx8_clk_is_resource_owned(rsrc_id)) { + pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id); + return ERR_PTR(-ENODEV); + } + + if (rsrc_id >= SC_R_LAST) + return NULL; + + if (gpr_id >= SC_C_LAST) + return NULL; + + gpr_scu_mux = kzalloc(sizeof(struct clk_mux_gpr_scu), GFP_KERNEL); + if (!gpr_scu_mux) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &clk_mux_gpr_scu_ops; + init.parent_names = parents; + init.num_parents = num_parents; + init.flags |= CLK_SET_PARENT_NOCACHE; + + gpr_scu_mux->hw.init = &init; + gpr_scu_mux->rsrc_id = rsrc_id; + gpr_scu_mux->gpr_id = gpr_id; + + clk = clk_register(NULL, &gpr_scu_mux->hw); + if (IS_ERR(clk)) + kfree(gpr_scu_mux); + + return clk; +} + +static u8 clk_mux2_scu_get_parent(struct clk_hw *hw) +{ + struct clk_mux2_scu *mux = to_clk_mux2_scu(hw); + sc_pm_clk_parent_t parent; + sc_err_t ret; + + if (!ccm_ipc_handle) + return -EBUSY; + + ret = sc_pm_get_clock_parent(ccm_ipc_handle, mux->rsrc_id, + mux->clk_type, &parent); + if (ret != SC_ERR_NONE) + return -EINVAL; + + return (u8)parent; +} + +static int clk_mux2_scu_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_mux2_scu *mux = to_clk_mux2_scu(hw); + sc_err_t ret; + + if (!ccm_ipc_handle) + return -EBUSY; + + ret = sc_pm_set_clock_parent(ccm_ipc_handle, mux->rsrc_id, + mux->clk_type, index); + if (ret != SC_ERR_NONE) + return -EINVAL; + + return 0; +} + +static const struct clk_ops clk_mux2_scu_ops = { + .get_parent = clk_mux2_scu_get_parent, + .set_parent = clk_mux2_scu_set_parent, +}; + + +struct clk *clk_register_mux2_scu(struct device *dev, const char *name, + const char **parents, int num_parents, + unsigned long flags, sc_rsrc_t rsrc_id, + sc_pm_clk_t clk_type) +{ + struct clk_mux2_scu *mux; + struct clk *clk; + struct clk_init_data init; + + if (!imx8_clk_is_resource_owned(rsrc_id)) { + pr_debug("skip clk %s rsrc %d not owned\n", name, rsrc_id); + return ERR_PTR(-ENODEV); + } + + if (rsrc_id >= SC_R_LAST) + return ERR_PTR(-EINVAL); + + mux = kzalloc(sizeof(struct clk_mux2_scu), GFP_KERNEL); + if (!mux) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &clk_mux2_scu_ops; + init.parent_names = parents; + init.num_parents = num_parents; + init.flags = flags |= CLK_SET_PARENT_NOCACHE; + + mux->hw.init = &init; + mux->rsrc_id = rsrc_id; + mux->clk_type = clk_type; + + clk = clk_register(NULL, &mux->hw); + if (IS_ERR(clk)) + kfree(mux); + + return clk; +} diff --git a/include/dt-bindings/clock/imx8qxp-clock.h b/include/dt-bindings/clock/imx8qxp-clock.h new file mode 100644 index 0000000000000000000000000000000000000000..6316d5a717804c297207cd613cd19da110d01c76 --- /dev/null +++ b/include/dt-bindings/clock/imx8qxp-clock.h @@ -0,0 +1,597 @@ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __DT_BINDINGS_CLOCK_IMX8QXP_H +#define __DT_BINDINGS_CLOCK_IMX8QXP_H + +#define IMX8QXP_CLK_DUMMY 0 + +#define IMX8QXP_UART0_IPG_CLK 1 +#define IMX8QXP_UART0_DIV 2 +#define IMX8QXP_UART0_CLK 3 + +#define IMX8QXP_IPG_DMA_CLK_ROOT 4 + +/* GPU Clocks. */ +#define IMX8QXP_GPU0_CORE_DIV 5 +#define IMX8QXP_GPU0_CORE_CLK 6 +#define IMX8QXP_GPU0_SHADER_DIV 7 +#define IMX8QXP_GPU0_SHADER_CLK 8 + +#define IMX8QXP_24MHZ 9 +#define IMX8QXP_GPT_3M 10 +#define IMX8QXP_32KHZ 11 + +/* LSIO SS */ +#define IMX8QXP_LSIO_MEM_CLK 12 +#define IMX8QXP_LSIO_BUS_CLK 13 +#define IMX8QXP_LSIO_PWM0_DIV 14 +#define IMX8QXP_LSIO_PWM0_IPG_S_CLK 15 +#define IMX8QXP_LSIO_PWM0_IPG_SLV_CLK 16 +#define IMX8QXP_LSIO_PWM0_IPG_MSTR_CLK 17 +#define IMX8QXP_LSIO_PWM0_HF_CLK 18 +#define IMX8QXP_LSIO_PWM0_CLK 19 +#define IMX8QXP_LSIO_PWM1_DIV 20 +#define IMX8QXP_LSIO_PWM1_IPG_S_CLK 21 +#define IMX8QXP_LSIO_PWM1_IPG_SLV_CLK 22 +#define IMX8QXP_LSIO_PWM1_IPG_MSTR_CLK 23 +#define IMX8QXP_LSIO_PWM1_HF_CLK 24 +#define IMX8QXP_LSIO_PWM1_CLK 25 +#define IMX8QXP_LSIO_PWM2_DIV 26 +#define IMX8QXP_LSIO_PWM2_IPG_S_CLK 27 +#define IMX8QXP_LSIO_PWM2_IPG_SLV_CLK 28 +#define IMX8QXP_LSIO_PWM2_IPG_MSTR_CLK 29 +#define IMX8QXP_LSIO_PWM2_HF_CLK 30 +#define IMX8QXP_LSIO_PWM2_CLK 31 +#define IMX8QXP_LSIO_PWM3_DIV 32 +#define IMX8QXP_LSIO_PWM3_IPG_S_CLK 33 +#define IMX8QXP_LSIO_PWM3_IPG_SLV_CLK 34 +#define IMX8QXP_LSIO_PWM3_IPG_MSTR_CLK 35 +#define IMX8QXP_LSIO_PWM3_HF_CLK 36 +#define IMX8QXP_LSIO_PWM3_CLK 37 +#define IMX8QXP_LSIO_PWM4_DIV 38 +#define IMX8QXP_LSIO_PWM4_IPG_S_CLK 39 +#define IMX8QXP_LSIO_PWM4_IPG_SLV_CLK 40 +#define IMX8QXP_LSIO_PWM4_IPG_MSTR_CLK 42 +#define IMX8QXP_LSIO_PWM4_HF_CLK 43 +#define IMX8QXP_LSIO_PWM4_CLK 44 +#define IMX8QXP_LSIO_PWM5_DIV 45 +#define IMX8QXP_LSIO_PWM5_IPG_S_CLK 46 +#define IMX8QXP_LSIO_PWM5_IPG_SLV_CLK 47 +#define IMX8QXP_LSIO_PWM5_IPG_MSTR_CLK 48 +#define IMX8QXP_LSIO_PWM5_HF_CLK 49 +#define IMX8QXP_LSIO_PWM5_CLK 50 +#define IMX8QXP_LSIO_PWM6_DIV 51 +#define IMX8QXP_LSIO_PWM6_IPG_S_CLK 52 +#define IMX8QXP_LSIO_PWM6_IPG_SLV_CLK 53 +#define IMX8QXP_LSIO_PWM6_IPG_MSTR_CLK 54 +#define IMX8QXP_LSIO_PWM6_HF_CLK 55 +#define IMX8QXP_LSIO_PWM6_CLK 56 +#define IMX8QXP_LSIO_PWM7_DIV 57 +#define IMX8QXP_LSIO_PWM7_IPG_S_CLK 58 +#define IMX8QXP_LSIO_PWM7_IPG_SLV_CLK 59 +#define IMX8QXP_LSIO_PWM7_IPG_MSTR_CLK 60 +#define IMX8QXP_LSIO_PWM7_HF_CLK 61 +#define IMX8QXP_LSIO_PWM7_CLK 62 +#define IMX8QXP_LSIO_GPT0_DIV 63 +#define IMX8QXP_LSIO_GPT0_IPG_S_CLK 64 +#define IMX8QXP_LSIO_GPT0_IPG_SLV_CLK 65 +#define IMX8QXP_LSIO_GPT0_IPG_MSTR_CLK 66 +#define IMX8QXP_LSIO_GPT0_HF_CLK 67 +#define IMX8QXP_LSIO_GPT0_CLK 68 +#define IMX8QXP_LSIO_GPT1_DIV 69 +#define IMX8QXP_LSIO_GPT1_IPG_S_CLK 70 +#define IMX8QXP_LSIO_GPT1_IPG_SLV_CLK 71 +#define IMX8QXP_LSIO_GPT1_IPG_MSTR_CLK 72 +#define IMX8QXP_LSIO_GPT1_HF_CLK 73 +#define IMX8QXP_LSIO_GPT1_CLK 74 +#define IMX8QXP_LSIO_GPT2_DIV 75 +#define IMX8QXP_LSIO_GPT2_IPG_S_CLK 76 +#define IMX8QXP_LSIO_GPT2_IPG_SLV_CLK 77 +#define IMX8QXP_LSIO_GPT2_IPG_MSTR_CLK 78 +#define IMX8QXP_LSIO_GPT2_HF_CLK 79 +#define IMX8QXP_LSIO_GPT2_CLK 80 +#define IMX8QXP_LSIO_GPT3_DIV 81 +#define IMX8QXP_LSIO_GPT3_IPG_S_CLK 82 +#define IMX8QXP_LSIO_GPT3_IPG_SLV_CLK 83 +#define IMX8QXP_LSIO_GPT3_IPG_MSTR_CLK 84 +#define IMX8QXP_LSIO_GPT3_HF_CLK 85 +#define IMX8QXP_LSIO_GPT3_CLK 86 +#define IMX8QXP_LSIO_GPT4_DIV 87 +#define IMX8QXP_LSIO_GPT4_IPG_S_CLK 88 +#define IMX8QXP_LSIO_GPT4_IPG_SLV_CLK 89 +#define IMX8QXP_LSIO_GPT4_IPG_MSTR_CLK 90 +#define IMX8QXP_LSIO_GPT4_HF_CLK 91 +#define IMX8QXP_LSIO_GPT4_CLK 92 +#define IMX8QXP_LSIO_FSPI0_DIV 93 +#define IMX8QXP_LSIO_FSPI0_HCLK 94 +#define IMX8QXP_LSIO_FSPI0_IPG_S_CLK 95 +#define IMX8QXP_LSIO_FSPI0_IPG_CLK 96 +#define IMX8QXP_LSIO_FSPI0_CLK 97 +#define IMX8QXP_LSIO_FSPI1_DIV 98 +#define IMX8QXP_LSIO_FSPI1_HCLK 99 +#define IMX8QXP_LSIO_FSPI1_IPG_S_CLK 100 +#define IMX8QXP_LSIO_FSPI1_IPG_CLK 101 +#define IMX8QXP_LSIO_FSPI1_CLK 102 +#define IMX8QXP_LSIO_GPIO0_IPG_S_CLK 103 +#define IMX8QXP_LSIO_GPIO1_IPG_S_CLK 104 +#define IMX8QXP_LSIO_GPIO2_IPG_S_CLK 105 +#define IMX8QXP_LSIO_GPIO3_IPG_S_CLK 106 +#define IMX8QXP_LSIO_GPIO4_IPG_S_CLK 107 +#define IMX8QXP_LSIO_GPIO5_IPG_S_CLK 108 +#define IMX8QXP_LSIO_GPIO6_IPG_S_CLK 109 +#define IMX8QXP_LSIO_GPIO7_IPG_S_CLK 110 +#define IMX8QXP_LSIO_ROMCP_REG_CLK 111 +#define IMX8QXP_LSIO_ROMCP_CLK 112 +#define IMX8QXP_LSIO_96KROM_CLK 113 +#define IMX8QXP_LSIO_OCRAM_MEM_CLK 114 +#define IMX8QXP_LSIO_OCRAM_CTRL_CLK 115 + +/* ADMA SS */ +#define IMX8QXP_UART1_IPG_CLK 116 +#define IMX8QXP_UART2_IPG_CLK 117 +#define IMX8QXP_UART3_IPG_CLK 118 +#define IMX8QXP_UART1_DIV 119 +#define IMX8QXP_UART2_DIV 120 +#define IMX8QXP_UART3_DIV 121 +#define IMX8QXP_UART1_CLK 122 +#define IMX8QXP_UART2_CLK 123 +#define IMX8QXP_UART3_CLK 124 +#define IMX8QXP_SPI0_IPG_CLK 125 +#define IMX8QXP_SPI1_IPG_CLK 126 +#define IMX8QXP_SPI2_IPG_CLK 127 +#define IMX8QXP_SPI3_IPG_CLK 128 +#define IMX8QXP_SPI0_DIV 129 +#define IMX8QXP_SPI1_DIV 130 +#define IMX8QXP_SPI2_DIV 131 +#define IMX8QXP_SPI3_DIV 132 +#define IMX8QXP_SPI0_CLK 133 +#define IMX8QXP_SPI1_CLK 134 +#define IMX8QXP_SPI2_CLK 135 +#define IMX8QXP_SPI3_CLK 136 +#define IMX8QXP_CAN0_IPG_CHI_CLK 137 +#define IMX8QXP_CAN1_IPG_CHI_CLK 138 +#define IMX8QXP_CAN2_IPG_CHI_CLK 139 +#define IMX8QXP_CAN0_IPG_CLK 140 +#define IMX8QXP_CAN1_IPG_CLK 141 +#define IMX8QXP_CAN2_IPG_CLK 142 +#define IMX8QXP_CAN0_DIV 143 +#define IMX8QXP_CAN1_DIV 144 +#define IMX8QXP_CAN2_DIV 145 +#define IMX8QXP_CAN0_CLK 146 +#define IMX8QXP_CAN1_CLK 147 +#define IMX8QXP_CAN2_CLK 148 +#define IMX8QXP_I2C0_IPG_CLK 149 +#define IMX8QXP_I2C1_IPG_CLK 150 +#define IMX8QXP_I2C2_IPG_CLK 151 +#define IMX8QXP_I2C3_IPG_CLK 152 +#define IMX8QXP_I2C0_DIV 153 +#define IMX8QXP_I2C1_DIV 154 +#define IMX8QXP_I2C2_DIV 155 +#define IMX8QXP_I2C3_DIV 156 +#define IMX8QXP_I2C0_CLK 157 +#define IMX8QXP_I2C1_CLK 158 +#define IMX8QXP_I2C2_CLK 159 +#define IMX8QXP_I2C3_CLK 160 +#define IMX8QXP_FTM0_IPG_CLK 161 +#define IMX8QXP_FTM1_IPG_CLK 162 +#define IMX8QXP_FTM0_DIV 163 +#define IMX8QXP_FTM1_DIV 164 +#define IMX8QXP_FTM0_CLK 165 +#define IMX8QXP_FTM1_CLK 166 +#define IMX8QXP_ADC0_IPG_CLK 167 +#define IMX8QXP_ADC0_DIV 168 +#define IMX8QXP_ADC0_CLK 169 +#define IMX8QXP_PWM_IPG_CLK 170 +#define IMX8QXP_PWM_DIV 171 +#define IMX8QXP_PWM_CLK 172 +#define IMX8QXP_LCD_IPG_CLK 173 +#define IMX8QXP_LCD_DIV 174 +#define IMX8QXP_LCD_CLK 175 + +/* Connectivity SS */ +#define IMX8QXP_AXI_CONN_CLK_ROOT 176 +#define IMX8QXP_AHB_CONN_CLK_ROOT 177 +#define IMX8QXP_IPG_CONN_CLK_ROOT 178 +#define IMX8QXP_SDHC0_IPG_CLK 179 +#define IMX8QXP_SDHC1_IPG_CLK 180 +#define IMX8QXP_SDHC2_IPG_CLK 181 +#define IMX8QXP_SDHC0_DIV 182 +#define IMX8QXP_SDHC1_DIV 183 +#define IMX8QXP_SDHC2_DIV 184 +#define IMX8QXP_SDHC0_CLK 185 +#define IMX8QXP_SDHC1_CLK 186 +#define IMX8QXP_SDHC2_CLK 187 +#define IMX8QXP_ENET0_ROOT_DIV 188 +#define IMX8QXP_ENET0_REF_DIV 189 +#define IMX8QXP_ENET1_REF_DIV 190 +#define IMX8QXP_ENET0_BYPASS_DIV 191 +#define IMX8QXP_ENET0_RGMII_DIV 192 +#define IMX8QXP_ENET1_ROOT_DIV 193 +#define IMX8QXP_ENET1_BYPASS_DIV 194 +#define IMX8QXP_ENET1_RGMII_DIV 195 +#define IMX8QXP_ENET0_AHB_CLK 196 +#define IMX8QXP_ENET0_IPG_S_CLK 197 +#define IMX8QXP_ENET0_IPG_CLK 198 +#define IMX8QXP_ENET1_AHB_CLK 199 +#define IMX8QXP_ENET1_IPG_S_CLK 200 +#define IMX8QXP_ENET1_IPG_CLK 201 +#define IMX8QXP_ENET0_ROOT_CLK 202 +#define IMX8QXP_ENET1_ROOT_CLK 203 +#define IMX8QXP_ENET0_TX_CLK 204 +#define IMX8QXP_ENET1_TX_CLK 205 +#define IMX8QXP_ENET0_PTP_CLK 206 +#define IMX8QXP_ENET1_PTP_CLK 207 +#define IMX8QXP_ENET0_REF_25MHZ_125MHZ_SEL 208 +#define IMX8QXP_ENET1_REF_25MHZ_125MHZ_SEL 209 +#define IMX8QXP_ENET0_RMII_TX_SEL 210 +#define IMX8QXP_ENET1_RMII_TX_SEL 211 +#define IMX8QXP_ENET0_RGMII_TX_CLK 212 +#define IMX8QXP_ENET1_RGMII_TX_CLK 213 +#define IMX8QXP_ENET0_RMII_RX_CLK 214 +#define IMX8QXP_ENET1_RMII_RX_CLK 215 +#define IMX8QXP_ENET0_REF_25MHZ_125MHZ_CLK 216 +#define IMX8QXP_ENET1_REF_25MHZ_125MHZ_CLK 217 +#define IMX8QXP_ENET0_REF_50MHZ_CLK 218 +#define IMX8QXP_ENET1_REF_50MHZ_CLK 219 +#define IMX8QXP_GPMI_BCH_IO_DIV 220 +#define IMX8QXP_GPMI_BCH_DIV 221 +#define IMX8QXP_GPMI_APB_CLK 222 +#define IMX8QXP_GPMI_APB_BCH_CLK 223 +#define IMX8QXP_GPMI_BCH_IO_CLK 224 +#define IMX8QXP_GPMI_BCH_CLK 225 +#define IMX8QXP_APBHDMA_CLK 226 +#define IMX8QXP_USB3_ACLK_DIV 227 +#define IMX8QXP_USB3_BUS_DIV 228 +#define IMX8QXP_USB3_LPM_DIV 229 +#define IMX8QXP_USB3_IPG_CLK 230 +#define IMX8QXP_USB3_CORE_PCLK 231 +#define IMX8QXP_USB3_PHY_CLK 232 +#define IMX8QXP_USB3_ACLK 233 +#define IMX8QXP_USB3_BUS_CLK 234 +#define IMX8QXP_USB3_LPM_CLK 235 +#define IMX8QXP_USB2_OH_AHB_CLK 236 +#define IMX8QXP_USB2_OH_IPG_S_CLK 237 +#define IMX8QXP_USB2_OH_IPG_S_PL301_CLK 238 +#define IMX8QXP_USB2_PHY_IPG_CLK 239 +#define IMX8QXP_EDMA_CLK 240 +#define IMX8QXP_EDMA_IPG_CLK 241 +#define IMX8QXP_MLB_HCLK 242 +#define IMX8QXP_MLB_CLK 243 +#define IMX8QXP_MLB_IPG_CLK 244 + +/* Display controller SS */ +/* DC part1 */ +#define IMX8QXP_DC_AXI_EXT_CLK 245 +#define IMX8QXP_DC_AXI_INT_CLK 246 +#define IMX8QXP_DC_CFG_CLK 247 +#define IMX8QXP_DC0_DISP0_CLK 248 +#define IMX8QXP_DC0_DISP1_CLK 249 +#define IMX8QXP_DC0_PRG0_RTRAM_CLK 250 +#define IMX8QXP_DC0_PRG0_APB_CLK 251 +#define IMX8QXP_DC0_PRG1_RTRAM_CLK 252 +#define IMX8QXP_DC0_PRG1_APB_CLK 253 +#define IMX8QXP_DC0_PRG2_RTRAM_CLK 254 +#define IMX8QXP_DC0_PRG2_APB_CLK 255 +#define IMX8QXP_DC0_PRG3_RTRAM_CLK 256 +#define IMX8QXP_DC0_PRG3_APB_CLK 257 +#define IMX8QXP_DC0_PRG4_RTRAM_CLK 258 +#define IMX8QXP_DC0_PRG4_APB_CLK 259 +#define IMX8QXP_DC0_PRG5_RTRAM_CLK 260 +#define IMX8QXP_DC0_PRG5_APB_CLK 261 +#define IMX8QXP_DC0_PRG6_RTRAM_CLK 262 +#define IMX8QXP_DC0_PRG6_APB_CLK 263 +#define IMX8QXP_DC0_PRG7_RTRAM_CLK 264 +#define IMX8QXP_DC0_PRG7_APB_CLK 265 +#define IMX8QXP_DC0_PRG8_RTRAM_CLK 266 +#define IMX8QXP_DC0_PRG8_APB_CLK 267 +#define IMX8QXP_DC0_DPR0_APB_CLK 268 +#define IMX8QXP_DC0_DPR0_B_CLK 269 +#define IMX8QXP_DC0_RTRAM0_CLK 270 +#define IMX8QXP_DC0_RTRAM1_CLK 271 + +/* MIPI-LVDS part1 */ +#define IMX8QXP_MIPI_IPG_CLK 272 +#define IMX8QXP_MIPI0_I2C0_DIV 273 +#define IMX8QXP_MIPI0_I2C1_DIV 274 +#define IMX8QXP_MIPI0_I2C0_CLK 275 +#define IMX8QXP_MIPI0_I2C1_CLK 276 +#define IMX8QXP_MIPI0_I2C0_IPG_CLK 278 +#define IMX8QXP_MIPI0_I2C1_IPG_CLK 280 +#define IMX8QXP_MIPI0_PWM_IPG_CLK 282 +#define IMX8QXP_MIPI0_PWM_32K_CLK 283 +#define IMX8QXP_MIPI0_GPIO_IPG_CLK 284 + +#define IMX8QXP_IMG_JPEG_ENC_IPG_CLK 285 +#define IMX8QXP_IMG_JPEG_ENC_CLK 286 +#define IMX8QXP_IMG_JPEG_DEC_IPG_CLK 287 +#define IMX8QXP_IMG_JPEG_DEC_CLK 288 +#define IMX8QXP_IMG_PXL_LINK_DC0_CLK 289 +#define IMX8QXP_IMG_PXL_LINK_DC1_CLK 290 +#define IMX8QXP_IMG_PXL_LINK_CSI0_CLK 291 +#define IMX8QXP_IMG_PXL_LINK_CSI1_CLK 292 +#define IMX8QXP_IMG_PXL_LINK_HDMI_IN_CLK 293 +#define IMX8QXP_IMG_PDMA_0_CLK 294 +#define IMX8QXP_IMG_PDMA_1_CLK 295 +#define IMX8QXP_IMG_PDMA_2_CLK 296 +#define IMX8QXP_IMG_PDMA_3_CLK 297 +#define IMX8QXP_IMG_PDMA_4_CLK 298 +#define IMX8QXP_IMG_PDMA_5_CLK 299 +#define IMX8QXP_IMG_PDMA_6_CLK 300 +#define IMX8QXP_IMG_PDMA_7_CLK 301 +#define IMX8QXP_IMG_AXI_CLK 302 +#define IMX8QXP_IMG_IPG_CLK 303 +#define IMX8QXP_IMG_PXL_CLK 304 + +#define IMX8QXP_CSI0_I2C0_DIV 305 +#define IMX8QXP_CSI0_PWM0_DIV 306 +#define IMX8QXP_CSI0_CORE_DIV 307 +#define IMX8QXP_CSI0_ESC_DIV 308 +#define IMX8QXP_CSI0_IPG_CLK_S 309 +#define IMX8QXP_CSI0_IPG_CLK 310 +#define IMX8QXP_CSI0_APB_CLK 311 +#define IMX8QXP_CSI0_I2C0_IPG_CLK 312 +#define IMX8QXP_CSI0_I2C0_CLK 313 +#define IMX8QXP_CSI0_PWM0_IPG_CLK 314 +#define IMX8QXP_CSI0_PWM0_CLK 315 +#define IMX8QXP_CSI0_CORE_CLK 316 +#define IMX8QXP_CSI0_ESC_CLK 317 + +#define IMX8QXP_HSIO_AXI_CLK 318 +#define IMX8QXP_HSIO_PER_CLK 319 +#define IMX8QXP_HSIO_PCIE_MSTR_AXI_CLK 320 +#define IMX8QXP_HSIO_PCIE_SLV_AXI_CLK 321 +#define IMX8QXP_HSIO_PCIE_DBI_AXI_CLK 322 +#define IMX8QXP_HSIO_PCIE_X1_PER_CLK 323 +#define IMX8QXP_HSIO_PHY_X1_PER_CLK 324 +#define IMX8QXP_HSIO_MISC_PER_CLK 325 +#define IMX8QXP_HSIO_PHY_X1_APB_CLK 326 +#define IMX8QXP_HSIO_GPIO_CLK 327 +#define IMX8QXP_HSIO_PHY_X1_PCLK 328 + +#define IMX8QXP_A35_DIV 329 + +/* ACM */ +#define IMX8QXP_EXT_AUD_MCLK0 330 +#define IMX8QXP_EXT_AUD_MCLK1 331 +#define IMX8QXP_ESAI0_RX_CLK 332 +#define IMX8QXP_ESAI0_RX_HF_CLK 333 +#define IMX8QXP_ESAI0_TX_CLK 334 +#define IMX8QXP_ESAI0_TX_HF_CLK 335 +#define IMX8QXP_SPDIF0_RX 336 +#define IMX8QXP_SAI0_RX_BCLK 337 +#define IMX8QXP_SAI0_TX_BCLK 338 +#define IMX8QXP_SAI1_RX_BCLK 339 +#define IMX8QXP_SAI1_TX_BCLK 340 +#define IMX8QXP_SAI2_RX_BCLK 341 +#define IMX8QXP_SAI3_RX_BCLK 342 +#define IMX8QXP_SAI4_RX_BCLK 343 + +#define IMX8QXP_ACM_AUD_CLK0_SEL 344 +#define IMX8QXP_ACM_AUD_CLK0_CLK 345 +#define IMX8QXP_ACM_AUD_CLK1_SEL 346 +#define IMX8QXP_ACM_AUD_CLK1_CLK 347 +#define IMX8QXP_ACM_MCLKOUT0_SEL 348 +#define IMX8QXP_ACM_MCLKOUT0_CLK 349 +#define IMX8QXP_ACM_MCLKOUT1_SEL 350 +#define IMX8QXP_ACM_MCLKOUT1_CLK 351 +#define IMX8QXP_ACM_ESAI0_MCLK_SEL 352 +#define IMX8QXP_ACM_ESAI0_MCLK_CLK 353 +#define IMX8QXP_ACM_GPT0_MUX_CLK_SEL 354 +#define IMX8QXP_ACM_GPT0_MUX_CLK_CLK 355 +#define IMX8QXP_ACM_GPT1_MUX_CLK_SEL 356 +#define IMX8QXP_ACM_GPT1_MUX_CLK_CLK 357 +#define IMX8QXP_ACM_GPT2_MUX_CLK_SEL 358 +#define IMX8QXP_ACM_GPT2_MUX_CLK_CLK 359 +#define IMX8QXP_ACM_GPT3_MUX_CLK_SEL 360 +#define IMX8QXP_ACM_GPT3_MUX_CLK_CLK 361 +#define IMX8QXP_ACM_GPT4_MUX_CLK_SEL 362 +#define IMX8QXP_ACM_GPT4_MUX_CLK_CLK 363 +#define IMX8QXP_ACM_GPT5_MUX_CLK_SEL 364 +#define IMX8QXP_ACM_GPT5_MUX_CLK_CLK 365 +#define IMX8QXP_ACM_SAI0_MCLK_SEL 366 +#define IMX8QXP_ACM_SAI0_MCLK_CLK 367 +#define IMX8QXP_ACM_SAI1_MCLK_SEL 368 +#define IMX8QXP_ACM_SAI1_MCLK_CLK 369 +#define IMX8QXP_ACM_SAI2_MCLK_SEL 370 +#define IMX8QXP_ACM_SAI2_MCLK_CLK 371 +#define IMX8QXP_ACM_SAI3_MCLK_SEL 372 +#define IMX8QXP_ACM_SAI3_MCLK_CLK 373 +#define IMX8QXP_ACM_SAI4_MCLK_SEL 374 +#define IMX8QXP_ACM_SAI4_MCLK_CLK 375 +#define IMX8QXP_ACM_SAI5_MCLK_SEL 376 +#define IMX8QXP_ACM_SAI5_MCLK_CLK 377 +#define IMX8QXP_ACM_SPDIF0_TX_CLK_SEL 378 +#define IMX8QXP_ACM_SPDIF0_TX_CLK_CLK 379 +#define IMX8QXP_ACM_MQS_TX_CLK_SEL 380 +#define IMX8QXP_ACM_MQS_TX_CLK_CLK 381 +#define IMX8QXP_ACM_ASRC0_MUX_CLK_SEL 382 +#define IMX8QXP_ACM_ASRC1_MUX_CLK_SEL 383 +#define IMX8QXP_ACM_ASRC0_MUX_CLK_CLK 384 +#define IMX8QXP_ACM_ASRC1_MUX_CLK_CLK 385 + +#define IMX8QXP_IPG_AUD_CLK_ROOT 386 + +/* Audio */ +#define IMX8QXP_AUD_PLL0_DIV 387 +#define IMX8QXP_AUD_PLL0 388 +#define IMX8QXP_AUD_PLL1_DIV 389 +#define IMX8QXP_AUD_PLL1 390 +#define IMX8QXP_AUD_AMIX_IPG 391 +#define IMX8QXP_AUD_ESAI_0_IPG 392 +#define IMX8QXP_AUD_ESAI_0_EXTAL_IPG 393 +#define IMX8QXP_AUD_SAI_0_IPG 394 +#define IMX8QXP_AUD_SAI_0_MCLK 395 +#define IMX8QXP_AUD_SAI_1_IPG 396 +#define IMX8QXP_AUD_SAI_1_MCLK 397 +#define IMX8QXP_AUD_SAI_2_IPG 398 +#define IMX8QXP_AUD_SAI_2_MCLK 399 +#define IMX8QXP_AUD_SAI_3_IPG 400 +#define IMX8QXP_AUD_SAI_3_MCLK 401 +#define IMX8QXP_AUD_SAI_4_IPG 402 +#define IMX8QXP_AUD_SAI_4_MCLK 403 +#define IMX8QXP_AUD_SAI_5_IPG 404 +#define IMX8QXP_AUD_SAI_5_MCLK 405 +#define IMX8QXP_AUD_MQS_IPG 406 +#define IMX8QXP_AUD_MQS_HMCLK 407 +#define IMX8QXP_AUD_GPT5_IPG 408 +#define IMX8QXP_AUD_GPT5_CLKIN 409 +#define IMX8QXP_AUD_GPT6_IPG 410 +#define IMX8QXP_AUD_GPT6_CLKIN 411 +#define IMX8QXP_AUD_GPT7_IPG 412 +#define IMX8QXP_AUD_GPT7_CLKIN 413 +#define IMX8QXP_AUD_GPT8_IPG 414 +#define IMX8QXP_AUD_GPT8_CLKIN 415 +#define IMX8QXP_AUD_GPT9_IPG 416 +#define IMX8QXP_AUD_GPT9_CLKIN 417 +#define IMX8QXP_AUD_GPT10_IPG 418 +#define IMX8QXP_AUD_GPT10_CLKIN 419 +#define IMX8QXP_AUD_ACM_AUD_PLL_CLK0_DIV 420 +#define IMX8QXP_AUD_ACM_AUD_PLL_CLK0_CLK 421 +#define IMX8QXP_AUD_ACM_AUD_PLL_CLK1_DIV 422 +#define IMX8QXP_AUD_ACM_AUD_PLL_CLK1_CLK 423 +#define IMX8QXP_AUD_ACM_AUD_REC_CLK0_DIV 424 +#define IMX8QXP_AUD_ACM_AUD_REC_CLK0_CLK 425 +#define IMX8QXP_AUD_ACM_AUD_REC_CLK1_DIV 426 +#define IMX8QXP_AUD_ACM_AUD_REC_CLK1_CLK 427 +#define IMX8QXP_AUD_MCLKOUT0 428 +#define IMX8QXP_AUD_MCLKOUT1 429 +#define IMX8QXP_AUD_SPDIF_0_TX_CLK 430 +#define IMX8QXP_AUD_SPDIF_0_GCLKW 431 +#define IMX8QXP_AUD_SPDIF_0_IPG 432 +#define IMX8QXP_AUD_ASRC_0_IPG 433 +#define IMX8QXP_AUD_ASRC_1_IPG 434 +#define IMX8QXP_AUD_DSP_ADB_ACLK 435 +#define IMX8QXP_AUD_DSP_IPG 436 +#define IMX8QXP_AUD_DSP_CORE_CLK 437 +#define IMX8QXP_AUD_OCRAM_IPG 438 + +/* DC part2 */ +#define IMX8QXP_DC0_DISP0_DIV 439 +#define IMX8QXP_DC0_DISP1_DIV 440 +#define IMX8QXP_DC0_BYPASS_0_DIV 441 +#define IMX8QXP_DC0_BYPASS_1_DIV 442 +#define IMX8QXP_DC0_PLL0_DIV 443 +#define IMX8QXP_DC0_PLL1_DIV 444 +#define IMX8QXP_DC0_PLL0_CLK 445 +#define IMX8QXP_DC0_PLL1_CLK 446 + +/* MIPI-LVDS part2 */ +#define IMX8QXP_MIPI0_BYPASS_CLK 447 +#define IMX8QXP_MIPI0_PIXEL_DIV 448 +#define IMX8QXP_MIPI0_PIXEL_CLK 449 +#define IMX8QXP_MIPI0_LVDS_PIXEL_DIV 450 +#define IMX8QXP_MIPI0_LVDS_PIXEL_CLK 451 +#define IMX8QXP_MIPI0_LVDS_BYPASS_CLK 452 +#define IMX8QXP_MIPI0_LVDS_PHY_DIV 453 +#define IMX8QXP_MIPI0_LVDS_PHY_CLK 454 +#define IMX8QXP_MIPI0_DSI_TX_ESC_DIV 455 +#define IMX8QXP_MIPI0_DSI_RX_ESC_DIV 456 +#define IMX8QXP_MIPI0_DSI_TX_ESC_CLK 457 +#define IMX8QXP_MIPI0_DSI_RX_ESC_CLK 458 +#define IMX8QXP_MIPI0_LIS_IPG_CLK 459 +#define IMX8QXP_MIPI1_I2C0_DIV 460 +#define IMX8QXP_MIPI1_I2C1_DIV 461 +#define IMX8QXP_MIPI1_I2C0_CLK 462 +#define IMX8QXP_MIPI1_I2C1_CLK 463 +#define IMX8QXP_MIPI1_I2C0_IPG_CLK 465 +#define IMX8QXP_MIPI1_I2C1_IPG_CLK 467 +#define IMX8QXP_MIPI1_PWM_IPG_CLK 469 +#define IMX8QXP_MIPI1_PWM_32K_CLK 470 +#define IMX8QXP_MIPI1_GPIO_IPG_CLK 471 +#define IMX8QXP_MIPI1_BYPASS_CLK 472 +#define IMX8QXP_MIPI1_PIXEL_DIV 473 +#define IMX8QXP_MIPI1_PIXEL_CLK 474 +#define IMX8QXP_MIPI1_LVDS_PIXEL_DIV 475 +#define IMX8QXP_MIPI1_LVDS_PIXEL_CLK 476 +#define IMX8QXP_MIPI1_LVDS_BYPASS_CLK 477 +#define IMX8QXP_MIPI1_LVDS_PHY_DIV 478 +#define IMX8QXP_MIPI1_LVDS_PHY_CLK 479 +#define IMX8QXP_MIPI1_DSI_TX_ESC_DIV 480 +#define IMX8QXP_MIPI1_DSI_RX_ESC_DIV 481 +#define IMX8QXP_MIPI1_DSI_TX_ESC_CLK 482 +#define IMX8QXP_MIPI1_DSI_RX_ESC_CLK 483 + +#define IMX8QXP_MIPI1_LIS_IPG_CLK 484 + +/* CM40 */ +#define IMX8QXP_CM40_IPG_CLK 485 +#define IMX8QXP_CM40_I2C_DIV 486 +#define IMX8QXP_CM40_I2C_CLK 487 +#define IMX8QXP_CM40_I2C_IPG_CLK 488 + +/* VPU clocks. */ +#define IMX8QXP_VPU_ENC_CLK 489 +#define IMX8QXP_VPU_DEC_CLK 490 + +/* MIPI-LVDS part3 */ +#define IMX8QXP_MIPI0_DSI_PLL_CLK 491 +#define IMX8QXP_MIPI0_DSI_PLL_DIV2_CLK 492 +#define IMX8QXP_MIPI0_LVDS_PIXEL_SEL 493 +#define IMX8QXP_MIPI0_LVDS_PHY_SEL 494 +#define IMX8QXP_MIPI0_DSI_TX_ESC_SEL 495 +#define IMX8QXP_MIPI0_DSI_RX_ESC_SEL 496 +#define IMX8QXP_MIPI0_DSI_PHY_SEL 498 +#define IMX8QXP_MIPI0_DSI_PHY_DIV 499 +#define IMX8QXP_MIPI0_DSI_PHY_CLK 500 +#define IMX8QXP_MIPI1_DSI_PLL_CLK 501 +#define IMX8QXP_MIPI1_DSI_PLL_DIV2_CLK 502 +#define IMX8QXP_MIPI1_LVDS_PIXEL_SEL 503 +#define IMX8QXP_MIPI1_LVDS_PHY_SEL 504 +#define IMX8QXP_MIPI1_DSI_TX_ESC_SEL 505 +#define IMX8QXP_MIPI1_DSI_RX_ESC_SEL 506 +#define IMX8QXP_MIPI1_DSI_PHY_SEL 507 +#define IMX8QXP_MIPI1_DSI_PHY_DIV 508 +#define IMX8QXP_MIPI1_DSI_PHY_CLK 509 + +/* DC part3 */ +#define IMX8QXP_DC0_DPR1_APB_CLK 510 +#define IMX8QXP_DC0_DPR1_B_CLK 511 + +#define IMX8QXP_CONN_PLL0_CLK 512 +#define IMX8QXP_CONN_PLL1_CLK 513 +#define IMX8QXP_SDHC0_SEL 514 +#define IMX8QXP_SDHC1_SEL 515 +#define IMX8QXP_SDHC2_SEL 516 + +/* PARALLER CSI */ +#define IMX8QXP_PARALLEL_CSI_CLK_DPLL 517 +#define IMX8QXP_PARALLEL_CSI_CLK_SEL 518 +#define IMX8QXP_PARALLEL_CSI_PER_CLK_DIV 519 +#define IMX8QXP_PARALLEL_CSI_PIXEL_CLK 520 +#define IMX8QXP_PARALLEL_CSI_IPG_CLK 521 +#define IMX8QXP_PARALLEL_CSI_MCLK_DIV 522 +#define IMX8QXP_PARALLEL_CSI_MISC0_CLK 523 + +#define IMX8QXP_MIPI0_PWM_DIV 524 +#define IMX8QXP_MIPI1_PWM_DIV 525 +#define IMX8QXP_MIPI0_PWM_CLK 526 +#define IMX8QXP_MIPI1_PWM_CLK 527 + +#define IMX8QXP_LSIO_MU5A_IPG_S_CLK 528 +#define IMX8QXP_LSIO_MU5A_IPG_CLK 529 + + +/* LCD part2 */ +#define IMX8QXP_LCD_PXL_BYPASS_DIV 530 +#define IMX8QXP_LCD_PXL_SEL 531 +#define IMX8QXP_LCD_PXL_DIV 532 +#define IMX8QXP_LCD_PXL_CLK 533 +#define IMX8QXP_ELCDIF_PLL_DIV 534 +#define IMX8QXP_ELCDIF_PLL 535 +#define IMX8QXP_LCD_SEL 536 + +#define IMX8QXP_CLK_END 537 +#endif /* __DT_BINDINGS_CLOCK_IMX8QXP_H */ diff --git a/include/soc/imx8/imx8qxp/lpcg.h b/include/soc/imx8/imx8qxp/lpcg.h new file mode 100644 index 0000000000000000000000000000000000000000..79b774d825ba6d17a780cd9efedc3454df8e62d1 --- /dev/null +++ b/include/soc/imx8/imx8qxp/lpcg.h @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2016 Freescale Semiconductor, Inc. + * Copyright 2017-2018 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _SC_LPCG_H +#define _SC_LPCG_H + +/*LSIO SS */ +#define PWM_0_LPCG 0x5D400000 +#define PWM_1_LPCG 0x5D410000 +#define PWM_2_LPCG 0x5D420000 +#define PWM_3_LPCG 0x5D430000 +#define PWM_4_LPCG 0x5D440000 +#define PWM_5_LPCG 0x5D450000 +#define PWM_6_LPCG 0x5D460000 +#define PWM_7_LPCG 0x5D470000 +#define GPIO_0_LPCG 0x5D480000 +#define GPIO_1_LPCG 0x5D490000 +#define GPIO_2_LPCG 0x5D4A0000 +#define GPIO_3_LPCG 0x5D4B0000 +#define GPIO_4_LPCG 0x5D4C0000 +#define GPIO_5_LPCG 0x5D4D0000 +#define GPIO_6_LPCG 0x5D4E0000 +#define GPIO_7_LPCG 0x5D4F0000 +#define FSPI_0_LPCG 0x5D520000 +#define FSPI_1_LPCG 0x5D530000 +#define GPT_0_LPCG 0x5D540000 +#define GPT_1_LPCG 0x5D550000 +#define GPT_2_LPCG 0x5D560000 +#define GPT_3_LPCG 0x5D570000 +#define GPT_4_LPCG 0x5D580000 +#define OCRAM_LPCG 0x5D590000 +#define KPP_LPCG 0x5D5A0000 +#define ROMCP_LPCG 0x5D500000 +#define MU_5A_LPCG 0x5D600000 +#define MU_6A_LPCG 0x5D610000 +#define MU_7A_LPCG 0x5D620000 +#define MU_8A_LPCG 0x5D630000 +#define MU_9A_LPCG 0x5D640000 +#define MU_10A_LPCG 0x5D650000 +#define MU_11A_LPCG 0x5D660000 +#define MU_12A_LPCG 0x5D670000 +#define MU_13A_LPCG 0x5D680000 + +/* HSIO SS */ +#define CRR_5_LPCG 0x5F0F0000 +#define CRR_4_LPCG 0x5F0E0000 +#define CRR_3_LPCG 0x5F0D0000 +#define CRR_2_LPCG 0x5F0C0000 +#define CRR_1_LPCG 0x5F0B0000 +#define CRR_0_LPCG 0x5F0A0000 +#define PHY_1_LPCG 0x5F090000 +#define PHY_2_LPCG 0x5F080000 +#define SATA_0_LPCG 0x5F070000 +#define PCIE_B_LPCG 0x5F060000 +#define PCIE_A_LPCG 0x5F050000 + +/* DMA SS */ +#define FLEX_CAN_2_LPCG 0x5ACF0000 +#define FLEX_CAN_1_LPCG 0x5ACE0000 +#define FLEX_CAN_0_LPCG 0x5ACD0000 +#define FTM_1_LPCG 0x5ACB0000 +#define FTM_0_LPCG 0x5ACA0000 +#define ADC_0_LPCG 0x5AC80000 +#define LPI2C_3_LPCG 0x5AC30000 +#define LPI2C_2_LPCG 0x5AC20000 +#define LPI2C_1_LPCG 0x5AC10000 +#define LPI2C_0_LPCG 0x5AC00000 +#define PWM_LPCG 0x5A590000 +#define LCD_LPCG 0x5A580000 +#define LPUART_3_LPCG 0x5A490000 +#define LPUART_2_LPCG 0x5A480000 +#define LPUART_1_LPCG 0x5A470000 +#define LPUART_0_LPCG 0x5A460000 +#define LPSPI_3_LPCG 0x5A430000 +#define LPSPI_2_LPCG 0x5A420000 +#define LPSPI_1_LPCG 0x5A410000 +#define LPSPI_0_LPCG 0x5A400000 + +/* Display SS */ +#define DC_0_LPCG 0x56010000 +#define DC_1_LPCG 0x57010000 + +/* LVDS */ +#define DI_LVDS_0_LPCG 0x56243000 +#define DI_LVDS_1_LPCG 0x57243000 + +/* DI HDMI */ +#define DI_HDMI_LPCG 0x56263000 + +/* RX-HDMI */ +#define RX_HDMI_LPCG 0x58263000 + +/* MIPI CSI SS */ +#define MIPI_CSI_0_LPCG 0x58223000 +#define MIPI_CSI_1_LPCG 0x58243000 + +/* PARALLEL CSI SS */ +#define PARALLEL_CSI_LPCG 0x58263000 + +/* Display MIPI SS */ +#define DI_MIPI0_LPCG 0x56223000 +#define DI_MIPI1_LPCG 0x56243000 + +/* Imaging SS */ +#define IMG_JPEG_ENC_LPCG 0x585F0000 +#define IMG_JPEG_DEC_LPCG 0x585D0000 +#define IMG_PXL_LINK_DC1_LPCG 0x585C0000 +#define IMG_PXL_LINK_DC0_LPCG 0x585B0000 +#define IMG_PXL_LINK_HDMI_LPCG 0x585A0000 +#define IMG_PXL_LINK_CSI1_LPCG 0x58590000 +#define IMG_PXL_LINK_CSI0_LPCG 0x58580000 +#define IMG_PDMA_7_LPCG 0x58570000 +#define IMG_PDMA_6_LPCG 0x58560000 +#define IMG_PDMA_5_LPCG 0x58550000 +#define IMG_PDMA_4_LPCG 0x58540000 +#define IMG_PDMA_3_LPCG 0x58530000 +#define IMG_PDMA_2_LPCG 0x58520000 +#define IMG_PDMA_1_LPCG 0x58510000 +#define IMG_PDMA_0_LPCG 0x58500000 + +/* HSIO SS */ +#define HSIO_GPIO_LPCG 0x5F100000 +#define HSIO_MISC_LPCG 0x5F0F0000 +#define HSIO_SATA_CRR4_LPCG 0x5F0E0000 +#define HSIO_PCIE_X1_CRR3_LPCG 0x5F0D0000 +#define HSIO_PCIE_X2_CRR2_LPCG 0x5F0C0000 +#define HSIO_PHY_X1_CRR1_LPCG 0x5F0B0000 +#define HSIO_PHY_X2_CRR0_LPCG 0x5F0A0000 +#define HSIO_PHY_X1_LPCG 0x5F090000 +#define HSIO_PHY_X2_LPCG 0x5F080000 +#define HSIO_SATA_LPCG 0x5F070000 +#define HSIO_PCIE_X1_LPCG 0x5F060000 +#define HSIO_PCIE_X2_LPCG 0x5F050000 + +/* M4 SS */ +#define M4_0_I2C_LPCG 0x37630000 +#define M4_0_LPUART_LPCG 0x37620000 +#define M4_0_LPIT_LPCG 0x37610000 +#define M4_1_I2C_LPCG 0x3B630000 +#define M4_1_LPUART_LPCG 0x3B620000 +#define M4_1_LPIT_LPCG 0x3B610000 + +/* Audio SS */ +#define AUD_ASRC_0_LPCG 0x59400000 +#define AUD_ESAI_0_LPCG 0x59410000 +#define AUD_SPDIF_0_LPCG 0x59420000 +#define AUD_SAI_0_LPCG 0x59440000 +#define AUD_SAI_1_LPCG 0x59450000 +#define AUD_SAI_2_LPCG 0x59460000 +#define AUD_SAI_3_LPCG 0x59470000 +#define AUD_GPT_5_LPCG 0x594B0000 +#define AUD_GPT_6_LPCG 0x594C0000 +#define AUD_GPT_7_LPCG 0x594D0000 +#define AUD_GPT_8_LPCG 0x594E0000 +#define AUD_GPT_9_LPCG 0x594F0000 +#define AUD_GPT_10_LPCG 0x59500000 +#define AUD_DSP_LPCG 0x59580000 +#define AUD_OCRAM_LPCG 0x59590000 +#define AUD_EDMA_0_LPCG 0x595f0000 +#define AUD_ASRC_1_LPCG 0x59c00000 +#define AUD_SAI_4_LPCG 0x59c20000 +#define AUD_SAI_5_LPCG 0x59c30000 +#define AUD_AMIX_LPCG 0x59c40000 +#define AUD_MQS_LPCG 0x59c50000 +#define AUD_ACM_LPCG 0x59c60000 +#define AUD_REC_CLK0_LPCG 0x59d00000 +#define AUD_REC_CLK1_LPCG 0x59d10000 +#define AUD_PLL_CLK0_LPCG 0x59d20000 +#define AUD_PLL_CLK1_LPCG 0x59d30000 +#define AUD_MCLKOUT0_LPCG 0x59d50000 +#define AUD_MCLKOUT1_LPCG 0x59d60000 +#define AUD_EDMA_1_LPCG 0x59df0000 + + +/* Connectivity SS */ +#define USDHC_0_LPCG 0x5B200000 +#define USDHC_1_LPCG 0x5B210000 +#define USDHC_2_LPCG 0x5B220000 +#define ENET_0_LPCG 0x5B230000 +#define ENET_1_LPCG 0x5B240000 +#define DTCP_LPCG 0x5B250000 +#define MLB_LPCG 0x5B260000 +#define USB_2_LPCG 0x5B270000 +#define USB_3_LPCG 0x5B280000 +#define NAND_LPCG 0x5B290000 +#define EDMA_LPCG 0x5B2A0000 + +/* CM40 SS */ +#define CM40_I2C_LPCG 0x37630000 + + +#endif