diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-26 11:34:35 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-26 11:34:35 -0700 |
commit | 4aa705b18bf17c4ff33ff7bbcd3f0c596443fa81 (patch) | |
tree | 3b166bff290d123ccaa88598ad2d45be67f5b358 /arch/arm/mach-imx | |
parent | c11d716218910c3aa2bac1bb641e6086ad649555 (diff) | |
parent | 2879e43f09122f8b3ef5456e3d7e48716b086e60 (diff) | |
download | lwn-4aa705b18bf17c4ff33ff7bbcd3f0c596443fa81.tar.gz lwn-4aa705b18bf17c4ff33ff7bbcd3f0c596443fa81.zip |
Merge tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC platform support updates from Kevin Hilman:
"Our SoC branch usually contains expanded support for new SoCs and
other core platform code. Some highlights from this round:
- sunxi: SMP support for A23 SoC
- socpga: big-endian support
- pxa: conversion to common clock framework
- bcm: SMP support for BCM63138
- imx: support new I.MX7D SoC
- zte: basic support for ZX296702 SoC"
* tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (134 commits)
ARM: zx: Add basic defconfig support for ZX296702
ARM: dts: zx: add an initial zx296702 dts and doc
clk: zx: add clock support to zx296702
dt-bindings: Add #defines for ZTE ZX296702 clocks
ARM: socfpga: fix build error due to secondary_startup
MAINTAINERS: ARM64: EXYNOS: Extend entry for ARM64 DTS
ARM: ep93xx: simone: support for SPI-based MMC/SD cards
MAINTAINERS: update Shawn's email to use kernel.org one
ARM: socfpga: support suspend to ram
ARM: socfpga: add CPU_METHOD_OF_DECLARE for Arria 10
ARM: socfpga: use CPU_METHOD_OF_DECLARE for socfpga_cyclone5
ARM: EXYNOS: register power domain driver from core_initcall
ARM: EXYNOS: use PS_HOLD based poweroff for all supported SoCs
ARM: SAMSUNG: Constify platform_device_id
ARM: EXYNOS: Constify irq_domain_ops
ARM: EXYNOS: add coupled cpuidle support for Exynos3250
ARM: EXYNOS: add exynos_get_boot_addr() helper
ARM: EXYNOS: add exynos_set_boot_addr() helper
ARM: EXYNOS: make exynos_core_restart() less verbose
ARM: EXYNOS: fix exynos_boot_secondary() return value on timeout
...
Diffstat (limited to 'arch/arm/mach-imx')
48 files changed, 484 insertions, 6215 deletions
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 388232ce92fc..573536f1bb73 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -1,8 +1,8 @@ menuconfig ARCH_MXC - bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 + bool "Freescale i.MX family" if ARCH_MULTI_V4_V5 || ARCH_MULTI_V6_V7 || ARM_SINGLE_ARMV7M select ARCH_REQUIRE_GPIOLIB select ARM_CPU_SUSPEND if PM - select CLKSRC_MMIO + select CLKSRC_IMX_GPT select GENERIC_IRQ_CHIP select PINCTRL select PM_OPP if PM @@ -462,10 +462,10 @@ config MACH_VPR200 endif -if ARCH_MULTI_V5 - comment "Device tree only" +if ARCH_MULTI_V5 + config SOC_IMX25 bool "i.MX25 support" select ARCH_MXC_IOMUX_V3 @@ -478,7 +478,7 @@ endif if ARCH_MULTI_V7 -comment "Device tree only" +comment "Cortex-A platforms" config SOC_IMX5 bool @@ -548,10 +548,33 @@ config SOC_IMX6SX help This enables support for Freescale i.MX6 SoloX processor. +config SOC_IMX7D + bool "i.MX7 Dual support" + select PINCTRL_IMX7D + select ARM_GIC + select HAVE_IMX_ANATOP + select HAVE_IMX_MMDC + help + This enables support for Freescale i.MX7 Dual processor. + +config SOC_LS1021A + bool "Freescale LS1021A support" + select ARM_GIC + select HAVE_ARM_ARCH_TIMER + select PCI_DOMAINS if PCI + select ZONE_DMA if ARM_LPAE + help + This enables support for Freescale LS1021A processor. + +endif + +comment "Cortex-A/Cortex-M asymmetric multiprocessing platforms" + +if ARCH_MULTI_V7 || ARM_SINGLE_ARMV7M + config SOC_VF610 bool "Vybrid Family VF610 support" - select IRQ_DOMAIN_HIERARCHY - select ARM_GIC + select ARM_GIC if ARCH_MULTI_V7 select PINCTRL_VF610 select PL310_ERRATA_769419 if CACHE_L2X0 select SMP_ON_UP if SMP @@ -565,7 +588,7 @@ choice default VF_USE_ARM_GLOBAL_TIMER config VF_USE_ARM_GLOBAL_TIMER - bool "Use ARM Global Timer" + bool "Use ARM Global Timer" if ARCH_MULTI_V7 select ARM_GLOBAL_TIMER select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK help @@ -579,16 +602,6 @@ choice endchoice -config SOC_LS1021A - bool "Freescale LS1021A support" - select ARM_GIC - select HAVE_ARM_ARCH_TIMER - select PCI_DOMAINS if PCI - select ZONE_DMA if ARM_LPAE - - help - This enables support for Freescale LS1021A processor. - endif source "arch/arm/mach-imx/devices/Kconfig" diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index eed609834ffb..37c502ac9595 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -1,23 +1,18 @@ -obj-y := time.o cpu.o system.o irq-common.o +obj-y := cpu.o system.o irq-common.o -obj-$(CONFIG_SOC_IMX1) += clk-imx1.o mm-imx1.o -obj-$(CONFIG_SOC_IMX21) += clk-imx21.o mm-imx21.o +obj-$(CONFIG_SOC_IMX1) += mm-imx1.o +obj-$(CONFIG_SOC_IMX21) += mm-imx21.o -obj-$(CONFIG_SOC_IMX25) += clk-imx25.o cpu-imx25.o mach-imx25.o +obj-$(CONFIG_SOC_IMX25) += cpu-imx25.o mach-imx25.o obj-$(CONFIG_SOC_IMX27) += cpu-imx27.o pm-imx27.o -obj-$(CONFIG_SOC_IMX27) += clk-imx27.o mm-imx27.o ehci-imx27.o +obj-$(CONFIG_SOC_IMX27) += mm-imx27.o ehci-imx27.o -obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o clk-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o -obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o clk-imx35.o ehci-imx35.o pm-imx3.o +obj-$(CONFIG_SOC_IMX31) += mm-imx3.o cpu-imx31.o iomux-imx31.o ehci-imx31.o pm-imx3.o +obj-$(CONFIG_SOC_IMX35) += mm-imx3.o cpu-imx35.o ehci-imx35.o pm-imx3.o imx5-pm-$(CONFIG_PM) += pm-imx5.o -obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o clk-imx51-imx53.o clk-cpu.o $(imx5-pm-y) - -obj-$(CONFIG_COMMON_CLK) += clk-pllv1.o clk-pllv2.o clk-pllv3.o clk-gate2.o \ - clk-pfd.o clk-busy.o clk.o \ - clk-fixup-div.o clk-fixup-mux.o \ - clk-gate-exclusive.o +obj-$(CONFIG_SOC_IMX5) += cpu-imx5.o $(imx5-pm-y) obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o @@ -85,13 +80,15 @@ AFLAGS_headsmp.o :=-Wa,-march=armv7-a obj-$(CONFIG_SMP) += headsmp.o platsmp.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o endif -obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o -obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o -obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o mach-imx6sx.o +obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o +obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o +obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o +obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o ifeq ($(CONFIG_SUSPEND),y) AFLAGS_suspend-imx6.o :=-Wa,-march=armv7-a obj-$(CONFIG_SOC_IMX6) += suspend-imx6.o +obj-$(CONFIG_SOC_IMX53) += suspend-imx53.o endif obj-$(CONFIG_SOC_IMX6) += pm-imx6.o @@ -99,7 +96,7 @@ obj-$(CONFIG_SOC_IMX50) += mach-imx50.o obj-$(CONFIG_SOC_IMX51) += mach-imx51.o obj-$(CONFIG_SOC_IMX53) += mach-imx53.o -obj-$(CONFIG_SOC_VF610) += clk-vf610.o mach-vf610.o +obj-$(CONFIG_SOC_VF610) += mach-vf610.o obj-$(CONFIG_SOC_LS1021A) += mach-ls1021a.o diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/arch/arm/mach-imx/Makefile.boot diff --git a/arch/arm/mach-imx/anatop.c b/arch/arm/mach-imx/anatop.c index 7f262fe4ba77..231bb250c571 100644 --- a/arch/arm/mach-imx/anatop.c +++ b/arch/arm/mach-imx/anatop.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Freescale Semiconductor, Inc. + * Copyright (C) 2013-2015 Freescale Semiconductor, Inc. * * The code contained herein is licensed under the GNU General Public * License. You may obtain a copy of the GNU General Public License @@ -28,6 +28,7 @@ #define ANADIG_USB2_CHRG_DETECT 0x210 #define ANADIG_DIGPROG 0x260 #define ANADIG_DIGPROG_IMX6SL 0x280 +#define ANADIG_DIGPROG_IMX7D 0x800 #define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG 0x40000 #define BM_ANADIG_REG_2P5_ENABLE_PULLDOWN 0x8 @@ -121,6 +122,8 @@ void __init imx_init_revision_from_anatop(void) WARN_ON(!anatop_base); if (of_device_is_compatible(np, "fsl,imx6sl-anatop")) offset = ANADIG_DIGPROG_IMX6SL; + if (of_device_is_compatible(np, "fsl,imx7d-anatop")) + offset = ANADIG_DIGPROG_IMX7D; digprog = readl_relaxed(anatop_base + offset); iounmap(anatop_base); diff --git a/arch/arm/mach-imx/clk-busy.c b/arch/arm/mach-imx/clk-busy.c deleted file mode 100644 index 4bb1bc419b79..000000000000 --- a/arch/arm/mach-imx/clk-busy.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2012 Freescale Semiconductor, Inc. - * Copyright 2012 Linaro Ltd. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include <linux/clk.h> -#include <linux/clk-provider.h> -#include <linux/io.h> -#include <linux/slab.h> -#include <linux/jiffies.h> -#include <linux/err.h> -#include "clk.h" - -static int clk_busy_wait(void __iomem *reg, u8 shift) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(10); - - while (readl_relaxed(reg) & (1 << shift)) - if (time_after(jiffies, timeout)) - return -ETIMEDOUT; - - return 0; -} - -struct clk_busy_divider { - struct clk_divider div; - const struct clk_ops *div_ops; - void __iomem *reg; - u8 shift; -}; - -static inline struct clk_busy_divider *to_clk_busy_divider(struct clk_hw *hw) -{ - struct clk_divider *div = container_of(hw, struct clk_divider, hw); - - return container_of(div, struct clk_busy_divider, div); -} - -static unsigned long clk_busy_divider_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct clk_busy_divider *busy = to_clk_busy_divider(hw); - - return busy->div_ops->recalc_rate(&busy->div.hw, parent_rate); -} - -static long clk_busy_divider_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) -{ - struct clk_busy_divider *busy = to_clk_busy_divider(hw); - - return busy->div_ops->round_rate(&busy->div.hw, rate, prate); -} - -static int clk_busy_divider_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct clk_busy_divider *busy = to_clk_busy_divider(hw); - int ret; - - ret = busy->div_ops->set_rate(&busy->div.hw, rate, parent_rate); - if (!ret) - ret = clk_busy_wait(busy->reg, busy->shift); - - return ret; -} - -static struct clk_ops clk_busy_divider_ops = { - .recalc_rate = clk_busy_divider_recalc_rate, - .round_rate = clk_busy_divider_round_rate, - .set_rate = clk_busy_divider_set_rate, -}; - -struct clk *imx_clk_busy_divider(const char *name, const char *parent_name, - void __iomem *reg, u8 shift, u8 width, - void __iomem *busy_reg, u8 busy_shift) -{ - struct clk_busy_divider *busy; - struct clk *clk; - struct clk_init_data init; - - busy = kzalloc(sizeof(*busy), GFP_KERNEL); - if (!busy) - return ERR_PTR(-ENOMEM); - - busy->reg = busy_reg; - busy->shift = busy_shift; - - busy->div.reg = reg; - busy->div.shift = shift; - busy->div.width = width; - busy->div.lock = &imx_ccm_lock; - busy->div_ops = &clk_divider_ops; - - init.name = name; - init.ops = &clk_busy_divider_ops; - init.flags = CLK_SET_RATE_PARENT; - init.parent_names = &parent_name; - init.num_parents = 1; - - busy->div.hw.init = &init; - - clk = clk_register(NULL, &busy->div.hw); - if (IS_ERR(clk)) - kfree(busy); - - return clk; -} - -struct clk_busy_mux { - struct clk_mux mux; - const struct clk_ops *mux_ops; - void __iomem *reg; - u8 shift; -}; - -static inline struct clk_busy_mux *to_clk_busy_mux(struct clk_hw *hw) -{ - struct clk_mux *mux = container_of(hw, struct clk_mux, hw); - - return container_of(mux, struct clk_busy_mux, mux); -} - -static u8 clk_busy_mux_get_parent(struct clk_hw *hw) -{ - struct clk_busy_mux *busy = to_clk_busy_mux(hw); - - return busy->mux_ops->get_parent(&busy->mux.hw); -} - -static int clk_busy_mux_set_parent(struct clk_hw *hw, u8 index) -{ - struct clk_busy_mux *busy = to_clk_busy_mux(hw); - int ret; - - ret = busy->mux_ops->set_parent(&busy->mux.hw, index); - if (!ret) - ret = clk_busy_wait(busy->reg, busy->shift); - - return ret; -} - -static struct clk_ops clk_busy_mux_ops = { - .get_parent = clk_busy_mux_get_parent, - .set_parent = clk_busy_mux_set_parent, -}; - -struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, - u8 width, void __iomem *busy_reg, u8 busy_shift, - const char **parent_names, int num_parents) -{ - struct clk_busy_mux *busy; - struct clk *clk; - struct clk_init_data init; - - busy = kzalloc(sizeof(*busy), GFP_KERNEL); - if (!busy) - return ERR_PTR(-ENOMEM); - - busy->reg = busy_reg; - busy->shift = busy_shift; - - busy->mux.reg = reg; - busy->mux.shift = shift; - busy->mux.mask = BIT(width) - 1; - busy->mux.lock = &imx_ccm_lock; - busy->mux_ops = &clk_mux_ops; - - init.name = name; - init.ops = &clk_busy_mux_ops; - init.flags = 0; - init.parent_names = parent_names; - init.num_parents = num_parents; - - busy->mux.hw.init = &init; - - clk = clk_register(NULL, &busy->mux.hw); - if (IS_ERR(clk)) - kfree(busy); - - return clk; -} diff --git a/arch/arm/mach-imx/clk-cpu.c b/arch/arm/mach-imx/clk-cpu.c deleted file mode 100644 index aa1c345e2a19..000000000000 --- a/arch/arm/mach-imx/clk-cpu.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2014 Lucas Stach <l.stach@pengutronix.de>, Pengutronix - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include <linux/clk.h> -#include <linux/clk-provider.h> -#include <linux/slab.h> - -struct clk_cpu { - struct clk_hw hw; - struct clk *div; - struct clk *mux; - struct clk *pll; - struct clk *step; -}; - -static inline struct clk_cpu *to_clk_cpu(struct clk_hw *hw) -{ - return container_of(hw, struct clk_cpu, hw); -} - -static unsigned long clk_cpu_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct clk_cpu *cpu = to_clk_cpu(hw); - - return clk_get_rate(cpu->div); -} - -static long clk_cpu_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) -{ - struct clk_cpu *cpu = to_clk_cpu(hw); - - return clk_round_rate(cpu->pll, rate); -} - -static int clk_cpu_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct clk_cpu *cpu = to_clk_cpu(hw); - int ret; - - /* switch to PLL bypass clock */ - ret = clk_set_parent(cpu->mux, cpu->step); - if (ret) - return ret; - - /* reprogram PLL */ - ret = clk_set_rate(cpu->pll, rate); - if (ret) { - clk_set_parent(cpu->mux, cpu->pll); - return ret; - } - /* switch back to PLL clock */ - clk_set_parent(cpu->mux, cpu->pll); - - /* Ensure the divider is what we expect */ - clk_set_rate(cpu->div, rate); - - return 0; -} - -static const struct clk_ops clk_cpu_ops = { - .recalc_rate = clk_cpu_recalc_rate, - .round_rate = clk_cpu_round_rate, - .set_rate = clk_cpu_set_rate, -}; - -struct clk *imx_clk_cpu(const char *name, const char *parent_name, - struct clk *div, struct clk *mux, struct clk *pll, - struct clk *step) -{ - struct clk_cpu *cpu; - struct clk *clk; - struct clk_init_data init; - - cpu = kzalloc(sizeof(*cpu), GFP_KERNEL); - if (!cpu) - return ERR_PTR(-ENOMEM); - - cpu->div = div; - cpu->mux = mux; - cpu->pll = pll; - cpu->step = step; - - init.name = name; - init.ops = &clk_cpu_ops; - init.flags = 0; - init.parent_names = &parent_name; - init.num_parents = 1; - - cpu->hw.init = &init; - - clk = clk_register(NULL, &cpu->hw); - if (IS_ERR(clk)) - kfree(cpu); - - return clk; -} diff --git a/arch/arm/mach-imx/clk-fixup-div.c b/arch/arm/mach-imx/clk-fixup-div.c deleted file mode 100644 index 21db020b1f2d..000000000000 --- a/arch/arm/mach-imx/clk-fixup-div.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2013 Freescale Semiconductor, Inc. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include <linux/clk-provider.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/slab.h> -#include "clk.h" - -#define to_clk_div(_hw) container_of(_hw, struct clk_divider, hw) -#define div_mask(d) ((1 << (d->width)) - 1) - -/** - * struct clk_fixup_div - imx integer fixup divider clock - * @divider: the parent class - * @ops: pointer to clk_ops of parent class - * @fixup: a hook to fixup the write value - * - * The imx fixup divider clock is a subclass of basic clk_divider - * with an addtional fixup hook. - */ -struct clk_fixup_div { - struct clk_divider divider; - const struct clk_ops *ops; - void (*fixup)(u32 *val); -}; - -static inline struct clk_fixup_div *to_clk_fixup_div(struct clk_hw *hw) -{ - struct clk_divider *divider = to_clk_div(hw); - - return container_of(divider, struct clk_fixup_div, divider); -} - -static unsigned long clk_fixup_div_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw); - - return fixup_div->ops->recalc_rate(&fixup_div->divider.hw, parent_rate); -} - -static long clk_fixup_div_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) -{ - struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw); - - return fixup_div->ops->round_rate(&fixup_div->divider.hw, rate, prate); -} - -static int clk_fixup_div_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct clk_fixup_div *fixup_div = to_clk_fixup_div(hw); - struct clk_divider *div = to_clk_div(hw); - unsigned int divider, value; - unsigned long flags = 0; - u32 val; - - divider = parent_rate / rate; - - /* Zero based divider */ - value = divider - 1; - - if (value > div_mask(div)) - value = div_mask(div); - - spin_lock_irqsave(div->lock, flags); - - val = readl(div->reg); - val &= ~(div_mask(div) << div->shift); - val |= value << div->shift; - fixup_div->fixup(&val); - writel(val, div->reg); - - spin_unlock_irqrestore(div->lock, flags); - - return 0; -} - -static const struct clk_ops clk_fixup_div_ops = { - .recalc_rate = clk_fixup_div_recalc_rate, - .round_rate = clk_fixup_div_round_rate, - .set_rate = clk_fixup_div_set_rate, -}; - -struct clk *imx_clk_fixup_divider(const char *name, const char *parent, - void __iomem *reg, u8 shift, u8 width, - void (*fixup)(u32 *val)) -{ - struct clk_fixup_div *fixup_div; - struct clk *clk; - struct clk_init_data init; - - if (!fixup) - return ERR_PTR(-EINVAL); - - fixup_div = kzalloc(sizeof(*fixup_div), GFP_KERNEL); - if (!fixup_div) - return ERR_PTR(-ENOMEM); - - init.name = name; - init.ops = &clk_fixup_div_ops; - init.flags = CLK_SET_RATE_PARENT; - init.parent_names = parent ? &parent : NULL; - init.num_parents = parent ? 1 : 0; - - fixup_div->divider.reg = reg; - fixup_div->divider.shift = shift; - fixup_div->divider.width = width; - fixup_div->divider.lock = &imx_ccm_lock; - fixup_div->divider.hw.init = &init; - fixup_div->ops = &clk_divider_ops; - fixup_div->fixup = fixup; - - clk = clk_register(NULL, &fixup_div->divider.hw); - if (IS_ERR(clk)) - kfree(fixup_div); - - return clk; -} diff --git a/arch/arm/mach-imx/clk-fixup-mux.c b/arch/arm/mach-imx/clk-fixup-mux.c deleted file mode 100644 index 0d40b35c557c..000000000000 --- a/arch/arm/mach-imx/clk-fixup-mux.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2013 Freescale Semiconductor, Inc. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include <linux/clk-provider.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/slab.h> -#include "clk.h" - -#define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) - -/** - * struct clk_fixup_mux - imx integer fixup multiplexer clock - * @mux: the parent class - * @ops: pointer to clk_ops of parent class - * @fixup: a hook to fixup the write value - * - * The imx fixup multiplexer clock is a subclass of basic clk_mux - * with an addtional fixup hook. - */ -struct clk_fixup_mux { - struct clk_mux mux; - const struct clk_ops *ops; - void (*fixup)(u32 *val); -}; - -static inline struct clk_fixup_mux *to_clk_fixup_mux(struct clk_hw *hw) -{ - struct clk_mux *mux = to_clk_mux(hw); - - return container_of(mux, struct clk_fixup_mux, mux); -} - -static u8 clk_fixup_mux_get_parent(struct clk_hw *hw) -{ - struct clk_fixup_mux *fixup_mux = to_clk_fixup_mux(hw); - - return fixup_mux->ops->get_parent(&fixup_mux->mux.hw); -} - -static int clk_fixup_mux_set_parent(struct clk_hw *hw, u8 index) -{ - struct clk_fixup_mux *fixup_mux = to_clk_fixup_mux(hw); - struct clk_mux *mux = to_clk_mux(hw); - unsigned long flags = 0; - u32 val; - - spin_lock_irqsave(mux->lock, flags); - - val = readl(mux->reg); - val &= ~(mux->mask << mux->shift); - val |= index << mux->shift; - fixup_mux->fixup(&val); - writel(val, mux->reg); - - spin_unlock_irqrestore(mux->lock, flags); - - return 0; -} - -static const struct clk_ops clk_fixup_mux_ops = { - .get_parent = clk_fixup_mux_get_parent, - .set_parent = clk_fixup_mux_set_parent, -}; - -struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg, - u8 shift, u8 width, const char **parents, - int num_parents, void (*fixup)(u32 *val)) -{ - struct clk_fixup_mux *fixup_mux; - struct clk *clk; - struct clk_init_data init; - - if (!fixup) - return ERR_PTR(-EINVAL); - - fixup_mux = kzalloc(sizeof(*fixup_mux), GFP_KERNEL); - if (!fixup_mux) - return ERR_PTR(-ENOMEM); - - init.name = name; - init.ops = &clk_fixup_mux_ops; - init.parent_names = parents; - init.num_parents = num_parents; - init.flags = 0; - - fixup_mux->mux.reg = reg; - fixup_mux->mux.shift = shift; - fixup_mux->mux.mask = BIT(width) - 1; - fixup_mux->mux.lock = &imx_ccm_lock; - fixup_mux->mux.hw.init = &init; - fixup_mux->ops = &clk_mux_ops; - fixup_mux->fixup = fixup; - - clk = clk_register(NULL, &fixup_mux->mux.hw); - if (IS_ERR(clk)) - kfree(fixup_mux); - - return clk; -} diff --git a/arch/arm/mach-imx/clk-gate-exclusive.c b/arch/arm/mach-imx/clk-gate-exclusive.c deleted file mode 100644 index c12f5f2e04dc..000000000000 --- a/arch/arm/mach-imx/clk-gate-exclusive.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright 2014 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/clk-provider.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/slab.h> -#include "clk.h" - -/** - * struct clk_gate_exclusive - i.MX specific gate clock which is mutually - * exclusive with other gate clocks - * - * @gate: the parent class - * @exclusive_mask: mask of gate bits which are mutually exclusive to this - * gate clock - * - * The imx exclusive gate clock is a subclass of basic clk_gate - * with an addtional mask to indicate which other gate bits in the same - * register is mutually exclusive to this gate clock. - */ -struct clk_gate_exclusive { - struct clk_gate gate; - u32 exclusive_mask; -}; - -static int clk_gate_exclusive_enable(struct clk_hw *hw) -{ - struct clk_gate *gate = container_of(hw, struct clk_gate, hw); - struct clk_gate_exclusive *exgate = container_of(gate, - struct clk_gate_exclusive, gate); - u32 val = readl(gate->reg); - - if (val & exgate->exclusive_mask) - return -EBUSY; - - return clk_gate_ops.enable(hw); -} - -static void clk_gate_exclusive_disable(struct clk_hw *hw) -{ - clk_gate_ops.disable(hw); -} - -static int clk_gate_exclusive_is_enabled(struct clk_hw *hw) -{ - return clk_gate_ops.is_enabled(hw); -} - -static const struct clk_ops clk_gate_exclusive_ops = { - .enable = clk_gate_exclusive_enable, - .disable = clk_gate_exclusive_disable, - .is_enabled = clk_gate_exclusive_is_enabled, -}; - -struct clk *imx_clk_gate_exclusive(const char *name, const char *parent, - void __iomem *reg, u8 shift, u32 exclusive_mask) -{ - struct clk_gate_exclusive *exgate; - struct clk_gate *gate; - struct clk *clk; - struct clk_init_data init; - - if (exclusive_mask == 0) - return ERR_PTR(-EINVAL); - - exgate = kzalloc(sizeof(*exgate), GFP_KERNEL); - if (!exgate) - return ERR_PTR(-ENOMEM); - gate = &exgate->gate; - - init.name = name; - init.ops = &clk_gate_exclusive_ops; - init.flags = CLK_SET_RATE_PARENT; - init.parent_names = parent ? &parent : NULL; - init.num_parents = parent ? 1 : 0; - - gate->reg = reg; - gate->bit_idx = shift; - gate->lock = &imx_ccm_lock; - gate->hw.init = &init; - exgate->exclusive_mask = exclusive_mask; - - clk = clk_register(NULL, &gate->hw); - if (IS_ERR(clk)) - kfree(exgate); - - return clk; -} diff --git a/arch/arm/mach-imx/clk-gate2.c b/arch/arm/mach-imx/clk-gate2.c deleted file mode 100644 index 8935bff99fe7..000000000000 --- a/arch/arm/mach-imx/clk-gate2.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Copyright (C) 2010-2011 Canonical Ltd <jeremy.kerr@canonical.com> - * Copyright (C) 2011-2012 Mike Turquette, Linaro Ltd <mturquette@linaro.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Gated clock implementation - */ - -#include <linux/clk-provider.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/io.h> -#include <linux/err.h> -#include <linux/string.h> -#include "clk.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 - */ - -struct clk_gate2 { - struct clk_hw hw; - void __iomem *reg; - u8 bit_idx; - u8 flags; - spinlock_t *lock; - unsigned int *share_count; -}; - -#define to_clk_gate2(_hw) container_of(_hw, struct clk_gate2, hw) - -static int clk_gate2_enable(struct clk_hw *hw) -{ - struct clk_gate2 *gate = to_clk_gate2(hw); - u32 reg; - unsigned long flags = 0; - - spin_lock_irqsave(gate->lock, flags); - - if (gate->share_count && (*gate->share_count)++ > 0) - goto out; - - reg = readl(gate->reg); - reg |= 3 << gate->bit_idx; - writel(reg, gate->reg); - -out: - spin_unlock_irqrestore(gate->lock, flags); - - return 0; -} - -static void clk_gate2_disable(struct clk_hw *hw) -{ - struct clk_gate2 *gate = to_clk_gate2(hw); - u32 reg; - unsigned long flags = 0; - - spin_lock_irqsave(gate->lock, flags); - - if (gate->share_count) { - if (WARN_ON(*gate->share_count == 0)) - goto out; - else if (--(*gate->share_count) > 0) - goto out; - } - - reg = readl(gate->reg); - reg &= ~(3 << gate->bit_idx); - writel(reg, gate->reg); - -out: - spin_unlock_irqrestore(gate->lock, flags); -} - -static int clk_gate2_reg_is_enabled(void __iomem *reg, u8 bit_idx) -{ - u32 val = readl(reg); - - if (((val >> bit_idx) & 1) == 1) - return 1; - - return 0; -} - -static int clk_gate2_is_enabled(struct clk_hw *hw) -{ - struct clk_gate2 *gate = to_clk_gate2(hw); - - return clk_gate2_reg_is_enabled(gate->reg, gate->bit_idx); -} - -static void clk_gate2_disable_unused(struct clk_hw *hw) -{ - struct clk_gate2 *gate = to_clk_gate2(hw); - unsigned long flags = 0; - u32 reg; - - spin_lock_irqsave(gate->lock, flags); - - if (!gate->share_count || *gate->share_count == 0) { - reg = readl(gate->reg); - reg &= ~(3 << gate->bit_idx); - writel(reg, gate->reg); - } - - spin_unlock_irqrestore(gate->lock, flags); -} - -static struct clk_ops clk_gate2_ops = { - .enable = clk_gate2_enable, - .disable = clk_gate2_disable, - .disable_unused = clk_gate2_disable_unused, - .is_enabled = clk_gate2_is_enabled, -}; - -struct clk *clk_register_gate2(struct device *dev, const char *name, - const char *parent_name, unsigned long flags, - void __iomem *reg, u8 bit_idx, - u8 clk_gate2_flags, spinlock_t *lock, - unsigned int *share_count) -{ - struct clk_gate2 *gate; - struct clk *clk; - struct clk_init_data init; - - gate = kzalloc(sizeof(struct clk_gate2), GFP_KERNEL); - if (!gate) - return ERR_PTR(-ENOMEM); - - /* struct clk_gate2 assignments */ - gate->reg = reg; - gate->bit_idx = bit_idx; - gate->flags = clk_gate2_flags; - gate->lock = lock; - gate->share_count = share_count; - - init.name = name; - init.ops = &clk_gate2_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)) - kfree(gate); - - return clk; -} diff --git a/arch/arm/mach-imx/clk-imx1.c b/arch/arm/mach-imx/clk-imx1.c deleted file mode 100644 index 37c307a8d896..000000000000 --- a/arch/arm/mach-imx/clk-imx1.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2008 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * 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. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include <linux/clk.h> -#include <linux/clkdev.h> -#include <linux/clk-provider.h> -#include <linux/err.h> -#include <linux/init.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <dt-bindings/clock/imx1-clock.h> - -#include "clk.h" -#include "common.h" -#include "hardware.h" - -static const char *prem_sel_clks[] = { "clk32_premult", "clk16m", }; -static const char *clko_sel_clks[] = { "per1", "hclk", "clk48m", "clk16m", - "prem", "fclk", }; - -static struct clk *clk[IMX1_CLK_MAX]; -static struct clk_onecell_data clk_data; - -static void __iomem *ccm __initdata; -#define CCM_CSCR (ccm + 0x0000) -#define CCM_MPCTL0 (ccm + 0x0004) -#define CCM_SPCTL0 (ccm + 0x000c) -#define CCM_PCDR (ccm + 0x0020) -#define SCM_GCCR (ccm + 0x0810) - -static void __init _mx1_clocks_init(unsigned long fref) -{ - clk[IMX1_CLK_DUMMY] = imx_clk_fixed("dummy", 0); - clk[IMX1_CLK_CLK32] = imx_obtain_fixed_clock("clk32", fref); - clk[IMX1_CLK_CLK16M_EXT] = imx_clk_fixed("clk16m_ext", 16000000); - clk[IMX1_CLK_CLK16M] = imx_clk_gate("clk16m", "clk16m_ext", CCM_CSCR, 17); - clk[IMX1_CLK_CLK32_PREMULT] = imx_clk_fixed_factor("clk32_premult", "clk32", 512, 1); - clk[IMX1_CLK_PREM] = imx_clk_mux("prem", CCM_CSCR, 16, 1, prem_sel_clks, ARRAY_SIZE(prem_sel_clks)); - clk[IMX1_CLK_MPLL] = imx_clk_pllv1("mpll", "clk32_premult", CCM_MPCTL0); - clk[IMX1_CLK_MPLL_GATE] = imx_clk_gate("mpll_gate", "mpll", CCM_CSCR, 0); - clk[IMX1_CLK_SPLL] = imx_clk_pllv1("spll", "prem", CCM_SPCTL0); - clk[IMX1_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1); - clk[IMX1_CLK_MCU] = imx_clk_divider("mcu", "clk32_premult", CCM_CSCR, 15, 1); - clk[IMX1_CLK_FCLK] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 15, 1); - clk[IMX1_CLK_HCLK] = imx_clk_divider("hclk", "spll_gate", CCM_CSCR, 10, 4); - clk[IMX1_CLK_CLK48M] = imx_clk_divider("clk48m", "spll_gate", CCM_CSCR, 26, 3); - clk[IMX1_CLK_PER1] = imx_clk_divider("per1", "spll_gate", CCM_PCDR, 0, 4); - clk[IMX1_CLK_PER2] = imx_clk_divider("per2", "spll_gate", CCM_PCDR, 4, 4); - clk[IMX1_CLK_PER3] = imx_clk_divider("per3", "spll_gate", CCM_PCDR, 16, 7); - clk[IMX1_CLK_CLKO] = imx_clk_mux("clko", CCM_CSCR, 29, 3, clko_sel_clks, ARRAY_SIZE(clko_sel_clks)); - clk[IMX1_CLK_UART3_GATE] = imx_clk_gate("uart3_gate", "hclk", SCM_GCCR, 6); - clk[IMX1_CLK_SSI2_GATE] = imx_clk_gate("ssi2_gate", "hclk", SCM_GCCR, 5); - clk[IMX1_CLK_BROM_GATE] = imx_clk_gate("brom_gate", "hclk", SCM_GCCR, 4); - clk[IMX1_CLK_DMA_GATE] = imx_clk_gate("dma_gate", "hclk", SCM_GCCR, 3); - clk[IMX1_CLK_CSI_GATE] = imx_clk_gate("csi_gate", "hclk", SCM_GCCR, 2); - clk[IMX1_CLK_MMA_GATE] = imx_clk_gate("mma_gate", "hclk", SCM_GCCR, 1); - clk[IMX1_CLK_USBD_GATE] = imx_clk_gate("usbd_gate", "clk48m", SCM_GCCR, 0); - - imx_check_clocks(clk, ARRAY_SIZE(clk)); -} - -int __init mx1_clocks_init(unsigned long fref) -{ - ccm = MX1_IO_ADDRESS(MX1_CCM_BASE_ADDR); - - _mx1_clocks_init(fref); - - clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx-gpt.0"); - clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx-gpt.0"); - clk_register_clkdev(clk[IMX1_CLK_DMA_GATE], "ahb", "imx1-dma"); - clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx1-dma"); - clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx1-uart.0"); - clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx1-uart.0"); - clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx1-uart.1"); - clk_register_clkdev(clk[IMX1_CLK_HCLK], "ipg", "imx1-uart.1"); - clk_register_clkdev(clk[IMX1_CLK_PER1], "per", "imx1-uart.2"); - clk_register_clkdev(clk[IMX1_CLK_UART3_GATE], "ipg", "imx1-uart.2"); - clk_register_clkdev(clk[IMX1_CLK_HCLK], NULL, "imx1-i2c.0"); - clk_register_clkdev(clk[IMX1_CLK_PER2], "per", "imx1-cspi.0"); - clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-cspi.0"); - clk_register_clkdev(clk[IMX1_CLK_PER2], "per", "imx1-cspi.1"); - clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-cspi.1"); - clk_register_clkdev(clk[IMX1_CLK_PER2], "per", "imx1-fb.0"); - clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ipg", "imx1-fb.0"); - clk_register_clkdev(clk[IMX1_CLK_DUMMY], "ahb", "imx1-fb.0"); - - mxc_timer_init(MX1_IO_ADDRESS(MX1_TIM1_BASE_ADDR), MX1_TIM1_INT); - - return 0; -} - -static void __init mx1_clocks_init_dt(struct device_node *np) -{ - ccm = of_iomap(np, 0); - BUG_ON(!ccm); - - _mx1_clocks_init(32768); - - clk_data.clks = clk; - clk_data.clk_num = ARRAY_SIZE(clk); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); -} -CLK_OF_DECLARE(imx1_ccm, "fsl,imx1-ccm", mx1_clocks_init_dt); diff --git a/arch/arm/mach-imx/clk-imx21.c b/arch/arm/mach-imx/clk-imx21.c deleted file mode 100644 index 4b4c75339aa6..000000000000 --- a/arch/arm/mach-imx/clk-imx21.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright 2008 Juergen Beisert, kernel@pengutronix.de - * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com - * - * 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. - */ - -#include <linux/clk.h> -#include <linux/clk-provider.h> -#include <linux/clkdev.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <dt-bindings/clock/imx21-clock.h> - -#include "clk.h" -#include "common.h" -#include "hardware.h" - -static void __iomem *ccm __initdata; - -/* Register offsets */ -#define CCM_CSCR (ccm + 0x00) -#define CCM_MPCTL0 (ccm + 0x04) -#define CCM_SPCTL0 (ccm + 0x0c) -#define CCM_PCDR0 (ccm + 0x18) -#define CCM_PCDR1 (ccm + 0x1c) -#define CCM_PCCR0 (ccm + 0x20) -#define CCM_PCCR1 (ccm + 0x24) - -static const char *mpll_osc_sel_clks[] = { "ckih_gate", "ckih_div1p5", }; -static const char *mpll_sel_clks[] = { "fpm_gate", "mpll_osc_sel", }; -static const char *spll_sel_clks[] = { "fpm_gate", "mpll_osc_sel", }; -static const char *ssi_sel_clks[] = { "spll_gate", "mpll_gate", }; - -static struct clk *clk[IMX21_CLK_MAX]; -static struct clk_onecell_data clk_data; - -static void __init _mx21_clocks_init(unsigned long lref, unsigned long href) -{ - BUG_ON(!ccm); - - clk[IMX21_CLK_DUMMY] = imx_clk_fixed("dummy", 0); - clk[IMX21_CLK_CKIL] = imx_obtain_fixed_clock("ckil", lref); - clk[IMX21_CLK_CKIH] = imx_obtain_fixed_clock("ckih", href); - clk[IMX21_CLK_FPM] = imx_clk_fixed_factor("fpm", "ckil", 512, 1); - clk[IMX21_CLK_CKIH_DIV1P5] = imx_clk_fixed_factor("ckih_div1p5", "ckih_gate", 2, 3); - - clk[IMX21_CLK_MPLL_GATE] = imx_clk_gate("mpll_gate", "mpll", CCM_CSCR, 0); - clk[IMX21_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1); - clk[IMX21_CLK_FPM_GATE] = imx_clk_gate("fpm_gate", "fpm", CCM_CSCR, 2); - clk[IMX21_CLK_CKIH_GATE] = imx_clk_gate_dis("ckih_gate", "ckih", CCM_CSCR, 3); - clk[IMX21_CLK_MPLL_OSC_SEL] = imx_clk_mux("mpll_osc_sel", CCM_CSCR, 4, 1, mpll_osc_sel_clks, ARRAY_SIZE(mpll_osc_sel_clks)); - clk[IMX21_CLK_IPG] = imx_clk_divider("ipg", "hclk", CCM_CSCR, 9, 1); - clk[IMX21_CLK_HCLK] = imx_clk_divider("hclk", "fclk", CCM_CSCR, 10, 4); - clk[IMX21_CLK_MPLL_SEL] = imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks, ARRAY_SIZE(mpll_sel_clks)); - clk[IMX21_CLK_SPLL_SEL] = imx_clk_mux("spll_sel", CCM_CSCR, 17, 1, spll_sel_clks, ARRAY_SIZE(spll_sel_clks)); - clk[IMX21_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", CCM_CSCR, 19, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks)); - clk[IMX21_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", CCM_CSCR, 20, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks)); - clk[IMX21_CLK_USB_DIV] = imx_clk_divider("usb_div", "spll_gate", CCM_CSCR, 26, 3); - clk[IMX21_CLK_FCLK] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 29, 3); - - clk[IMX21_CLK_MPLL] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0); - - clk[IMX21_CLK_SPLL] = imx_clk_pllv1("spll", "spll_sel", CCM_SPCTL0); - - clk[IMX21_CLK_NFC_DIV] = imx_clk_divider("nfc_div", "fclk", CCM_PCDR0, 12, 4); - clk[IMX21_CLK_SSI1_DIV] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6); - clk[IMX21_CLK_SSI2_DIV] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 6); - - clk[IMX21_CLK_PER1] = imx_clk_divider("per1", "mpll_gate", CCM_PCDR1, 0, 6); - clk[IMX21_CLK_PER2] = imx_clk_divider("per2", "mpll_gate", CCM_PCDR1, 8, 6); - clk[IMX21_CLK_PER3] = imx_clk_divider("per3", "mpll_gate", CCM_PCDR1, 16, 6); - clk[IMX21_CLK_PER4] = imx_clk_divider("per4", "mpll_gate", CCM_PCDR1, 24, 6); - - clk[IMX21_CLK_UART1_IPG_GATE] = imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR0, 0); - clk[IMX21_CLK_UART2_IPG_GATE] = imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR0, 1); - clk[IMX21_CLK_UART3_IPG_GATE] = imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR0, 2); - clk[IMX21_CLK_UART4_IPG_GATE] = imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR0, 3); - clk[IMX21_CLK_CSPI1_IPG_GATE] = imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 4); - clk[IMX21_CLK_CSPI2_IPG_GATE] = imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 5); - clk[IMX21_CLK_SSI1_GATE] = imx_clk_gate("ssi1_gate", "ipg", CCM_PCCR0, 6); - clk[IMX21_CLK_SSI2_GATE] = imx_clk_gate("ssi2_gate", "ipg", CCM_PCCR0, 7); - clk[IMX21_CLK_SDHC1_IPG_GATE] = imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 9); - clk[IMX21_CLK_SDHC2_IPG_GATE] = imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 10); - clk[IMX21_CLK_GPIO_GATE] = imx_clk_gate("gpio_gate", "ipg", CCM_PCCR0, 11); - clk[IMX21_CLK_I2C_GATE] = imx_clk_gate("i2c_gate", "ipg", CCM_PCCR0, 12); - clk[IMX21_CLK_DMA_GATE] = imx_clk_gate("dma_gate", "ipg", CCM_PCCR0, 13); - clk[IMX21_CLK_USB_GATE] = imx_clk_gate("usb_gate", "usb_div", CCM_PCCR0, 14); - clk[IMX21_CLK_EMMA_GATE] = imx_clk_gate("emma_gate", "ipg", CCM_PCCR0, 15); - clk[IMX21_CLK_SSI2_BAUD_GATE] = imx_clk_gate("ssi2_baud_gate", "ipg", CCM_PCCR0, 16); - clk[IMX21_CLK_SSI1_BAUD_GATE] = imx_clk_gate("ssi1_baud_gate", "ipg", CCM_PCCR0, 17); - clk[IMX21_CLK_LCDC_IPG_GATE] = imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 18); - clk[IMX21_CLK_NFC_GATE] = imx_clk_gate("nfc_gate", "nfc_div", CCM_PCCR0, 19); - clk[IMX21_CLK_SLCDC_HCLK_GATE] = imx_clk_gate("slcdc_hclk_gate", "hclk", CCM_PCCR0, 21); - clk[IMX21_CLK_PER4_GATE] = imx_clk_gate("per4_gate", "per4", CCM_PCCR0, 22); - clk[IMX21_CLK_BMI_GATE] = imx_clk_gate("bmi_gate", "hclk", CCM_PCCR0, 23); - clk[IMX21_CLK_USB_HCLK_GATE] = imx_clk_gate("usb_hclk_gate", "hclk", CCM_PCCR0, 24); - clk[IMX21_CLK_SLCDC_GATE] = imx_clk_gate("slcdc_gate", "hclk", CCM_PCCR0, 25); - clk[IMX21_CLK_LCDC_HCLK_GATE] = imx_clk_gate("lcdc_hclk_gate", "hclk", CCM_PCCR0, 26); - clk[IMX21_CLK_EMMA_HCLK_GATE] = imx_clk_gate("emma_hclk_gate", "hclk", CCM_PCCR0, 27); - clk[IMX21_CLK_BROM_GATE] = imx_clk_gate("brom_gate", "hclk", CCM_PCCR0, 28); - clk[IMX21_CLK_DMA_HCLK_GATE] = imx_clk_gate("dma_hclk_gate", "hclk", CCM_PCCR0, 30); - clk[IMX21_CLK_CSI_HCLK_GATE] = imx_clk_gate("csi_hclk_gate", "hclk", CCM_PCCR0, 31); - - clk[IMX21_CLK_CSPI3_IPG_GATE] = imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR1, 23); - clk[IMX21_CLK_WDOG_GATE] = imx_clk_gate("wdog_gate", "ipg", CCM_PCCR1, 24); - clk[IMX21_CLK_GPT1_IPG_GATE] = imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR1, 25); - clk[IMX21_CLK_GPT2_IPG_GATE] = imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR1, 26); - clk[IMX21_CLK_GPT3_IPG_GATE] = imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR1, 27); - clk[IMX21_CLK_PWM_IPG_GATE] = imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR1, 28); - clk[IMX21_CLK_RTC_GATE] = imx_clk_gate("rtc_gate", "ipg", CCM_PCCR1, 29); - clk[IMX21_CLK_KPP_GATE] = imx_clk_gate("kpp_gate", "ipg", CCM_PCCR1, 30); - clk[IMX21_CLK_OWIRE_GATE] = imx_clk_gate("owire_gate", "ipg", CCM_PCCR1, 31); - - imx_check_clocks(clk, ARRAY_SIZE(clk)); -} - -int __init mx21_clocks_init(unsigned long lref, unsigned long href) -{ - ccm = ioremap(MX21_CCM_BASE_ADDR, SZ_2K); - - _mx21_clocks_init(lref, href); - - clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.0"); - clk_register_clkdev(clk[IMX21_CLK_UART1_IPG_GATE], "ipg", "imx21-uart.0"); - clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.1"); - clk_register_clkdev(clk[IMX21_CLK_UART2_IPG_GATE], "ipg", "imx21-uart.1"); - clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.2"); - clk_register_clkdev(clk[IMX21_CLK_UART3_IPG_GATE], "ipg", "imx21-uart.2"); - clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.3"); - clk_register_clkdev(clk[IMX21_CLK_UART4_IPG_GATE], "ipg", "imx21-uart.3"); - clk_register_clkdev(clk[IMX21_CLK_GPT1_IPG_GATE], "ipg", "imx-gpt.0"); - clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx-gpt.0"); - clk_register_clkdev(clk[IMX21_CLK_PER2], "per", "imx21-cspi.0"); - clk_register_clkdev(clk[IMX21_CLK_CSPI1_IPG_GATE], "ipg", "imx21-cspi.0"); - clk_register_clkdev(clk[IMX21_CLK_PER2], "per", "imx21-cspi.1"); - clk_register_clkdev(clk[IMX21_CLK_CSPI2_IPG_GATE], "ipg", "imx21-cspi.1"); - clk_register_clkdev(clk[IMX21_CLK_PER2], "per", "imx21-cspi.2"); - clk_register_clkdev(clk[IMX21_CLK_CSPI3_IPG_GATE], "ipg", "imx21-cspi.2"); - clk_register_clkdev(clk[IMX21_CLK_PER3], "per", "imx21-fb.0"); - clk_register_clkdev(clk[IMX21_CLK_LCDC_IPG_GATE], "ipg", "imx21-fb.0"); - clk_register_clkdev(clk[IMX21_CLK_LCDC_HCLK_GATE], "ahb", "imx21-fb.0"); - clk_register_clkdev(clk[IMX21_CLK_USB_GATE], "per", "imx21-hcd.0"); - clk_register_clkdev(clk[IMX21_CLK_USB_HCLK_GATE], "ahb", "imx21-hcd.0"); - clk_register_clkdev(clk[IMX21_CLK_NFC_GATE], NULL, "imx21-nand.0"); - clk_register_clkdev(clk[IMX21_CLK_DMA_HCLK_GATE], "ahb", "imx21-dma"); - clk_register_clkdev(clk[IMX21_CLK_DMA_GATE], "ipg", "imx21-dma"); - clk_register_clkdev(clk[IMX21_CLK_WDOG_GATE], NULL, "imx2-wdt.0"); - clk_register_clkdev(clk[IMX21_CLK_I2C_GATE], NULL, "imx21-i2c.0"); - clk_register_clkdev(clk[IMX21_CLK_OWIRE_GATE], NULL, "mxc_w1.0"); - - mxc_timer_init(MX21_IO_ADDRESS(MX21_GPT1_BASE_ADDR), MX21_INT_GPT1); - - return 0; -} - -static void __init mx21_clocks_init_dt(struct device_node *np) -{ - ccm = of_iomap(np, 0); - - _mx21_clocks_init(32768, 26000000); - - clk_data.clks = clk; - clk_data.clk_num = ARRAY_SIZE(clk); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); -} -CLK_OF_DECLARE(imx27_ccm, "fsl,imx21-ccm", mx21_clocks_init_dt); diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c deleted file mode 100644 index 9c2633a9de9f..000000000000 --- a/arch/arm/mach-imx/clk-imx25.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * Copyright (C) 2009 by Sascha Hauer, Pengutronix - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/list.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/clkdev.h> -#include <linux/err.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> - -#include "clk.h" -#include "common.h" -#include "hardware.h" - -#define CCM_MPCTL 0x00 -#define CCM_UPCTL 0x04 -#define CCM_CCTL 0x08 -#define CCM_CGCR0 0x0C -#define CCM_CGCR1 0x10 -#define CCM_CGCR2 0x14 -#define CCM_PCDR0 0x18 -#define CCM_PCDR1 0x1C -#define CCM_PCDR2 0x20 -#define CCM_PCDR3 0x24 -#define CCM_RCSR 0x28 -#define CCM_CRDR 0x2C -#define CCM_DCVR0 0x30 -#define CCM_DCVR1 0x34 -#define CCM_DCVR2 0x38 -#define CCM_DCVR3 0x3c -#define CCM_LTR0 0x40 -#define CCM_LTR1 0x44 -#define CCM_LTR2 0x48 -#define CCM_LTR3 0x4c -#define CCM_MCR 0x64 - -#define ccm(x) (ccm_base + (x)) - -static struct clk_onecell_data clk_data; - -static const char *cpu_sel_clks[] = { "mpll", "mpll_cpu_3_4", }; -static const char *per_sel_clks[] = { "ahb", "upll", }; -static const char *cko_sel_clks[] = { "dummy", "osc", "cpu", "ahb", - "ipg", "dummy", "dummy", "dummy", - "dummy", "dummy", "per0", "per2", - "per13", "per14", "usbotg_ahb", "dummy",}; - -enum mx25_clks { - dummy, osc, mpll, upll, mpll_cpu_3_4, cpu_sel, cpu, ahb, usb_div, ipg, - per0_sel, per1_sel, per2_sel, per3_sel, per4_sel, per5_sel, per6_sel, - per7_sel, per8_sel, per9_sel, per10_sel, per11_sel, per12_sel, - per13_sel, per14_sel, per15_sel, per0, per1, per2, per3, per4, per5, - per6, per7, per8, per9, per10, per11, per12, per13, per14, per15, - csi_ipg_per, epit_ipg_per, esai_ipg_per, esdhc1_ipg_per, esdhc2_ipg_per, - gpt_ipg_per, i2c_ipg_per, lcdc_ipg_per, nfc_ipg_per, owire_ipg_per, - pwm_ipg_per, sim1_ipg_per, sim2_ipg_per, ssi1_ipg_per, ssi2_ipg_per, - uart_ipg_per, ata_ahb, reserved1, csi_ahb, emi_ahb, esai_ahb, esdhc1_ahb, - esdhc2_ahb, fec_ahb, lcdc_ahb, rtic_ahb, sdma_ahb, slcdc_ahb, usbotg_ahb, - reserved2, reserved3, reserved4, reserved5, can1_ipg, can2_ipg, csi_ipg, - cspi1_ipg, cspi2_ipg, cspi3_ipg, dryice_ipg, ect_ipg, epit1_ipg, epit2_ipg, - reserved6, esdhc1_ipg, esdhc2_ipg, fec_ipg, reserved7, reserved8, reserved9, - gpt1_ipg, gpt2_ipg, gpt3_ipg, gpt4_ipg, reserved10, reserved11, reserved12, - iim_ipg, reserved13, reserved14, kpp_ipg, lcdc_ipg, reserved15, pwm1_ipg, - pwm2_ipg, pwm3_ipg, pwm4_ipg, rngb_ipg, reserved16, scc_ipg, sdma_ipg, - sim1_ipg, sim2_ipg, slcdc_ipg, spba_ipg, ssi1_ipg, ssi2_ipg, tsc_ipg, - uart1_ipg, uart2_ipg, uart3_ipg, uart4_ipg, uart5_ipg, reserved17, - wdt_ipg, cko_div, cko_sel, cko, clk_max -}; - -static struct clk *clk[clk_max]; - -static int __init __mx25_clocks_init(unsigned long osc_rate, - void __iomem *ccm_base) -{ - BUG_ON(!ccm_base); - - clk[dummy] = imx_clk_fixed("dummy", 0); - clk[osc] = imx_clk_fixed("osc", osc_rate); - clk[mpll] = imx_clk_pllv1("mpll", "osc", ccm(CCM_MPCTL)); - clk[upll] = imx_clk_pllv1("upll", "osc", ccm(CCM_UPCTL)); - clk[mpll_cpu_3_4] = imx_clk_fixed_factor("mpll_cpu_3_4", "mpll", 3, 4); - clk[cpu_sel] = imx_clk_mux("cpu_sel", ccm(CCM_CCTL), 14, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks)); - clk[cpu] = imx_clk_divider("cpu", "cpu_sel", ccm(CCM_CCTL), 30, 2); - clk[ahb] = imx_clk_divider("ahb", "cpu", ccm(CCM_CCTL), 28, 2); - clk[usb_div] = imx_clk_divider("usb_div", "upll", ccm(CCM_CCTL), 16, 6); - clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2); - clk[per0_sel] = imx_clk_mux("per0_sel", ccm(CCM_MCR), 0, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); - clk[per1_sel] = imx_clk_mux("per1_sel", ccm(CCM_MCR), 1, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); - clk[per2_sel] = imx_clk_mux("per2_sel", ccm(CCM_MCR), 2, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); - clk[per3_sel] = imx_clk_mux("per3_sel", ccm(CCM_MCR), 3, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); - clk[per4_sel] = imx_clk_mux("per4_sel", ccm(CCM_MCR), 4, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); - clk[per5_sel] = imx_clk_mux("per5_sel", ccm(CCM_MCR), 5, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); - clk[per6_sel] = imx_clk_mux("per6_sel", ccm(CCM_MCR), 6, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); - clk[per7_sel] = imx_clk_mux("per7_sel", ccm(CCM_MCR), 7, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); - clk[per8_sel] = imx_clk_mux("per8_sel", ccm(CCM_MCR), 8, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); - clk[per9_sel] = imx_clk_mux("per9_sel", ccm(CCM_MCR), 9, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); - clk[per10_sel] = imx_clk_mux("per10_sel", ccm(CCM_MCR), 10, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); - clk[per11_sel] = imx_clk_mux("per11_sel", ccm(CCM_MCR), 11, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); - clk[per12_sel] = imx_clk_mux("per12_sel", ccm(CCM_MCR), 12, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); - clk[per13_sel] = imx_clk_mux("per13_sel", ccm(CCM_MCR), 13, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); - clk[per14_sel] = imx_clk_mux("per14_sel", ccm(CCM_MCR), 14, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); - clk[per15_sel] = imx_clk_mux("per15_sel", ccm(CCM_MCR), 15, 1, per_sel_clks, ARRAY_SIZE(per_sel_clks)); - clk[cko_div] = imx_clk_divider("cko_div", "cko_sel", ccm(CCM_MCR), 24, 6); - clk[cko_sel] = imx_clk_mux("cko_sel", ccm(CCM_MCR), 20, 4, cko_sel_clks, ARRAY_SIZE(cko_sel_clks)); - clk[cko] = imx_clk_gate("cko", "cko_div", ccm(CCM_MCR), 30); - clk[per0] = imx_clk_divider("per0", "per0_sel", ccm(CCM_PCDR0), 0, 6); - clk[per1] = imx_clk_divider("per1", "per1_sel", ccm(CCM_PCDR0), 8, 6); - clk[per2] = imx_clk_divider("per2", "per2_sel", ccm(CCM_PCDR0), 16, 6); - clk[per3] = imx_clk_divider("per3", "per3_sel", ccm(CCM_PCDR0), 24, 6); - clk[per4] = imx_clk_divider("per4", "per4_sel", ccm(CCM_PCDR1), 0, 6); - clk[per5] = imx_clk_divider("per5", "per5_sel", ccm(CCM_PCDR1), 8, 6); - clk[per6] = imx_clk_divider("per6", "per6_sel", ccm(CCM_PCDR1), 16, 6); - clk[per7] = imx_clk_divider("per7", "per7_sel", ccm(CCM_PCDR1), 24, 6); - clk[per8] = imx_clk_divider("per8", "per8_sel", ccm(CCM_PCDR2), 0, 6); - clk[per9] = imx_clk_divider("per9", "per9_sel", ccm(CCM_PCDR2), 8, 6); - clk[per10] = imx_clk_divider("per10", "per10_sel", ccm(CCM_PCDR2), 16, 6); - clk[per11] = imx_clk_divider("per11", "per11_sel", ccm(CCM_PCDR2), 24, 6); - clk[per12] = imx_clk_divider("per12", "per12_sel", ccm(CCM_PCDR3), 0, 6); - clk[per13] = imx_clk_divider("per13", "per13_sel", ccm(CCM_PCDR3), 8, 6); - clk[per14] = imx_clk_divider("per14", "per14_sel", ccm(CCM_PCDR3), 16, 6); - clk[per15] = imx_clk_divider("per15", "per15_sel", ccm(CCM_PCDR3), 24, 6); - clk[csi_ipg_per] = imx_clk_gate("csi_ipg_per", "per0", ccm(CCM_CGCR0), 0); - clk[epit_ipg_per] = imx_clk_gate("epit_ipg_per", "per1", ccm(CCM_CGCR0), 1); - clk[esai_ipg_per] = imx_clk_gate("esai_ipg_per", "per2", ccm(CCM_CGCR0), 2); - clk[esdhc1_ipg_per] = imx_clk_gate("esdhc1_ipg_per", "per3", ccm(CCM_CGCR0), 3); - clk[esdhc2_ipg_per] = imx_clk_gate("esdhc2_ipg_per", "per4", ccm(CCM_CGCR0), 4); - clk[gpt_ipg_per] = imx_clk_gate("gpt_ipg_per", "per5", ccm(CCM_CGCR0), 5); - clk[i2c_ipg_per] = imx_clk_gate("i2c_ipg_per", "per6", ccm(CCM_CGCR0), 6); - clk[lcdc_ipg_per] = imx_clk_gate("lcdc_ipg_per", "per7", ccm(CCM_CGCR0), 7); - clk[nfc_ipg_per] = imx_clk_gate("nfc_ipg_per", "per8", ccm(CCM_CGCR0), 8); - clk[owire_ipg_per] = imx_clk_gate("owire_ipg_per", "per9", ccm(CCM_CGCR0), 9); - clk[pwm_ipg_per] = imx_clk_gate("pwm_ipg_per", "per10", ccm(CCM_CGCR0), 10); - clk[sim1_ipg_per] = imx_clk_gate("sim1_ipg_per", "per11", ccm(CCM_CGCR0), 11); - clk[sim2_ipg_per] = imx_clk_gate("sim2_ipg_per", "per12", ccm(CCM_CGCR0), 12); - clk[ssi1_ipg_per] = imx_clk_gate("ssi1_ipg_per", "per13", ccm(CCM_CGCR0), 13); - clk[ssi2_ipg_per] = imx_clk_gate("ssi2_ipg_per", "per14", ccm(CCM_CGCR0), 14); - clk[uart_ipg_per] = imx_clk_gate("uart_ipg_per", "per15", ccm(CCM_CGCR0), 15); - clk[ata_ahb] = imx_clk_gate("ata_ahb", "ahb", ccm(CCM_CGCR0), 16); - /* CCM_CGCR0(17): reserved */ - clk[csi_ahb] = imx_clk_gate("csi_ahb", "ahb", ccm(CCM_CGCR0), 18); - clk[emi_ahb] = imx_clk_gate("emi_ahb", "ahb", ccm(CCM_CGCR0), 19); - clk[esai_ahb] = imx_clk_gate("esai_ahb", "ahb", ccm(CCM_CGCR0), 20); - clk[esdhc1_ahb] = imx_clk_gate("esdhc1_ahb", "ahb", ccm(CCM_CGCR0), 21); - clk[esdhc2_ahb] = imx_clk_gate("esdhc2_ahb", "ahb", ccm(CCM_CGCR0), 22); - clk[fec_ahb] = imx_clk_gate("fec_ahb", "ahb", ccm(CCM_CGCR0), 23); - clk[lcdc_ahb] = imx_clk_gate("lcdc_ahb", "ahb", ccm(CCM_CGCR0), 24); - clk[rtic_ahb] = imx_clk_gate("rtic_ahb", "ahb", ccm(CCM_CGCR0), 25); - clk[sdma_ahb] = imx_clk_gate("sdma_ahb", "ahb", ccm(CCM_CGCR0), 26); - clk[slcdc_ahb] = imx_clk_gate("slcdc_ahb", "ahb", ccm(CCM_CGCR0), 27); - clk[usbotg_ahb] = imx_clk_gate("usbotg_ahb", "ahb", ccm(CCM_CGCR0), 28); - /* CCM_CGCR0(29-31): reserved */ - /* CCM_CGCR1(0): reserved in datasheet, used as audmux in FSL kernel */ - clk[can1_ipg] = imx_clk_gate("can1_ipg", "ipg", ccm(CCM_CGCR1), 2); - clk[can2_ipg] = imx_clk_gate("can2_ipg", "ipg", ccm(CCM_CGCR1), 3); - clk[csi_ipg] = imx_clk_gate("csi_ipg", "ipg", ccm(CCM_CGCR1), 4); - clk[cspi1_ipg] = imx_clk_gate("cspi1_ipg", "ipg", ccm(CCM_CGCR1), 5); - clk[cspi2_ipg] = imx_clk_gate("cspi2_ipg", "ipg", ccm(CCM_CGCR1), 6); - clk[cspi3_ipg] = imx_clk_gate("cspi3_ipg", "ipg", ccm(CCM_CGCR1), 7); - clk[dryice_ipg] = imx_clk_gate("dryice_ipg", "ipg", ccm(CCM_CGCR1), 8); - clk[ect_ipg] = imx_clk_gate("ect_ipg", "ipg", ccm(CCM_CGCR1), 9); - clk[epit1_ipg] = imx_clk_gate("epit1_ipg", "ipg", ccm(CCM_CGCR1), 10); - clk[epit2_ipg] = imx_clk_gate("epit2_ipg", "ipg", ccm(CCM_CGCR1), 11); - /* CCM_CGCR1(12): reserved in datasheet, used as esai in FSL kernel */ - clk[esdhc1_ipg] = imx_clk_gate("esdhc1_ipg", "ipg", ccm(CCM_CGCR1), 13); - clk[esdhc2_ipg] = imx_clk_gate("esdhc2_ipg", "ipg", ccm(CCM_CGCR1), 14); - clk[fec_ipg] = imx_clk_gate("fec_ipg", "ipg", ccm(CCM_CGCR1), 15); - /* CCM_CGCR1(16): reserved in datasheet, used as gpio1 in FSL kernel */ - /* CCM_CGCR1(17): reserved in datasheet, used as gpio2 in FSL kernel */ - /* CCM_CGCR1(18): reserved in datasheet, used as gpio3 in FSL kernel */ - clk[gpt1_ipg] = imx_clk_gate("gpt1_ipg", "ipg", ccm(CCM_CGCR1), 19); - clk[gpt2_ipg] = imx_clk_gate("gpt2_ipg", "ipg", ccm(CCM_CGCR1), 20); - clk[gpt3_ipg] = imx_clk_gate("gpt3_ipg", "ipg", ccm(CCM_CGCR1), 21); - clk[gpt4_ipg] = imx_clk_gate("gpt4_ipg", "ipg", ccm(CCM_CGCR1), 22); - /* CCM_CGCR1(23): reserved in datasheet, used as i2c1 in FSL kernel */ - /* CCM_CGCR1(24): reserved in datasheet, used as i2c2 in FSL kernel */ - /* CCM_CGCR1(25): reserved in datasheet, used as i2c3 in FSL kernel */ - clk[iim_ipg] = imx_clk_gate("iim_ipg", "ipg", ccm(CCM_CGCR1), 26); - /* CCM_CGCR1(27): reserved in datasheet, used as iomuxc in FSL kernel */ - /* CCM_CGCR1(28): reserved in datasheet, used as kpp in FSL kernel */ - clk[kpp_ipg] = imx_clk_gate("kpp_ipg", "ipg", ccm(CCM_CGCR1), 28); - clk[lcdc_ipg] = imx_clk_gate("lcdc_ipg", "ipg", ccm(CCM_CGCR1), 29); - /* CCM_CGCR1(30): reserved in datasheet, used as owire in FSL kernel */ - clk[pwm1_ipg] = imx_clk_gate("pwm1_ipg", "ipg", ccm(CCM_CGCR1), 31); - clk[pwm2_ipg] = imx_clk_gate("pwm2_ipg", "ipg", ccm(CCM_CGCR2), 0); - clk[pwm3_ipg] = imx_clk_gate("pwm3_ipg", "ipg", ccm(CCM_CGCR2), 1); - clk[pwm4_ipg] = imx_clk_gate("pwm4_ipg", "ipg", ccm(CCM_CGCR2), 2); - clk[rngb_ipg] = imx_clk_gate("rngb_ipg", "ipg", ccm(CCM_CGCR2), 3); - /* CCM_CGCR2(4): reserved in datasheet, used as rtic in FSL kernel */ - clk[scc_ipg] = imx_clk_gate("scc_ipg", "ipg", ccm(CCM_CGCR2), 5); - clk[sdma_ipg] = imx_clk_gate("sdma_ipg", "ipg", ccm(CCM_CGCR2), 6); - clk[sim1_ipg] = imx_clk_gate("sim1_ipg", "ipg", ccm(CCM_CGCR2), 7); - clk[sim2_ipg] = imx_clk_gate("sim2_ipg", "ipg", ccm(CCM_CGCR2), 8); - clk[slcdc_ipg] = imx_clk_gate("slcdc_ipg", "ipg", ccm(CCM_CGCR2), 9); - clk[spba_ipg] = imx_clk_gate("spba_ipg", "ipg", ccm(CCM_CGCR2), 10); - clk[ssi1_ipg] = imx_clk_gate("ssi1_ipg", "ipg", ccm(CCM_CGCR2), 11); - clk[ssi2_ipg] = imx_clk_gate("ssi2_ipg", "ipg", ccm(CCM_CGCR2), 12); - clk[tsc_ipg] = imx_clk_gate("tsc_ipg", "ipg", ccm(CCM_CGCR2), 13); - clk[uart1_ipg] = imx_clk_gate("uart1_ipg", "ipg", ccm(CCM_CGCR2), 14); - clk[uart2_ipg] = imx_clk_gate("uart2_ipg", "ipg", ccm(CCM_CGCR2), 15); - clk[uart3_ipg] = imx_clk_gate("uart3_ipg", "ipg", ccm(CCM_CGCR2), 16); - clk[uart4_ipg] = imx_clk_gate("uart4_ipg", "ipg", ccm(CCM_CGCR2), 17); - clk[uart5_ipg] = imx_clk_gate("uart5_ipg", "ipg", ccm(CCM_CGCR2), 18); - /* CCM_CGCR2(19): reserved in datasheet, but used as wdt in FSL kernel */ - clk[wdt_ipg] = imx_clk_gate("wdt_ipg", "ipg", ccm(CCM_CGCR2), 19); - - imx_check_clocks(clk, ARRAY_SIZE(clk)); - - clk_prepare_enable(clk[emi_ahb]); - - /* Clock source for gpt must be derived from AHB */ - clk_set_parent(clk[per5_sel], clk[ahb]); - - /* - * Let's initially set up CLKO parent as ipg, since this configuration - * is used on some imx25 board designs to clock the audio codec. - */ - clk_set_parent(clk[cko_sel], clk[ipg]); - - return 0; -} - -static void __init mx25_clocks_init_dt(struct device_node *np) -{ - struct device_node *refnp; - unsigned long osc_rate = 24000000; - void __iomem *ccm; - - /* retrieve the freqency of fixed clocks from device tree */ - for_each_compatible_node(refnp, NULL, "fixed-clock") { - u32 rate; - if (of_property_read_u32(refnp, "clock-frequency", &rate)) - continue; - - if (of_device_is_compatible(refnp, "fsl,imx-osc")) - osc_rate = rate; - } - - ccm = of_iomap(np, 0); - __mx25_clocks_init(osc_rate, ccm); - - clk_data.clks = clk; - clk_data.clk_num = ARRAY_SIZE(clk); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); -} -CLK_OF_DECLARE(imx25_ccm, "fsl,imx25-ccm", mx25_clocks_init_dt); diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c deleted file mode 100644 index ab6349ec23b9..000000000000 --- a/arch/arm/mach-imx/clk-imx27.c +++ /dev/null @@ -1,258 +0,0 @@ -#include <linux/clk.h> -#include <linux/clk-provider.h> -#include <linux/clkdev.h> -#include <linux/err.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <dt-bindings/clock/imx27-clock.h> - -#include "clk.h" -#include "common.h" -#include "hardware.h" - -static void __iomem *ccm __initdata; - -/* Register offsets */ -#define CCM_CSCR (ccm + 0x00) -#define CCM_MPCTL0 (ccm + 0x04) -#define CCM_MPCTL1 (ccm + 0x08) -#define CCM_SPCTL0 (ccm + 0x0c) -#define CCM_SPCTL1 (ccm + 0x10) -#define CCM_PCDR0 (ccm + 0x18) -#define CCM_PCDR1 (ccm + 0x1c) -#define CCM_PCCR0 (ccm + 0x20) -#define CCM_PCCR1 (ccm + 0x24) -#define CCM_CCSR (ccm + 0x28) - -static const char *vpu_sel_clks[] = { "spll", "mpll_main2", }; -static const char *cpu_sel_clks[] = { "mpll_main2", "mpll", }; -static const char *mpll_sel_clks[] = { "fpm", "mpll_osc_sel", }; -static const char *mpll_osc_sel_clks[] = { "ckih_gate", "ckih_div1p5", }; -static const char *clko_sel_clks[] = { - "ckil", "fpm", "ckih_gate", "ckih_gate", - "ckih_gate", "mpll", "spll", "cpu_div", - "ahb", "ipg", "per1_div", "per2_div", - "per3_div", "per4_div", "ssi1_div", "ssi2_div", - "nfc_div", "mshc_div", "vpu_div", "60m", - "32k", "usb_div", "dptc", -}; - -static const char *ssi_sel_clks[] = { "spll_gate", "mpll", }; - -static struct clk *clk[IMX27_CLK_MAX]; -static struct clk_onecell_data clk_data; - -static void __init _mx27_clocks_init(unsigned long fref) -{ - BUG_ON(!ccm); - - clk[IMX27_CLK_DUMMY] = imx_clk_fixed("dummy", 0); - clk[IMX27_CLK_CKIH] = imx_clk_fixed("ckih", fref); - clk[IMX27_CLK_CKIL] = imx_clk_fixed("ckil", 32768); - clk[IMX27_CLK_FPM] = imx_clk_fixed_factor("fpm", "ckil", 1024, 1); - clk[IMX27_CLK_CKIH_DIV1P5] = imx_clk_fixed_factor("ckih_div1p5", "ckih_gate", 2, 3); - clk[IMX27_CLK_CKIH_GATE] = imx_clk_gate_dis("ckih_gate", "ckih", CCM_CSCR, 3); - clk[IMX27_CLK_MPLL_OSC_SEL] = imx_clk_mux("mpll_osc_sel", CCM_CSCR, 4, 1, mpll_osc_sel_clks, ARRAY_SIZE(mpll_osc_sel_clks)); - clk[IMX27_CLK_MPLL_SEL] = imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks, ARRAY_SIZE(mpll_sel_clks)); - clk[IMX27_CLK_MPLL] = imx_clk_pllv1("mpll", "mpll_sel", CCM_MPCTL0); - clk[IMX27_CLK_SPLL] = imx_clk_pllv1("spll", "ckih_gate", CCM_SPCTL0); - clk[IMX27_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1); - clk[IMX27_CLK_MPLL_MAIN2] = imx_clk_fixed_factor("mpll_main2", "mpll", 2, 3); - - if (mx27_revision() >= IMX_CHIP_REVISION_2_0) { - clk[IMX27_CLK_AHB] = imx_clk_divider("ahb", "mpll_main2", CCM_CSCR, 8, 2); - clk[IMX27_CLK_IPG] = imx_clk_fixed_factor("ipg", "ahb", 1, 2); - } else { - clk[IMX27_CLK_AHB] = imx_clk_divider("ahb", "mpll_main2", CCM_CSCR, 9, 4); - clk[IMX27_CLK_IPG] = imx_clk_divider("ipg", "ahb", CCM_CSCR, 8, 1); - } - - clk[IMX27_CLK_MSHC_DIV] = imx_clk_divider("mshc_div", "ahb", CCM_PCDR0, 0, 6); - clk[IMX27_CLK_NFC_DIV] = imx_clk_divider("nfc_div", "ahb", CCM_PCDR0, 6, 4); - clk[IMX27_CLK_PER1_DIV] = imx_clk_divider("per1_div", "mpll_main2", CCM_PCDR1, 0, 6); - clk[IMX27_CLK_PER2_DIV] = imx_clk_divider("per2_div", "mpll_main2", CCM_PCDR1, 8, 6); - clk[IMX27_CLK_PER3_DIV] = imx_clk_divider("per3_div", "mpll_main2", CCM_PCDR1, 16, 6); - clk[IMX27_CLK_PER4_DIV] = imx_clk_divider("per4_div", "mpll_main2", CCM_PCDR1, 24, 6); - clk[IMX27_CLK_VPU_SEL] = imx_clk_mux("vpu_sel", CCM_CSCR, 21, 1, vpu_sel_clks, ARRAY_SIZE(vpu_sel_clks)); - clk[IMX27_CLK_VPU_DIV] = imx_clk_divider("vpu_div", "vpu_sel", CCM_PCDR0, 10, 6); - clk[IMX27_CLK_USB_DIV] = imx_clk_divider("usb_div", "spll_gate", CCM_CSCR, 28, 3); - clk[IMX27_CLK_CPU_SEL] = imx_clk_mux("cpu_sel", CCM_CSCR, 15, 1, cpu_sel_clks, ARRAY_SIZE(cpu_sel_clks)); - clk[IMX27_CLK_CLKO_SEL] = imx_clk_mux("clko_sel", CCM_CCSR, 0, 5, clko_sel_clks, ARRAY_SIZE(clko_sel_clks)); - - if (mx27_revision() >= IMX_CHIP_REVISION_2_0) - clk[IMX27_CLK_CPU_DIV] = imx_clk_divider("cpu_div", "cpu_sel", CCM_CSCR, 12, 2); - else - clk[IMX27_CLK_CPU_DIV] = imx_clk_divider("cpu_div", "cpu_sel", CCM_CSCR, 13, 3); - - clk[IMX27_CLK_CLKO_DIV] = imx_clk_divider("clko_div", "clko_sel", CCM_PCDR0, 22, 3); - clk[IMX27_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", CCM_CSCR, 22, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks)); - clk[IMX27_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", CCM_CSCR, 23, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks)); - clk[IMX27_CLK_SSI1_DIV] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6); - clk[IMX27_CLK_SSI2_DIV] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 6); - clk[IMX27_CLK_CLKO_EN] = imx_clk_gate("clko_en", "clko_div", CCM_PCCR0, 0); - clk[IMX27_CLK_SSI2_IPG_GATE] = imx_clk_gate("ssi2_ipg_gate", "ipg", CCM_PCCR0, 0); - clk[IMX27_CLK_SSI1_IPG_GATE] = imx_clk_gate("ssi1_ipg_gate", "ipg", CCM_PCCR0, 1); - clk[IMX27_CLK_SLCDC_IPG_GATE] = imx_clk_gate("slcdc_ipg_gate", "ipg", CCM_PCCR0, 2); - clk[IMX27_CLK_SDHC3_IPG_GATE] = imx_clk_gate("sdhc3_ipg_gate", "ipg", CCM_PCCR0, 3); - clk[IMX27_CLK_SDHC2_IPG_GATE] = imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 4); - clk[IMX27_CLK_SDHC1_IPG_GATE] = imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 5); - clk[IMX27_CLK_SCC_IPG_GATE] = imx_clk_gate("scc_ipg_gate", "ipg", CCM_PCCR0, 6); - clk[IMX27_CLK_SAHARA_IPG_GATE] = imx_clk_gate("sahara_ipg_gate", "ipg", CCM_PCCR0, 7); - clk[IMX27_CLK_RTIC_IPG_GATE] = imx_clk_gate("rtic_ipg_gate", "ipg", CCM_PCCR0, 8); - clk[IMX27_CLK_RTC_IPG_GATE] = imx_clk_gate("rtc_ipg_gate", "ipg", CCM_PCCR0, 9); - clk[IMX27_CLK_PWM_IPG_GATE] = imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR0, 11); - clk[IMX27_CLK_OWIRE_IPG_GATE] = imx_clk_gate("owire_ipg_gate", "ipg", CCM_PCCR0, 12); - clk[IMX27_CLK_MSHC_IPG_GATE] = imx_clk_gate("mshc_ipg_gate", "ipg", CCM_PCCR0, 13); - clk[IMX27_CLK_LCDC_IPG_GATE] = imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 14); - clk[IMX27_CLK_KPP_IPG_GATE] = imx_clk_gate("kpp_ipg_gate", "ipg", CCM_PCCR0, 15); - clk[IMX27_CLK_IIM_IPG_GATE] = imx_clk_gate("iim_ipg_gate", "ipg", CCM_PCCR0, 16); - clk[IMX27_CLK_I2C2_IPG_GATE] = imx_clk_gate("i2c2_ipg_gate", "ipg", CCM_PCCR0, 17); - clk[IMX27_CLK_I2C1_IPG_GATE] = imx_clk_gate("i2c1_ipg_gate", "ipg", CCM_PCCR0, 18); - clk[IMX27_CLK_GPT6_IPG_GATE] = imx_clk_gate("gpt6_ipg_gate", "ipg", CCM_PCCR0, 19); - clk[IMX27_CLK_GPT5_IPG_GATE] = imx_clk_gate("gpt5_ipg_gate", "ipg", CCM_PCCR0, 20); - clk[IMX27_CLK_GPT4_IPG_GATE] = imx_clk_gate("gpt4_ipg_gate", "ipg", CCM_PCCR0, 21); - clk[IMX27_CLK_GPT3_IPG_GATE] = imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR0, 22); - clk[IMX27_CLK_GPT2_IPG_GATE] = imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR0, 23); - clk[IMX27_CLK_GPT1_IPG_GATE] = imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR0, 24); - clk[IMX27_CLK_GPIO_IPG_GATE] = imx_clk_gate("gpio_ipg_gate", "ipg", CCM_PCCR0, 25); - clk[IMX27_CLK_FEC_IPG_GATE] = imx_clk_gate("fec_ipg_gate", "ipg", CCM_PCCR0, 26); - clk[IMX27_CLK_EMMA_IPG_GATE] = imx_clk_gate("emma_ipg_gate", "ipg", CCM_PCCR0, 27); - clk[IMX27_CLK_DMA_IPG_GATE] = imx_clk_gate("dma_ipg_gate", "ipg", CCM_PCCR0, 28); - clk[IMX27_CLK_CSPI3_IPG_GATE] = imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR0, 29); - clk[IMX27_CLK_CSPI2_IPG_GATE] = imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 30); - clk[IMX27_CLK_CSPI1_IPG_GATE] = imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 31); - clk[IMX27_CLK_MSHC_BAUD_GATE] = imx_clk_gate("mshc_baud_gate", "mshc_div", CCM_PCCR1, 2); - clk[IMX27_CLK_NFC_BAUD_GATE] = imx_clk_gate("nfc_baud_gate", "nfc_div", CCM_PCCR1, 3); - clk[IMX27_CLK_SSI2_BAUD_GATE] = imx_clk_gate("ssi2_baud_gate", "ssi2_div", CCM_PCCR1, 4); - clk[IMX27_CLK_SSI1_BAUD_GATE] = imx_clk_gate("ssi1_baud_gate", "ssi1_div", CCM_PCCR1, 5); - clk[IMX27_CLK_VPU_BAUD_GATE] = imx_clk_gate("vpu_baud_gate", "vpu_div", CCM_PCCR1, 6); - clk[IMX27_CLK_PER4_GATE] = imx_clk_gate("per4_gate", "per4_div", CCM_PCCR1, 7); - clk[IMX27_CLK_PER3_GATE] = imx_clk_gate("per3_gate", "per3_div", CCM_PCCR1, 8); - clk[IMX27_CLK_PER2_GATE] = imx_clk_gate("per2_gate", "per2_div", CCM_PCCR1, 9); - clk[IMX27_CLK_PER1_GATE] = imx_clk_gate("per1_gate", "per1_div", CCM_PCCR1, 10); - clk[IMX27_CLK_USB_AHB_GATE] = imx_clk_gate("usb_ahb_gate", "ahb", CCM_PCCR1, 11); - clk[IMX27_CLK_SLCDC_AHB_GATE] = imx_clk_gate("slcdc_ahb_gate", "ahb", CCM_PCCR1, 12); - clk[IMX27_CLK_SAHARA_AHB_GATE] = imx_clk_gate("sahara_ahb_gate", "ahb", CCM_PCCR1, 13); - clk[IMX27_CLK_RTIC_AHB_GATE] = imx_clk_gate("rtic_ahb_gate", "ahb", CCM_PCCR1, 14); - clk[IMX27_CLK_LCDC_AHB_GATE] = imx_clk_gate("lcdc_ahb_gate", "ahb", CCM_PCCR1, 15); - clk[IMX27_CLK_VPU_AHB_GATE] = imx_clk_gate("vpu_ahb_gate", "ahb", CCM_PCCR1, 16); - clk[IMX27_CLK_FEC_AHB_GATE] = imx_clk_gate("fec_ahb_gate", "ahb", CCM_PCCR1, 17); - clk[IMX27_CLK_EMMA_AHB_GATE] = imx_clk_gate("emma_ahb_gate", "ahb", CCM_PCCR1, 18); - clk[IMX27_CLK_EMI_AHB_GATE] = imx_clk_gate("emi_ahb_gate", "ahb", CCM_PCCR1, 19); - clk[IMX27_CLK_DMA_AHB_GATE] = imx_clk_gate("dma_ahb_gate", "ahb", CCM_PCCR1, 20); - clk[IMX27_CLK_CSI_AHB_GATE] = imx_clk_gate("csi_ahb_gate", "ahb", CCM_PCCR1, 21); - clk[IMX27_CLK_BROM_AHB_GATE] = imx_clk_gate("brom_ahb_gate", "ahb", CCM_PCCR1, 22); - clk[IMX27_CLK_ATA_AHB_GATE] = imx_clk_gate("ata_ahb_gate", "ahb", CCM_PCCR1, 23); - clk[IMX27_CLK_WDOG_IPG_GATE] = imx_clk_gate("wdog_ipg_gate", "ipg", CCM_PCCR1, 24); - clk[IMX27_CLK_USB_IPG_GATE] = imx_clk_gate("usb_ipg_gate", "ipg", CCM_PCCR1, 25); - clk[IMX27_CLK_UART6_IPG_GATE] = imx_clk_gate("uart6_ipg_gate", "ipg", CCM_PCCR1, 26); - clk[IMX27_CLK_UART5_IPG_GATE] = imx_clk_gate("uart5_ipg_gate", "ipg", CCM_PCCR1, 27); - clk[IMX27_CLK_UART4_IPG_GATE] = imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR1, 28); - clk[IMX27_CLK_UART3_IPG_GATE] = imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR1, 29); - clk[IMX27_CLK_UART2_IPG_GATE] = imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR1, 30); - clk[IMX27_CLK_UART1_IPG_GATE] = imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR1, 31); - - imx_check_clocks(clk, ARRAY_SIZE(clk)); - - clk_register_clkdev(clk[IMX27_CLK_CPU_DIV], NULL, "cpu0"); - - clk_prepare_enable(clk[IMX27_CLK_EMI_AHB_GATE]); - - imx_print_silicon_rev("i.MX27", mx27_revision()); -} - -int __init mx27_clocks_init(unsigned long fref) -{ - ccm = ioremap(MX27_CCM_BASE_ADDR, SZ_4K); - - _mx27_clocks_init(fref); - - clk_register_clkdev(clk[IMX27_CLK_UART1_IPG_GATE], "ipg", "imx21-uart.0"); - clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.0"); - clk_register_clkdev(clk[IMX27_CLK_UART2_IPG_GATE], "ipg", "imx21-uart.1"); - clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.1"); - clk_register_clkdev(clk[IMX27_CLK_UART3_IPG_GATE], "ipg", "imx21-uart.2"); - clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.2"); - clk_register_clkdev(clk[IMX27_CLK_UART4_IPG_GATE], "ipg", "imx21-uart.3"); - clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.3"); - clk_register_clkdev(clk[IMX27_CLK_UART5_IPG_GATE], "ipg", "imx21-uart.4"); - clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.4"); - clk_register_clkdev(clk[IMX27_CLK_UART6_IPG_GATE], "ipg", "imx21-uart.5"); - clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx21-uart.5"); - clk_register_clkdev(clk[IMX27_CLK_GPT1_IPG_GATE], "ipg", "imx-gpt.0"); - clk_register_clkdev(clk[IMX27_CLK_PER1_GATE], "per", "imx-gpt.0"); - clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx21-mmc.0"); - clk_register_clkdev(clk[IMX27_CLK_SDHC1_IPG_GATE], "ipg", "imx21-mmc.0"); - clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx21-mmc.1"); - clk_register_clkdev(clk[IMX27_CLK_SDHC2_IPG_GATE], "ipg", "imx21-mmc.1"); - clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx21-mmc.2"); - clk_register_clkdev(clk[IMX27_CLK_SDHC2_IPG_GATE], "ipg", "imx21-mmc.2"); - clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx27-cspi.0"); - clk_register_clkdev(clk[IMX27_CLK_CSPI1_IPG_GATE], "ipg", "imx27-cspi.0"); - clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx27-cspi.1"); - clk_register_clkdev(clk[IMX27_CLK_CSPI2_IPG_GATE], "ipg", "imx27-cspi.1"); - clk_register_clkdev(clk[IMX27_CLK_PER2_GATE], "per", "imx27-cspi.2"); - clk_register_clkdev(clk[IMX27_CLK_CSPI3_IPG_GATE], "ipg", "imx27-cspi.2"); - clk_register_clkdev(clk[IMX27_CLK_PER3_GATE], "per", "imx21-fb.0"); - clk_register_clkdev(clk[IMX27_CLK_LCDC_IPG_GATE], "ipg", "imx21-fb.0"); - clk_register_clkdev(clk[IMX27_CLK_LCDC_AHB_GATE], "ahb", "imx21-fb.0"); - clk_register_clkdev(clk[IMX27_CLK_CSI_AHB_GATE], "ahb", "imx27-camera.0"); - clk_register_clkdev(clk[IMX27_CLK_PER4_GATE], "per", "imx27-camera.0"); - clk_register_clkdev(clk[IMX27_CLK_USB_DIV], "per", "imx-udc-mx27"); - clk_register_clkdev(clk[IMX27_CLK_USB_IPG_GATE], "ipg", "imx-udc-mx27"); - clk_register_clkdev(clk[IMX27_CLK_USB_AHB_GATE], "ahb", "imx-udc-mx27"); - clk_register_clkdev(clk[IMX27_CLK_USB_DIV], "per", "mxc-ehci.0"); - clk_register_clkdev(clk[IMX27_CLK_USB_IPG_GATE], "ipg", "mxc-ehci.0"); - clk_register_clkdev(clk[IMX27_CLK_USB_AHB_GATE], "ahb", "mxc-ehci.0"); - clk_register_clkdev(clk[IMX27_CLK_USB_DIV], "per", "mxc-ehci.1"); - clk_register_clkdev(clk[IMX27_CLK_USB_IPG_GATE], "ipg", "mxc-ehci.1"); - clk_register_clkdev(clk[IMX27_CLK_USB_AHB_GATE], "ahb", "mxc-ehci.1"); - clk_register_clkdev(clk[IMX27_CLK_USB_DIV], "per", "mxc-ehci.2"); - clk_register_clkdev(clk[IMX27_CLK_USB_IPG_GATE], "ipg", "mxc-ehci.2"); - clk_register_clkdev(clk[IMX27_CLK_USB_AHB_GATE], "ahb", "mxc-ehci.2"); - clk_register_clkdev(clk[IMX27_CLK_SSI1_IPG_GATE], NULL, "imx-ssi.0"); - clk_register_clkdev(clk[IMX27_CLK_SSI2_IPG_GATE], NULL, "imx-ssi.1"); - clk_register_clkdev(clk[IMX27_CLK_NFC_BAUD_GATE], NULL, "imx27-nand.0"); - clk_register_clkdev(clk[IMX27_CLK_VPU_BAUD_GATE], "per", "coda-imx27.0"); - clk_register_clkdev(clk[IMX27_CLK_VPU_AHB_GATE], "ahb", "coda-imx27.0"); - clk_register_clkdev(clk[IMX27_CLK_DMA_AHB_GATE], "ahb", "imx27-dma"); - clk_register_clkdev(clk[IMX27_CLK_DMA_IPG_GATE], "ipg", "imx27-dma"); - clk_register_clkdev(clk[IMX27_CLK_FEC_IPG_GATE], "ipg", "imx27-fec.0"); - clk_register_clkdev(clk[IMX27_CLK_FEC_AHB_GATE], "ahb", "imx27-fec.0"); - clk_register_clkdev(clk[IMX27_CLK_WDOG_IPG_GATE], NULL, "imx2-wdt.0"); - clk_register_clkdev(clk[IMX27_CLK_I2C1_IPG_GATE], NULL, "imx21-i2c.0"); - clk_register_clkdev(clk[IMX27_CLK_I2C2_IPG_GATE], NULL, "imx21-i2c.1"); - clk_register_clkdev(clk[IMX27_CLK_OWIRE_IPG_GATE], NULL, "mxc_w1.0"); - clk_register_clkdev(clk[IMX27_CLK_KPP_IPG_GATE], NULL, "imx-keypad"); - clk_register_clkdev(clk[IMX27_CLK_EMMA_AHB_GATE], "emma-ahb", "imx27-camera.0"); - clk_register_clkdev(clk[IMX27_CLK_EMMA_IPG_GATE], "emma-ipg", "imx27-camera.0"); - clk_register_clkdev(clk[IMX27_CLK_EMMA_AHB_GATE], "ahb", "m2m-emmaprp.0"); - clk_register_clkdev(clk[IMX27_CLK_EMMA_IPG_GATE], "ipg", "m2m-emmaprp.0"); - - mxc_timer_init(MX27_IO_ADDRESS(MX27_GPT1_BASE_ADDR), MX27_INT_GPT1); - - return 0; -} - -static void __init mx27_clocks_init_dt(struct device_node *np) -{ - struct device_node *refnp; - u32 fref = 26000000; /* default */ - - for_each_compatible_node(refnp, NULL, "fixed-clock") { - if (!of_device_is_compatible(refnp, "fsl,imx-osc26m")) - continue; - - if (!of_property_read_u32(refnp, "clock-frequency", &fref)) - break; - } - - ccm = of_iomap(np, 0); - - _mx27_clocks_init(fref); - - clk_data.clks = clk; - clk_data.clk_num = ARRAY_SIZE(clk); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); -} -CLK_OF_DECLARE(imx27_ccm, "fsl,imx27-ccm", mx27_clocks_init_dt); diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c deleted file mode 100644 index 286ef422cebc..000000000000 --- a/arch/arm/mach-imx/clk-imx31.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2012 Sascha Hauer <kernel@pengutronix.de> - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation. - */ - -#include <linux/module.h> -#include <linux/clk.h> -#include <linux/clkdev.h> -#include <linux/io.h> -#include <linux/err.h> -#include <linux/of.h> - -#include "clk.h" -#include "common.h" -#include "crmregs-imx3.h" -#include "hardware.h" -#include "mx31.h" - -static const char *mcu_main_sel[] = { "spll", "mpll", }; -static const char *per_sel[] = { "per_div", "ipg", }; -static const char *csi_sel[] = { "upll", "spll", }; -static const char *fir_sel[] = { "mcu_main", "upll", "spll" }; - -enum mx31_clks { - dummy, ckih, ckil, mpll, spll, upll, mcu_main, hsp, ahb, nfc, ipg, - per_div, per, csi, fir, csi_div, usb_div_pre, usb_div_post, fir_div_pre, - fir_div_post, sdhc1_gate, sdhc2_gate, gpt_gate, epit1_gate, epit2_gate, - iim_gate, ata_gate, sdma_gate, cspi3_gate, rng_gate, uart1_gate, - uart2_gate, ssi1_gate, i2c1_gate, i2c2_gate, i2c3_gate, hantro_gate, - mstick1_gate, mstick2_gate, csi_gate, rtc_gate, wdog_gate, pwm_gate, - sim_gate, ect_gate, usb_gate, kpp_gate, ipu_gate, uart3_gate, - uart4_gate, uart5_gate, owire_gate, ssi2_gate, cspi1_gate, cspi2_gate, - gacc_gate, emi_gate, rtic_gate, firi_gate, clk_max -}; - -static struct clk *clk[clk_max]; -static struct clk_onecell_data clk_data; - -int __init mx31_clocks_init(unsigned long fref) -{ - void __iomem *base = MX31_IO_ADDRESS(MX31_CCM_BASE_ADDR); - struct device_node *np; - - clk[dummy] = imx_clk_fixed("dummy", 0); - clk[ckih] = imx_clk_fixed("ckih", fref); - clk[ckil] = imx_clk_fixed("ckil", 32768); - clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MXC_CCM_MPCTL); - clk[spll] = imx_clk_pllv1("spll", "ckih", base + MXC_CCM_SRPCTL); - clk[upll] = imx_clk_pllv1("upll", "ckih", base + MXC_CCM_UPCTL); - clk[mcu_main] = imx_clk_mux("mcu_main", base + MXC_CCM_PMCR0, 31, 1, mcu_main_sel, ARRAY_SIZE(mcu_main_sel)); - clk[hsp] = imx_clk_divider("hsp", "mcu_main", base + MXC_CCM_PDR0, 11, 3); - clk[ahb] = imx_clk_divider("ahb", "mcu_main", base + MXC_CCM_PDR0, 3, 3); - clk[nfc] = imx_clk_divider("nfc", "ahb", base + MXC_CCM_PDR0, 8, 3); - clk[ipg] = imx_clk_divider("ipg", "ahb", base + MXC_CCM_PDR0, 6, 2); - clk[per_div] = imx_clk_divider("per_div", "upll", base + MXC_CCM_PDR0, 16, 5); - clk[per] = imx_clk_mux("per", base + MXC_CCM_CCMR, 24, 1, per_sel, ARRAY_SIZE(per_sel)); - clk[csi] = imx_clk_mux("csi_sel", base + MXC_CCM_CCMR, 25, 1, csi_sel, ARRAY_SIZE(csi_sel)); - clk[fir] = imx_clk_mux("fir_sel", base + MXC_CCM_CCMR, 11, 2, fir_sel, ARRAY_SIZE(fir_sel)); - clk[csi_div] = imx_clk_divider("csi_div", "csi_sel", base + MXC_CCM_PDR0, 23, 9); - clk[usb_div_pre] = imx_clk_divider("usb_div_pre", "upll", base + MXC_CCM_PDR1, 30, 2); - clk[usb_div_post] = imx_clk_divider("usb_div_post", "usb_div_pre", base + MXC_CCM_PDR1, 27, 3); - clk[fir_div_pre] = imx_clk_divider("fir_div_pre", "fir_sel", base + MXC_CCM_PDR1, 24, 3); - clk[fir_div_post] = imx_clk_divider("fir_div_post", "fir_div_pre", base + MXC_CCM_PDR1, 23, 6); - clk[sdhc1_gate] = imx_clk_gate2("sdhc1_gate", "per", base + MXC_CCM_CGR0, 0); - clk[sdhc2_gate] = imx_clk_gate2("sdhc2_gate", "per", base + MXC_CCM_CGR0, 2); - clk[gpt_gate] = imx_clk_gate2("gpt_gate", "per", base + MXC_CCM_CGR0, 4); - clk[epit1_gate] = imx_clk_gate2("epit1_gate", "per", base + MXC_CCM_CGR0, 6); - clk[epit2_gate] = imx_clk_gate2("epit2_gate", "per", base + MXC_CCM_CGR0, 8); - clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MXC_CCM_CGR0, 10); - clk[ata_gate] = imx_clk_gate2("ata_gate", "ipg", base + MXC_CCM_CGR0, 12); - clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ahb", base + MXC_CCM_CGR0, 14); - clk[cspi3_gate] = imx_clk_gate2("cspi3_gate", "ipg", base + MXC_CCM_CGR0, 16); - clk[rng_gate] = imx_clk_gate2("rng_gate", "ipg", base + MXC_CCM_CGR0, 18); - clk[uart1_gate] = imx_clk_gate2("uart1_gate", "per", base + MXC_CCM_CGR0, 20); - clk[uart2_gate] = imx_clk_gate2("uart2_gate", "per", base + MXC_CCM_CGR0, 22); - clk[ssi1_gate] = imx_clk_gate2("ssi1_gate", "spll", base + MXC_CCM_CGR0, 24); - clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "per", base + MXC_CCM_CGR0, 26); - clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "per", base + MXC_CCM_CGR0, 28); - clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "per", base + MXC_CCM_CGR0, 30); - clk[hantro_gate] = imx_clk_gate2("hantro_gate", "per", base + MXC_CCM_CGR1, 0); - clk[mstick1_gate] = imx_clk_gate2("mstick1_gate", "per", base + MXC_CCM_CGR1, 2); - clk[mstick2_gate] = imx_clk_gate2("mstick2_gate", "per", base + MXC_CCM_CGR1, 4); - clk[csi_gate] = imx_clk_gate2("csi_gate", "csi_div", base + MXC_CCM_CGR1, 6); - clk[rtc_gate] = imx_clk_gate2("rtc_gate", "ipg", base + MXC_CCM_CGR1, 8); - clk[wdog_gate] = imx_clk_gate2("wdog_gate", "ipg", base + MXC_CCM_CGR1, 10); - clk[pwm_gate] = imx_clk_gate2("pwm_gate", "per", base + MXC_CCM_CGR1, 12); - clk[sim_gate] = imx_clk_gate2("sim_gate", "per", base + MXC_CCM_CGR1, 14); - clk[ect_gate] = imx_clk_gate2("ect_gate", "per", base + MXC_CCM_CGR1, 16); - clk[usb_gate] = imx_clk_gate2("usb_gate", "ahb", base + MXC_CCM_CGR1, 18); - clk[kpp_gate] = imx_clk_gate2("kpp_gate", "ipg", base + MXC_CCM_CGR1, 20); - clk[ipu_gate] = imx_clk_gate2("ipu_gate", "hsp", base + MXC_CCM_CGR1, 22); - clk[uart3_gate] = imx_clk_gate2("uart3_gate", "per", base + MXC_CCM_CGR1, 24); - clk[uart4_gate] = imx_clk_gate2("uart4_gate", "per", base + MXC_CCM_CGR1, 26); - clk[uart5_gate] = imx_clk_gate2("uart5_gate", "per", base + MXC_CCM_CGR1, 28); - clk[owire_gate] = imx_clk_gate2("owire_gate", "per", base + MXC_CCM_CGR1, 30); - clk[ssi2_gate] = imx_clk_gate2("ssi2_gate", "spll", base + MXC_CCM_CGR2, 0); - clk[cspi1_gate] = imx_clk_gate2("cspi1_gate", "ipg", base + MXC_CCM_CGR2, 2); - clk[cspi2_gate] = imx_clk_gate2("cspi2_gate", "ipg", base + MXC_CCM_CGR2, 4); - clk[gacc_gate] = imx_clk_gate2("gacc_gate", "per", base + MXC_CCM_CGR2, 6); - clk[emi_gate] = imx_clk_gate2("emi_gate", "ahb", base + MXC_CCM_CGR2, 8); - clk[rtic_gate] = imx_clk_gate2("rtic_gate", "ahb", base + MXC_CCM_CGR2, 10); - clk[firi_gate] = imx_clk_gate2("firi_gate", "upll", base+MXC_CCM_CGR2, 12); - - imx_check_clocks(clk, ARRAY_SIZE(clk)); - - np = of_find_compatible_node(NULL, NULL, "fsl,imx31-ccm"); - - if (np) { - clk_data.clks = clk; - clk_data.clk_num = ARRAY_SIZE(clk); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); - } - - clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0"); - clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0"); - clk_register_clkdev(clk[cspi1_gate], NULL, "imx31-cspi.0"); - clk_register_clkdev(clk[cspi2_gate], NULL, "imx31-cspi.1"); - clk_register_clkdev(clk[cspi3_gate], NULL, "imx31-cspi.2"); - clk_register_clkdev(clk[pwm_gate], "pwm", NULL); - clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0"); - clk_register_clkdev(clk[rtc_gate], NULL, "imx21-rtc"); - clk_register_clkdev(clk[epit1_gate], "epit", NULL); - clk_register_clkdev(clk[epit2_gate], "epit", NULL); - clk_register_clkdev(clk[nfc], NULL, "imx27-nand.0"); - clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core"); - clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb"); - clk_register_clkdev(clk[kpp_gate], NULL, "imx-keypad"); - clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.0"); - clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.0"); - clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0"); - clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.1"); - clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.1"); - clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1"); - clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.2"); - clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.2"); - clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2"); - clk_register_clkdev(clk[usb_div_post], "per", "imx-udc-mx27"); - clk_register_clkdev(clk[usb_gate], "ahb", "imx-udc-mx27"); - clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx27"); - clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); - /* i.mx31 has the i.mx21 type uart */ - clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0"); - clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0"); - clk_register_clkdev(clk[uart2_gate], "per", "imx21-uart.1"); - clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.1"); - clk_register_clkdev(clk[uart3_gate], "per", "imx21-uart.2"); - clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.2"); - clk_register_clkdev(clk[uart4_gate], "per", "imx21-uart.3"); - clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.3"); - clk_register_clkdev(clk[uart5_gate], "per", "imx21-uart.4"); - clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.4"); - clk_register_clkdev(clk[i2c1_gate], NULL, "imx21-i2c.0"); - clk_register_clkdev(clk[i2c2_gate], NULL, "imx21-i2c.1"); - clk_register_clkdev(clk[i2c3_gate], NULL, "imx21-i2c.2"); - clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1.0"); - clk_register_clkdev(clk[sdhc1_gate], NULL, "imx31-mmc.0"); - clk_register_clkdev(clk[sdhc2_gate], NULL, "imx31-mmc.1"); - clk_register_clkdev(clk[ssi1_gate], NULL, "imx-ssi.0"); - clk_register_clkdev(clk[ssi2_gate], NULL, "imx-ssi.1"); - clk_register_clkdev(clk[firi_gate], "firi", NULL); - clk_register_clkdev(clk[ata_gate], NULL, "pata_imx"); - clk_register_clkdev(clk[rtic_gate], "rtic", NULL); - clk_register_clkdev(clk[rng_gate], NULL, "mxc_rnga"); - clk_register_clkdev(clk[sdma_gate], NULL, "imx31-sdma"); - clk_register_clkdev(clk[iim_gate], "iim", NULL); - - clk_set_parent(clk[csi], clk[upll]); - clk_prepare_enable(clk[emi_gate]); - clk_prepare_enable(clk[iim_gate]); - mx31_revision(); - clk_disable_unprepare(clk[iim_gate]); - - mxc_timer_init(MX31_IO_ADDRESS(MX31_GPT1_BASE_ADDR), MX31_INT_GPT); - - return 0; -} - -int __init mx31_clocks_init_dt(void) -{ - struct device_node *np; - u32 fref = 26000000; /* default */ - - for_each_compatible_node(np, NULL, "fixed-clock") { - if (!of_device_is_compatible(np, "fsl,imx-osc26m")) - continue; - - if (!of_property_read_u32(np, "clock-frequency", &fref)) - break; - } - - return mx31_clocks_init(fref); -} diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c deleted file mode 100644 index a0d2b57fd376..000000000000 --- a/arch/arm/mach-imx/clk-imx35.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright (C) 2012 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include <linux/mm.h> -#include <linux/delay.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/clkdev.h> -#include <linux/of.h> -#include <linux/err.h> - -#include "crmregs-imx3.h" -#include "clk.h" -#include "common.h" -#include "hardware.h" - -struct arm_ahb_div { - unsigned char arm, ahb, sel; -}; - -static struct arm_ahb_div clk_consumer[] = { - { .arm = 1, .ahb = 4, .sel = 0}, - { .arm = 1, .ahb = 3, .sel = 1}, - { .arm = 2, .ahb = 2, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 4, .ahb = 1, .sel = 0}, - { .arm = 1, .ahb = 5, .sel = 0}, - { .arm = 1, .ahb = 8, .sel = 0}, - { .arm = 1, .ahb = 6, .sel = 1}, - { .arm = 2, .ahb = 4, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, - { .arm = 4, .ahb = 2, .sel = 0}, - { .arm = 0, .ahb = 0, .sel = 0}, -}; - -static char hsp_div_532[] = { 4, 8, 3, 0 }; -static char hsp_div_400[] = { 3, 6, 3, 0 }; - -static struct clk_onecell_data clk_data; - -static const char *std_sel[] = {"ppll", "arm"}; -static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"}; - -enum mx35_clks { - ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg, - arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel, - esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre, - spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre, - ssi2_div_post, usb_sel, usb_div, nfc_div, asrc_gate, pata_gate, - audmux_gate, can1_gate, can2_gate, cspi1_gate, cspi2_gate, ect_gate, - edio_gate, emi_gate, epit1_gate, epit2_gate, esai_gate, esdhc1_gate, - esdhc2_gate, esdhc3_gate, fec_gate, gpio1_gate, gpio2_gate, gpio3_gate, - gpt_gate, i2c1_gate, i2c2_gate, i2c3_gate, iomuxc_gate, ipu_gate, - kpp_gate, mlb_gate, mshc_gate, owire_gate, pwm_gate, rngc_gate, - rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate, - ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate, - wdog_gate, max_gate, admux_gate, csi_gate, csi_div, csi_sel, iim_gate, - gpu2d_gate, clk_max -}; - -static struct clk *clk[clk_max]; - -int __init mx35_clocks_init(void) -{ - void __iomem *base = MX35_IO_ADDRESS(MX35_CCM_BASE_ADDR); - u32 pdr0, consumer_sel, hsp_sel; - struct arm_ahb_div *aad; - unsigned char *hsp_div; - - pdr0 = __raw_readl(base + MXC_CCM_PDR0); - consumer_sel = (pdr0 >> 16) & 0xf; - aad = &clk_consumer[consumer_sel]; - if (!aad->arm) { - pr_err("i.MX35 clk: illegal consumer mux selection 0x%x\n", consumer_sel); - /* - * We are basically stuck. Continue with a default entry and hope we - * get far enough to actually show the above message - */ - aad = &clk_consumer[0]; - } - - clk[ckih] = imx_clk_fixed("ckih", 24000000); - clk[mpll] = imx_clk_pllv1("mpll", "ckih", base + MX35_CCM_MPCTL); - clk[ppll] = imx_clk_pllv1("ppll", "ckih", base + MX35_CCM_PPCTL); - - clk[mpll] = imx_clk_fixed_factor("mpll_075", "mpll", 3, 4); - - if (aad->sel) - clk[arm] = imx_clk_fixed_factor("arm", "mpll_075", 1, aad->arm); - else - clk[arm] = imx_clk_fixed_factor("arm", "mpll", 1, aad->arm); - - if (clk_get_rate(clk[arm]) > 400000000) - hsp_div = hsp_div_532; - else - hsp_div = hsp_div_400; - - hsp_sel = (pdr0 >> 20) & 0x3; - if (!hsp_div[hsp_sel]) { - pr_err("i.MX35 clk: illegal hsp clk selection 0x%x\n", hsp_sel); - hsp_sel = 0; - } - - clk[hsp] = imx_clk_fixed_factor("hsp", "arm", 1, hsp_div[hsp_sel]); - - clk[ahb] = imx_clk_fixed_factor("ahb", "arm", 1, aad->ahb); - clk[ipg] = imx_clk_fixed_factor("ipg", "ahb", 1, 2); - - clk[arm_per_div] = imx_clk_divider("arm_per_div", "arm", base + MX35_CCM_PDR4, 16, 6); - clk[ahb_per_div] = imx_clk_divider("ahb_per_div", "ahb", base + MXC_CCM_PDR0, 12, 3); - clk[ipg_per] = imx_clk_mux("ipg_per", base + MXC_CCM_PDR0, 26, 1, ipg_per_sel, ARRAY_SIZE(ipg_per_sel)); - - clk[uart_sel] = imx_clk_mux("uart_sel", base + MX35_CCM_PDR3, 14, 1, std_sel, ARRAY_SIZE(std_sel)); - clk[uart_div] = imx_clk_divider("uart_div", "uart_sel", base + MX35_CCM_PDR4, 10, 6); - - clk[esdhc_sel] = imx_clk_mux("esdhc_sel", base + MX35_CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel)); - clk[esdhc1_div] = imx_clk_divider("esdhc1_div", "esdhc_sel", base + MX35_CCM_PDR3, 0, 6); - clk[esdhc2_div] = imx_clk_divider("esdhc2_div", "esdhc_sel", base + MX35_CCM_PDR3, 8, 6); - clk[esdhc3_div] = imx_clk_divider("esdhc3_div", "esdhc_sel", base + MX35_CCM_PDR3, 16, 6); - - clk[spdif_sel] = imx_clk_mux("spdif_sel", base + MX35_CCM_PDR3, 22, 1, std_sel, ARRAY_SIZE(std_sel)); - clk[spdif_div_pre] = imx_clk_divider("spdif_div_pre", "spdif_sel", base + MX35_CCM_PDR3, 29, 3); /* divide by 1 not allowed */ - clk[spdif_div_post] = imx_clk_divider("spdif_div_post", "spdif_div_pre", base + MX35_CCM_PDR3, 23, 6); - - clk[ssi_sel] = imx_clk_mux("ssi_sel", base + MX35_CCM_PDR2, 6, 1, std_sel, ARRAY_SIZE(std_sel)); - clk[ssi1_div_pre] = imx_clk_divider("ssi1_div_pre", "ssi_sel", base + MX35_CCM_PDR2, 24, 3); - clk[ssi1_div_post] = imx_clk_divider("ssi1_div_post", "ssi1_div_pre", base + MX35_CCM_PDR2, 0, 6); - clk[ssi2_div_pre] = imx_clk_divider("ssi2_div_pre", "ssi_sel", base + MX35_CCM_PDR2, 27, 3); - clk[ssi2_div_post] = imx_clk_divider("ssi2_div_post", "ssi2_div_pre", base + MX35_CCM_PDR2, 8, 6); - - clk[usb_sel] = imx_clk_mux("usb_sel", base + MX35_CCM_PDR4, 9, 1, std_sel, ARRAY_SIZE(std_sel)); - clk[usb_div] = imx_clk_divider("usb_div", "usb_sel", base + MX35_CCM_PDR4, 22, 6); - - clk[nfc_div] = imx_clk_divider("nfc_div", "ahb", base + MX35_CCM_PDR4, 28, 4); - - clk[csi_sel] = imx_clk_mux("csi_sel", base + MX35_CCM_PDR2, 7, 1, std_sel, ARRAY_SIZE(std_sel)); - clk[csi_div] = imx_clk_divider("csi_div", "csi_sel", base + MX35_CCM_PDR2, 16, 6); - - clk[asrc_gate] = imx_clk_gate2("asrc_gate", "ipg", base + MX35_CCM_CGR0, 0); - clk[pata_gate] = imx_clk_gate2("pata_gate", "ipg", base + MX35_CCM_CGR0, 2); - clk[audmux_gate] = imx_clk_gate2("audmux_gate", "ipg", base + MX35_CCM_CGR0, 4); - clk[can1_gate] = imx_clk_gate2("can1_gate", "ipg", base + MX35_CCM_CGR0, 6); - clk[can2_gate] = imx_clk_gate2("can2_gate", "ipg", base + MX35_CCM_CGR0, 8); - clk[cspi1_gate] = imx_clk_gate2("cspi1_gate", "ipg", base + MX35_CCM_CGR0, 10); - clk[cspi2_gate] = imx_clk_gate2("cspi2_gate", "ipg", base + MX35_CCM_CGR0, 12); - clk[ect_gate] = imx_clk_gate2("ect_gate", "ipg", base + MX35_CCM_CGR0, 14); - clk[edio_gate] = imx_clk_gate2("edio_gate", "ipg", base + MX35_CCM_CGR0, 16); - clk[emi_gate] = imx_clk_gate2("emi_gate", "ipg", base + MX35_CCM_CGR0, 18); - clk[epit1_gate] = imx_clk_gate2("epit1_gate", "ipg", base + MX35_CCM_CGR0, 20); - clk[epit2_gate] = imx_clk_gate2("epit2_gate", "ipg", base + MX35_CCM_CGR0, 22); - clk[esai_gate] = imx_clk_gate2("esai_gate", "ipg", base + MX35_CCM_CGR0, 24); - clk[esdhc1_gate] = imx_clk_gate2("esdhc1_gate", "esdhc1_div", base + MX35_CCM_CGR0, 26); - clk[esdhc2_gate] = imx_clk_gate2("esdhc2_gate", "esdhc2_div", base + MX35_CCM_CGR0, 28); - clk[esdhc3_gate] = imx_clk_gate2("esdhc3_gate", "esdhc3_div", base + MX35_CCM_CGR0, 30); - - clk[fec_gate] = imx_clk_gate2("fec_gate", "ipg", base + MX35_CCM_CGR1, 0); - clk[gpio1_gate] = imx_clk_gate2("gpio1_gate", "ipg", base + MX35_CCM_CGR1, 2); - clk[gpio2_gate] = imx_clk_gate2("gpio2_gate", "ipg", base + MX35_CCM_CGR1, 4); - clk[gpio3_gate] = imx_clk_gate2("gpio3_gate", "ipg", base + MX35_CCM_CGR1, 6); - clk[gpt_gate] = imx_clk_gate2("gpt_gate", "ipg", base + MX35_CCM_CGR1, 8); - clk[i2c1_gate] = imx_clk_gate2("i2c1_gate", "ipg_per", base + MX35_CCM_CGR1, 10); - clk[i2c2_gate] = imx_clk_gate2("i2c2_gate", "ipg_per", base + MX35_CCM_CGR1, 12); - clk[i2c3_gate] = imx_clk_gate2("i2c3_gate", "ipg_per", base + MX35_CCM_CGR1, 14); - clk[iomuxc_gate] = imx_clk_gate2("iomuxc_gate", "ipg", base + MX35_CCM_CGR1, 16); - clk[ipu_gate] = imx_clk_gate2("ipu_gate", "hsp", base + MX35_CCM_CGR1, 18); - clk[kpp_gate] = imx_clk_gate2("kpp_gate", "ipg", base + MX35_CCM_CGR1, 20); - clk[mlb_gate] = imx_clk_gate2("mlb_gate", "ahb", base + MX35_CCM_CGR1, 22); - clk[mshc_gate] = imx_clk_gate2("mshc_gate", "dummy", base + MX35_CCM_CGR1, 24); - clk[owire_gate] = imx_clk_gate2("owire_gate", "ipg_per", base + MX35_CCM_CGR1, 26); - clk[pwm_gate] = imx_clk_gate2("pwm_gate", "ipg_per", base + MX35_CCM_CGR1, 28); - clk[rngc_gate] = imx_clk_gate2("rngc_gate", "ipg", base + MX35_CCM_CGR1, 30); - - clk[rtc_gate] = imx_clk_gate2("rtc_gate", "ipg", base + MX35_CCM_CGR2, 0); - clk[rtic_gate] = imx_clk_gate2("rtic_gate", "ahb", base + MX35_CCM_CGR2, 2); - clk[scc_gate] = imx_clk_gate2("scc_gate", "ipg", base + MX35_CCM_CGR2, 4); - clk[sdma_gate] = imx_clk_gate2("sdma_gate", "ahb", base + MX35_CCM_CGR2, 6); - clk[spba_gate] = imx_clk_gate2("spba_gate", "ipg", base + MX35_CCM_CGR2, 8); - clk[spdif_gate] = imx_clk_gate2("spdif_gate", "spdif_div_post", base + MX35_CCM_CGR2, 10); - clk[ssi1_gate] = imx_clk_gate2("ssi1_gate", "ssi1_div_post", base + MX35_CCM_CGR2, 12); - clk[ssi2_gate] = imx_clk_gate2("ssi2_gate", "ssi2_div_post", base + MX35_CCM_CGR2, 14); - clk[uart1_gate] = imx_clk_gate2("uart1_gate", "uart_div", base + MX35_CCM_CGR2, 16); - clk[uart2_gate] = imx_clk_gate2("uart2_gate", "uart_div", base + MX35_CCM_CGR2, 18); - clk[uart3_gate] = imx_clk_gate2("uart3_gate", "uart_div", base + MX35_CCM_CGR2, 20); - clk[usbotg_gate] = imx_clk_gate2("usbotg_gate", "ahb", base + MX35_CCM_CGR2, 22); - clk[wdog_gate] = imx_clk_gate2("wdog_gate", "ipg", base + MX35_CCM_CGR2, 24); - clk[max_gate] = imx_clk_gate2("max_gate", "dummy", base + MX35_CCM_CGR2, 26); - clk[admux_gate] = imx_clk_gate2("admux_gate", "ipg", base + MX35_CCM_CGR2, 30); - - clk[csi_gate] = imx_clk_gate2("csi_gate", "csi_div", base + MX35_CCM_CGR3, 0); - clk[iim_gate] = imx_clk_gate2("iim_gate", "ipg", base + MX35_CCM_CGR3, 2); - clk[gpu2d_gate] = imx_clk_gate2("gpu2d_gate", "ahb", base + MX35_CCM_CGR3, 4); - - imx_check_clocks(clk, ARRAY_SIZE(clk)); - - clk_register_clkdev(clk[pata_gate], NULL, "pata_imx"); - clk_register_clkdev(clk[can1_gate], NULL, "flexcan.0"); - clk_register_clkdev(clk[can2_gate], NULL, "flexcan.1"); - clk_register_clkdev(clk[cspi1_gate], "per", "imx35-cspi.0"); - clk_register_clkdev(clk[cspi1_gate], "ipg", "imx35-cspi.0"); - clk_register_clkdev(clk[cspi2_gate], "per", "imx35-cspi.1"); - clk_register_clkdev(clk[cspi2_gate], "ipg", "imx35-cspi.1"); - clk_register_clkdev(clk[epit1_gate], NULL, "imx-epit.0"); - clk_register_clkdev(clk[epit2_gate], NULL, "imx-epit.1"); - clk_register_clkdev(clk[esdhc1_gate], "per", "sdhci-esdhc-imx35.0"); - clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.0"); - clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.0"); - clk_register_clkdev(clk[esdhc2_gate], "per", "sdhci-esdhc-imx35.1"); - clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.1"); - clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.1"); - clk_register_clkdev(clk[esdhc3_gate], "per", "sdhci-esdhc-imx35.2"); - clk_register_clkdev(clk[ipg], "ipg", "sdhci-esdhc-imx35.2"); - clk_register_clkdev(clk[ahb], "ahb", "sdhci-esdhc-imx35.2"); - /* i.mx35 has the i.mx27 type fec */ - clk_register_clkdev(clk[fec_gate], NULL, "imx27-fec.0"); - clk_register_clkdev(clk[gpt_gate], "per", "imx-gpt.0"); - clk_register_clkdev(clk[ipg], "ipg", "imx-gpt.0"); - clk_register_clkdev(clk[i2c1_gate], NULL, "imx21-i2c.0"); - clk_register_clkdev(clk[i2c2_gate], NULL, "imx21-i2c.1"); - clk_register_clkdev(clk[i2c3_gate], NULL, "imx21-i2c.2"); - clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core"); - clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb"); - clk_register_clkdev(clk[kpp_gate], NULL, "imx-keypad"); - clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1"); - clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma"); - clk_register_clkdev(clk[ssi1_gate], NULL, "imx-ssi.0"); - clk_register_clkdev(clk[ssi2_gate], NULL, "imx-ssi.1"); - /* i.mx35 has the i.mx21 type uart */ - clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0"); - clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0"); - clk_register_clkdev(clk[uart2_gate], "per", "imx21-uart.1"); - clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.1"); - clk_register_clkdev(clk[uart3_gate], "per", "imx21-uart.2"); - clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.2"); - clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.0"); - clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0"); - clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.0"); - clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.1"); - clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.1"); - clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.1"); - clk_register_clkdev(clk[usb_div], "per", "mxc-ehci.2"); - clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.2"); - clk_register_clkdev(clk[usbotg_gate], "ahb", "mxc-ehci.2"); - clk_register_clkdev(clk[usb_div], "per", "imx-udc-mx27"); - clk_register_clkdev(clk[ipg], "ipg", "imx-udc-mx27"); - clk_register_clkdev(clk[usbotg_gate], "ahb", "imx-udc-mx27"); - clk_register_clkdev(clk[wdog_gate], NULL, "imx2-wdt.0"); - clk_register_clkdev(clk[nfc_div], NULL, "imx25-nand.0"); - clk_register_clkdev(clk[csi_gate], NULL, "mx3-camera.0"); - clk_register_clkdev(clk[admux_gate], "audmux", NULL); - - clk_prepare_enable(clk[spba_gate]); - clk_prepare_enable(clk[gpio1_gate]); - clk_prepare_enable(clk[gpio2_gate]); - clk_prepare_enable(clk[gpio3_gate]); - clk_prepare_enable(clk[iim_gate]); - clk_prepare_enable(clk[emi_gate]); - clk_prepare_enable(clk[max_gate]); - clk_prepare_enable(clk[iomuxc_gate]); - - /* - * SCC is needed to boot via mmc after a watchdog reset. The clock code - * before conversion to common clk also enabled UART1 (which isn't - * handled here and not needed for mmc) and IIM (which is enabled - * unconditionally above). - */ - clk_prepare_enable(clk[scc_gate]); - - imx_print_silicon_rev("i.MX35", mx35_revision()); - -#ifdef CONFIG_MXC_USE_EPIT - epit_timer_init(MX35_IO_ADDRESS(MX35_EPIT1_BASE_ADDR), MX35_INT_EPIT1); -#else - mxc_timer_init(MX35_IO_ADDRESS(MX35_GPT1_BASE_ADDR), MX35_INT_GPT); -#endif - - return 0; -} - -static void __init mx35_clocks_init_dt(struct device_node *ccm_node) -{ - clk_data.clks = clk; - clk_data.clk_num = ARRAY_SIZE(clk); - of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data); - - mx35_clocks_init(); -} -CLK_OF_DECLARE(imx35, "fsl,imx35-ccm", mx35_clocks_init_dt); diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c deleted file mode 100644 index 0f7e536147cb..000000000000 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ /dev/null @@ -1,573 +0,0 @@ -/* - * Copyright (C) 2011 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ -#include <linux/mm.h> -#include <linux/delay.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/clkdev.h> -#include <linux/clk-provider.h> -#include <linux/err.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> -#include <dt-bindings/clock/imx5-clock.h> - -#include "clk.h" -#include "common.h" -#include "hardware.h" - -#define MX51_DPLL1_BASE 0x83f80000 -#define MX51_DPLL2_BASE 0x83f84000 -#define MX51_DPLL3_BASE 0x83f88000 - -#define MX53_DPLL1_BASE 0x63f80000 -#define MX53_DPLL2_BASE 0x63f84000 -#define MX53_DPLL3_BASE 0x63f88000 -#define MX53_DPLL4_BASE 0x63f8c000 - -#define MXC_CCM_CCR (ccm_base + 0x00) -#define MXC_CCM_CCDR (ccm_base + 0x04) -#define MXC_CCM_CSR (ccm_base + 0x08) -#define MXC_CCM_CCSR (ccm_base + 0x0c) -#define MXC_CCM_CACRR (ccm_base + 0x10) -#define MXC_CCM_CBCDR (ccm_base + 0x14) -#define MXC_CCM_CBCMR (ccm_base + 0x18) -#define MXC_CCM_CSCMR1 (ccm_base + 0x1c) -#define MXC_CCM_CSCMR2 (ccm_base + 0x20) -#define MXC_CCM_CSCDR1 (ccm_base + 0x24) -#define MXC_CCM_CS1CDR (ccm_base + 0x28) -#define MXC_CCM_CS2CDR (ccm_base + 0x2c) -#define MXC_CCM_CDCDR (ccm_base + 0x30) -#define MXC_CCM_CHSCDR (ccm_base + 0x34) -#define MXC_CCM_CSCDR2 (ccm_base + 0x38) -#define MXC_CCM_CSCDR3 (ccm_base + 0x3c) -#define MXC_CCM_CSCDR4 (ccm_base + 0x40) -#define MXC_CCM_CWDR (ccm_base + 0x44) -#define MXC_CCM_CDHIPR (ccm_base + 0x48) -#define MXC_CCM_CDCR (ccm_base + 0x4c) -#define MXC_CCM_CTOR (ccm_base + 0x50) -#define MXC_CCM_CLPCR (ccm_base + 0x54) -#define MXC_CCM_CISR (ccm_base + 0x58) -#define MXC_CCM_CIMR (ccm_base + 0x5c) -#define MXC_CCM_CCOSR (ccm_base + 0x60) -#define MXC_CCM_CGPR (ccm_base + 0x64) -#define MXC_CCM_CCGR0 (ccm_base + 0x68) -#define MXC_CCM_CCGR1 (ccm_base + 0x6c) -#define MXC_CCM_CCGR2 (ccm_base + 0x70) -#define MXC_CCM_CCGR3 (ccm_base + 0x74) -#define MXC_CCM_CCGR4 (ccm_base + 0x78) -#define MXC_CCM_CCGR5 (ccm_base + 0x7c) -#define MXC_CCM_CCGR6 (ccm_base + 0x80) -#define MXC_CCM_CCGR7 (ccm_base + 0x84) - -/* Low-power Audio Playback Mode clock */ -static const char *lp_apm_sel[] = { "osc", }; - -/* This is used multiple times */ -static const char *standard_pll_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "lp_apm", }; -static const char *periph_apm_sel[] = { "pll1_sw", "pll3_sw", "lp_apm", }; -static const char *main_bus_sel[] = { "pll2_sw", "periph_apm", }; -static const char *per_lp_apm_sel[] = { "main_bus", "lp_apm", }; -static const char *per_root_sel[] = { "per_podf", "ipg", }; -static const char *esdhc_c_sel[] = { "esdhc_a_podf", "esdhc_b_podf", }; -static const char *esdhc_d_sel[] = { "esdhc_a_podf", "esdhc_b_podf", }; -static const char *ssi_apm_sels[] = { "ckih1", "lp_amp", "ckih2", }; -static const char *ssi_clk_sels[] = { "pll1_sw", "pll2_sw", "pll3_sw", "ssi_apm", }; -static const char *ssi3_clk_sels[] = { "ssi1_root_gate", "ssi2_root_gate", }; -static const char *ssi_ext1_com_sels[] = { "ssi_ext1_podf", "ssi1_root_gate", }; -static const char *ssi_ext2_com_sels[] = { "ssi_ext2_podf", "ssi2_root_gate", }; -static const char *emi_slow_sel[] = { "main_bus", "ahb", }; -static const char *usb_phy_sel_str[] = { "osc", "usb_phy_podf", }; -static const char *mx51_ipu_di0_sel[] = { "di_pred", "osc", "ckih1", "tve_di", }; -static const char *mx53_ipu_di0_sel[] = { "di_pred", "osc", "ckih1", "di_pll4_podf", "dummy", "ldb_di0_gate", }; -static const char *mx53_ldb_di0_sel[] = { "pll3_sw", "pll4_sw", }; -static const char *mx51_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "ipp_di1", }; -static const char *mx53_ipu_di1_sel[] = { "di_pred", "osc", "ckih1", "tve_di", "ipp_di1", "ldb_di1_gate", }; -static const char *mx53_ldb_di1_sel[] = { "pll3_sw", "pll4_sw", }; -static const char *mx51_tve_ext_sel[] = { "osc", "ckih1", }; -static const char *mx53_tve_ext_sel[] = { "pll4_sw", "ckih1", }; -static const char *mx51_tve_sel[] = { "tve_pred", "tve_ext_sel", }; -static const char *ipu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; -static const char *gpu3d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" }; -static const char *gpu2d_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb" }; -static const char *vpu_sel[] = { "axi_a", "axi_b", "emi_slow_gate", "ahb", }; -static const char *mx53_can_sel[] = { "ipg", "ckih1", "ckih2", "lp_apm", }; -static const char *mx53_cko1_sel[] = { - "cpu_podf", "pll1_sw", "pll2_sw", "pll3_sw", - "emi_slow_podf", "pll4_sw", "nfc_podf", "dummy", - "di_pred", "dummy", "dummy", "ahb", - "ipg", "per_root", "ckil", "dummy",}; -static const char *mx53_cko2_sel[] = { - "dummy"/* dptc_core */, "dummy"/* dptc_perich */, - "dummy", "esdhc_a_podf", - "usboh3_podf", "dummy"/* wrck_clk_root */, - "ecspi_podf", "dummy"/* pll1_ref_clk */, - "esdhc_b_podf", "dummy"/* ddr_clk_root */, - "dummy"/* arm_axi_clk_root */, "dummy"/* usb_phy_out */, - "vpu_sel", "ipu_sel", - "osc", "ckih1", - "dummy", "esdhc_c_sel", - "ssi1_root_podf", "ssi2_root_podf", - "dummy", "dummy", - "dummy"/* lpsr_clk_root */, "dummy"/* pgc_clk_root */, - "dummy"/* tve_out */, "usb_phy_sel", - "tve_sel", "lp_apm", - "uart_root", "dummy"/* spdif0_clk_root */, - "dummy", "dummy", }; -static const char *mx51_spdif_xtal_sel[] = { "osc", "ckih", "ckih2", }; -static const char *mx53_spdif_xtal_sel[] = { "osc", "ckih", "ckih2", "pll4_sw", }; -static const char *spdif_sel[] = { "pll1_sw", "pll2_sw", "pll3_sw", "spdif_xtal_sel", }; -static const char *spdif0_com_sel[] = { "spdif0_podf", "ssi1_root_gate", }; -static const char *mx51_spdif1_com_sel[] = { "spdif1_podf", "ssi2_root_gate", }; -static const char *step_sels[] = { "lp_apm", }; -static const char *cpu_podf_sels[] = { "pll1_sw", "step_sel" }; - -static struct clk *clk[IMX5_CLK_END]; -static struct clk_onecell_data clk_data; - -static void __init mx5_clocks_common_init(void __iomem *ccm_base) -{ - imx5_pm_set_ccm_base(ccm_base); - - clk[IMX5_CLK_DUMMY] = imx_clk_fixed("dummy", 0); - clk[IMX5_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0); - clk[IMX5_CLK_OSC] = imx_obtain_fixed_clock("osc", 0); - clk[IMX5_CLK_CKIH1] = imx_obtain_fixed_clock("ckih1", 0); - clk[IMX5_CLK_CKIH2] = imx_obtain_fixed_clock("ckih2", 0); - - clk[IMX5_CLK_PERIPH_APM] = imx_clk_mux("periph_apm", MXC_CCM_CBCMR, 12, 2, - periph_apm_sel, ARRAY_SIZE(periph_apm_sel)); - clk[IMX5_CLK_MAIN_BUS] = imx_clk_mux("main_bus", MXC_CCM_CBCDR, 25, 1, - main_bus_sel, ARRAY_SIZE(main_bus_sel)); - clk[IMX5_CLK_PER_LP_APM] = imx_clk_mux("per_lp_apm", MXC_CCM_CBCMR, 1, 1, - per_lp_apm_sel, ARRAY_SIZE(per_lp_apm_sel)); - clk[IMX5_CLK_PER_PRED1] = imx_clk_divider("per_pred1", "per_lp_apm", MXC_CCM_CBCDR, 6, 2); - clk[IMX5_CLK_PER_PRED2] = imx_clk_divider("per_pred2", "per_pred1", MXC_CCM_CBCDR, 3, 3); - clk[IMX5_CLK_PER_PODF] = imx_clk_divider("per_podf", "per_pred2", MXC_CCM_CBCDR, 0, 3); - clk[IMX5_CLK_PER_ROOT] = imx_clk_mux("per_root", MXC_CCM_CBCMR, 0, 1, - per_root_sel, ARRAY_SIZE(per_root_sel)); - clk[IMX5_CLK_AHB] = imx_clk_divider("ahb", "main_bus", MXC_CCM_CBCDR, 10, 3); - clk[IMX5_CLK_AHB_MAX] = imx_clk_gate2("ahb_max", "ahb", MXC_CCM_CCGR0, 28); - clk[IMX5_CLK_AIPS_TZ1] = imx_clk_gate2("aips_tz1", "ahb", MXC_CCM_CCGR0, 24); - clk[IMX5_CLK_AIPS_TZ2] = imx_clk_gate2("aips_tz2", "ahb", MXC_CCM_CCGR0, 26); - clk[IMX5_CLK_TMAX1] = imx_clk_gate2("tmax1", "ahb", MXC_CCM_CCGR1, 0); - clk[IMX5_CLK_TMAX2] = imx_clk_gate2("tmax2", "ahb", MXC_CCM_CCGR1, 2); - clk[IMX5_CLK_TMAX3] = imx_clk_gate2("tmax3", "ahb", MXC_CCM_CCGR1, 4); - clk[IMX5_CLK_SPBA] = imx_clk_gate2("spba", "ipg", MXC_CCM_CCGR5, 0); - clk[IMX5_CLK_IPG] = imx_clk_divider("ipg", "ahb", MXC_CCM_CBCDR, 8, 2); - clk[IMX5_CLK_AXI_A] = imx_clk_divider("axi_a", "main_bus", MXC_CCM_CBCDR, 16, 3); - clk[IMX5_CLK_AXI_B] = imx_clk_divider("axi_b", "main_bus", MXC_CCM_CBCDR, 19, 3); - clk[IMX5_CLK_UART_SEL] = imx_clk_mux("uart_sel", MXC_CCM_CSCMR1, 24, 2, - standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); - clk[IMX5_CLK_UART_PRED] = imx_clk_divider("uart_pred", "uart_sel", MXC_CCM_CSCDR1, 3, 3); - clk[IMX5_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_pred", MXC_CCM_CSCDR1, 0, 3); - - clk[IMX5_CLK_ESDHC_A_SEL] = imx_clk_mux("esdhc_a_sel", MXC_CCM_CSCMR1, 20, 2, - standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); - clk[IMX5_CLK_ESDHC_B_SEL] = imx_clk_mux("esdhc_b_sel", MXC_CCM_CSCMR1, 16, 2, - standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); - clk[IMX5_CLK_ESDHC_A_PRED] = imx_clk_divider("esdhc_a_pred", "esdhc_a_sel", MXC_CCM_CSCDR1, 16, 3); - clk[IMX5_CLK_ESDHC_A_PODF] = imx_clk_divider("esdhc_a_podf", "esdhc_a_pred", MXC_CCM_CSCDR1, 11, 3); - clk[IMX5_CLK_ESDHC_B_PRED] = imx_clk_divider("esdhc_b_pred", "esdhc_b_sel", MXC_CCM_CSCDR1, 22, 3); - clk[IMX5_CLK_ESDHC_B_PODF] = imx_clk_divider("esdhc_b_podf", "esdhc_b_pred", MXC_CCM_CSCDR1, 19, 3); - clk[IMX5_CLK_ESDHC_C_SEL] = imx_clk_mux("esdhc_c_sel", MXC_CCM_CSCMR1, 19, 1, esdhc_c_sel, ARRAY_SIZE(esdhc_c_sel)); - clk[IMX5_CLK_ESDHC_D_SEL] = imx_clk_mux("esdhc_d_sel", MXC_CCM_CSCMR1, 18, 1, esdhc_d_sel, ARRAY_SIZE(esdhc_d_sel)); - - clk[IMX5_CLK_EMI_SEL] = imx_clk_mux("emi_sel", MXC_CCM_CBCDR, 26, 1, - emi_slow_sel, ARRAY_SIZE(emi_slow_sel)); - clk[IMX5_CLK_EMI_SLOW_PODF] = imx_clk_divider("emi_slow_podf", "emi_sel", MXC_CCM_CBCDR, 22, 3); - clk[IMX5_CLK_NFC_PODF] = imx_clk_divider("nfc_podf", "emi_slow_podf", MXC_CCM_CBCDR, 13, 3); - clk[IMX5_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", MXC_CCM_CSCMR1, 4, 2, - standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); - clk[IMX5_CLK_ECSPI_PRED] = imx_clk_divider("ecspi_pred", "ecspi_sel", MXC_CCM_CSCDR2, 25, 3); - clk[IMX5_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_pred", MXC_CCM_CSCDR2, 19, 6); - clk[IMX5_CLK_USBOH3_SEL] = imx_clk_mux("usboh3_sel", MXC_CCM_CSCMR1, 22, 2, - standard_pll_sel, ARRAY_SIZE(standard_pll_sel)); - clk[IMX5_CLK_USBOH3_PRED] = imx_clk_divider("usboh3_pred", "usboh3_sel", MXC_CCM_CSCDR1, 8, 3); - clk[IMX5_CLK_USBOH3_PODF] = imx_clk_divider("usboh3_podf", "usboh3_pred", MXC_CCM_CSCDR1, 6, 2); - clk[IMX5_CLK_USB_PHY_PRED] = imx_clk_divider("usb_phy_pred", "pll3_sw", MXC_CCM_CDCDR, 3, 3); - clk[IMX5_CLK_USB_PHY_PODF] = imx_clk_divider("usb_phy_podf", "usb_phy_pred", MXC_CCM_CDCDR, 0, 3); - clk[IMX5_CLK_USB_PHY_SEL] = imx_clk_mux("usb_phy_sel", MXC_CCM_CSCMR1, 26, 1, - usb_phy_sel_str, ARRAY_SIZE(usb_phy_sel_str)); - clk[IMX5_CLK_STEP_SEL] = imx_clk_mux("step_sel", MXC_CCM_CCSR, 7, 2, step_sels, ARRAY_SIZE(step_sels)); - clk[IMX5_CLK_CPU_PODF_SEL] = imx_clk_mux("cpu_podf_sel", MXC_CCM_CCSR, 2, 1, cpu_podf_sels, ARRAY_SIZE(cpu_podf_sels)); - clk[IMX5_CLK_CPU_PODF] = imx_clk_divider("cpu_podf", "cpu_podf_sel", MXC_CCM_CACRR, 0, 3); - clk[IMX5_CLK_DI_PRED] = imx_clk_divider("di_pred", "pll3_sw", MXC_CCM_CDCDR, 6, 3); - clk[IMX5_CLK_IIM_GATE] = imx_clk_gate2("iim_gate", "ipg", MXC_CCM_CCGR0, 30); - clk[IMX5_CLK_UART1_IPG_GATE] = imx_clk_gate2("uart1_ipg_gate", "ipg", MXC_CCM_CCGR1, 6); - clk[IMX5_CLK_UART1_PER_GATE] = imx_clk_gate2("uart1_per_gate", "uart_root", MXC_CCM_CCGR1, 8); - clk[IMX5_CLK_UART2_IPG_GATE] = imx_clk_gate2("uart2_ipg_gate", "ipg", MXC_CCM_CCGR1, 10); - clk[IMX5_CLK_UART2_PER_GATE] = imx_clk_gate2("uart2_per_gate", "uart_root", MXC_CCM_CCGR1, 12); - clk[IMX5_CLK_UART3_IPG_GATE] = imx_clk_gate2("uart3_ipg_gate", "ipg", MXC_CCM_CCGR1, 14); - clk[IMX5_CLK_UART3_PER_GATE] = imx_clk_gate2("uart3_per_gate", "uart_root", MXC_CCM_CCGR1, 16); - clk[IMX5_CLK_I2C1_GATE] = imx_clk_gate2("i2c1_gate", "per_root", MXC_CCM_CCGR1, 18); - clk[IMX5_CLK_I2C2_GATE] = imx_clk_gate2("i2c2_gate", "per_root", MXC_CCM_CCGR1, 20); - clk[IMX5_CLK_PWM1_IPG_GATE] = imx_clk_gate2("pwm1_ipg_gate", "ipg", MXC_CCM_CCGR2, 10); - clk[IMX5_CLK_PWM1_HF_GATE] = imx_clk_gate2("pwm1_hf_gate", "per_root", MXC_CCM_CCGR2, 12); - clk[IMX5_CLK_PWM2_IPG_GATE] = imx_clk_gate2("pwm2_ipg_gate", "ipg", MXC_CCM_CCGR2, 14); - clk[IMX5_CLK_PWM2_HF_GATE] = imx_clk_gate2("pwm2_hf_gate", "per_root", MXC_CCM_CCGR2, 16); - clk[IMX5_CLK_GPT_IPG_GATE] = imx_clk_gate2("gpt_ipg_gate", "ipg", MXC_CCM_CCGR2, 18); - clk[IMX5_CLK_GPT_HF_GATE] = imx_clk_gate2("gpt_hf_gate", "per_root", MXC_CCM_CCGR2, 20); - clk[IMX5_CLK_FEC_GATE] = imx_clk_gate2("fec_gate", "ipg", MXC_CCM_CCGR2, 24); - clk[IMX5_CLK_USBOH3_GATE] = imx_clk_gate2("usboh3_gate", "ipg", MXC_CCM_CCGR2, 26); - clk[IMX5_CLK_USBOH3_PER_GATE] = imx_clk_gate2("usboh3_per_gate", "usboh3_podf", MXC_CCM_CCGR2, 28); - clk[IMX5_CLK_ESDHC1_IPG_GATE] = imx_clk_gate2("esdhc1_ipg_gate", "ipg", MXC_CCM_CCGR3, 0); - clk[IMX5_CLK_ESDHC2_IPG_GATE] = imx_clk_gate2("esdhc2_ipg_gate", "ipg", MXC_CCM_CCGR3, 4); - clk[IMX5_CLK_ESDHC3_IPG_GATE] = imx_clk_gate2("esdhc3_ipg_gate", "ipg", MXC_CCM_CCGR3, 8); - clk[IMX5_CLK_ESDHC4_IPG_GATE] = imx_clk_gate2("esdhc4_ipg_gate", "ipg", MXC_CCM_CCGR3, 12); - clk[IMX5_CLK_SSI1_IPG_GATE] = imx_clk_gate2("ssi1_ipg_gate", "ipg", MXC_CCM_CCGR3, 16); - clk[IMX5_CLK_SSI2_IPG_GATE] = imx_clk_gate2("ssi2_ipg_gate", "ipg", MXC_CCM_CCGR3, 20); - clk[IMX5_CLK_SSI3_IPG_GATE] = imx_clk_gate2("ssi3_ipg_gate", "ipg", MXC_CCM_CCGR3, 24); - clk[IMX5_CLK_ECSPI1_IPG_GATE] = imx_clk_gate2("ecspi1_ipg_gate", "ipg", MXC_CCM_CCGR4, 18); - clk[IMX5_CLK_ECSPI1_PER_GATE] = imx_clk_gate2("ecspi1_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 20); - clk[IMX5_CLK_ECSPI2_IPG_GATE] = imx_clk_gate2("ecspi2_ipg_gate", "ipg", MXC_CCM_CCGR4, 22); - clk[IMX5_CLK_ECSPI2_PER_GATE] = imx_clk_gate2("ecspi2_per_gate", "ecspi_podf", MXC_CCM_CCGR4, 24); - clk[IMX5_CLK_CSPI_IPG_GATE] = imx_clk_gate2("cspi_ipg_gate", "ipg", MXC_CCM_CCGR4, 26); - clk[IMX5_CLK_SDMA_GATE] = imx_clk_gate2("sdma_gate", "ipg", MXC_CCM_CCGR4, 30); - clk[IMX5_CLK_EMI_FAST_GATE] = imx_clk_gate2("emi_fast_gate", "dummy", MXC_CCM_CCGR5, 14); - clk[IMX5_CLK_EMI_SLOW_GATE] = imx_clk_gate2("emi_slow_gate", "emi_slow_podf", MXC_CCM_CCGR5, 16); - clk[IMX5_CLK_IPU_SEL] = imx_clk_mux("ipu_sel", MXC_CCM_CBCMR, 6, 2, ipu_sel, ARRAY_SIZE(ipu_sel)); - clk[IMX5_CLK_IPU_GATE] = imx_clk_gate2("ipu_gate", "ipu_sel", MXC_CCM_CCGR5, 10); - clk[IMX5_CLK_NFC_GATE] = imx_clk_gate2("nfc_gate", "nfc_podf", MXC_CCM_CCGR5, 20); - clk[IMX5_CLK_IPU_DI0_GATE] = imx_clk_gate2("ipu_di0_gate", "ipu_di0_sel", MXC_CCM_CCGR6, 10); - clk[IMX5_CLK_IPU_DI1_GATE] = imx_clk_gate2("ipu_di1_gate", "ipu_di1_sel", MXC_CCM_CCGR6, 12); - clk[IMX5_CLK_GPU3D_SEL] = imx_clk_mux("gpu3d_sel", MXC_CCM_CBCMR, 4, 2, gpu3d_sel, ARRAY_SIZE(gpu3d_sel)); - clk[IMX5_CLK_GPU2D_SEL] = imx_clk_mux("gpu2d_sel", MXC_CCM_CBCMR, 16, 2, gpu2d_sel, ARRAY_SIZE(gpu2d_sel)); - clk[IMX5_CLK_GPU3D_GATE] = imx_clk_gate2("gpu3d_gate", "gpu3d_sel", MXC_CCM_CCGR5, 2); - clk[IMX5_CLK_GARB_GATE] = imx_clk_gate2("garb_gate", "axi_a", MXC_CCM_CCGR5, 4); - clk[IMX5_CLK_GPU2D_GATE] = imx_clk_gate2("gpu2d_gate", "gpu2d_sel", MXC_CCM_CCGR6, 14); - clk[IMX5_CLK_VPU_SEL] = imx_clk_mux("vpu_sel", MXC_CCM_CBCMR, 14, 2, vpu_sel, ARRAY_SIZE(vpu_sel)); - clk[IMX5_CLK_VPU_GATE] = imx_clk_gate2("vpu_gate", "vpu_sel", MXC_CCM_CCGR5, 6); - clk[IMX5_CLK_VPU_REFERENCE_GATE] = imx_clk_gate2("vpu_reference_gate", "osc", MXC_CCM_CCGR5, 8); - clk[IMX5_CLK_UART4_IPG_GATE] = imx_clk_gate2("uart4_ipg_gate", "ipg", MXC_CCM_CCGR7, 8); - clk[IMX5_CLK_UART4_PER_GATE] = imx_clk_gate2("uart4_per_gate", "uart_root", MXC_CCM_CCGR7, 10); - clk[IMX5_CLK_UART5_IPG_GATE] = imx_clk_gate2("uart5_ipg_gate", "ipg", MXC_CCM_CCGR7, 12); - clk[IMX5_CLK_UART5_PER_GATE] = imx_clk_gate2("uart5_per_gate", "uart_root", MXC_CCM_CCGR7, 14); - clk[IMX5_CLK_GPC_DVFS] = imx_clk_gate2("gpc_dvfs", "dummy", MXC_CCM_CCGR5, 24); - - clk[IMX5_CLK_SSI_APM] = imx_clk_mux("ssi_apm", MXC_CCM_CSCMR1, 8, 2, ssi_apm_sels, ARRAY_SIZE(ssi_apm_sels)); - clk[IMX5_CLK_SSI1_ROOT_SEL] = imx_clk_mux("ssi1_root_sel", MXC_CCM_CSCMR1, 14, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); - clk[IMX5_CLK_SSI2_ROOT_SEL] = imx_clk_mux("ssi2_root_sel", MXC_CCM_CSCMR1, 12, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); - clk[IMX5_CLK_SSI3_ROOT_SEL] = imx_clk_mux("ssi3_root_sel", MXC_CCM_CSCMR1, 11, 1, ssi3_clk_sels, ARRAY_SIZE(ssi3_clk_sels)); - clk[IMX5_CLK_SSI_EXT1_SEL] = imx_clk_mux("ssi_ext1_sel", MXC_CCM_CSCMR1, 28, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); - clk[IMX5_CLK_SSI_EXT2_SEL] = imx_clk_mux("ssi_ext2_sel", MXC_CCM_CSCMR1, 30, 2, ssi_clk_sels, ARRAY_SIZE(ssi_clk_sels)); - clk[IMX5_CLK_SSI_EXT1_COM_SEL] = imx_clk_mux("ssi_ext1_com_sel", MXC_CCM_CSCMR1, 0, 1, ssi_ext1_com_sels, ARRAY_SIZE(ssi_ext1_com_sels)); - clk[IMX5_CLK_SSI_EXT2_COM_SEL] = imx_clk_mux("ssi_ext2_com_sel", MXC_CCM_CSCMR1, 1, 1, ssi_ext2_com_sels, ARRAY_SIZE(ssi_ext2_com_sels)); - clk[IMX5_CLK_SSI1_ROOT_PRED] = imx_clk_divider("ssi1_root_pred", "ssi1_root_sel", MXC_CCM_CS1CDR, 6, 3); - clk[IMX5_CLK_SSI1_ROOT_PODF] = imx_clk_divider("ssi1_root_podf", "ssi1_root_pred", MXC_CCM_CS1CDR, 0, 6); - clk[IMX5_CLK_SSI2_ROOT_PRED] = imx_clk_divider("ssi2_root_pred", "ssi2_root_sel", MXC_CCM_CS2CDR, 6, 3); - clk[IMX5_CLK_SSI2_ROOT_PODF] = imx_clk_divider("ssi2_root_podf", "ssi2_root_pred", MXC_CCM_CS2CDR, 0, 6); - clk[IMX5_CLK_SSI_EXT1_PRED] = imx_clk_divider("ssi_ext1_pred", "ssi_ext1_sel", MXC_CCM_CS1CDR, 22, 3); - clk[IMX5_CLK_SSI_EXT1_PODF] = imx_clk_divider("ssi_ext1_podf", "ssi_ext1_pred", MXC_CCM_CS1CDR, 16, 6); - clk[IMX5_CLK_SSI_EXT2_PRED] = imx_clk_divider("ssi_ext2_pred", "ssi_ext2_sel", MXC_CCM_CS2CDR, 22, 3); - clk[IMX5_CLK_SSI_EXT2_PODF] = imx_clk_divider("ssi_ext2_podf", "ssi_ext2_pred", MXC_CCM_CS2CDR, 16, 6); - clk[IMX5_CLK_SSI1_ROOT_GATE] = imx_clk_gate2("ssi1_root_gate", "ssi1_root_podf", MXC_CCM_CCGR3, 18); - clk[IMX5_CLK_SSI2_ROOT_GATE] = imx_clk_gate2("ssi2_root_gate", "ssi2_root_podf", MXC_CCM_CCGR3, 22); - clk[IMX5_CLK_SSI3_ROOT_GATE] = imx_clk_gate2("ssi3_root_gate", "ssi3_root_sel", MXC_CCM_CCGR3, 26); - clk[IMX5_CLK_SSI_EXT1_GATE] = imx_clk_gate2("ssi_ext1_gate", "ssi_ext1_com_sel", MXC_CCM_CCGR3, 28); - clk[IMX5_CLK_SSI_EXT2_GATE] = imx_clk_gate2("ssi_ext2_gate", "ssi_ext2_com_sel", MXC_CCM_CCGR3, 30); - clk[IMX5_CLK_EPIT1_IPG_GATE] = imx_clk_gate2("epit1_ipg_gate", "ipg", MXC_CCM_CCGR2, 2); - clk[IMX5_CLK_EPIT1_HF_GATE] = imx_clk_gate2("epit1_hf_gate", "per_root", MXC_CCM_CCGR2, 4); - clk[IMX5_CLK_EPIT2_IPG_GATE] = imx_clk_gate2("epit2_ipg_gate", "ipg", MXC_CCM_CCGR2, 6); - clk[IMX5_CLK_EPIT2_HF_GATE] = imx_clk_gate2("epit2_hf_gate", "per_root", MXC_CCM_CCGR2, 8); - clk[IMX5_CLK_OWIRE_GATE] = imx_clk_gate2("owire_gate", "per_root", MXC_CCM_CCGR2, 22); - clk[IMX5_CLK_SRTC_GATE] = imx_clk_gate2("srtc_gate", "per_root", MXC_CCM_CCGR4, 28); - clk[IMX5_CLK_PATA_GATE] = imx_clk_gate2("pata_gate", "ipg", MXC_CCM_CCGR4, 0); - clk[IMX5_CLK_SPDIF0_SEL] = imx_clk_mux("spdif0_sel", MXC_CCM_CSCMR2, 0, 2, spdif_sel, ARRAY_SIZE(spdif_sel)); - clk[IMX5_CLK_SPDIF0_PRED] = imx_clk_divider("spdif0_pred", "spdif0_sel", MXC_CCM_CDCDR, 25, 3); - clk[IMX5_CLK_SPDIF0_PODF] = imx_clk_divider("spdif0_podf", "spdif0_pred", MXC_CCM_CDCDR, 19, 6); - clk[IMX5_CLK_SPDIF0_COM_SEL] = imx_clk_mux_flags("spdif0_com_sel", MXC_CCM_CSCMR2, 4, 1, - spdif0_com_sel, ARRAY_SIZE(spdif0_com_sel), CLK_SET_RATE_PARENT); - clk[IMX5_CLK_SPDIF0_GATE] = imx_clk_gate2("spdif0_gate", "spdif0_com_sel", MXC_CCM_CCGR5, 26); - clk[IMX5_CLK_SPDIF_IPG_GATE] = imx_clk_gate2("spdif_ipg_gate", "ipg", MXC_CCM_CCGR5, 30); - clk[IMX5_CLK_SAHARA_IPG_GATE] = imx_clk_gate2("sahara_ipg_gate", "ipg", MXC_CCM_CCGR4, 14); - clk[IMX5_CLK_SATA_REF] = imx_clk_fixed_factor("sata_ref", "usb_phy1_gate", 1, 1); - - clk_register_clkdev(clk[IMX5_CLK_CPU_PODF], NULL, "cpu0"); - clk_register_clkdev(clk[IMX5_CLK_GPC_DVFS], "gpc_dvfs", NULL); - - /* Set SDHC parents to be PLL2 */ - clk_set_parent(clk[IMX5_CLK_ESDHC_A_SEL], clk[IMX5_CLK_PLL2_SW]); - clk_set_parent(clk[IMX5_CLK_ESDHC_B_SEL], clk[IMX5_CLK_PLL2_SW]); - - /* move usb phy clk to 24MHz */ - clk_set_parent(clk[IMX5_CLK_USB_PHY_SEL], clk[IMX5_CLK_OSC]); - - clk_prepare_enable(clk[IMX5_CLK_GPC_DVFS]); - clk_prepare_enable(clk[IMX5_CLK_AHB_MAX]); /* esdhc3 */ - clk_prepare_enable(clk[IMX5_CLK_AIPS_TZ1]); - clk_prepare_enable(clk[IMX5_CLK_AIPS_TZ2]); /* fec */ - clk_prepare_enable(clk[IMX5_CLK_SPBA]); - clk_prepare_enable(clk[IMX5_CLK_EMI_FAST_GATE]); /* fec */ - clk_prepare_enable(clk[IMX5_CLK_EMI_SLOW_GATE]); /* eim */ - clk_prepare_enable(clk[IMX5_CLK_MIPI_HSC1_GATE]); - clk_prepare_enable(clk[IMX5_CLK_MIPI_HSC2_GATE]); - clk_prepare_enable(clk[IMX5_CLK_MIPI_ESC_GATE]); - clk_prepare_enable(clk[IMX5_CLK_MIPI_HSP_GATE]); - clk_prepare_enable(clk[IMX5_CLK_TMAX1]); - clk_prepare_enable(clk[IMX5_CLK_TMAX2]); /* esdhc2, fec */ - clk_prepare_enable(clk[IMX5_CLK_TMAX3]); /* esdhc1, esdhc4 */ -} - -static void __init mx50_clocks_init(struct device_node *np) -{ - void __iomem *ccm_base; - void __iomem *pll_base; - unsigned long r; - - pll_base = ioremap(MX53_DPLL1_BASE, SZ_16K); - WARN_ON(!pll_base); - clk[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", pll_base); - - pll_base = ioremap(MX53_DPLL2_BASE, SZ_16K); - WARN_ON(!pll_base); - clk[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", pll_base); - - pll_base = ioremap(MX53_DPLL3_BASE, SZ_16K); - WARN_ON(!pll_base); - clk[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", pll_base); - - ccm_base = of_iomap(np, 0); - WARN_ON(!ccm_base); - - mx5_clocks_common_init(ccm_base); - - clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 10, 1, - lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); - clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); - clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6); - clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10); - clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); - clk[IMX5_CLK_USB_PHY1_GATE] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10); - clk[IMX5_CLK_USB_PHY2_GATE] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12); - clk[IMX5_CLK_I2C3_GATE] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22); - - clk[IMX5_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4, - mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel)); - clk[IMX5_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3); - clk[IMX5_CLK_CKO1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7); - - clk[IMX5_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5, - mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel)); - clk[IMX5_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3); - clk[IMX5_CLK_CKO2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24); - - imx_check_clocks(clk, ARRAY_SIZE(clk)); - - clk_data.clks = clk; - clk_data.clk_num = ARRAY_SIZE(clk); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); - - /* set SDHC root clock to 200MHZ*/ - clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 200000000); - clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 200000000); - - clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]); - imx_print_silicon_rev("i.MX50", IMX_CHIP_REVISION_1_1); - clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]); - - r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000); - clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r); -} -CLK_OF_DECLARE(imx50_ccm, "fsl,imx50-ccm", mx50_clocks_init); - -static void __init mx51_clocks_init(struct device_node *np) -{ - void __iomem *ccm_base; - void __iomem *pll_base; - u32 val; - - pll_base = ioremap(MX51_DPLL1_BASE, SZ_16K); - WARN_ON(!pll_base); - clk[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", pll_base); - - pll_base = ioremap(MX51_DPLL2_BASE, SZ_16K); - WARN_ON(!pll_base); - clk[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", pll_base); - - pll_base = ioremap(MX51_DPLL3_BASE, SZ_16K); - WARN_ON(!pll_base); - clk[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", pll_base); - - ccm_base = of_iomap(np, 0); - WARN_ON(!ccm_base); - - mx5_clocks_common_init(ccm_base); - - clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 9, 1, - lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); - clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, - mx51_ipu_di0_sel, ARRAY_SIZE(mx51_ipu_di0_sel)); - clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, - mx51_ipu_di1_sel, ARRAY_SIZE(mx51_ipu_di1_sel)); - clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, - mx51_tve_ext_sel, ARRAY_SIZE(mx51_tve_ext_sel), CLK_SET_RATE_PARENT); - clk[IMX5_CLK_TVE_SEL] = imx_clk_mux("tve_sel", MXC_CCM_CSCMR1, 7, 1, - mx51_tve_sel, ARRAY_SIZE(mx51_tve_sel)); - clk[IMX5_CLK_TVE_GATE] = imx_clk_gate2("tve_gate", "tve_sel", MXC_CCM_CCGR2, 30); - clk[IMX5_CLK_TVE_PRED] = imx_clk_divider("tve_pred", "pll3_sw", MXC_CCM_CDCDR, 28, 3); - clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); - clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 6); - clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 10); - clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); - clk[IMX5_CLK_USB_PHY_GATE] = imx_clk_gate2("usb_phy_gate", "usb_phy_sel", MXC_CCM_CCGR2, 0); - clk[IMX5_CLK_HSI2C_GATE] = imx_clk_gate2("hsi2c_gate", "ipg", MXC_CCM_CCGR1, 22); - clk[IMX5_CLK_MIPI_HSC1_GATE] = imx_clk_gate2("mipi_hsc1_gate", "ipg", MXC_CCM_CCGR4, 6); - clk[IMX5_CLK_MIPI_HSC2_GATE] = imx_clk_gate2("mipi_hsc2_gate", "ipg", MXC_CCM_CCGR4, 8); - clk[IMX5_CLK_MIPI_ESC_GATE] = imx_clk_gate2("mipi_esc_gate", "ipg", MXC_CCM_CCGR4, 10); - clk[IMX5_CLK_MIPI_HSP_GATE] = imx_clk_gate2("mipi_hsp_gate", "ipg", MXC_CCM_CCGR4, 12); - clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2, - mx51_spdif_xtal_sel, ARRAY_SIZE(mx51_spdif_xtal_sel)); - clk[IMX5_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", MXC_CCM_CSCMR2, 2, 2, - spdif_sel, ARRAY_SIZE(spdif_sel)); - clk[IMX5_CLK_SPDIF1_PRED] = imx_clk_divider("spdif1_pred", "spdif1_sel", MXC_CCM_CDCDR, 16, 3); - clk[IMX5_CLK_SPDIF1_PODF] = imx_clk_divider("spdif1_podf", "spdif1_pred", MXC_CCM_CDCDR, 9, 6); - clk[IMX5_CLK_SPDIF1_COM_SEL] = imx_clk_mux("spdif1_com_sel", MXC_CCM_CSCMR2, 5, 1, - mx51_spdif1_com_sel, ARRAY_SIZE(mx51_spdif1_com_sel)); - clk[IMX5_CLK_SPDIF1_GATE] = imx_clk_gate2("spdif1_gate", "spdif1_com_sel", MXC_CCM_CCGR5, 28); - - imx_check_clocks(clk, ARRAY_SIZE(clk)); - - clk_data.clks = clk; - clk_data.clk_num = ARRAY_SIZE(clk); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); - - /* set the usboh3 parent to pll2_sw */ - clk_set_parent(clk[IMX5_CLK_USBOH3_SEL], clk[IMX5_CLK_PLL2_SW]); - - /* set SDHC root clock to 166.25MHZ*/ - clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 166250000); - clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 166250000); - - clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]); - imx_print_silicon_rev("i.MX51", mx51_revision()); - clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]); - - /* - * Reference Manual says: Functionality of CCDR[18] and CLPCR[23] is no - * longer supported. Set to one for better power saving. - * - * The effect of not setting these bits is that MIPI clocks can't be - * enabled without the IPU clock being enabled aswell. - */ - val = readl(MXC_CCM_CCDR); - val |= 1 << 18; - writel(val, MXC_CCM_CCDR); - - val = readl(MXC_CCM_CLPCR); - val |= 1 << 23; - writel(val, MXC_CCM_CLPCR); -} -CLK_OF_DECLARE(imx51_ccm, "fsl,imx51-ccm", mx51_clocks_init); - -static void __init mx53_clocks_init(struct device_node *np) -{ - void __iomem *ccm_base; - void __iomem *pll_base; - unsigned long r; - - pll_base = ioremap(MX53_DPLL1_BASE, SZ_16K); - WARN_ON(!pll_base); - clk[IMX5_CLK_PLL1_SW] = imx_clk_pllv2("pll1_sw", "osc", pll_base); - - pll_base = ioremap(MX53_DPLL2_BASE, SZ_16K); - WARN_ON(!pll_base); - clk[IMX5_CLK_PLL2_SW] = imx_clk_pllv2("pll2_sw", "osc", pll_base); - - pll_base = ioremap(MX53_DPLL3_BASE, SZ_16K); - WARN_ON(!pll_base); - clk[IMX5_CLK_PLL3_SW] = imx_clk_pllv2("pll3_sw", "osc", pll_base); - - pll_base = ioremap(MX53_DPLL4_BASE, SZ_16K); - WARN_ON(!pll_base); - clk[IMX5_CLK_PLL4_SW] = imx_clk_pllv2("pll4_sw", "osc", pll_base); - - ccm_base = of_iomap(np, 0); - WARN_ON(!ccm_base); - - mx5_clocks_common_init(ccm_base); - - clk[IMX5_CLK_LP_APM] = imx_clk_mux("lp_apm", MXC_CCM_CCSR, 10, 1, - lp_apm_sel, ARRAY_SIZE(lp_apm_sel)); - clk[IMX5_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); - clk[IMX5_CLK_LDB_DI1_DIV] = imx_clk_divider_flags("ldb_di1_div", "ldb_di1_div_3_5", MXC_CCM_CSCMR2, 11, 1, 0); - clk[IMX5_CLK_LDB_DI1_SEL] = imx_clk_mux_flags("ldb_di1_sel", MXC_CCM_CSCMR2, 9, 1, - mx53_ldb_di1_sel, ARRAY_SIZE(mx53_ldb_di1_sel), CLK_SET_RATE_PARENT); - clk[IMX5_CLK_DI_PLL4_PODF] = imx_clk_divider("di_pll4_podf", "pll4_sw", MXC_CCM_CDCDR, 16, 3); - clk[IMX5_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); - clk[IMX5_CLK_LDB_DI0_DIV] = imx_clk_divider_flags("ldb_di0_div", "ldb_di0_div_3_5", MXC_CCM_CSCMR2, 10, 1, 0); - clk[IMX5_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", MXC_CCM_CSCMR2, 8, 1, - mx53_ldb_di0_sel, ARRAY_SIZE(mx53_ldb_di0_sel), CLK_SET_RATE_PARENT); - clk[IMX5_CLK_LDB_DI0_GATE] = imx_clk_gate2("ldb_di0_gate", "ldb_di0_div", MXC_CCM_CCGR6, 28); - clk[IMX5_CLK_LDB_DI1_GATE] = imx_clk_gate2("ldb_di1_gate", "ldb_di1_div", MXC_CCM_CCGR6, 30); - clk[IMX5_CLK_IPU_DI0_SEL] = imx_clk_mux("ipu_di0_sel", MXC_CCM_CSCMR2, 26, 3, - mx53_ipu_di0_sel, ARRAY_SIZE(mx53_ipu_di0_sel)); - clk[IMX5_CLK_IPU_DI1_SEL] = imx_clk_mux("ipu_di1_sel", MXC_CCM_CSCMR2, 29, 3, - mx53_ipu_di1_sel, ARRAY_SIZE(mx53_ipu_di1_sel)); - clk[IMX5_CLK_TVE_EXT_SEL] = imx_clk_mux_flags("tve_ext_sel", MXC_CCM_CSCMR1, 6, 1, - mx53_tve_ext_sel, ARRAY_SIZE(mx53_tve_ext_sel), CLK_SET_RATE_PARENT); - clk[IMX5_CLK_TVE_GATE] = imx_clk_gate2("tve_gate", "tve_pred", MXC_CCM_CCGR2, 30); - clk[IMX5_CLK_TVE_PRED] = imx_clk_divider("tve_pred", "tve_ext_sel", MXC_CCM_CDCDR, 28, 3); - clk[IMX5_CLK_ESDHC1_PER_GATE] = imx_clk_gate2("esdhc1_per_gate", "esdhc_a_podf", MXC_CCM_CCGR3, 2); - clk[IMX5_CLK_ESDHC2_PER_GATE] = imx_clk_gate2("esdhc2_per_gate", "esdhc_c_sel", MXC_CCM_CCGR3, 6); - clk[IMX5_CLK_ESDHC3_PER_GATE] = imx_clk_gate2("esdhc3_per_gate", "esdhc_b_podf", MXC_CCM_CCGR3, 10); - clk[IMX5_CLK_ESDHC4_PER_GATE] = imx_clk_gate2("esdhc4_per_gate", "esdhc_d_sel", MXC_CCM_CCGR3, 14); - clk[IMX5_CLK_USB_PHY1_GATE] = imx_clk_gate2("usb_phy1_gate", "usb_phy_sel", MXC_CCM_CCGR4, 10); - clk[IMX5_CLK_USB_PHY2_GATE] = imx_clk_gate2("usb_phy2_gate", "usb_phy_sel", MXC_CCM_CCGR4, 12); - clk[IMX5_CLK_CAN_SEL] = imx_clk_mux("can_sel", MXC_CCM_CSCMR2, 6, 2, - mx53_can_sel, ARRAY_SIZE(mx53_can_sel)); - clk[IMX5_CLK_CAN1_SERIAL_GATE] = imx_clk_gate2("can1_serial_gate", "can_sel", MXC_CCM_CCGR6, 22); - clk[IMX5_CLK_CAN1_IPG_GATE] = imx_clk_gate2("can1_ipg_gate", "ipg", MXC_CCM_CCGR6, 20); - clk[IMX5_CLK_OCRAM] = imx_clk_gate2("ocram", "ahb", MXC_CCM_CCGR6, 2); - clk[IMX5_CLK_CAN2_SERIAL_GATE] = imx_clk_gate2("can2_serial_gate", "can_sel", MXC_CCM_CCGR4, 8); - clk[IMX5_CLK_CAN2_IPG_GATE] = imx_clk_gate2("can2_ipg_gate", "ipg", MXC_CCM_CCGR4, 6); - clk[IMX5_CLK_I2C3_GATE] = imx_clk_gate2("i2c3_gate", "per_root", MXC_CCM_CCGR1, 22); - clk[IMX5_CLK_SATA_GATE] = imx_clk_gate2("sata_gate", "ipg", MXC_CCM_CCGR4, 2); - - clk[IMX5_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", MXC_CCM_CCOSR, 0, 4, - mx53_cko1_sel, ARRAY_SIZE(mx53_cko1_sel)); - clk[IMX5_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", MXC_CCM_CCOSR, 4, 3); - clk[IMX5_CLK_CKO1] = imx_clk_gate2("cko1", "cko1_podf", MXC_CCM_CCOSR, 7); - - clk[IMX5_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", MXC_CCM_CCOSR, 16, 5, - mx53_cko2_sel, ARRAY_SIZE(mx53_cko2_sel)); - clk[IMX5_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", MXC_CCM_CCOSR, 21, 3); - clk[IMX5_CLK_CKO2] = imx_clk_gate2("cko2", "cko2_podf", MXC_CCM_CCOSR, 24); - clk[IMX5_CLK_SPDIF_XTAL_SEL] = imx_clk_mux("spdif_xtal_sel", MXC_CCM_CSCMR1, 2, 2, - mx53_spdif_xtal_sel, ARRAY_SIZE(mx53_spdif_xtal_sel)); - clk[IMX5_CLK_ARM] = imx_clk_cpu("arm", "cpu_podf", - clk[IMX5_CLK_CPU_PODF], - clk[IMX5_CLK_CPU_PODF_SEL], - clk[IMX5_CLK_PLL1_SW], - clk[IMX5_CLK_STEP_SEL]); - - imx_check_clocks(clk, ARRAY_SIZE(clk)); - - clk_data.clks = clk; - clk_data.clk_num = ARRAY_SIZE(clk); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); - - /* set SDHC root clock to 200MHZ*/ - clk_set_rate(clk[IMX5_CLK_ESDHC_A_PODF], 200000000); - clk_set_rate(clk[IMX5_CLK_ESDHC_B_PODF], 200000000); - - /* move can bus clk to 24MHz */ - clk_set_parent(clk[IMX5_CLK_CAN_SEL], clk[IMX5_CLK_LP_APM]); - - /* make sure step clock is running from 24MHz */ - clk_set_parent(clk[IMX5_CLK_STEP_SEL], clk[IMX5_CLK_LP_APM]); - - clk_prepare_enable(clk[IMX5_CLK_IIM_GATE]); - imx_print_silicon_rev("i.MX53", mx53_revision()); - clk_disable_unprepare(clk[IMX5_CLK_IIM_GATE]); - - r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000); - clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r); -} -CLK_OF_DECLARE(imx53_ccm, "fsl,imx53-ccm", mx53_clocks_init); diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c deleted file mode 100644 index 469a150bf98f..000000000000 --- a/arch/arm/mach-imx/clk-imx6q.c +++ /dev/null @@ -1,534 +0,0 @@ -/* - * Copyright 2011-2013 Freescale Semiconductor, Inc. - * Copyright 2011 Linaro Ltd. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include <linux/init.h> -#include <linux/types.h> -#include <linux/clk.h> -#include <linux/clkdev.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> -#include <dt-bindings/clock/imx6qdl-clock.h> - -#include "clk.h" -#include "common.h" -#include "hardware.h" - -static const char *step_sels[] = { "osc", "pll2_pfd2_396m", }; -static const char *pll1_sw_sels[] = { "pll1_sys", "step", }; -static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", }; -static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", "dummy", }; -static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", }; -static const char *periph_sels[] = { "periph_pre", "periph_clk2", }; -static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", }; -static const char *axi_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", }; -static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll3_pfd3_454m", "pll3_usb_otg", }; -static const char *gpu_axi_sels[] = { "axi", "ahb", }; -static const char *gpu2d_core_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", }; -static const char *gpu3d_core_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll2_pfd2_396m", }; -static const char *gpu3d_shader_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll2_pfd1_594m", "pll3_pfd0_720m", }; -static const char *ipu_sels[] = { "mmdc_ch0_axi", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; -static const char *ldb_di_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "mmdc_ch1_axi", "pll3_usb_otg", }; -static const char *ipu_di_pre_sels[] = { "mmdc_ch0_axi", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd1_540m", }; -static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; -static const char *ipu1_di1_sels[] = { "ipu1_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; -static const char *ipu2_di0_sels[] = { "ipu2_di0_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; -static const char *ipu2_di1_sels[] = { "ipu2_di1_pre", "dummy", "dummy", "ldb_di0", "ldb_di1", }; -static const char *hsi_tx_sels[] = { "pll3_120m", "pll2_pfd2_396m", }; -static const char *pcie_axi_sels[] = { "axi", "ahb", }; -static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll3_pfd3_454m", "pll4_audio_div", }; -static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; -static const char *enfc_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", }; -static const char *eim_sels[] = { "pll2_pfd2_396m", "pll3_usb_otg", "axi", "pll2_pfd0_352m", }; -static const char *eim_slow_sels[] = { "axi", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", }; -static const char *vdo_axi_sels[] = { "axi", "ahb", }; -static const char *vpu_axi_sels[] = { "axi", "pll2_pfd2_396m", "pll2_pfd0_352m", }; -static const char *cko1_sels[] = { "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div", - "dummy", "axi", "enfc", "ipu1_di0", "ipu1_di1", "ipu2_di0", - "ipu2_di1", "ahb", "ipg", "ipg_per", "ckil", "pll4_audio_div", }; -static const char *cko2_sels[] = { - "mmdc_ch0_axi", "mmdc_ch1_axi", "usdhc4", "usdhc1", - "gpu2d_axi", "dummy", "ecspi_root", "gpu3d_axi", - "usdhc3", "dummy", "arm", "ipu1", - "ipu2", "vdo_axi", "osc", "gpu2d_core", - "gpu3d_core", "usdhc2", "ssi1", "ssi2", - "ssi3", "gpu3d_shader", "vpu_axi", "can_root", - "ldb_di0", "ldb_di1", "esai_extal", "eim_slow", - "uart_serial", "spdif", "asrc", "hsi_tx", -}; -static const char *cko_sels[] = { "cko1", "cko2", }; -static const char *lvds_sels[] = { - "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", - "pll4_audio", "pll5_video", "pll8_mlb", "enet_ref", - "pcie_ref_125m", "sata_ref_100m", -}; -static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", "lvds2_in", "dummy", }; -static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", }; -static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", }; -static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", }; -static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", }; -static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", }; -static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; -static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; - -static struct clk *clk[IMX6QDL_CLK_END]; -static struct clk_onecell_data clk_data; - -static unsigned int const clks_init_on[] __initconst = { - IMX6QDL_CLK_MMDC_CH0_AXI, - IMX6QDL_CLK_ROM, - IMX6QDL_CLK_ARM, -}; - -static struct clk_div_table clk_enet_ref_table[] = { - { .val = 0, .div = 20, }, - { .val = 1, .div = 10, }, - { .val = 2, .div = 5, }, - { .val = 3, .div = 4, }, - { /* sentinel */ } -}; - -static struct clk_div_table post_div_table[] = { - { .val = 2, .div = 1, }, - { .val = 1, .div = 2, }, - { .val = 0, .div = 4, }, - { /* sentinel */ } -}; - -static struct clk_div_table video_div_table[] = { - { .val = 0, .div = 1, }, - { .val = 1, .div = 2, }, - { .val = 2, .div = 1, }, - { .val = 3, .div = 4, }, - { /* sentinel */ } -}; - -static unsigned int share_count_esai; -static unsigned int share_count_asrc; -static unsigned int share_count_ssi1; -static unsigned int share_count_ssi2; -static unsigned int share_count_ssi3; -static unsigned int share_count_mipi_core_cfg; - -static void __init imx6q_clocks_init(struct device_node *ccm_node) -{ - struct device_node *np; - void __iomem *base; - int i; - int ret; - - clk[IMX6QDL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); - clk[IMX6QDL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0); - clk[IMX6QDL_CLK_CKIH] = imx_obtain_fixed_clock("ckih1", 0); - clk[IMX6QDL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0); - /* Clock source from external clock via CLK1/2 PADs */ - clk[IMX6QDL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0); - clk[IMX6QDL_CLK_ANACLK2] = imx_obtain_fixed_clock("anaclk2", 0); - - np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop"); - base = of_iomap(np, 0); - WARN_ON(!base); - - /* Audio/video PLL post dividers do not work on i.MX6q revision 1.0 */ - if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) { - post_div_table[1].div = 1; - post_div_table[2].div = 1; - video_div_table[1].div = 1; - video_div_table[3].div = 1; - } - - clk[IMX6QDL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clk[IMX6QDL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clk[IMX6QDL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clk[IMX6QDL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clk[IMX6QDL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clk[IMX6QDL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clk[IMX6QDL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - - /* type name parent_name base div_mask */ - clk[IMX6QDL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f); - clk[IMX6QDL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1); - clk[IMX6QDL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3); - clk[IMX6QDL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f); - clk[IMX6QDL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f); - clk[IMX6QDL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3); - clk[IMX6QDL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3); - - clk[IMX6QDL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); - - /* Do not bypass PLLs initially */ - clk_set_parent(clk[IMX6QDL_PLL1_BYPASS], clk[IMX6QDL_CLK_PLL1]); - clk_set_parent(clk[IMX6QDL_PLL2_BYPASS], clk[IMX6QDL_CLK_PLL2]); - clk_set_parent(clk[IMX6QDL_PLL3_BYPASS], clk[IMX6QDL_CLK_PLL3]); - clk_set_parent(clk[IMX6QDL_PLL4_BYPASS], clk[IMX6QDL_CLK_PLL4]); - clk_set_parent(clk[IMX6QDL_PLL5_BYPASS], clk[IMX6QDL_CLK_PLL5]); - clk_set_parent(clk[IMX6QDL_PLL6_BYPASS], clk[IMX6QDL_CLK_PLL6]); - clk_set_parent(clk[IMX6QDL_PLL7_BYPASS], clk[IMX6QDL_CLK_PLL7]); - - clk[IMX6QDL_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13); - clk[IMX6QDL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); - clk[IMX6QDL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); - clk[IMX6QDL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); - clk[IMX6QDL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); - clk[IMX6QDL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); - clk[IMX6QDL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); - - /* - * Bit 20 is the reserved and read-only bit, we do this only for: - * - Do nothing for usbphy clk_enable/disable - * - Keep refcount when do usbphy clk_enable/disable, in that case, - * the clk framework may need to enable/disable usbphy's parent - */ - clk[IMX6QDL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20); - clk[IMX6QDL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20); - - /* - * usbphy*_gate needs to be on after system boots up, and software - * never needs to control it anymore. - */ - clk[IMX6QDL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6); - clk[IMX6QDL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6); - - clk[IMX6QDL_CLK_SATA_REF] = imx_clk_fixed_factor("sata_ref", "pll6_enet", 1, 5); - clk[IMX6QDL_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 4); - - clk[IMX6QDL_CLK_SATA_REF_100M] = imx_clk_gate("sata_ref_100m", "sata_ref", base + 0xe0, 20); - clk[IMX6QDL_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19); - - clk[IMX6QDL_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, - base + 0xe0, 0, 2, 0, clk_enet_ref_table, - &imx_ccm_lock); - - clk[IMX6QDL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); - clk[IMX6QDL_CLK_LVDS2_SEL] = imx_clk_mux("lvds2_sel", base + 0x160, 5, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); - - /* - * lvds1_gate and lvds2_gate are pseudo-gates. Both can be - * independently configured as clock inputs or outputs. We treat - * the "output_enable" bit as a gate, even though it's really just - * enabling clock output. - */ - clk[IMX6QDL_CLK_LVDS1_GATE] = imx_clk_gate_exclusive("lvds1_gate", "lvds1_sel", base + 0x160, 10, BIT(12)); - clk[IMX6QDL_CLK_LVDS2_GATE] = imx_clk_gate_exclusive("lvds2_gate", "lvds2_sel", base + 0x160, 11, BIT(13)); - - clk[IMX6QDL_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10)); - clk[IMX6QDL_CLK_LVDS2_IN] = imx_clk_gate_exclusive("lvds2_in", "anaclk2", base + 0x160, 13, BIT(11)); - - /* name parent_name reg idx */ - clk[IMX6QDL_CLK_PLL2_PFD0_352M] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); - clk[IMX6QDL_CLK_PLL2_PFD1_594M] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1); - clk[IMX6QDL_CLK_PLL2_PFD2_396M] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2); - clk[IMX6QDL_CLK_PLL3_PFD0_720M] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0); - clk[IMX6QDL_CLK_PLL3_PFD1_540M] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1); - clk[IMX6QDL_CLK_PLL3_PFD2_508M] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2); - clk[IMX6QDL_CLK_PLL3_PFD3_454M] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3); - - /* name parent_name mult div */ - clk[IMX6QDL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2); - clk[IMX6QDL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4); - clk[IMX6QDL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); - clk[IMX6QDL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); - clk[IMX6QDL_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2); - clk[IMX6QDL_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); - clk[IMX6QDL_CLK_VIDEO_27M] = imx_clk_fixed_factor("video_27m", "pll3_pfd1_540m", 1, 20); - if (cpu_is_imx6dl()) { - clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_fixed_factor("gpu2d_axi", "mmdc_ch0_axi_podf", 1, 1); - clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_fixed_factor("gpu3d_axi", "mmdc_ch0_axi_podf", 1, 1); - } - - clk[IMX6QDL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); - clk[IMX6QDL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock); - clk[IMX6QDL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); - clk[IMX6QDL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); - - np = ccm_node; - base = of_iomap(np, 0); - WARN_ON(!base); - - imx6q_pm_set_ccm_base(base); - - /* name reg shift width parent_names num_parents */ - clk[IMX6QDL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); - clk[IMX6QDL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); - clk[IMX6QDL_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); - clk[IMX6QDL_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); - clk[IMX6QDL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); - clk[IMX6QDL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); - clk[IMX6QDL_CLK_AXI_SEL] = imx_clk_mux("axi_sel", base + 0x14, 6, 2, axi_sels, ARRAY_SIZE(axi_sels)); - clk[IMX6QDL_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); - clk[IMX6QDL_CLK_ASRC_SEL] = imx_clk_mux("asrc_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); - clk[IMX6QDL_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels)); - if (cpu_is_imx6q()) { - clk[IMX6QDL_CLK_GPU2D_AXI] = imx_clk_mux("gpu2d_axi", base + 0x18, 0, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); - clk[IMX6QDL_CLK_GPU3D_AXI] = imx_clk_mux("gpu3d_axi", base + 0x18, 1, 1, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); - } - clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels, ARRAY_SIZE(gpu2d_core_sels)); - clk[IMX6QDL_CLK_GPU3D_CORE_SEL] = imx_clk_mux("gpu3d_core_sel", base + 0x18, 4, 2, gpu3d_core_sels, ARRAY_SIZE(gpu3d_core_sels)); - clk[IMX6QDL_CLK_GPU3D_SHADER_SEL] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8, 2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels)); - clk[IMX6QDL_CLK_IPU1_SEL] = imx_clk_mux("ipu1_sel", base + 0x3c, 9, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); - clk[IMX6QDL_CLK_IPU2_SEL] = imx_clk_mux("ipu2_sel", base + 0x3c, 14, 2, ipu_sels, ARRAY_SIZE(ipu_sels)); - clk[IMX6QDL_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_LDB_DI1_SEL] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di_sels, ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_IPU1_DI0_PRE_SEL] = imx_clk_mux_flags("ipu1_di0_pre_sel", base + 0x34, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_IPU1_DI1_PRE_SEL] = imx_clk_mux_flags("ipu1_di1_pre_sel", base + 0x34, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_IPU2_DI0_PRE_SEL] = imx_clk_mux_flags("ipu2_di0_pre_sel", base + 0x38, 6, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_IPU2_DI1_PRE_SEL] = imx_clk_mux_flags("ipu2_di1_pre_sel", base + 0x38, 15, 3, ipu_di_pre_sels, ARRAY_SIZE(ipu_di_pre_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_IPU1_DI0_SEL] = imx_clk_mux_flags("ipu1_di0_sel", base + 0x34, 0, 3, ipu1_di0_sels, ARRAY_SIZE(ipu1_di0_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_IPU1_DI1_SEL] = imx_clk_mux_flags("ipu1_di1_sel", base + 0x34, 9, 3, ipu1_di1_sels, ARRAY_SIZE(ipu1_di1_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_IPU2_DI0_SEL] = imx_clk_mux_flags("ipu2_di0_sel", base + 0x38, 0, 3, ipu2_di0_sels, ARRAY_SIZE(ipu2_di0_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_IPU2_DI1_SEL] = imx_clk_mux_flags("ipu2_di1_sel", base + 0x38, 9, 3, ipu2_di1_sels, ARRAY_SIZE(ipu2_di1_sels), CLK_SET_RATE_PARENT); - clk[IMX6QDL_CLK_HSI_TX_SEL] = imx_clk_mux("hsi_tx_sel", base + 0x30, 28, 1, hsi_tx_sels, ARRAY_SIZE(hsi_tx_sels)); - clk[IMX6QDL_CLK_PCIE_AXI_SEL] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels)); - clk[IMX6QDL_CLK_SSI1_SEL] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_SSI2_SEL] = imx_clk_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_SSI3_SEL] = imx_clk_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_USDHC1_SEL] = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_USDHC2_SEL] = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_USDHC3_SEL] = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_USDHC4_SEL] = imx_clk_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_ENFC_SEL] = imx_clk_mux("enfc_sel", base + 0x2c, 16, 2, enfc_sels, ARRAY_SIZE(enfc_sels)); - clk[IMX6QDL_CLK_EIM_SEL] = imx_clk_fixup_mux("eim_sel", base + 0x1c, 27, 2, eim_sels, ARRAY_SIZE(eim_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_EIM_SLOW_SEL] = imx_clk_fixup_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_VDO_AXI_SEL] = imx_clk_mux("vdo_axi_sel", base + 0x18, 11, 1, vdo_axi_sels, ARRAY_SIZE(vdo_axi_sels)); - clk[IMX6QDL_CLK_VPU_AXI_SEL] = imx_clk_mux("vpu_axi_sel", base + 0x18, 14, 2, vpu_axi_sels, ARRAY_SIZE(vpu_axi_sels)); - clk[IMX6QDL_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels)); - clk[IMX6QDL_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels)); - clk[IMX6QDL_CLK_CKO] = imx_clk_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels)); - - /* name reg shift width busy: reg, shift parent_names num_parents */ - clk[IMX6QDL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); - clk[IMX6QDL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels)); - - /* name parent_name reg shift width */ - clk[IMX6QDL_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); - clk[IMX6QDL_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); - clk[IMX6QDL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2); - clk[IMX6QDL_CLK_IPG_PER] = imx_clk_fixup_divider("ipg_per", "ipg", base + 0x1c, 0, 6, imx_cscmr1_fixup); - clk[IMX6QDL_CLK_ESAI_PRED] = imx_clk_divider("esai_pred", "esai_sel", base + 0x28, 9, 3); - clk[IMX6QDL_CLK_ESAI_PODF] = imx_clk_divider("esai_podf", "esai_pred", base + 0x28, 25, 3); - clk[IMX6QDL_CLK_ASRC_PRED] = imx_clk_divider("asrc_pred", "asrc_sel", base + 0x30, 12, 3); - clk[IMX6QDL_CLK_ASRC_PODF] = imx_clk_divider("asrc_podf", "asrc_pred", base + 0x30, 9, 3); - clk[IMX6QDL_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); - clk[IMX6QDL_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); - clk[IMX6QDL_CLK_CAN_ROOT] = imx_clk_divider("can_root", "pll3_60m", base + 0x20, 2, 6); - clk[IMX6QDL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "pll3_60m", base + 0x38, 19, 6); - clk[IMX6QDL_CLK_GPU2D_CORE_PODF] = imx_clk_divider("gpu2d_core_podf", "gpu2d_core_sel", base + 0x18, 23, 3); - clk[IMX6QDL_CLK_GPU3D_CORE_PODF] = imx_clk_divider("gpu3d_core_podf", "gpu3d_core_sel", base + 0x18, 26, 3); - clk[IMX6QDL_CLK_GPU3D_SHADER] = imx_clk_divider("gpu3d_shader", "gpu3d_shader_sel", base + 0x18, 29, 3); - clk[IMX6QDL_CLK_IPU1_PODF] = imx_clk_divider("ipu1_podf", "ipu1_sel", base + 0x3c, 11, 3); - clk[IMX6QDL_CLK_IPU2_PODF] = imx_clk_divider("ipu2_podf", "ipu2_sel", base + 0x3c, 16, 3); - clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); - clk[IMX6QDL_CLK_LDB_DI0_PODF] = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0); - clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); - clk[IMX6QDL_CLK_LDB_DI1_PODF] = imx_clk_divider_flags("ldb_di1_podf", "ldb_di1_div_3_5", base + 0x20, 11, 1, 0); - clk[IMX6QDL_CLK_IPU1_DI0_PRE] = imx_clk_divider("ipu1_di0_pre", "ipu1_di0_pre_sel", base + 0x34, 3, 3); - clk[IMX6QDL_CLK_IPU1_DI1_PRE] = imx_clk_divider("ipu1_di1_pre", "ipu1_di1_pre_sel", base + 0x34, 12, 3); - clk[IMX6QDL_CLK_IPU2_DI0_PRE] = imx_clk_divider("ipu2_di0_pre", "ipu2_di0_pre_sel", base + 0x38, 3, 3); - clk[IMX6QDL_CLK_IPU2_DI1_PRE] = imx_clk_divider("ipu2_di1_pre", "ipu2_di1_pre_sel", base + 0x38, 12, 3); - clk[IMX6QDL_CLK_HSI_TX_PODF] = imx_clk_divider("hsi_tx_podf", "hsi_tx_sel", base + 0x30, 29, 3); - clk[IMX6QDL_CLK_SSI1_PRED] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3); - clk[IMX6QDL_CLK_SSI1_PODF] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6); - clk[IMX6QDL_CLK_SSI2_PRED] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3); - clk[IMX6QDL_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6); - clk[IMX6QDL_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3); - clk[IMX6QDL_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6); - clk[IMX6QDL_CLK_UART_SERIAL_PODF] = imx_clk_divider("uart_serial_podf", "pll3_80m", base + 0x24, 0, 6); - clk[IMX6QDL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3); - clk[IMX6QDL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3); - clk[IMX6QDL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3); - clk[IMX6QDL_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3); - clk[IMX6QDL_CLK_ENFC_PRED] = imx_clk_divider("enfc_pred", "enfc_sel", base + 0x2c, 18, 3); - clk[IMX6QDL_CLK_ENFC_PODF] = imx_clk_divider("enfc_podf", "enfc_pred", base + 0x2c, 21, 6); - clk[IMX6QDL_CLK_EIM_PODF] = imx_clk_fixup_divider("eim_podf", "eim_sel", base + 0x1c, 20, 3, imx_cscmr1_fixup); - clk[IMX6QDL_CLK_EIM_SLOW_PODF] = imx_clk_fixup_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3, imx_cscmr1_fixup); - clk[IMX6QDL_CLK_VPU_AXI_PODF] = imx_clk_divider("vpu_axi_podf", "vpu_axi_sel", base + 0x24, 25, 3); - clk[IMX6QDL_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3); - clk[IMX6QDL_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3); - - /* name parent_name reg shift width busy: reg, shift */ - clk[IMX6QDL_CLK_AXI] = imx_clk_busy_divider("axi", "axi_sel", base + 0x14, 16, 3, base + 0x48, 0); - clk[IMX6QDL_CLK_MMDC_CH0_AXI_PODF] = imx_clk_busy_divider("mmdc_ch0_axi_podf", "periph", base + 0x14, 19, 3, base + 0x48, 4); - clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF] = imx_clk_busy_divider("mmdc_ch1_axi_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); - clk[IMX6QDL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); - clk[IMX6QDL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); - - /* name parent_name reg shift */ - clk[IMX6QDL_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4); - clk[IMX6QDL_CLK_ASRC] = imx_clk_gate2_shared("asrc", "asrc_podf", base + 0x68, 6, &share_count_asrc); - clk[IMX6QDL_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); - clk[IMX6QDL_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); - clk[IMX6QDL_CLK_CAN1_IPG] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14); - clk[IMX6QDL_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_root", base + 0x68, 16); - clk[IMX6QDL_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18); - clk[IMX6QDL_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_root", base + 0x68, 20); - clk[IMX6QDL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0); - clk[IMX6QDL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2); - clk[IMX6QDL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4); - clk[IMX6QDL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6); - if (cpu_is_imx6dl()) - clk[IMX6DL_CLK_I2C4] = imx_clk_gate2("i2c4", "ipg_per", base + 0x6c, 8); - else - clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8); - clk[IMX6QDL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10); - clk[IMX6QDL_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai); - clk[IMX6QDL_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai); - clk[IMX6QDL_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); - clk[IMX6QDL_CLK_GPT_IPG] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20); - clk[IMX6QDL_CLK_GPT_IPG_PER] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22); - if (cpu_is_imx6dl()) - /* - * The multiplexer and divider of imx6q clock gpu3d_shader get - * redefined/reused as gpu2d_core_sel and gpu2d_core_podf on imx6dl. - */ - clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu3d_shader", base + 0x6c, 24); - else - clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24); - clk[IMX6QDL_CLK_GPU3D_CORE] = imx_clk_gate2("gpu3d_core", "gpu3d_core_podf", base + 0x6c, 26); - clk[IMX6QDL_CLK_HDMI_IAHB] = imx_clk_gate2("hdmi_iahb", "ahb", base + 0x70, 0); - clk[IMX6QDL_CLK_HDMI_ISFR] = imx_clk_gate2("hdmi_isfr", "video_27m", base + 0x70, 4); - clk[IMX6QDL_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_per", base + 0x70, 6); - clk[IMX6QDL_CLK_I2C2] = imx_clk_gate2("i2c2", "ipg_per", base + 0x70, 8); - clk[IMX6QDL_CLK_I2C3] = imx_clk_gate2("i2c3", "ipg_per", base + 0x70, 10); - clk[IMX6QDL_CLK_IIM] = imx_clk_gate2("iim", "ipg", base + 0x70, 12); - clk[IMX6QDL_CLK_ENFC] = imx_clk_gate2("enfc", "enfc_podf", base + 0x70, 14); - clk[IMX6QDL_CLK_VDOA] = imx_clk_gate2("vdoa", "vdo_axi", base + 0x70, 26); - clk[IMX6QDL_CLK_IPU1] = imx_clk_gate2("ipu1", "ipu1_podf", base + 0x74, 0); - clk[IMX6QDL_CLK_IPU1_DI0] = imx_clk_gate2("ipu1_di0", "ipu1_di0_sel", base + 0x74, 2); - clk[IMX6QDL_CLK_IPU1_DI1] = imx_clk_gate2("ipu1_di1", "ipu1_di1_sel", base + 0x74, 4); - clk[IMX6QDL_CLK_IPU2] = imx_clk_gate2("ipu2", "ipu2_podf", base + 0x74, 6); - clk[IMX6QDL_CLK_IPU2_DI0] = imx_clk_gate2("ipu2_di0", "ipu2_di0_sel", base + 0x74, 8); - clk[IMX6QDL_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_podf", base + 0x74, 12); - clk[IMX6QDL_CLK_LDB_DI1] = imx_clk_gate2("ldb_di1", "ldb_di1_podf", base + 0x74, 14); - clk[IMX6QDL_CLK_IPU2_DI1] = imx_clk_gate2("ipu2_di1", "ipu2_di1_sel", base + 0x74, 10); - clk[IMX6QDL_CLK_HSI_TX] = imx_clk_gate2_shared("hsi_tx", "hsi_tx_podf", base + 0x74, 16, &share_count_mipi_core_cfg); - clk[IMX6QDL_CLK_MIPI_CORE_CFG] = imx_clk_gate2_shared("mipi_core_cfg", "video_27m", base + 0x74, 16, &share_count_mipi_core_cfg); - clk[IMX6QDL_CLK_MIPI_IPG] = imx_clk_gate2_shared("mipi_ipg", "ipg", base + 0x74, 16, &share_count_mipi_core_cfg); - if (cpu_is_imx6dl()) - /* - * The multiplexer and divider of the imx6q clock gpu2d get - * redefined/reused as mlb_sys_sel and mlb_sys_clk_podf on imx6dl. - */ - clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "gpu2d_core_podf", base + 0x74, 18); - else - clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "axi", base + 0x74, 18); - clk[IMX6QDL_CLK_MMDC_CH0_AXI] = imx_clk_gate2("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20); - clk[IMX6QDL_CLK_MMDC_CH1_AXI] = imx_clk_gate2("mmdc_ch1_axi", "mmdc_ch1_axi_podf", base + 0x74, 22); - clk[IMX6QDL_CLK_OCRAM] = imx_clk_gate2("ocram", "ahb", base + 0x74, 28); - clk[IMX6QDL_CLK_OPENVG_AXI] = imx_clk_gate2("openvg_axi", "axi", base + 0x74, 30); - clk[IMX6QDL_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "pcie_axi_sel", base + 0x78, 0); - clk[IMX6QDL_CLK_PER1_BCH] = imx_clk_gate2("per1_bch", "usdhc3", base + 0x78, 12); - clk[IMX6QDL_CLK_PWM1] = imx_clk_gate2("pwm1", "ipg_per", base + 0x78, 16); - clk[IMX6QDL_CLK_PWM2] = imx_clk_gate2("pwm2", "ipg_per", base + 0x78, 18); - clk[IMX6QDL_CLK_PWM3] = imx_clk_gate2("pwm3", "ipg_per", base + 0x78, 20); - clk[IMX6QDL_CLK_PWM4] = imx_clk_gate2("pwm4", "ipg_per", base + 0x78, 22); - clk[IMX6QDL_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24); - clk[IMX6QDL_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26); - clk[IMX6QDL_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28); - clk[IMX6QDL_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); - clk[IMX6QDL_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); - clk[IMX6QDL_CLK_SATA] = imx_clk_gate2("sata", "ipg", base + 0x7c, 4); - clk[IMX6QDL_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); - clk[IMX6QDL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); - clk[IMX6QDL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif_podf", base + 0x7c, 14); - clk[IMX6QDL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); - clk[IMX6QDL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); - clk[IMX6QDL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); - clk[IMX6QDL_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1); - clk[IMX6QDL_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2); - clk[IMX6QDL_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3); - clk[IMX6QDL_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24); - clk[IMX6QDL_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_serial_podf", base + 0x7c, 26); - clk[IMX6QDL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0); - clk[IMX6QDL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2); - clk[IMX6QDL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4); - clk[IMX6QDL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6); - clk[IMX6QDL_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8); - clk[IMX6QDL_CLK_EIM_SLOW] = imx_clk_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10); - clk[IMX6QDL_CLK_VDO_AXI] = imx_clk_gate2("vdo_axi", "vdo_axi_sel", base + 0x80, 12); - clk[IMX6QDL_CLK_VPU_AXI] = imx_clk_gate2("vpu_axi", "vpu_axi_podf", base + 0x80, 14); - clk[IMX6QDL_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7); - clk[IMX6QDL_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24); - - /* - * The gpt_3m clock is not available on i.MX6Q TO1.0. Let's point it - * to clock gpt_ipg_per to ease the gpt driver code. - */ - if (cpu_is_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0) - clk[IMX6QDL_CLK_GPT_3M] = clk[IMX6QDL_CLK_GPT_IPG_PER]; - - imx_check_clocks(clk, ARRAY_SIZE(clk)); - - clk_data.clks = clk; - clk_data.clk_num = ARRAY_SIZE(clk); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); - - clk_register_clkdev(clk[IMX6QDL_CLK_ENET_REF], "enet_ref", NULL); - - if ((imx_get_soc_revision() != IMX_CHIP_REVISION_1_0) || - cpu_is_imx6dl()) { - clk_set_parent(clk[IMX6QDL_CLK_LDB_DI0_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]); - clk_set_parent(clk[IMX6QDL_CLK_LDB_DI1_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]); - } - - clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI0_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]); - clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI1_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]); - clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI0_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]); - clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI1_PRE_SEL], clk[IMX6QDL_CLK_PLL5_VIDEO_DIV]); - clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI0_SEL], clk[IMX6QDL_CLK_IPU1_DI0_PRE]); - clk_set_parent(clk[IMX6QDL_CLK_IPU1_DI1_SEL], clk[IMX6QDL_CLK_IPU1_DI1_PRE]); - clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI0_SEL], clk[IMX6QDL_CLK_IPU2_DI0_PRE]); - clk_set_parent(clk[IMX6QDL_CLK_IPU2_DI1_SEL], clk[IMX6QDL_CLK_IPU2_DI1_PRE]); - - /* - * The gpmi needs 100MHz frequency in the EDO/Sync mode, - * We can not get the 100MHz from the pll2_pfd0_352m. - * So choose pll2_pfd2_396m as enfc_sel's parent. - */ - clk_set_parent(clk[IMX6QDL_CLK_ENFC_SEL], clk[IMX6QDL_CLK_PLL2_PFD2_396M]); - - for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) - clk_prepare_enable(clk[clks_init_on[i]]); - - if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { - clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY1_GATE]); - clk_prepare_enable(clk[IMX6QDL_CLK_USBPHY2_GATE]); - } - - /* - * Let's initially set up CLKO with OSC24M, since this configuration - * is widely used by imx6q board designs to clock audio codec. - */ - ret = clk_set_parent(clk[IMX6QDL_CLK_CKO2_SEL], clk[IMX6QDL_CLK_OSC]); - if (!ret) - ret = clk_set_parent(clk[IMX6QDL_CLK_CKO], clk[IMX6QDL_CLK_CKO2]); - if (ret) - pr_warn("failed to set up CLKO: %d\n", ret); - - /* Audio-related clocks configuration */ - clk_set_parent(clk[IMX6QDL_CLK_SPDIF_SEL], clk[IMX6QDL_CLK_PLL3_PFD3_454M]); - - /* All existing boards with PCIe use LVDS1 */ - if (IS_ENABLED(CONFIG_PCI_IMX6)) - clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]); - - /* Set initial power mode */ - imx6q_set_lpm(WAIT_CLOCKED); -} -CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init); diff --git a/arch/arm/mach-imx/clk-imx6sl.c b/arch/arm/mach-imx/clk-imx6sl.c deleted file mode 100644 index e982ebe10814..000000000000 --- a/arch/arm/mach-imx/clk-imx6sl.c +++ /dev/null @@ -1,450 +0,0 @@ -/* - * Copyright 2013-2014 Freescale Semiconductor, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include <linux/clk.h> -#include <linux/clkdev.h> -#include <linux/err.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> -#include <dt-bindings/clock/imx6sl-clock.h> - -#include "clk.h" -#include "common.h" - -#define CCSR 0xc -#define BM_CCSR_PLL1_SW_CLK_SEL (1 << 2) -#define CACRR 0x10 -#define CDHIPR 0x48 -#define BM_CDHIPR_ARM_PODF_BUSY (1 << 16) -#define ARM_WAIT_DIV_396M 2 -#define ARM_WAIT_DIV_792M 4 -#define ARM_WAIT_DIV_996M 6 - -#define PLL_ARM 0x0 -#define BM_PLL_ARM_DIV_SELECT (0x7f << 0) -#define BM_PLL_ARM_POWERDOWN (1 << 12) -#define BM_PLL_ARM_ENABLE (1 << 13) -#define BM_PLL_ARM_LOCK (1 << 31) -#define PLL_ARM_DIV_792M 66 - -static const char *step_sels[] = { "osc", "pll2_pfd2", }; -static const char *pll1_sw_sels[] = { "pll1_sys", "step", }; -static const char *ocram_alt_sels[] = { "pll2_pfd2", "pll3_pfd1", }; -static const char *ocram_sels[] = { "periph", "ocram_alt_sels", }; -static const char *pre_periph_sels[] = { "pll2_bus", "pll2_pfd2", "pll2_pfd0", "pll2_198m", }; -static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", "dummy", }; -static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", }; -static const char *periph_sels[] = { "pre_periph_sel", "periph_clk2_podf", }; -static const char *periph2_sels[] = { "pre_periph2_sel", "periph2_clk2_podf", }; -static const char *csi_sels[] = { "osc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", }; -static const char *lcdif_axi_sels[] = { "pll2_bus", "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", }; -static const char *usdhc_sels[] = { "pll2_pfd2", "pll2_pfd0", }; -static const char *ssi_sels[] = { "pll3_pfd2", "pll3_pfd3", "pll4_audio_div", "dummy", }; -static const char *perclk_sels[] = { "ipg", "osc", }; -static const char *pxp_axi_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd2", "pll3_pfd3", }; -static const char *epdc_axi_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd2", "pll3_pfd2", }; -static const char *gpu2d_ovg_sels[] = { "pll3_pfd1", "pll3_usb_otg", "pll2_bus", "pll2_pfd2", }; -static const char *gpu2d_sels[] = { "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", "pll2_bus", }; -static const char *lcdif_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll3_pfd0", "pll3_pfd1", }; -static const char *epdc_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd1", "pll3_pfd1", }; -static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2", "pll3_pfd3", "pll3_usb_otg", }; -static const char *ecspi_sels[] = { "pll3_60m", "osc", }; -static const char *uart_sels[] = { "pll3_80m", "osc", }; -static const char *lvds_sels[] = { - "pll1_sys", "pll2_bus", "pll2_pfd0", "pll2_pfd1", "pll2_pfd2", "dummy", "pll4_audio", "pll5_video", - "dummy", "enet_ref", "dummy", "dummy", "pll3_usb_otg", "pll7_usb_host", "pll3_pfd0", "pll3_pfd1", - "pll3_pfd2", "pll3_pfd3", "osc", "dummy", "dummy", "dummy", "dummy", "dummy", - "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", -}; -static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", }; -static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", }; -static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", }; -static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", }; -static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", }; -static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", }; -static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; -static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; - -static struct clk_div_table clk_enet_ref_table[] = { - { .val = 0, .div = 20, }, - { .val = 1, .div = 10, }, - { .val = 2, .div = 5, }, - { .val = 3, .div = 4, }, - { } -}; - -static struct clk_div_table post_div_table[] = { - { .val = 2, .div = 1, }, - { .val = 1, .div = 2, }, - { .val = 0, .div = 4, }, - { } -}; - -static struct clk_div_table video_div_table[] = { - { .val = 0, .div = 1, }, - { .val = 1, .div = 2, }, - { .val = 2, .div = 1, }, - { .val = 3, .div = 4, }, - { } -}; - -static unsigned int share_count_ssi1; -static unsigned int share_count_ssi2; -static unsigned int share_count_ssi3; - -static struct clk *clks[IMX6SL_CLK_END]; -static struct clk_onecell_data clk_data; -static void __iomem *ccm_base; -static void __iomem *anatop_base; - -static const u32 clks_init_on[] __initconst = { - IMX6SL_CLK_IPG, IMX6SL_CLK_ARM, IMX6SL_CLK_MMDC_ROOT, -}; - -/* - * ERR005311 CCM: After exit from WAIT mode, unwanted interrupt(s) taken - * during WAIT mode entry process could cause cache memory - * corruption. - * - * Software workaround: - * To prevent this issue from occurring, software should ensure that the - * ARM to IPG clock ratio is less than 12:5 (that is < 2.4x), before - * entering WAIT mode. - * - * This function will set the ARM clk to max value within the 12:5 limit. - * As IPG clock is fixed at 66MHz(so ARM freq must not exceed 158.4MHz), - * ARM freq are one of below setpoints: 396MHz, 792MHz and 996MHz, since - * the clk APIs can NOT be called in idle thread(may cause kernel schedule - * as there is sleep function in PLL wait function), so here we just slow - * down ARM to below freq according to previous freq: - * - * run mode wait mode - * 396MHz -> 132MHz; - * 792MHz -> 158.4MHz; - * 996MHz -> 142.3MHz; - */ -static int imx6sl_get_arm_divider_for_wait(void) -{ - if (readl_relaxed(ccm_base + CCSR) & BM_CCSR_PLL1_SW_CLK_SEL) { - return ARM_WAIT_DIV_396M; - } else { - if ((readl_relaxed(anatop_base + PLL_ARM) & - BM_PLL_ARM_DIV_SELECT) == PLL_ARM_DIV_792M) - return ARM_WAIT_DIV_792M; - else - return ARM_WAIT_DIV_996M; - } -} - -static void imx6sl_enable_pll_arm(bool enable) -{ - static u32 saved_pll_arm; - u32 val; - - if (enable) { - saved_pll_arm = val = readl_relaxed(anatop_base + PLL_ARM); - val |= BM_PLL_ARM_ENABLE; - val &= ~BM_PLL_ARM_POWERDOWN; - writel_relaxed(val, anatop_base + PLL_ARM); - while (!(__raw_readl(anatop_base + PLL_ARM) & BM_PLL_ARM_LOCK)) - ; - } else { - writel_relaxed(saved_pll_arm, anatop_base + PLL_ARM); - } -} - -void imx6sl_set_wait_clk(bool enter) -{ - static unsigned long saved_arm_div; - int arm_div_for_wait = imx6sl_get_arm_divider_for_wait(); - - /* - * According to hardware design, arm podf change need - * PLL1 clock enabled. - */ - if (arm_div_for_wait == ARM_WAIT_DIV_396M) - imx6sl_enable_pll_arm(true); - - if (enter) { - saved_arm_div = readl_relaxed(ccm_base + CACRR); - writel_relaxed(arm_div_for_wait, ccm_base + CACRR); - } else { - writel_relaxed(saved_arm_div, ccm_base + CACRR); - } - while (__raw_readl(ccm_base + CDHIPR) & BM_CDHIPR_ARM_PODF_BUSY) - ; - - if (arm_div_for_wait == ARM_WAIT_DIV_396M) - imx6sl_enable_pll_arm(false); -} - -static void __init imx6sl_clocks_init(struct device_node *ccm_node) -{ - struct device_node *np; - void __iomem *base; - int i; - int ret; - - clks[IMX6SL_CLK_DUMMY] = imx_clk_fixed("dummy", 0); - clks[IMX6SL_CLK_CKIL] = imx_obtain_fixed_clock("ckil", 0); - clks[IMX6SL_CLK_OSC] = imx_obtain_fixed_clock("osc", 0); - /* Clock source from external clock via CLK1 PAD */ - clks[IMX6SL_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0); - - np = of_find_compatible_node(NULL, NULL, "fsl,imx6sl-anatop"); - base = of_iomap(np, 0); - WARN_ON(!base); - anatop_base = base; - - clks[IMX6SL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clks[IMX6SL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clks[IMX6SL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clks[IMX6SL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clks[IMX6SL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clks[IMX6SL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clks[IMX6SL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - - /* type name parent_name base div_mask */ - clks[IMX6SL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f); - clks[IMX6SL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1); - clks[IMX6SL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3); - clks[IMX6SL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f); - clks[IMX6SL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f); - clks[IMX6SL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3); - clks[IMX6SL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3); - - clks[IMX6SL_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX6SL_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX6SL_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX6SL_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX6SL_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX6SL_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX6SL_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); - - /* Do not bypass PLLs initially */ - clk_set_parent(clks[IMX6SL_PLL1_BYPASS], clks[IMX6SL_CLK_PLL1]); - clk_set_parent(clks[IMX6SL_PLL2_BYPASS], clks[IMX6SL_CLK_PLL2]); - clk_set_parent(clks[IMX6SL_PLL3_BYPASS], clks[IMX6SL_CLK_PLL3]); - clk_set_parent(clks[IMX6SL_PLL4_BYPASS], clks[IMX6SL_CLK_PLL4]); - clk_set_parent(clks[IMX6SL_PLL5_BYPASS], clks[IMX6SL_CLK_PLL5]); - clk_set_parent(clks[IMX6SL_PLL6_BYPASS], clks[IMX6SL_CLK_PLL6]); - clk_set_parent(clks[IMX6SL_PLL7_BYPASS], clks[IMX6SL_CLK_PLL7]); - - clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13); - clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); - clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); - clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); - clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); - clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); - clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); - - clks[IMX6SL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); - clks[IMX6SL_CLK_LVDS1_OUT] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12)); - clks[IMX6SL_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10)); - - /* - * usbphy1 and usbphy2 are implemented as dummy gates using reserve - * bit 20. They are used by phy driver to keep the refcount of - * parent PLL correct. usbphy1_gate and usbphy2_gate only needs to be - * turned on during boot, and software will not need to control it - * anymore after that. - */ - clks[IMX6SL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20); - clks[IMX6SL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20); - clks[IMX6SL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6); - clks[IMX6SL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6); - - /* dev name parent_name flags reg shift width div: flags, div_table lock */ - clks[IMX6SL_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); - clks[IMX6SL_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock); - clks[IMX6SL_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); - clks[IMX6SL_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); - clks[IMX6SL_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, base + 0xe0, 0, 2, 0, clk_enet_ref_table, &imx_ccm_lock); - - /* name parent_name reg idx */ - clks[IMX6SL_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0", "pll2_bus", base + 0x100, 0); - clks[IMX6SL_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1", "pll2_bus", base + 0x100, 1); - clks[IMX6SL_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2", "pll2_bus", base + 0x100, 2); - clks[IMX6SL_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0", "pll3_usb_otg", base + 0xf0, 0); - clks[IMX6SL_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1", "pll3_usb_otg", base + 0xf0, 1); - clks[IMX6SL_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_usb_otg", base + 0xf0, 2); - clks[IMX6SL_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_usb_otg", base + 0xf0, 3); - - /* name parent_name mult div */ - clks[IMX6SL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2", 1, 2); - clks[IMX6SL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4); - clks[IMX6SL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); - clks[IMX6SL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); - - np = ccm_node; - base = of_iomap(np, 0); - WARN_ON(!base); - ccm_base = base; - - /* Reuse imx6q pm code */ - imx6q_pm_set_ccm_base(base); - - /* name reg shift width parent_names num_parents */ - clks[IMX6SL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); - clks[IMX6SL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); - clks[IMX6SL_CLK_OCRAM_ALT_SEL] = imx_clk_mux("ocram_alt_sel", base + 0x14, 7, 1, ocram_alt_sels, ARRAY_SIZE(ocram_alt_sels)); - clks[IMX6SL_CLK_OCRAM_SEL] = imx_clk_mux("ocram_sel", base + 0x14, 6, 1, ocram_sels, ARRAY_SIZE(ocram_sels)); - clks[IMX6SL_CLK_PRE_PERIPH2_SEL] = imx_clk_mux("pre_periph2_sel", base + 0x18, 21, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels)); - clks[IMX6SL_CLK_PRE_PERIPH_SEL] = imx_clk_mux("pre_periph_sel", base + 0x18, 18, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels)); - clks[IMX6SL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); - clks[IMX6SL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); - clks[IMX6SL_CLK_CSI_SEL] = imx_clk_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels)); - clks[IMX6SL_CLK_LCDIF_AXI_SEL] = imx_clk_mux("lcdif_axi_sel", base + 0x3c, 14, 2, lcdif_axi_sels, ARRAY_SIZE(lcdif_axi_sels)); - clks[IMX6SL_CLK_USDHC1_SEL] = imx_clk_fixup_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); - clks[IMX6SL_CLK_USDHC2_SEL] = imx_clk_fixup_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); - clks[IMX6SL_CLK_USDHC3_SEL] = imx_clk_fixup_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); - clks[IMX6SL_CLK_USDHC4_SEL] = imx_clk_fixup_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels), imx_cscmr1_fixup); - clks[IMX6SL_CLK_SSI1_SEL] = imx_clk_fixup_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); - clks[IMX6SL_CLK_SSI2_SEL] = imx_clk_fixup_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); - clks[IMX6SL_CLK_SSI3_SEL] = imx_clk_fixup_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels), imx_cscmr1_fixup); - clks[IMX6SL_CLK_PERCLK_SEL] = imx_clk_fixup_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels), imx_cscmr1_fixup); - clks[IMX6SL_CLK_PXP_AXI_SEL] = imx_clk_mux("pxp_axi_sel", base + 0x34, 6, 3, pxp_axi_sels, ARRAY_SIZE(pxp_axi_sels)); - clks[IMX6SL_CLK_EPDC_AXI_SEL] = imx_clk_mux("epdc_axi_sel", base + 0x34, 15, 3, epdc_axi_sels, ARRAY_SIZE(epdc_axi_sels)); - clks[IMX6SL_CLK_GPU2D_OVG_SEL] = imx_clk_mux("gpu2d_ovg_sel", base + 0x18, 4, 2, gpu2d_ovg_sels, ARRAY_SIZE(gpu2d_ovg_sels)); - clks[IMX6SL_CLK_GPU2D_SEL] = imx_clk_mux("gpu2d_sel", base + 0x18, 8, 2, gpu2d_sels, ARRAY_SIZE(gpu2d_sels)); - clks[IMX6SL_CLK_LCDIF_PIX_SEL] = imx_clk_mux("lcdif_pix_sel", base + 0x38, 6, 3, lcdif_pix_sels, ARRAY_SIZE(lcdif_pix_sels)); - clks[IMX6SL_CLK_EPDC_PIX_SEL] = imx_clk_mux("epdc_pix_sel", base + 0x38, 15, 3, epdc_pix_sels, ARRAY_SIZE(epdc_pix_sels)); - clks[IMX6SL_CLK_SPDIF0_SEL] = imx_clk_mux("spdif0_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels)); - clks[IMX6SL_CLK_SPDIF1_SEL] = imx_clk_mux("spdif1_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); - clks[IMX6SL_CLK_EXTERN_AUDIO_SEL] = imx_clk_mux("extern_audio_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); - clks[IMX6SL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); - clks[IMX6SL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); - - /* name reg shift width busy: reg, shift parent_names num_parents */ - clks[IMX6SL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); - clks[IMX6SL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels)); - - /* name parent_name reg shift width */ - clks[IMX6SL_CLK_OCRAM_PODF] = imx_clk_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3); - clks[IMX6SL_CLK_PERIPH_CLK2_PODF] = imx_clk_divider("periph_clk2_podf", "periph_clk2_sel", base + 0x14, 27, 3); - clks[IMX6SL_CLK_PERIPH2_CLK2_PODF] = imx_clk_divider("periph2_clk2_podf", "periph2_clk2_sel", base + 0x14, 0, 3); - clks[IMX6SL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2); - clks[IMX6SL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3); - clks[IMX6SL_CLK_LCDIF_AXI_PODF] = imx_clk_divider("lcdif_axi_podf", "lcdif_axi_sel", base + 0x3c, 16, 3); - clks[IMX6SL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3); - clks[IMX6SL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3); - clks[IMX6SL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3); - clks[IMX6SL_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3); - clks[IMX6SL_CLK_SSI1_PRED] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3); - clks[IMX6SL_CLK_SSI1_PODF] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6); - clks[IMX6SL_CLK_SSI2_PRED] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3); - clks[IMX6SL_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6); - clks[IMX6SL_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3); - clks[IMX6SL_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6); - clks[IMX6SL_CLK_PERCLK] = imx_clk_fixup_divider("perclk", "perclk_sel", base + 0x1c, 0, 6, imx_cscmr1_fixup); - clks[IMX6SL_CLK_PXP_AXI_PODF] = imx_clk_divider("pxp_axi_podf", "pxp_axi_sel", base + 0x34, 3, 3); - clks[IMX6SL_CLK_EPDC_AXI_PODF] = imx_clk_divider("epdc_axi_podf", "epdc_axi_sel", base + 0x34, 12, 3); - clks[IMX6SL_CLK_GPU2D_OVG_PODF] = imx_clk_divider("gpu2d_ovg_podf", "gpu2d_ovg_sel", base + 0x18, 26, 3); - clks[IMX6SL_CLK_GPU2D_PODF] = imx_clk_divider("gpu2d_podf", "gpu2d_sel", base + 0x18, 29, 3); - clks[IMX6SL_CLK_LCDIF_PIX_PRED] = imx_clk_divider("lcdif_pix_pred", "lcdif_pix_sel", base + 0x38, 3, 3); - clks[IMX6SL_CLK_EPDC_PIX_PRED] = imx_clk_divider("epdc_pix_pred", "epdc_pix_sel", base + 0x38, 12, 3); - clks[IMX6SL_CLK_LCDIF_PIX_PODF] = imx_clk_fixup_divider("lcdif_pix_podf", "lcdif_pix_pred", base + 0x1c, 20, 3, imx_cscmr1_fixup); - clks[IMX6SL_CLK_EPDC_PIX_PODF] = imx_clk_divider("epdc_pix_podf", "epdc_pix_pred", base + 0x18, 23, 3); - clks[IMX6SL_CLK_SPDIF0_PRED] = imx_clk_divider("spdif0_pred", "spdif0_sel", base + 0x30, 25, 3); - clks[IMX6SL_CLK_SPDIF0_PODF] = imx_clk_divider("spdif0_podf", "spdif0_pred", base + 0x30, 22, 3); - clks[IMX6SL_CLK_SPDIF1_PRED] = imx_clk_divider("spdif1_pred", "spdif1_sel", base + 0x30, 12, 3); - clks[IMX6SL_CLK_SPDIF1_PODF] = imx_clk_divider("spdif1_podf", "spdif1_pred", base + 0x30, 9, 3); - clks[IMX6SL_CLK_EXTERN_AUDIO_PRED] = imx_clk_divider("extern_audio_pred", "extern_audio_sel", base + 0x28, 9, 3); - clks[IMX6SL_CLK_EXTERN_AUDIO_PODF] = imx_clk_divider("extern_audio_podf", "extern_audio_pred", base + 0x28, 25, 3); - clks[IMX6SL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "ecspi_sel", base + 0x38, 19, 6); - clks[IMX6SL_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_sel", base + 0x24, 0, 6); - - /* name parent_name reg shift width busy: reg, shift */ - clks[IMX6SL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); - clks[IMX6SL_CLK_MMDC_ROOT] = imx_clk_busy_divider("mmdc", "periph2", base + 0x14, 3, 3, base + 0x48, 2); - clks[IMX6SL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); - - /* name parent_name reg shift */ - clks[IMX6SL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0); - clks[IMX6SL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2); - clks[IMX6SL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4); - clks[IMX6SL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6); - clks[IMX6SL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10); - clks[IMX6SL_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12); - clks[IMX6SL_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14); - clks[IMX6SL_CLK_EXTERN_AUDIO] = imx_clk_gate2("extern_audio", "extern_audio_podf", base + 0x6c, 16); - clks[IMX6SL_CLK_GPT] = imx_clk_gate2("gpt", "perclk", base + 0x6c, 20); - clks[IMX6SL_CLK_GPT_SERIAL] = imx_clk_gate2("gpt_serial", "perclk", base + 0x6c, 22); - clks[IMX6SL_CLK_GPU2D_OVG] = imx_clk_gate2("gpu2d_ovg", "gpu2d_ovg_podf", base + 0x6c, 26); - clks[IMX6SL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6); - clks[IMX6SL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8); - clks[IMX6SL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); - clks[IMX6SL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); - clks[IMX6SL_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x74, 0); - clks[IMX6SL_CLK_PXP_AXI] = imx_clk_gate2("pxp_axi", "pxp_axi_podf", base + 0x74, 2); - clks[IMX6SL_CLK_EPDC_AXI] = imx_clk_gate2("epdc_axi", "epdc_axi_podf", base + 0x74, 4); - clks[IMX6SL_CLK_LCDIF_AXI] = imx_clk_gate2("lcdif_axi", "lcdif_axi_podf", base + 0x74, 6); - clks[IMX6SL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_pix_podf", base + 0x74, 8); - clks[IMX6SL_CLK_EPDC_PIX] = imx_clk_gate2("epdc_pix", "epdc_pix_podf", base + 0x74, 10); - clks[IMX6SL_CLK_OCRAM] = imx_clk_gate2("ocram", "ocram_podf", base + 0x74, 28); - clks[IMX6SL_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16); - clks[IMX6SL_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18); - clks[IMX6SL_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20); - clks[IMX6SL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22); - clks[IMX6SL_CLK_SDMA] = imx_clk_gate2("sdma", "ipg", base + 0x7c, 6); - clks[IMX6SL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); - clks[IMX6SL_CLK_SPDIF] = imx_clk_gate2("spdif", "spdif0_podf", base + 0x7c, 14); - clks[IMX6SL_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); - clks[IMX6SL_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); - clks[IMX6SL_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); - clks[IMX6SL_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1); - clks[IMX6SL_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2); - clks[IMX6SL_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3); - clks[IMX6SL_CLK_UART] = imx_clk_gate2("uart", "ipg", base + 0x7c, 24); - clks[IMX6SL_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_root", base + 0x7c, 26); - clks[IMX6SL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0); - clks[IMX6SL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2); - clks[IMX6SL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4); - clks[IMX6SL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6); - clks[IMX6SL_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8); - - imx_check_clocks(clks, ARRAY_SIZE(clks)); - - clk_data.clks = clks; - clk_data.clk_num = ARRAY_SIZE(clks); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); - - /* Ensure the AHB clk is at 132MHz. */ - ret = clk_set_rate(clks[IMX6SL_CLK_AHB], 132000000); - if (ret) - pr_warn("%s: failed to set AHB clock rate %d!\n", - __func__, ret); - - /* - * Make sure those always on clocks are enabled to maintain the correct - * usecount and enabling/disabling of parent PLLs. - */ - for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) - clk_prepare_enable(clks[clks_init_on[i]]); - - if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { - clk_prepare_enable(clks[IMX6SL_CLK_USBPHY1_GATE]); - clk_prepare_enable(clks[IMX6SL_CLK_USBPHY2_GATE]); - } - - /* Audio-related clocks configuration */ - clk_set_parent(clks[IMX6SL_CLK_SPDIF0_SEL], clks[IMX6SL_CLK_PLL3_PFD3]); - - /* set PLL5 video as lcdif pix parent clock */ - clk_set_parent(clks[IMX6SL_CLK_LCDIF_PIX_SEL], - clks[IMX6SL_CLK_PLL5_VIDEO_DIV]); - - clk_set_parent(clks[IMX6SL_CLK_LCDIF_AXI_SEL], - clks[IMX6SL_CLK_PLL2_PFD2]); - - /* Set initial power mode */ - imx6q_set_lpm(WAIT_CLOCKED); -} -CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init); diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/arch/arm/mach-imx/clk-imx6sx.c deleted file mode 100644 index 87c5b0911ddd..000000000000 --- a/arch/arm/mach-imx/clk-imx6sx.c +++ /dev/null @@ -1,567 +0,0 @@ -/* - * Copyright (C) 2014 Freescale Semiconductor, Inc. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include <dt-bindings/clock/imx6sx-clock.h> -#include <linux/clk.h> -#include <linux/clkdev.h> -#include <linux/err.h> -#include <linux/init.h> -#include <linux/io.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> -#include <linux/types.h> - -#include "clk.h" -#include "common.h" - -#define CCDR 0x4 -#define BM_CCM_CCDR_MMDC_CH0_MASK (0x2 << 16) - -static const char *step_sels[] = { "osc", "pll2_pfd2_396m", }; -static const char *pll1_sw_sels[] = { "pll1_sys", "step", }; -static const char *periph_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll2_198m", }; -static const char *periph2_pre_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll2_pfd0_352m", "pll4_audio_div", }; -static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", }; -static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "osc", }; -static const char *periph_sels[] = { "periph_pre", "periph_clk2", }; -static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", }; -static const char *ocram_sels[] = { "periph", "pll2_pfd2_396m", "periph", "pll3_pfd1_540m", }; -static const char *audio_sels[] = { "pll4_audio_div", "pll3_pfd2_508m", "pll5_video_div", "pll3_usb_otg", }; -static const char *gpu_axi_sels[] = { "pll2_pfd2_396m", "pll3_pfd0_720m", "pll3_pfd1_540m", "pll2_bus", }; -static const char *gpu_core_sels[] = { "pll3_pfd1_540m", "pll3_pfd0_720m", "pll2_bus", "pll2_pfd2_396m", }; -static const char *ldb_di0_div_sels[] = { "ldb_di0_div_3_5", "ldb_di0_div_7", }; -static const char *ldb_di1_div_sels[] = { "ldb_di1_div_3_5", "ldb_di1_div_7", }; -static const char *ldb_di0_sels[] = { "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_pfd3_594m", "pll2_pfd1_594m", "pll3_pfd3_454m", }; -static const char *ldb_di1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", }; -static const char *pcie_axi_sels[] = { "axi", "ahb", }; -static const char *ssi_sels[] = { "pll3_pfd2_508m", "pll5_video_div", "pll4_audio_div", }; -static const char *qspi1_sels[] = { "pll3_usb_otg", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll2_bus", "pll3_pfd3_454m", "pll3_pfd2_508m", }; -static const char *perclk_sels[] = { "ipg", "osc", }; -static const char *usdhc_sels[] = { "pll2_pfd2_396m", "pll2_pfd0_352m", }; -static const char *vid_sels[] = { "pll3_pfd1_540m", "pll3_usb_otg", "pll3_pfd3_454m", "pll4_audio_div", "pll5_video_div", }; -static const char *can_sels[] = { "pll3_60m", "osc", "pll3_80m", "dummy", }; -static const char *uart_sels[] = { "pll3_80m", "osc", }; -static const char *qspi2_sels[] = { "pll2_pfd0_352m", "pll2_bus", "pll3_usb_otg", "pll2_pfd2_396m", "pll3_pfd3_454m", "dummy", "dummy", "dummy", }; -static const char *enet_pre_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd2_508m", }; -static const char *enet_sels[] = { "enet_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", }; -static const char *m4_pre_sels[] = { "pll2_bus", "pll3_usb_otg", "osc", "pll2_pfd0_352m", "pll2_pfd2_396m", "pll3_pfd3_454m", }; -static const char *m4_sels[] = { "m4_pre_sel", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", }; -static const char *eim_slow_sels[] = { "ocram", "pll3_usb_otg", "pll2_pfd2_396m", "pll2_pfd0_352m", }; -static const char *ecspi_sels[] = { "pll3_60m", "osc", }; -static const char *lcdif1_pre_sels[] = { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd1_594m", "pll3_pfd1_540m", }; -static const char *lcdif1_sels[] = { "lcdif1_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", }; -static const char *lcdif2_pre_sels[] = { "pll2_bus", "pll3_pfd3_454m", "pll5_video_div", "pll2_pfd0_352m", "pll2_pfd3_594m", "pll3_pfd1_540m", }; -static const char *lcdif2_sels[] = { "lcdif2_podf", "ipp_di0", "ipp_di1", "ldb_di0", "ldb_di1", }; -static const char *display_sels[] = { "pll2_bus", "pll2_pfd2_396m", "pll3_usb_otg", "pll3_pfd1_540m", }; -static const char *csi_sels[] = { "osc", "pll2_pfd2_396m", "pll3_120m", "pll3_pfd1_540m", }; -static const char *cko1_sels[] = { - "pll3_usb_otg", "pll2_bus", "pll1_sys", "pll5_video_div", - "dummy", "ocram", "dummy", "pxp_axi", "epdc_axi", "lcdif_pix", - "epdc_pix", "ahb", "ipg", "perclk", "ckil", "pll4_audio_div", -}; -static const char *cko2_sels[] = { - "dummy", "mmdc_p0_fast", "usdhc4", "usdhc1", "dummy", "wrck", - "ecspi_root", "dummy", "usdhc3", "pcie", "arm", "csi_core", - "lcdif_axi", "dummy", "osc", "dummy", "gpu2d_ovg_core", - "usdhc2", "ssi1", "ssi2", "ssi3", "gpu2d_core", "dummy", - "dummy", "dummy", "dummy", "esai_extal", "eim_slow", "uart_serial", - "spdif", "asrc", "dummy", -}; -static const char *cko_sels[] = { "cko1", "cko2", }; -static const char *lvds_sels[] = { - "arm", "pll1_sys", "dummy", "dummy", "dummy", "dummy", "dummy", "pll5_video_div", - "dummy", "dummy", "pcie_ref_125m", "dummy", "usbphy1", "usbphy2", -}; -static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", }; -static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", }; -static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", }; -static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", }; -static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", }; -static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", }; -static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; -static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; - -static struct clk *clks[IMX6SX_CLK_CLK_END]; -static struct clk_onecell_data clk_data; - -static int const clks_init_on[] __initconst = { - IMX6SX_CLK_AIPS_TZ1, IMX6SX_CLK_AIPS_TZ2, IMX6SX_CLK_AIPS_TZ3, - IMX6SX_CLK_IPMUX1, IMX6SX_CLK_IPMUX2, IMX6SX_CLK_IPMUX3, - IMX6SX_CLK_WAKEUP, IMX6SX_CLK_MMDC_P0_FAST, IMX6SX_CLK_MMDC_P0_IPG, - IMX6SX_CLK_ROM, IMX6SX_CLK_ARM, IMX6SX_CLK_IPG, IMX6SX_CLK_OCRAM, - IMX6SX_CLK_PER2_MAIN, IMX6SX_CLK_PERCLK, IMX6SX_CLK_M4, - IMX6SX_CLK_QSPI1, IMX6SX_CLK_QSPI2, IMX6SX_CLK_UART_IPG, - IMX6SX_CLK_UART_SERIAL, IMX6SX_CLK_I2C3, IMX6SX_CLK_ECSPI5, - IMX6SX_CLK_CAN1_IPG, IMX6SX_CLK_CAN1_SERIAL, IMX6SX_CLK_CAN2_IPG, - IMX6SX_CLK_CAN2_SERIAL, IMX6SX_CLK_CANFD, IMX6SX_CLK_EPIT1, - IMX6SX_CLK_EPIT2, -}; - -static struct clk_div_table clk_enet_ref_table[] = { - { .val = 0, .div = 20, }, - { .val = 1, .div = 10, }, - { .val = 2, .div = 5, }, - { .val = 3, .div = 4, }, - { } -}; - -static struct clk_div_table post_div_table[] = { - { .val = 2, .div = 1, }, - { .val = 1, .div = 2, }, - { .val = 0, .div = 4, }, - { } -}; - -static struct clk_div_table video_div_table[] = { - { .val = 0, .div = 1, }, - { .val = 1, .div = 2, }, - { .val = 2, .div = 1, }, - { .val = 3, .div = 4, }, - { } -}; - -static u32 share_count_asrc; -static u32 share_count_audio; -static u32 share_count_esai; -static u32 share_count_ssi1; -static u32 share_count_ssi2; -static u32 share_count_ssi3; - -static void __init imx6sx_clocks_init(struct device_node *ccm_node) -{ - struct device_node *np; - void __iomem *base; - int i; - - clks[IMX6SX_CLK_DUMMY] = imx_clk_fixed("dummy", 0); - - clks[IMX6SX_CLK_CKIL] = of_clk_get_by_name(ccm_node, "ckil"); - clks[IMX6SX_CLK_OSC] = of_clk_get_by_name(ccm_node, "osc"); - - /* ipp_di clock is external input */ - clks[IMX6SX_CLK_IPP_DI0] = of_clk_get_by_name(ccm_node, "ipp_di0"); - clks[IMX6SX_CLK_IPP_DI1] = of_clk_get_by_name(ccm_node, "ipp_di1"); - - /* Clock source from external clock via CLK1 PAD */ - clks[IMX6SX_CLK_ANACLK1] = imx_obtain_fixed_clock("anaclk1", 0); - - np = of_find_compatible_node(NULL, NULL, "fsl,imx6sx-anatop"); - base = of_iomap(np, 0); - WARN_ON(!base); - - clks[IMX6SX_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clks[IMX6SX_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clks[IMX6SX_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clks[IMX6SX_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clks[IMX6SX_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clks[IMX6SX_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clks[IMX6SX_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - - /* type name parent_name base div_mask */ - clks[IMX6SX_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "pll1_bypass_src", base + 0x00, 0x7f); - clks[IMX6SX_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", base + 0x30, 0x1); - clks[IMX6SX_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "pll3_bypass_src", base + 0x10, 0x3); - clks[IMX6SX_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", base + 0x70, 0x7f); - clks[IMX6SX_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "pll5_bypass_src", base + 0xa0, 0x7f); - clks[IMX6SX_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "pll6_bypass_src", base + 0xe0, 0x3); - clks[IMX6SX_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "pll7_bypass_src", base + 0x20, 0x3); - - clks[IMX6SX_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX6SX_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX6SX_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX6SX_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX6SX_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX6SX_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); - clks[IMX6SX_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); - - /* Do not bypass PLLs initially */ - clk_set_parent(clks[IMX6SX_PLL1_BYPASS], clks[IMX6SX_CLK_PLL1]); - clk_set_parent(clks[IMX6SX_PLL2_BYPASS], clks[IMX6SX_CLK_PLL2]); - clk_set_parent(clks[IMX6SX_PLL3_BYPASS], clks[IMX6SX_CLK_PLL3]); - clk_set_parent(clks[IMX6SX_PLL4_BYPASS], clks[IMX6SX_CLK_PLL4]); - clk_set_parent(clks[IMX6SX_PLL5_BYPASS], clks[IMX6SX_CLK_PLL5]); - clk_set_parent(clks[IMX6SX_PLL6_BYPASS], clks[IMX6SX_CLK_PLL6]); - clk_set_parent(clks[IMX6SX_PLL7_BYPASS], clks[IMX6SX_CLK_PLL7]); - - clks[IMX6SX_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13); - clks[IMX6SX_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13); - clks[IMX6SX_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13); - clks[IMX6SX_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13); - clks[IMX6SX_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13); - clks[IMX6SX_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13); - clks[IMX6SX_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13); - - /* - * Bit 20 is the reserved and read-only bit, we do this only for: - * - Do nothing for usbphy clk_enable/disable - * - Keep refcount when do usbphy clk_enable/disable, in that case, - * the clk framework may need to enable/disable usbphy's parent - */ - clks[IMX6SX_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20); - clks[IMX6SX_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20); - - /* - * usbphy*_gate needs to be on after system boots up, and software - * never needs to control it anymore. - */ - clks[IMX6SX_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6); - clks[IMX6SX_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6); - - /* FIXME 100MHz is used for pcie ref for all imx6 pcie, excepted imx6q */ - clks[IMX6SX_CLK_PCIE_REF] = imx_clk_fixed_factor("pcie_ref", "pll6_enet", 1, 5); - clks[IMX6SX_CLK_PCIE_REF_125M] = imx_clk_gate("pcie_ref_125m", "pcie_ref", base + 0xe0, 19); - - clks[IMX6SX_CLK_LVDS1_OUT] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12)); - clks[IMX6SX_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10)); - - clks[IMX6SX_CLK_ENET_REF] = clk_register_divider_table(NULL, "enet_ref", "pll6_enet", 0, - base + 0xe0, 0, 2, 0, clk_enet_ref_table, - &imx_ccm_lock); - clks[IMX6SX_CLK_ENET2_REF] = clk_register_divider_table(NULL, "enet2_ref", "pll6_enet", 0, - base + 0xe0, 2, 2, 0, clk_enet_ref_table, - &imx_ccm_lock); - clks[IMX6SX_CLK_ENET2_REF_125M] = imx_clk_gate("enet2_ref_125m", "enet2_ref", base + 0xe0, 20); - - clks[IMX6SX_CLK_ENET_PTP_REF] = imx_clk_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20); - clks[IMX6SX_CLK_ENET_PTP] = imx_clk_gate("enet_ptp_25m", "enet_ptp_ref", base + 0xe0, 21); - - /* name parent_name reg idx */ - clks[IMX6SX_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0_352m", "pll2_bus", base + 0x100, 0); - clks[IMX6SX_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1_594m", "pll2_bus", base + 0x100, 1); - clks[IMX6SX_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2_396m", "pll2_bus", base + 0x100, 2); - clks[IMX6SX_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3_594m", "pll2_bus", base + 0x100, 3); - clks[IMX6SX_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0_720m", "pll3_usb_otg", base + 0xf0, 0); - clks[IMX6SX_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1_540m", "pll3_usb_otg", base + 0xf0, 1); - clks[IMX6SX_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2); - clks[IMX6SX_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3); - - /* name parent_name mult div */ - clks[IMX6SX_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2_396m", 1, 2); - clks[IMX6SX_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4); - clks[IMX6SX_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6); - clks[IMX6SX_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8); - clks[IMX6SX_CLK_TWD] = imx_clk_fixed_factor("twd", "arm", 1, 2); - clks[IMX6SX_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8); - - clks[IMX6SX_CLK_PLL4_POST_DIV] = clk_register_divider_table(NULL, "pll4_post_div", "pll4_audio", - CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock); - clks[IMX6SX_CLK_PLL4_AUDIO_DIV] = clk_register_divider(NULL, "pll4_audio_div", "pll4_post_div", - CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock); - clks[IMX6SX_CLK_PLL5_POST_DIV] = clk_register_divider_table(NULL, "pll5_post_div", "pll5_video", - CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock); - clks[IMX6SX_CLK_PLL5_VIDEO_DIV] = clk_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", - CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock); - - /* name reg shift width parent_names num_parents */ - clks[IMX6SX_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels)); - - np = ccm_node; - base = of_iomap(np, 0); - WARN_ON(!base); - - imx6q_pm_set_ccm_base(base); - - /* name reg shift width parent_names num_parents */ - clks[IMX6SX_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels)); - clks[IMX6SX_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels)); - clks[IMX6SX_CLK_OCRAM_SEL] = imx_clk_mux("ocram_sel", base + 0x14, 6, 2, ocram_sels, ARRAY_SIZE(ocram_sels)); - clks[IMX6SX_CLK_PERIPH_PRE] = imx_clk_mux("periph_pre", base + 0x18, 18, 2, periph_pre_sels, ARRAY_SIZE(periph_pre_sels)); - clks[IMX6SX_CLK_PERIPH2_PRE] = imx_clk_mux("periph2_pre", base + 0x18, 21, 2, periph2_pre_sels, ARRAY_SIZE(periph2_pre_sels)); - clks[IMX6SX_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels)); - clks[IMX6SX_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels)); - clks[IMX6SX_CLK_PCIE_AXI_SEL] = imx_clk_mux("pcie_axi_sel", base + 0x18, 10, 1, pcie_axi_sels, ARRAY_SIZE(pcie_axi_sels)); - clks[IMX6SX_CLK_GPU_AXI_SEL] = imx_clk_mux("gpu_axi_sel", base + 0x18, 8, 2, gpu_axi_sels, ARRAY_SIZE(gpu_axi_sels)); - clks[IMX6SX_CLK_GPU_CORE_SEL] = imx_clk_mux("gpu_core_sel", base + 0x18, 4, 2, gpu_core_sels, ARRAY_SIZE(gpu_core_sels)); - clks[IMX6SX_CLK_EIM_SLOW_SEL] = imx_clk_mux("eim_slow_sel", base + 0x1c, 29, 2, eim_slow_sels, ARRAY_SIZE(eim_slow_sels)); - clks[IMX6SX_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); - clks[IMX6SX_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); - clks[IMX6SX_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); - clks[IMX6SX_CLK_USDHC4_SEL] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels)); - clks[IMX6SX_CLK_SSI3_SEL] = imx_clk_mux("ssi3_sel", base + 0x1c, 14, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); - clks[IMX6SX_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", base + 0x1c, 12, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); - clks[IMX6SX_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", base + 0x1c, 10, 2, ssi_sels, ARRAY_SIZE(ssi_sels)); - clks[IMX6SX_CLK_QSPI1_SEL] = imx_clk_mux_flags("qspi1_sel", base + 0x1c, 7, 3, qspi1_sels, ARRAY_SIZE(qspi1_sels), CLK_SET_RATE_PARENT); - clks[IMX6SX_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels)); - clks[IMX6SX_CLK_VID_SEL] = imx_clk_mux("vid_sel", base + 0x20, 21, 3, vid_sels, ARRAY_SIZE(vid_sels)); - clks[IMX6SX_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", base + 0x20, 19, 2, audio_sels, ARRAY_SIZE(audio_sels)); - clks[IMX6SX_CLK_CAN_SEL] = imx_clk_mux("can_sel", base + 0x20, 8, 2, can_sels, ARRAY_SIZE(can_sels)); - clks[IMX6SX_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels)); - clks[IMX6SX_CLK_QSPI2_SEL] = imx_clk_mux_flags("qspi2_sel", base + 0x2c, 15, 3, qspi2_sels, ARRAY_SIZE(qspi2_sels), CLK_SET_RATE_PARENT); - clks[IMX6SX_CLK_SPDIF_SEL] = imx_clk_mux("spdif_sel", base + 0x30, 20, 2, audio_sels, ARRAY_SIZE(audio_sels)); - clks[IMX6SX_CLK_AUDIO_SEL] = imx_clk_mux("audio_sel", base + 0x30, 7, 2, audio_sels, ARRAY_SIZE(audio_sels)); - clks[IMX6SX_CLK_ENET_PRE_SEL] = imx_clk_mux("enet_pre_sel", base + 0x34, 15, 3, enet_pre_sels, ARRAY_SIZE(enet_pre_sels)); - clks[IMX6SX_CLK_ENET_SEL] = imx_clk_mux("enet_sel", base + 0x34, 9, 3, enet_sels, ARRAY_SIZE(enet_sels)); - clks[IMX6SX_CLK_M4_PRE_SEL] = imx_clk_mux("m4_pre_sel", base + 0x34, 6, 3, m4_pre_sels, ARRAY_SIZE(m4_pre_sels)); - clks[IMX6SX_CLK_M4_SEL] = imx_clk_mux("m4_sel", base + 0x34, 0, 3, m4_sels, ARRAY_SIZE(m4_sels)); - clks[IMX6SX_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels)); - clks[IMX6SX_CLK_LCDIF2_PRE_SEL] = imx_clk_mux("lcdif2_pre_sel", base + 0x38, 6, 3, lcdif2_pre_sels, ARRAY_SIZE(lcdif2_pre_sels)); - clks[IMX6SX_CLK_LCDIF2_SEL] = imx_clk_mux("lcdif2_sel", base + 0x38, 0, 3, lcdif2_sels, ARRAY_SIZE(lcdif2_sels)); - clks[IMX6SX_CLK_DISPLAY_SEL] = imx_clk_mux("display_sel", base + 0x3c, 14, 2, display_sels, ARRAY_SIZE(display_sels)); - clks[IMX6SX_CLK_CSI_SEL] = imx_clk_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels)); - clks[IMX6SX_CLK_CKO1_SEL] = imx_clk_mux("cko1_sel", base + 0x60, 0, 4, cko1_sels, ARRAY_SIZE(cko1_sels)); - clks[IMX6SX_CLK_CKO2_SEL] = imx_clk_mux("cko2_sel", base + 0x60, 16, 5, cko2_sels, ARRAY_SIZE(cko2_sels)); - clks[IMX6SX_CLK_CKO] = imx_clk_mux("cko", base + 0x60, 8, 1, cko_sels, ARRAY_SIZE(cko_sels)); - - clks[IMX6SX_CLK_LDB_DI1_DIV_SEL] = imx_clk_mux_flags("ldb_di1_div_sel", base + 0x20, 11, 1, ldb_di1_div_sels, ARRAY_SIZE(ldb_di1_div_sels), CLK_SET_RATE_PARENT); - clks[IMX6SX_CLK_LDB_DI0_DIV_SEL] = imx_clk_mux_flags("ldb_di0_div_sel", base + 0x20, 10, 1, ldb_di0_div_sels, ARRAY_SIZE(ldb_di0_div_sels), CLK_SET_RATE_PARENT); - clks[IMX6SX_CLK_LDB_DI1_SEL] = imx_clk_mux_flags("ldb_di1_sel", base + 0x2c, 12, 3, ldb_di1_sels, ARRAY_SIZE(ldb_di1_sels), CLK_SET_RATE_PARENT); - clks[IMX6SX_CLK_LDB_DI0_SEL] = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9, 3, ldb_di0_sels, ARRAY_SIZE(ldb_di0_sels), CLK_SET_RATE_PARENT); - clks[IMX6SX_CLK_LCDIF1_PRE_SEL] = imx_clk_mux_flags("lcdif1_pre_sel", base + 0x38, 15, 3, lcdif1_pre_sels, ARRAY_SIZE(lcdif1_pre_sels), CLK_SET_RATE_PARENT); - clks[IMX6SX_CLK_LCDIF1_SEL] = imx_clk_mux_flags("lcdif1_sel", base + 0x38, 9, 3, lcdif1_sels, ARRAY_SIZE(lcdif1_sels), CLK_SET_RATE_PARENT); - - /* name parent_name reg shift width */ - clks[IMX6SX_CLK_PERIPH_CLK2] = imx_clk_divider("periph_clk2", "periph_clk2_sel", base + 0x14, 27, 3); - clks[IMX6SX_CLK_PERIPH2_CLK2] = imx_clk_divider("periph2_clk2", "periph2_clk2_sel", base + 0x14, 0, 3); - clks[IMX6SX_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2); - clks[IMX6SX_CLK_GPU_CORE_PODF] = imx_clk_divider("gpu_core_podf", "gpu_core_sel", base + 0x18, 29, 3); - clks[IMX6SX_CLK_GPU_AXI_PODF] = imx_clk_divider("gpu_axi_podf", "gpu_axi_sel", base + 0x18, 26, 3); - clks[IMX6SX_CLK_LCDIF1_PODF] = imx_clk_divider("lcdif1_podf", "lcdif1_pred", base + 0x18, 23, 3); - clks[IMX6SX_CLK_QSPI1_PODF] = imx_clk_divider("qspi1_podf", "qspi1_sel", base + 0x1c, 26, 3); - clks[IMX6SX_CLK_EIM_SLOW_PODF] = imx_clk_divider("eim_slow_podf", "eim_slow_sel", base + 0x1c, 23, 3); - clks[IMX6SX_CLK_LCDIF2_PODF] = imx_clk_divider("lcdif2_podf", "lcdif2_pred", base + 0x1c, 20, 3); - clks[IMX6SX_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6); - clks[IMX6SX_CLK_VID_PODF] = imx_clk_divider("vid_podf", "vid_sel", base + 0x20, 24, 2); - clks[IMX6SX_CLK_CAN_PODF] = imx_clk_divider("can_podf", "can_sel", base + 0x20, 2, 6); - clks[IMX6SX_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3); - clks[IMX6SX_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3); - clks[IMX6SX_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3); - clks[IMX6SX_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3); - clks[IMX6SX_CLK_UART_PODF] = imx_clk_divider("uart_podf", "uart_sel", base + 0x24, 0, 6); - clks[IMX6SX_CLK_ESAI_PRED] = imx_clk_divider("esai_pred", "esai_sel", base + 0x28, 9, 3); - clks[IMX6SX_CLK_ESAI_PODF] = imx_clk_divider("esai_podf", "esai_pred", base + 0x28, 25, 3); - clks[IMX6SX_CLK_SSI3_PRED] = imx_clk_divider("ssi3_pred", "ssi3_sel", base + 0x28, 22, 3); - clks[IMX6SX_CLK_SSI3_PODF] = imx_clk_divider("ssi3_podf", "ssi3_pred", base + 0x28, 16, 6); - clks[IMX6SX_CLK_SSI1_PRED] = imx_clk_divider("ssi1_pred", "ssi1_sel", base + 0x28, 6, 3); - clks[IMX6SX_CLK_SSI1_PODF] = imx_clk_divider("ssi1_podf", "ssi1_pred", base + 0x28, 0, 6); - clks[IMX6SX_CLK_QSPI2_PRED] = imx_clk_divider("qspi2_pred", "qspi2_sel", base + 0x2c, 18, 3); - clks[IMX6SX_CLK_QSPI2_PODF] = imx_clk_divider("qspi2_podf", "qspi2_pred", base + 0x2c, 21, 6); - clks[IMX6SX_CLK_SSI2_PRED] = imx_clk_divider("ssi2_pred", "ssi2_sel", base + 0x2c, 6, 3); - clks[IMX6SX_CLK_SSI2_PODF] = imx_clk_divider("ssi2_podf", "ssi2_pred", base + 0x2c, 0, 6); - clks[IMX6SX_CLK_SPDIF_PRED] = imx_clk_divider("spdif_pred", "spdif_sel", base + 0x30, 25, 3); - clks[IMX6SX_CLK_SPDIF_PODF] = imx_clk_divider("spdif_podf", "spdif_pred", base + 0x30, 22, 3); - clks[IMX6SX_CLK_AUDIO_PRED] = imx_clk_divider("audio_pred", "audio_sel", base + 0x30, 12, 3); - clks[IMX6SX_CLK_AUDIO_PODF] = imx_clk_divider("audio_podf", "audio_pred", base + 0x30, 9, 3); - clks[IMX6SX_CLK_ENET_PODF] = imx_clk_divider("enet_podf", "enet_pre_sel", base + 0x34, 12, 3); - clks[IMX6SX_CLK_M4_PODF] = imx_clk_divider("m4_podf", "m4_sel", base + 0x34, 3, 3); - clks[IMX6SX_CLK_ECSPI_PODF] = imx_clk_divider("ecspi_podf", "ecspi_sel", base + 0x38, 19, 6); - clks[IMX6SX_CLK_LCDIF1_PRED] = imx_clk_divider("lcdif1_pred", "lcdif1_pre_sel", base + 0x38, 12, 3); - clks[IMX6SX_CLK_LCDIF2_PRED] = imx_clk_divider("lcdif2_pred", "lcdif2_pre_sel", base + 0x38, 3, 3); - clks[IMX6SX_CLK_DISPLAY_PODF] = imx_clk_divider("display_podf", "display_sel", base + 0x3c, 16, 3); - clks[IMX6SX_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3); - clks[IMX6SX_CLK_CKO1_PODF] = imx_clk_divider("cko1_podf", "cko1_sel", base + 0x60, 4, 3); - clks[IMX6SX_CLK_CKO2_PODF] = imx_clk_divider("cko2_podf", "cko2_sel", base + 0x60, 21, 3); - - clks[IMX6SX_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7); - clks[IMX6SX_CLK_LDB_DI0_DIV_7] = imx_clk_fixed_factor("ldb_di0_div_7", "ldb_di0_sel", 1, 7); - clks[IMX6SX_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7); - clks[IMX6SX_CLK_LDB_DI1_DIV_7] = imx_clk_fixed_factor("ldb_di1_div_7", "ldb_di1_sel", 1, 7); - - /* name reg shift width busy: reg, shift parent_names num_parents */ - clks[IMX6SX_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels)); - clks[IMX6SX_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels)); - /* name parent_name reg shift width busy: reg, shift */ - clks[IMX6SX_CLK_OCRAM_PODF] = imx_clk_busy_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3, base + 0x48, 0); - clks[IMX6SX_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1); - clks[IMX6SX_CLK_MMDC_PODF] = imx_clk_busy_divider("mmdc_podf", "periph2", base + 0x14, 3, 3, base + 0x48, 2); - clks[IMX6SX_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16); - - /* name parent_name reg shift */ - /* CCGR0 */ - clks[IMX6SX_CLK_AIPS_TZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0); - clks[IMX6SX_CLK_AIPS_TZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2); - clks[IMX6SX_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4); - clks[IMX6SX_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); - clks[IMX6SX_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); - clks[IMX6SX_CLK_CAAM_MEM] = imx_clk_gate2("caam_mem", "ahb", base + 0x68, 8); - clks[IMX6SX_CLK_CAAM_ACLK] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10); - clks[IMX6SX_CLK_CAAM_IPG] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12); - clks[IMX6SX_CLK_CAN1_IPG] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14); - clks[IMX6SX_CLK_CAN1_SERIAL] = imx_clk_gate2("can1_serial", "can_podf", base + 0x68, 16); - clks[IMX6SX_CLK_CAN2_IPG] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18); - clks[IMX6SX_CLK_CAN2_SERIAL] = imx_clk_gate2("can2_serial", "can_podf", base + 0x68, 20); - clks[IMX6SX_CLK_DCIC1] = imx_clk_gate2("dcic1", "display_podf", base + 0x68, 24); - clks[IMX6SX_CLK_DCIC2] = imx_clk_gate2("dcic2", "display_podf", base + 0x68, 26); - clks[IMX6SX_CLK_AIPS_TZ3] = imx_clk_gate2("aips_tz3", "ahb", base + 0x68, 30); - - /* CCGR1 */ - clks[IMX6SX_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_podf", base + 0x6c, 0); - clks[IMX6SX_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_podf", base + 0x6c, 2); - clks[IMX6SX_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_podf", base + 0x6c, 4); - clks[IMX6SX_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_podf", base + 0x6c, 6); - clks[IMX6SX_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_podf", base + 0x6c, 8); - clks[IMX6SX_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12); - clks[IMX6SX_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14); - clks[IMX6SX_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai); - clks[IMX6SX_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai); - clks[IMX6SX_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai); - clks[IMX6SX_CLK_WAKEUP] = imx_clk_gate2("wakeup", "ipg", base + 0x6c, 18); - clks[IMX6SX_CLK_GPT_BUS] = imx_clk_gate2("gpt_bus", "perclk", base + 0x6c, 20); - clks[IMX6SX_CLK_GPT_SERIAL] = imx_clk_gate2("gpt_serial", "perclk", base + 0x6c, 22); - clks[IMX6SX_CLK_GPU] = imx_clk_gate2("gpu", "gpu_core_podf", base + 0x6c, 26); - clks[IMX6SX_CLK_CANFD] = imx_clk_gate2("canfd", "can_podf", base + 0x6c, 30); - - /* CCGR2 */ - clks[IMX6SX_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x70, 2); - clks[IMX6SX_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6); - clks[IMX6SX_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8); - clks[IMX6SX_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10); - clks[IMX6SX_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12); - clks[IMX6SX_CLK_IOMUXC] = imx_clk_gate2("iomuxc", "lcdif1_podf", base + 0x70, 14); - clks[IMX6SX_CLK_IPMUX1] = imx_clk_gate2("ipmux1", "ahb", base + 0x70, 16); - clks[IMX6SX_CLK_IPMUX2] = imx_clk_gate2("ipmux2", "ahb", base + 0x70, 18); - clks[IMX6SX_CLK_IPMUX3] = imx_clk_gate2("ipmux3", "ahb", base + 0x70, 20); - clks[IMX6SX_CLK_TZASC1] = imx_clk_gate2("tzasc1", "mmdc_podf", base + 0x70, 22); - clks[IMX6SX_CLK_LCDIF_APB] = imx_clk_gate2("lcdif_apb", "display_podf", base + 0x70, 28); - clks[IMX6SX_CLK_PXP_AXI] = imx_clk_gate2("pxp_axi", "display_podf", base + 0x70, 30); - - /* CCGR3 */ - clks[IMX6SX_CLK_M4] = imx_clk_gate2("m4", "m4_podf", base + 0x74, 2); - clks[IMX6SX_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x74, 4); - clks[IMX6SX_CLK_ENET_AHB] = imx_clk_gate2("enet_ahb", "enet_sel", base + 0x74, 4); - clks[IMX6SX_CLK_DISPLAY_AXI] = imx_clk_gate2("display_axi", "display_podf", base + 0x74, 6); - clks[IMX6SX_CLK_LCDIF2_PIX] = imx_clk_gate2("lcdif2_pix", "lcdif2_sel", base + 0x74, 8); - clks[IMX6SX_CLK_LCDIF1_PIX] = imx_clk_gate2("lcdif1_pix", "lcdif1_sel", base + 0x74, 10); - clks[IMX6SX_CLK_LDB_DI0] = imx_clk_gate2("ldb_di0", "ldb_di0_div_sel", base + 0x74, 12); - clks[IMX6SX_CLK_QSPI1] = imx_clk_gate2("qspi1", "qspi1_podf", base + 0x74, 14); - clks[IMX6SX_CLK_MLB] = imx_clk_gate2("mlb", "ahb", base + 0x74, 18); - clks[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_gate2("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20); - clks[IMX6SX_CLK_MMDC_P0_IPG] = imx_clk_gate2("mmdc_p0_ipg", "ipg", base + 0x74, 24); - clks[IMX6SX_CLK_OCRAM] = imx_clk_gate2("ocram", "ocram_podf", base + 0x74, 28); - - /* CCGR4 */ - clks[IMX6SX_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "display_podf", base + 0x78, 0); - clks[IMX6SX_CLK_QSPI2] = imx_clk_gate2("qspi2", "qspi2_podf", base + 0x78, 10); - clks[IMX6SX_CLK_PER1_BCH] = imx_clk_gate2("per1_bch", "usdhc3", base + 0x78, 12); - clks[IMX6SX_CLK_PER2_MAIN] = imx_clk_gate2("per2_main", "ahb", base + 0x78, 14); - clks[IMX6SX_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16); - clks[IMX6SX_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18); - clks[IMX6SX_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20); - clks[IMX6SX_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22); - clks[IMX6SX_CLK_GPMI_BCH_APB] = imx_clk_gate2("gpmi_bch_apb", "usdhc3", base + 0x78, 24); - clks[IMX6SX_CLK_GPMI_BCH] = imx_clk_gate2("gpmi_bch", "usdhc4", base + 0x78, 26); - clks[IMX6SX_CLK_GPMI_IO] = imx_clk_gate2("gpmi_io", "qspi2_podf", base + 0x78, 28); - clks[IMX6SX_CLK_GPMI_APB] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); - - /* CCGR5 */ - clks[IMX6SX_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); - clks[IMX6SX_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); - clks[IMX6SX_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); - clks[IMX6SX_CLK_AUDIO] = imx_clk_gate2_shared("audio", "audio_podf", base + 0x7c, 14, &share_count_audio); - clks[IMX6SX_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio); - clks[IMX6SX_CLK_SSI1_IPG] = imx_clk_gate2_shared("ssi1_ipg", "ipg", base + 0x7c, 18, &share_count_ssi1); - clks[IMX6SX_CLK_SSI2_IPG] = imx_clk_gate2_shared("ssi2_ipg", "ipg", base + 0x7c, 20, &share_count_ssi2); - clks[IMX6SX_CLK_SSI3_IPG] = imx_clk_gate2_shared("ssi3_ipg", "ipg", base + 0x7c, 22, &share_count_ssi3); - clks[IMX6SX_CLK_SSI1] = imx_clk_gate2_shared("ssi1", "ssi1_podf", base + 0x7c, 18, &share_count_ssi1); - clks[IMX6SX_CLK_SSI2] = imx_clk_gate2_shared("ssi2", "ssi2_podf", base + 0x7c, 20, &share_count_ssi2); - clks[IMX6SX_CLK_SSI3] = imx_clk_gate2_shared("ssi3", "ssi3_podf", base + 0x7c, 22, &share_count_ssi3); - clks[IMX6SX_CLK_UART_IPG] = imx_clk_gate2("uart_ipg", "ipg", base + 0x7c, 24); - clks[IMX6SX_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_podf", base + 0x7c, 26); - clks[IMX6SX_CLK_SAI1_IPG] = imx_clk_gate2("sai1_ipg", "ipg", base + 0x7c, 28); - clks[IMX6SX_CLK_SAI2_IPG] = imx_clk_gate2("sai2_ipg", "ipg", base + 0x7c, 30); - clks[IMX6SX_CLK_SAI1] = imx_clk_gate2("sai1", "ssi1_podf", base + 0x7c, 28); - clks[IMX6SX_CLK_SAI2] = imx_clk_gate2("sai2", "ssi2_podf", base + 0x7c, 30); - - /* CCGR6 */ - clks[IMX6SX_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0); - clks[IMX6SX_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2); - clks[IMX6SX_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4); - clks[IMX6SX_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6); - clks[IMX6SX_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8); - clks[IMX6SX_CLK_EIM_SLOW] = imx_clk_gate2("eim_slow", "eim_slow_podf", base + 0x80, 10); - clks[IMX6SX_CLK_PWM8] = imx_clk_gate2("pwm8", "perclk", base + 0x80, 16); - clks[IMX6SX_CLK_VADC] = imx_clk_gate2("vadc", "vid_podf", base + 0x80, 20); - clks[IMX6SX_CLK_GIS] = imx_clk_gate2("gis", "display_podf", base + 0x80, 22); - clks[IMX6SX_CLK_I2C4] = imx_clk_gate2("i2c4", "perclk", base + 0x80, 24); - clks[IMX6SX_CLK_PWM5] = imx_clk_gate2("pwm5", "perclk", base + 0x80, 26); - clks[IMX6SX_CLK_PWM6] = imx_clk_gate2("pwm6", "perclk", base + 0x80, 28); - clks[IMX6SX_CLK_PWM7] = imx_clk_gate2("pwm7", "perclk", base + 0x80, 30); - - clks[IMX6SX_CLK_CKO1] = imx_clk_gate("cko1", "cko1_podf", base + 0x60, 7); - clks[IMX6SX_CLK_CKO2] = imx_clk_gate("cko2", "cko2_podf", base + 0x60, 24); - - /* mask handshake of mmdc */ - writel_relaxed(BM_CCM_CCDR_MMDC_CH0_MASK, base + CCDR); - - imx_check_clocks(clks, ARRAY_SIZE(clks)); - - clk_data.clks = clks; - clk_data.clk_num = ARRAY_SIZE(clks); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); - - for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) - clk_prepare_enable(clks[clks_init_on[i]]); - - if (IS_ENABLED(CONFIG_USB_MXS_PHY)) { - clk_prepare_enable(clks[IMX6SX_CLK_USBPHY1_GATE]); - clk_prepare_enable(clks[IMX6SX_CLK_USBPHY2_GATE]); - } - - /* Set the default 132MHz for EIM module */ - clk_set_parent(clks[IMX6SX_CLK_EIM_SLOW_SEL], clks[IMX6SX_CLK_PLL2_PFD2]); - clk_set_rate(clks[IMX6SX_CLK_EIM_SLOW], 132000000); - - /* set parent clock for LCDIF1 pixel clock */ - clk_set_parent(clks[IMX6SX_CLK_LCDIF1_PRE_SEL], clks[IMX6SX_CLK_PLL5_VIDEO_DIV]); - clk_set_parent(clks[IMX6SX_CLK_LCDIF1_SEL], clks[IMX6SX_CLK_LCDIF1_PODF]); - - /* Set the parent clks of PCIe lvds1 and pcie_axi to be pcie ref, axi */ - if (clk_set_parent(clks[IMX6SX_CLK_LVDS1_SEL], clks[IMX6SX_CLK_PCIE_REF_125M])) - pr_err("Failed to set pcie bus parent clk.\n"); - if (clk_set_parent(clks[IMX6SX_CLK_PCIE_AXI_SEL], clks[IMX6SX_CLK_AXI])) - pr_err("Failed to set pcie parent clk.\n"); - - /* - * Init enet system AHB clock, set to 200MHz - * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB - */ - clk_set_parent(clks[IMX6SX_CLK_ENET_PRE_SEL], clks[IMX6SX_CLK_PLL2_PFD2]); - clk_set_parent(clks[IMX6SX_CLK_ENET_SEL], clks[IMX6SX_CLK_ENET_PODF]); - clk_set_rate(clks[IMX6SX_CLK_ENET_PODF], 200000000); - clk_set_rate(clks[IMX6SX_CLK_ENET_REF], 125000000); - clk_set_rate(clks[IMX6SX_CLK_ENET2_REF], 125000000); - - /* Audio clocks */ - clk_set_rate(clks[IMX6SX_CLK_PLL4_AUDIO_DIV], 393216000); - - clk_set_parent(clks[IMX6SX_CLK_SPDIF_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]); - clk_set_rate(clks[IMX6SX_CLK_SPDIF_PODF], 98304000); - - clk_set_parent(clks[IMX6SX_CLK_AUDIO_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]); - clk_set_rate(clks[IMX6SX_CLK_AUDIO_PODF], 24000000); - - clk_set_parent(clks[IMX6SX_CLK_SSI1_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]); - clk_set_parent(clks[IMX6SX_CLK_SSI2_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]); - clk_set_parent(clks[IMX6SX_CLK_SSI3_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]); - clk_set_rate(clks[IMX6SX_CLK_SSI1_PODF], 24576000); - clk_set_rate(clks[IMX6SX_CLK_SSI2_PODF], 24576000); - clk_set_rate(clks[IMX6SX_CLK_SSI3_PODF], 24576000); - - clk_set_parent(clks[IMX6SX_CLK_ESAI_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]); - clk_set_rate(clks[IMX6SX_CLK_ESAI_PODF], 24576000); - - /* Set parent clock for vadc */ - clk_set_parent(clks[IMX6SX_CLK_VID_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]); - - /* default parent of can_sel clock is invalid, manually set it here */ - clk_set_parent(clks[IMX6SX_CLK_CAN_SEL], clks[IMX6SX_CLK_PLL3_60M]); - - /* Update gpu clock from default 528M to 720M */ - clk_set_parent(clks[IMX6SX_CLK_GPU_CORE_SEL], clks[IMX6SX_CLK_PLL3_PFD0]); - clk_set_parent(clks[IMX6SX_CLK_GPU_AXI_SEL], clks[IMX6SX_CLK_PLL3_PFD0]); - - clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]); - clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]); - - /* Set initial power mode */ - imx6q_set_lpm(WAIT_CLOCKED); -} -CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init); diff --git a/arch/arm/mach-imx/clk-pfd.c b/arch/arm/mach-imx/clk-pfd.c deleted file mode 100644 index 0b0f6f66ec56..000000000000 --- a/arch/arm/mach-imx/clk-pfd.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright 2012 Freescale Semiconductor, Inc. - * Copyright 2012 Linaro Ltd. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include <linux/clk.h> -#include <linux/clk-provider.h> -#include <linux/io.h> -#include <linux/slab.h> -#include <linux/err.h> -#include "clk.h" - -/** - * struct clk_pfd - IMX PFD clock - * @clk_hw: clock source - * @reg: PFD register address - * @idx: the index of PFD encoded in the register - * - * PFD clock found on i.MX6 series. Each register for PFD has 4 clk_pfd - * data encoded, and member idx is used to specify the one. And each - * register has SET, CLR and TOG registers at offset 0x4 0x8 and 0xc. - */ -struct clk_pfd { - struct clk_hw hw; - void __iomem *reg; - u8 idx; -}; - -#define to_clk_pfd(_hw) container_of(_hw, struct clk_pfd, hw) - -#define SET 0x4 -#define CLR 0x8 -#define OTG 0xc - -static int clk_pfd_enable(struct clk_hw *hw) -{ - struct clk_pfd *pfd = to_clk_pfd(hw); - - writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + CLR); - - return 0; -} - -static void clk_pfd_disable(struct clk_hw *hw) -{ - struct clk_pfd *pfd = to_clk_pfd(hw); - - writel_relaxed(1 << ((pfd->idx + 1) * 8 - 1), pfd->reg + SET); -} - -static unsigned long clk_pfd_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct clk_pfd *pfd = to_clk_pfd(hw); - u64 tmp = parent_rate; - u8 frac = (readl_relaxed(pfd->reg) >> (pfd->idx * 8)) & 0x3f; - - tmp *= 18; - do_div(tmp, frac); - - return tmp; -} - -static long clk_pfd_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) -{ - u64 tmp = *prate; - u8 frac; - - tmp = tmp * 18 + rate / 2; - do_div(tmp, rate); - frac = tmp; - if (frac < 12) - frac = 12; - else if (frac > 35) - frac = 35; - tmp = *prate; - tmp *= 18; - do_div(tmp, frac); - - return tmp; -} - -static int clk_pfd_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct clk_pfd *pfd = to_clk_pfd(hw); - u64 tmp = parent_rate; - u8 frac; - - tmp = tmp * 18 + rate / 2; - do_div(tmp, rate); - frac = tmp; - if (frac < 12) - frac = 12; - else if (frac > 35) - frac = 35; - - writel_relaxed(0x3f << (pfd->idx * 8), pfd->reg + CLR); - writel_relaxed(frac << (pfd->idx * 8), pfd->reg + SET); - - return 0; -} - -static int clk_pfd_is_enabled(struct clk_hw *hw) -{ - struct clk_pfd *pfd = to_clk_pfd(hw); - - if (readl_relaxed(pfd->reg) & (1 << ((pfd->idx + 1) * 8 - 1))) - return 0; - - return 1; -} - -static const struct clk_ops clk_pfd_ops = { - .enable = clk_pfd_enable, - .disable = clk_pfd_disable, - .recalc_rate = clk_pfd_recalc_rate, - .round_rate = clk_pfd_round_rate, - .set_rate = clk_pfd_set_rate, - .is_enabled = clk_pfd_is_enabled, -}; - -struct clk *imx_clk_pfd(const char *name, const char *parent_name, - void __iomem *reg, u8 idx) -{ - struct clk_pfd *pfd; - struct clk *clk; - struct clk_init_data init; - - pfd = kzalloc(sizeof(*pfd), GFP_KERNEL); - if (!pfd) - return ERR_PTR(-ENOMEM); - - pfd->reg = reg; - pfd->idx = idx; - - init.name = name; - init.ops = &clk_pfd_ops; - init.flags = 0; - init.parent_names = &parent_name; - init.num_parents = 1; - - pfd->hw.init = &init; - - clk = clk_register(NULL, &pfd->hw); - if (IS_ERR(clk)) - kfree(pfd); - - return clk; -} diff --git a/arch/arm/mach-imx/clk-pllv1.c b/arch/arm/mach-imx/clk-pllv1.c deleted file mode 100644 index d21d14ca46c1..000000000000 --- a/arch/arm/mach-imx/clk-pllv1.c +++ /dev/null @@ -1,126 +0,0 @@ -#include <linux/clk.h> -#include <linux/clk-provider.h> -#include <linux/io.h> -#include <linux/slab.h> -#include <linux/kernel.h> -#include <linux/err.h> - -#include "clk.h" -#include "common.h" -#include "hardware.h" - -/** - * pll v1 - * - * @clk_hw clock source - * @parent the parent clock name - * @base base address of pll registers - * - * PLL clock version 1, found on i.MX1/21/25/27/31/35 - */ - -#define MFN_BITS (10) -#define MFN_SIGN (BIT(MFN_BITS - 1)) -#define MFN_MASK (MFN_SIGN - 1) - -struct clk_pllv1 { - struct clk_hw hw; - void __iomem *base; -}; - -#define to_clk_pllv1(clk) (container_of(clk, struct clk_pllv1, clk)) - -static inline bool mfn_is_negative(unsigned int mfn) -{ - return !cpu_is_mx1() && !cpu_is_mx21() && (mfn & MFN_SIGN); -} - -static unsigned long clk_pllv1_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct clk_pllv1 *pll = to_clk_pllv1(hw); - long long ll; - int mfn_abs; - unsigned int mfi, mfn, mfd, pd; - u32 reg; - unsigned long rate; - - reg = readl(pll->base); - - /* - * Get the resulting clock rate from a PLL register value and the input - * frequency. PLLs with this register layout can be found on i.MX1, - * i.MX21, i.MX27 and i,MX31 - * - * mfi + mfn / (mfd + 1) - * f = 2 * f_ref * -------------------- - * pd + 1 - */ - - mfi = (reg >> 10) & 0xf; - mfn = reg & 0x3ff; - mfd = (reg >> 16) & 0x3ff; - pd = (reg >> 26) & 0xf; - - mfi = mfi <= 5 ? 5 : mfi; - - mfn_abs = mfn; - - /* - * On all i.MXs except i.MX1 and i.MX21 mfn is a 10bit - * 2's complements number. - * On i.MX27 the bit 9 is the sign bit. - */ - if (mfn_is_negative(mfn)) { - if (cpu_is_mx27()) - mfn_abs = mfn & MFN_MASK; - else - mfn_abs = BIT(MFN_BITS) - mfn; - } - - rate = parent_rate * 2; - rate /= pd + 1; - - ll = (unsigned long long)rate * mfn_abs; - - do_div(ll, mfd + 1); - - if (mfn_is_negative(mfn)) - ll = -ll; - - ll = (rate * mfi) + ll; - - return ll; -} - -static struct clk_ops clk_pllv1_ops = { - .recalc_rate = clk_pllv1_recalc_rate, -}; - -struct clk *imx_clk_pllv1(const char *name, const char *parent, - void __iomem *base) -{ - struct clk_pllv1 *pll; - struct clk *clk; - struct clk_init_data init; - - pll = kmalloc(sizeof(*pll), GFP_KERNEL); - if (!pll) - return ERR_PTR(-ENOMEM); - - pll->base = base; - - init.name = name; - init.ops = &clk_pllv1_ops; - init.flags = 0; - init.parent_names = &parent; - init.num_parents = 1; - - pll->hw.init = &init; - - clk = clk_register(NULL, &pll->hw); - if (IS_ERR(clk)) - kfree(pll); - - return clk; -} diff --git a/arch/arm/mach-imx/clk-pllv2.c b/arch/arm/mach-imx/clk-pllv2.c deleted file mode 100644 index 20889d59b44d..000000000000 --- a/arch/arm/mach-imx/clk-pllv2.c +++ /dev/null @@ -1,266 +0,0 @@ -#include <linux/kernel.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/errno.h> -#include <linux/delay.h> -#include <linux/slab.h> -#include <linux/err.h> - -#include <asm/div64.h> - -#include "clk.h" - -#define to_clk_pllv2(clk) (container_of(clk, struct clk_pllv2, clk)) - -/* PLL Register Offsets */ -#define MXC_PLL_DP_CTL 0x00 -#define MXC_PLL_DP_CONFIG 0x04 -#define MXC_PLL_DP_OP 0x08 -#define MXC_PLL_DP_MFD 0x0C -#define MXC_PLL_DP_MFN 0x10 -#define MXC_PLL_DP_MFNMINUS 0x14 -#define MXC_PLL_DP_MFNPLUS 0x18 -#define MXC_PLL_DP_HFS_OP 0x1C -#define MXC_PLL_DP_HFS_MFD 0x20 -#define MXC_PLL_DP_HFS_MFN 0x24 -#define MXC_PLL_DP_MFN_TOGC 0x28 -#define MXC_PLL_DP_DESTAT 0x2c - -/* PLL Register Bit definitions */ -#define MXC_PLL_DP_CTL_MUL_CTRL 0x2000 -#define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000 -#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET 12 -#define MXC_PLL_DP_CTL_ADE 0x800 -#define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400 -#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK (3 << 8) -#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET 8 -#define MXC_PLL_DP_CTL_HFSM 0x80 -#define MXC_PLL_DP_CTL_PRE 0x40 -#define MXC_PLL_DP_CTL_UPEN 0x20 -#define MXC_PLL_DP_CTL_RST 0x10 -#define MXC_PLL_DP_CTL_RCP 0x8 -#define MXC_PLL_DP_CTL_PLM 0x4 -#define MXC_PLL_DP_CTL_BRM0 0x2 -#define MXC_PLL_DP_CTL_LRF 0x1 - -#define MXC_PLL_DP_CONFIG_BIST 0x8 -#define MXC_PLL_DP_CONFIG_SJC_CE 0x4 -#define MXC_PLL_DP_CONFIG_AREN 0x2 -#define MXC_PLL_DP_CONFIG_LDREQ 0x1 - -#define MXC_PLL_DP_OP_MFI_OFFSET 4 -#define MXC_PLL_DP_OP_MFI_MASK (0xF << 4) -#define MXC_PLL_DP_OP_PDF_OFFSET 0 -#define MXC_PLL_DP_OP_PDF_MASK 0xF - -#define MXC_PLL_DP_MFD_OFFSET 0 -#define MXC_PLL_DP_MFD_MASK 0x07FFFFFF - -#define MXC_PLL_DP_MFN_OFFSET 0x0 -#define MXC_PLL_DP_MFN_MASK 0x07FFFFFF - -#define MXC_PLL_DP_MFN_TOGC_TOG_DIS (1 << 17) -#define MXC_PLL_DP_MFN_TOGC_TOG_EN (1 << 16) -#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET 0x0 -#define MXC_PLL_DP_MFN_TOGC_CNT_MASK 0xFFFF - -#define MXC_PLL_DP_DESTAT_TOG_SEL (1 << 31) -#define MXC_PLL_DP_DESTAT_MFN 0x07FFFFFF - -#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */ - -struct clk_pllv2 { - struct clk_hw hw; - void __iomem *base; -}; - -static unsigned long __clk_pllv2_recalc_rate(unsigned long parent_rate, - u32 dp_ctl, u32 dp_op, u32 dp_mfd, u32 dp_mfn) -{ - long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; - unsigned long dbl; - s64 temp; - - dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN; - - pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK; - mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET; - mfi = (mfi <= 5) ? 5 : mfi; - mfd = dp_mfd & MXC_PLL_DP_MFD_MASK; - mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK; - /* Sign extend to 32-bits */ - if (mfn >= 0x04000000) { - mfn |= 0xFC000000; - mfn_abs = -mfn; - } - - ref_clk = 2 * parent_rate; - if (dbl != 0) - ref_clk *= 2; - - ref_clk /= (pdf + 1); - temp = (u64) ref_clk * mfn_abs; - do_div(temp, mfd + 1); - if (mfn < 0) - temp = -temp; - temp = (ref_clk * mfi) + temp; - - return temp; -} - -static unsigned long clk_pllv2_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - u32 dp_op, dp_mfd, dp_mfn, dp_ctl; - void __iomem *pllbase; - struct clk_pllv2 *pll = to_clk_pllv2(hw); - - pllbase = pll->base; - - dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); - dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP); - dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD); - dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN); - - return __clk_pllv2_recalc_rate(parent_rate, dp_ctl, dp_op, dp_mfd, dp_mfn); -} - -static int __clk_pllv2_set_rate(unsigned long rate, unsigned long parent_rate, - u32 *dp_op, u32 *dp_mfd, u32 *dp_mfn) -{ - u32 reg; - long mfi, pdf, mfn, mfd = 999999; - s64 temp64; - unsigned long quad_parent_rate; - - quad_parent_rate = 4 * parent_rate; - pdf = mfi = -1; - while (++pdf < 16 && mfi < 5) - mfi = rate * (pdf+1) / quad_parent_rate; - if (mfi > 15) - return -EINVAL; - pdf--; - - temp64 = rate * (pdf + 1) - quad_parent_rate * mfi; - do_div(temp64, quad_parent_rate / 1000000); - mfn = (long)temp64; - - reg = mfi << 4 | pdf; - - *dp_op = reg; - *dp_mfd = mfd; - *dp_mfn = mfn; - - return 0; -} - -static int clk_pllv2_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct clk_pllv2 *pll = to_clk_pllv2(hw); - void __iomem *pllbase; - u32 dp_ctl, dp_op, dp_mfd, dp_mfn; - int ret; - - pllbase = pll->base; - - - ret = __clk_pllv2_set_rate(rate, parent_rate, &dp_op, &dp_mfd, &dp_mfn); - if (ret) - return ret; - - dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL); - /* use dpdck0_2 */ - __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL); - - __raw_writel(dp_op, pllbase + MXC_PLL_DP_OP); - __raw_writel(dp_mfd, pllbase + MXC_PLL_DP_MFD); - __raw_writel(dp_mfn, pllbase + MXC_PLL_DP_MFN); - - return 0; -} - -static long clk_pllv2_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) -{ - u32 dp_op, dp_mfd, dp_mfn; - - __clk_pllv2_set_rate(rate, *prate, &dp_op, &dp_mfd, &dp_mfn); - return __clk_pllv2_recalc_rate(*prate, MXC_PLL_DP_CTL_DPDCK0_2_EN, - dp_op, dp_mfd, dp_mfn); -} - -static int clk_pllv2_prepare(struct clk_hw *hw) -{ - struct clk_pllv2 *pll = to_clk_pllv2(hw); - u32 reg; - void __iomem *pllbase; - int i = 0; - - pllbase = pll->base; - reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN; - __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); - - /* Wait for lock */ - do { - reg = __raw_readl(pllbase + MXC_PLL_DP_CTL); - if (reg & MXC_PLL_DP_CTL_LRF) - break; - - udelay(1); - } while (++i < MAX_DPLL_WAIT_TRIES); - - if (i == MAX_DPLL_WAIT_TRIES) { - pr_err("MX5: pll locking failed\n"); - return -EINVAL; - } - - return 0; -} - -static void clk_pllv2_unprepare(struct clk_hw *hw) -{ - struct clk_pllv2 *pll = to_clk_pllv2(hw); - u32 reg; - void __iomem *pllbase; - - pllbase = pll->base; - reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN; - __raw_writel(reg, pllbase + MXC_PLL_DP_CTL); -} - -static struct clk_ops clk_pllv2_ops = { - .prepare = clk_pllv2_prepare, - .unprepare = clk_pllv2_unprepare, - .recalc_rate = clk_pllv2_recalc_rate, - .round_rate = clk_pllv2_round_rate, - .set_rate = clk_pllv2_set_rate, -}; - -struct clk *imx_clk_pllv2(const char *name, const char *parent, - void __iomem *base) -{ - struct clk_pllv2 *pll; - struct clk *clk; - struct clk_init_data init; - - pll = kzalloc(sizeof(*pll), GFP_KERNEL); - if (!pll) - return ERR_PTR(-ENOMEM); - - pll->base = base; - - init.name = name; - init.ops = &clk_pllv2_ops; - init.flags = 0; - init.parent_names = &parent; - init.num_parents = 1; - - pll->hw.init = &init; - - clk = clk_register(NULL, &pll->hw); - if (IS_ERR(clk)) - kfree(pll); - - return clk; -} diff --git a/arch/arm/mach-imx/clk-pllv3.c b/arch/arm/mach-imx/clk-pllv3.c deleted file mode 100644 index 641ebc508920..000000000000 --- a/arch/arm/mach-imx/clk-pllv3.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright 2012 Freescale Semiconductor, Inc. - * Copyright 2012 Linaro Ltd. - * - * The code contained herein is licensed under the GNU General Public - * License. You may obtain a copy of the GNU General Public License - * Version 2 or later at the following locations: - * - * http://www.opensource.org/licenses/gpl-license.html - * http://www.gnu.org/copyleft/gpl.html - */ - -#include <linux/clk.h> -#include <linux/clk-provider.h> -#include <linux/delay.h> -#include <linux/io.h> -#include <linux/slab.h> -#include <linux/jiffies.h> -#include <linux/err.h> -#include "clk.h" - -#define PLL_NUM_OFFSET 0x10 -#define PLL_DENOM_OFFSET 0x20 - -#define BM_PLL_POWER (0x1 << 12) -#define BM_PLL_LOCK (0x1 << 31) - -/** - * struct clk_pllv3 - IMX PLL clock version 3 - * @clk_hw: clock source - * @base: base address of PLL registers - * @powerup_set: set POWER bit to power up the PLL - * @div_mask: mask of divider bits - * @div_shift: shift of divider bits - * - * IMX PLL clock version 3, found on i.MX6 series. Divider for pllv3 - * is actually a multiplier, and always sits at bit 0. - */ -struct clk_pllv3 { - struct clk_hw hw; - void __iomem *base; - bool powerup_set; - u32 div_mask; - u32 div_shift; -}; - -#define to_clk_pllv3(_hw) container_of(_hw, struct clk_pllv3, hw) - -static int clk_pllv3_wait_lock(struct clk_pllv3 *pll) -{ - unsigned long timeout = jiffies + msecs_to_jiffies(10); - u32 val = readl_relaxed(pll->base) & BM_PLL_POWER; - - /* No need to wait for lock when pll is not powered up */ - if ((pll->powerup_set && !val) || (!pll->powerup_set && val)) - return 0; - - /* Wait for PLL to lock */ - do { - if (readl_relaxed(pll->base) & BM_PLL_LOCK) - break; - if (time_after(jiffies, timeout)) - break; - usleep_range(50, 500); - } while (1); - - return readl_relaxed(pll->base) & BM_PLL_LOCK ? 0 : -ETIMEDOUT; -} - -static int clk_pllv3_prepare(struct clk_hw *hw) -{ - struct clk_pllv3 *pll = to_clk_pllv3(hw); - u32 val; - - val = readl_relaxed(pll->base); - if (pll->powerup_set) - val |= BM_PLL_POWER; - else - val &= ~BM_PLL_POWER; - writel_relaxed(val, pll->base); - - return clk_pllv3_wait_lock(pll); -} - -static void clk_pllv3_unprepare(struct clk_hw *hw) -{ - struct clk_pllv3 *pll = to_clk_pllv3(hw); - u32 val; - - val = readl_relaxed(pll->base); - if (pll->powerup_set) - val &= ~BM_PLL_POWER; - else - val |= BM_PLL_POWER; - writel_relaxed(val, pll->base); -} - -static unsigned long clk_pllv3_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct clk_pllv3 *pll = to_clk_pllv3(hw); - u32 div = (readl_relaxed(pll->base) >> pll->div_shift) & pll->div_mask; - - return (div == 1) ? parent_rate * 22 : parent_rate * 20; -} - -static long clk_pllv3_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) -{ - unsigned long parent_rate = *prate; - - return (rate >= parent_rate * 22) ? parent_rate * 22 : - parent_rate * 20; -} - -static int clk_pllv3_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct clk_pllv3 *pll = to_clk_pllv3(hw); - u32 val, div; - - if (rate == parent_rate * 22) - div = 1; - else if (rate == parent_rate * 20) - div = 0; - else - return -EINVAL; - - val = readl_relaxed(pll->base); - val &= ~(pll->div_mask << pll->div_shift); - val |= (div << pll->div_shift); - writel_relaxed(val, pll->base); - - return clk_pllv3_wait_lock(pll); -} - -static const struct clk_ops clk_pllv3_ops = { - .prepare = clk_pllv3_prepare, - .unprepare = clk_pllv3_unprepare, - .recalc_rate = clk_pllv3_recalc_rate, - .round_rate = clk_pllv3_round_rate, - .set_rate = clk_pllv3_set_rate, -}; - -static unsigned long clk_pllv3_sys_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct clk_pllv3 *pll = to_clk_pllv3(hw); - u32 div = readl_relaxed(pll->base) & pll->div_mask; - - return parent_rate * div / 2; -} - -static long clk_pllv3_sys_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) -{ - unsigned long parent_rate = *prate; - unsigned long min_rate = parent_rate * 54 / 2; - unsigned long max_rate = parent_rate * 108 / 2; - u32 div; - - if (rate > max_rate) - rate = max_rate; - else if (rate < min_rate) - rate = min_rate; - div = rate * 2 / parent_rate; - - return parent_rate * div / 2; -} - -static int clk_pllv3_sys_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct clk_pllv3 *pll = to_clk_pllv3(hw); - unsigned long min_rate = parent_rate * 54 / 2; - unsigned long max_rate = parent_rate * 108 / 2; - u32 val, div; - - if (rate < min_rate || rate > max_rate) - return -EINVAL; - - div = rate * 2 / parent_rate; - val = readl_relaxed(pll->base); - val &= ~pll->div_mask; - val |= div; - writel_relaxed(val, pll->base); - - return clk_pllv3_wait_lock(pll); -} - -static const struct clk_ops clk_pllv3_sys_ops = { - .prepare = clk_pllv3_prepare, - .unprepare = clk_pllv3_unprepare, - .recalc_rate = clk_pllv3_sys_recalc_rate, - .round_rate = clk_pllv3_sys_round_rate, - .set_rate = clk_pllv3_sys_set_rate, -}; - -static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct clk_pllv3 *pll = to_clk_pllv3(hw); - u32 mfn = readl_relaxed(pll->base + PLL_NUM_OFFSET); - u32 mfd = readl_relaxed(pll->base + PLL_DENOM_OFFSET); - u32 div = readl_relaxed(pll->base) & pll->div_mask; - - return (parent_rate * div) + ((parent_rate / mfd) * mfn); -} - -static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) -{ - unsigned long parent_rate = *prate; - unsigned long min_rate = parent_rate * 27; - unsigned long max_rate = parent_rate * 54; - u32 div; - u32 mfn, mfd = 1000000; - s64 temp64; - - if (rate > max_rate) - rate = max_rate; - else if (rate < min_rate) - rate = min_rate; - - div = rate / parent_rate; - temp64 = (u64) (rate - div * parent_rate); - temp64 *= mfd; - do_div(temp64, parent_rate); - mfn = temp64; - - return parent_rate * div + parent_rate / mfd * mfn; -} - -static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct clk_pllv3 *pll = to_clk_pllv3(hw); - unsigned long min_rate = parent_rate * 27; - unsigned long max_rate = parent_rate * 54; - u32 val, div; - u32 mfn, mfd = 1000000; - s64 temp64; - - if (rate < min_rate || rate > max_rate) - return -EINVAL; - - div = rate / parent_rate; - temp64 = (u64) (rate - div * parent_rate); - temp64 *= mfd; - do_div(temp64, parent_rate); - mfn = temp64; - - val = readl_relaxed(pll->base); - val &= ~pll->div_mask; - val |= div; - writel_relaxed(val, pll->base); - writel_relaxed(mfn, pll->base + PLL_NUM_OFFSET); - writel_relaxed(mfd, pll->base + PLL_DENOM_OFFSET); - - return clk_pllv3_wait_lock(pll); -} - -static const struct clk_ops clk_pllv3_av_ops = { - .prepare = clk_pllv3_prepare, - .unprepare = clk_pllv3_unprepare, - .recalc_rate = clk_pllv3_av_recalc_rate, - .round_rate = clk_pllv3_av_round_rate, - .set_rate = clk_pllv3_av_set_rate, -}; - -static unsigned long clk_pllv3_enet_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - return 500000000; -} - -static const struct clk_ops clk_pllv3_enet_ops = { - .prepare = clk_pllv3_prepare, - .unprepare = clk_pllv3_unprepare, - .recalc_rate = clk_pllv3_enet_recalc_rate, -}; - -struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, - const char *parent_name, void __iomem *base, - u32 div_mask) -{ - struct clk_pllv3 *pll; - const struct clk_ops *ops; - struct clk *clk; - struct clk_init_data init; - - pll = kzalloc(sizeof(*pll), GFP_KERNEL); - if (!pll) - return ERR_PTR(-ENOMEM); - - switch (type) { - case IMX_PLLV3_SYS: - ops = &clk_pllv3_sys_ops; - break; - case IMX_PLLV3_USB_VF610: - pll->div_shift = 1; - case IMX_PLLV3_USB: - ops = &clk_pllv3_ops; - pll->powerup_set = true; - break; - case IMX_PLLV3_AV: - ops = &clk_pllv3_av_ops; - break; - case IMX_PLLV3_ENET: - ops = &clk_pllv3_enet_ops; - break; - default: - ops = &clk_pllv3_ops; - } - pll->base = base; - pll->div_mask = div_mask; - - init.name = name; - init.ops = ops; - init.flags = 0; - init.parent_names = &parent_name; - init.num_parents = 1; - - pll->hw.init = &init; - - clk = clk_register(NULL, &pll->hw); - if (IS_ERR(clk)) - kfree(pll); - - return clk; -} diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c deleted file mode 100644 index 61876ed6e11e..000000000000 --- a/arch/arm/mach-imx/clk-vf610.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright 2012-2013 Freescale Semiconductor, Inc. - * - * 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. - * - */ - -#include <linux/of_address.h> -#include <linux/clk.h> -#include <dt-bindings/clock/vf610-clock.h> - -#include "clk.h" - -#define CCM_CCR (ccm_base + 0x00) -#define CCM_CSR (ccm_base + 0x04) -#define CCM_CCSR (ccm_base + 0x08) -#define CCM_CACRR (ccm_base + 0x0c) -#define CCM_CSCMR1 (ccm_base + 0x10) -#define CCM_CSCDR1 (ccm_base + 0x14) -#define CCM_CSCDR2 (ccm_base + 0x18) -#define CCM_CSCDR3 (ccm_base + 0x1c) -#define CCM_CSCMR2 (ccm_base + 0x20) -#define CCM_CSCDR4 (ccm_base + 0x24) -#define CCM_CLPCR (ccm_base + 0x2c) -#define CCM_CISR (ccm_base + 0x30) -#define CCM_CIMR (ccm_base + 0x34) -#define CCM_CGPR (ccm_base + 0x3c) -#define CCM_CCGR0 (ccm_base + 0x40) -#define CCM_CCGR1 (ccm_base + 0x44) -#define CCM_CCGR2 (ccm_base + 0x48) -#define CCM_CCGR3 (ccm_base + 0x4c) -#define CCM_CCGR4 (ccm_base + 0x50) -#define CCM_CCGR5 (ccm_base + 0x54) -#define CCM_CCGR6 (ccm_base + 0x58) -#define CCM_CCGR7 (ccm_base + 0x5c) -#define CCM_CCGR8 (ccm_base + 0x60) -#define CCM_CCGR9 (ccm_base + 0x64) -#define CCM_CCGR10 (ccm_base + 0x68) -#define CCM_CCGR11 (ccm_base + 0x6c) -#define CCM_CMEOR0 (ccm_base + 0x70) -#define CCM_CMEOR1 (ccm_base + 0x74) -#define CCM_CMEOR2 (ccm_base + 0x78) -#define CCM_CMEOR3 (ccm_base + 0x7c) -#define CCM_CMEOR4 (ccm_base + 0x80) -#define CCM_CMEOR5 (ccm_base + 0x84) -#define CCM_CPPDSR (ccm_base + 0x88) -#define CCM_CCOWR (ccm_base + 0x8c) -#define CCM_CCPGR0 (ccm_base + 0x90) -#define CCM_CCPGR1 (ccm_base + 0x94) -#define CCM_CCPGR2 (ccm_base + 0x98) -#define CCM_CCPGR3 (ccm_base + 0x9c) - -#define CCM_CCGRx_CGn(n) ((n) * 2) - -#define PFD_PLL1_BASE (anatop_base + 0x2b0) -#define PFD_PLL2_BASE (anatop_base + 0x100) -#define PFD_PLL3_BASE (anatop_base + 0xf0) -#define PLL1_CTRL (anatop_base + 0x270) -#define PLL2_CTRL (anatop_base + 0x30) -#define PLL3_CTRL (anatop_base + 0x10) -#define PLL4_CTRL (anatop_base + 0x70) -#define PLL5_CTRL (anatop_base + 0xe0) -#define PLL6_CTRL (anatop_base + 0xa0) -#define PLL7_CTRL (anatop_base + 0x20) -#define ANA_MISC1 (anatop_base + 0x160) - -static void __iomem *anatop_base; -static void __iomem *ccm_base; - -/* sources for multiplexer clocks, this is used multiple times */ -static const char *fast_sels[] = { "firc", "fxosc", }; -static const char *slow_sels[] = { "sirc_32k", "sxosc", }; -static const char *pll1_sels[] = { "pll1_sys", "pll1_pfd1", "pll1_pfd2", "pll1_pfd3", "pll1_pfd4", }; -static const char *pll2_sels[] = { "pll2_bus", "pll2_pfd1", "pll2_pfd2", "pll2_pfd3", "pll2_pfd4", }; -static const char *pll_bypass_src_sels[] = { "fast_clk_sel", "lvds1_in", }; -static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", }; -static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", }; -static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", }; -static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", }; -static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", }; -static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", }; -static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", }; -static const char *sys_sels[] = { "fast_clk_sel", "slow_clk_sel", "pll2_pfd_sel", "pll2_bus", "pll1_pfd_sel", "pll3_usb_otg", }; -static const char *ddr_sels[] = { "pll2_pfd2", "sys_sel", }; -static const char *rmii_sels[] = { "enet_ext", "audio_ext", "enet_50m", "enet_25m", }; -static const char *enet_ts_sels[] = { "enet_ext", "fxosc", "audio_ext", "usb", "enet_ts", "enet_25m", "enet_50m", }; -static const char *esai_sels[] = { "audio_ext", "mlb", "spdif_rx", "pll4_audio_div", }; -static const char *sai_sels[] = { "audio_ext", "mlb", "spdif_rx", "pll4_audio_div", }; -static const char *nfc_sels[] = { "platform_bus", "pll1_pfd1", "pll3_pfd1", "pll3_pfd3", }; -static const char *qspi_sels[] = { "pll3_usb_otg", "pll3_pfd4", "pll2_pfd4", "pll1_pfd4", }; -static const char *esdhc_sels[] = { "pll3_usb_otg", "pll3_pfd3", "pll1_pfd3", "platform_bus", }; -static const char *dcu_sels[] = { "pll1_pfd2", "pll3_usb_otg", }; -static const char *gpu_sels[] = { "pll2_pfd2", "pll3_pfd2", }; -static const char *vadc_sels[] = { "pll6_video_div", "pll3_usb_otg_div", "pll3_usb_otg", }; -/* FTM counter clock source, not module clock */ -static const char *ftm_ext_sels[] = {"sirc_128k", "sxosc", "fxosc_half", "audio_ext", }; -static const char *ftm_fix_sels[] = { "sxosc", "ipg_bus", }; - - -static struct clk_div_table pll4_audio_div_table[] = { - { .val = 0, .div = 1 }, - { .val = 1, .div = 2 }, - { .val = 2, .div = 6 }, - { .val = 3, .div = 8 }, - { .val = 4, .div = 10 }, - { .val = 5, .div = 12 }, - { .val = 6, .div = 14 }, - { .val = 7, .div = 16 }, - { } -}; - -static struct clk *clk[VF610_CLK_END]; -static struct clk_onecell_data clk_data; - -static unsigned int const clks_init_on[] __initconst = { - VF610_CLK_SYS_BUS, - VF610_CLK_DDR_SEL, -}; - -static struct clk * __init vf610_get_fixed_clock( - struct device_node *ccm_node, const char *name) -{ - struct clk *clk = of_clk_get_by_name(ccm_node, name); - - /* Backward compatibility if device tree is missing clks assignments */ - if (IS_ERR(clk)) - clk = imx_obtain_fixed_clock(name, 0); - return clk; -}; - -static void __init vf610_clocks_init(struct device_node *ccm_node) -{ - struct device_node *np; - int i; - - clk[VF610_CLK_DUMMY] = imx_clk_fixed("dummy", 0); - clk[VF610_CLK_SIRC_128K] = imx_clk_fixed("sirc_128k", 128000); - clk[VF610_CLK_SIRC_32K] = imx_clk_fixed("sirc_32k", 32000); - clk[VF610_CLK_FIRC] = imx_clk_fixed("firc", 24000000); - - clk[VF610_CLK_SXOSC] = vf610_get_fixed_clock(ccm_node, "sxosc"); - clk[VF610_CLK_FXOSC] = vf610_get_fixed_clock(ccm_node, "fxosc"); - clk[VF610_CLK_AUDIO_EXT] = vf610_get_fixed_clock(ccm_node, "audio_ext"); - clk[VF610_CLK_ENET_EXT] = vf610_get_fixed_clock(ccm_node, "enet_ext"); - - /* Clock source from external clock via LVDs PAD */ - clk[VF610_CLK_ANACLK1] = vf610_get_fixed_clock(ccm_node, "anaclk1"); - - clk[VF610_CLK_FXOSC_HALF] = imx_clk_fixed_factor("fxosc_half", "fxosc", 1, 2); - - np = of_find_compatible_node(NULL, NULL, "fsl,vf610-anatop"); - anatop_base = of_iomap(np, 0); - BUG_ON(!anatop_base); - - np = ccm_node; - ccm_base = of_iomap(np, 0); - BUG_ON(!ccm_base); - - clk[VF610_CLK_SLOW_CLK_SEL] = imx_clk_mux("slow_clk_sel", CCM_CCSR, 4, 1, slow_sels, ARRAY_SIZE(slow_sels)); - clk[VF610_CLK_FASK_CLK_SEL] = imx_clk_mux("fast_clk_sel", CCM_CCSR, 5, 1, fast_sels, ARRAY_SIZE(fast_sels)); - - clk[VF610_CLK_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", PLL1_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clk[VF610_CLK_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", PLL2_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clk[VF610_CLK_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", PLL3_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clk[VF610_CLK_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", PLL4_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clk[VF610_CLK_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", PLL5_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clk[VF610_CLK_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", PLL6_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - clk[VF610_CLK_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", PLL7_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels)); - - clk[VF610_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll1", "pll1_bypass_src", PLL1_CTRL, 0x1); - clk[VF610_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", PLL2_CTRL, 0x1); - clk[VF610_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB_VF610, "pll3", "pll3_bypass_src", PLL3_CTRL, 0x2); - clk[VF610_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", PLL4_CTRL, 0x7f); - clk[VF610_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll5", "pll5_bypass_src", PLL5_CTRL, 0x3); - clk[VF610_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_AV, "pll6", "pll6_bypass_src", PLL6_CTRL, 0x7f); - clk[VF610_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB_VF610, "pll7", "pll7_bypass_src", PLL7_CTRL, 0x2); - - clk[VF610_PLL1_BYPASS] = imx_clk_mux_flags("pll1_bypass", PLL1_CTRL, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels), CLK_SET_RATE_PARENT); - clk[VF610_PLL2_BYPASS] = imx_clk_mux_flags("pll2_bypass", PLL2_CTRL, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels), CLK_SET_RATE_PARENT); - clk[VF610_PLL3_BYPASS] = imx_clk_mux_flags("pll3_bypass", PLL3_CTRL, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels), CLK_SET_RATE_PARENT); - clk[VF610_PLL4_BYPASS] = imx_clk_mux_flags("pll4_bypass", PLL4_CTRL, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels), CLK_SET_RATE_PARENT); - clk[VF610_PLL5_BYPASS] = imx_clk_mux_flags("pll5_bypass", PLL5_CTRL, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels), CLK_SET_RATE_PARENT); - clk[VF610_PLL6_BYPASS] = imx_clk_mux_flags("pll6_bypass", PLL6_CTRL, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels), CLK_SET_RATE_PARENT); - clk[VF610_PLL7_BYPASS] = imx_clk_mux_flags("pll7_bypass", PLL7_CTRL, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels), CLK_SET_RATE_PARENT); - - /* Do not bypass PLLs initially */ - clk_set_parent(clk[VF610_PLL1_BYPASS], clk[VF610_CLK_PLL1]); - clk_set_parent(clk[VF610_PLL2_BYPASS], clk[VF610_CLK_PLL2]); - clk_set_parent(clk[VF610_PLL3_BYPASS], clk[VF610_CLK_PLL3]); - clk_set_parent(clk[VF610_PLL4_BYPASS], clk[VF610_CLK_PLL4]); - clk_set_parent(clk[VF610_PLL5_BYPASS], clk[VF610_CLK_PLL5]); - clk_set_parent(clk[VF610_PLL6_BYPASS], clk[VF610_CLK_PLL6]); - clk_set_parent(clk[VF610_PLL7_BYPASS], clk[VF610_CLK_PLL7]); - - clk[VF610_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", PLL1_CTRL, 13); - clk[VF610_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", PLL2_CTRL, 13); - clk[VF610_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", PLL3_CTRL, 13); - clk[VF610_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", PLL4_CTRL, 13); - clk[VF610_CLK_PLL5_ENET] = imx_clk_gate("pll5_enet", "pll5_bypass", PLL5_CTRL, 13); - clk[VF610_CLK_PLL6_VIDEO] = imx_clk_gate("pll6_video", "pll6_bypass", PLL6_CTRL, 13); - clk[VF610_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", PLL7_CTRL, 13); - - clk[VF610_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", ANA_MISC1, 12, BIT(10)); - - clk[VF610_CLK_PLL1_PFD1] = imx_clk_pfd("pll1_pfd1", "pll1_sys", PFD_PLL1_BASE, 0); - clk[VF610_CLK_PLL1_PFD2] = imx_clk_pfd("pll1_pfd2", "pll1_sys", PFD_PLL1_BASE, 1); - clk[VF610_CLK_PLL1_PFD3] = imx_clk_pfd("pll1_pfd3", "pll1_sys", PFD_PLL1_BASE, 2); - clk[VF610_CLK_PLL1_PFD4] = imx_clk_pfd("pll1_pfd4", "pll1_sys", PFD_PLL1_BASE, 3); - - clk[VF610_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1", "pll2_bus", PFD_PLL2_BASE, 0); - clk[VF610_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2", "pll2_bus", PFD_PLL2_BASE, 1); - clk[VF610_CLK_PLL2_PFD3] = imx_clk_pfd("pll2_pfd3", "pll2_bus", PFD_PLL2_BASE, 2); - clk[VF610_CLK_PLL2_PFD4] = imx_clk_pfd("pll2_pfd4", "pll2_bus", PFD_PLL2_BASE, 3); - - clk[VF610_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1", "pll3_usb_otg", PFD_PLL3_BASE, 0); - clk[VF610_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_usb_otg", PFD_PLL3_BASE, 1); - clk[VF610_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_usb_otg", PFD_PLL3_BASE, 2); - clk[VF610_CLK_PLL3_PFD4] = imx_clk_pfd("pll3_pfd4", "pll3_usb_otg", PFD_PLL3_BASE, 3); - - clk[VF610_CLK_PLL1_PFD_SEL] = imx_clk_mux("pll1_pfd_sel", CCM_CCSR, 16, 3, pll1_sels, 5); - clk[VF610_CLK_PLL2_PFD_SEL] = imx_clk_mux("pll2_pfd_sel", CCM_CCSR, 19, 3, pll2_sels, 5); - clk[VF610_CLK_SYS_SEL] = imx_clk_mux("sys_sel", CCM_CCSR, 0, 3, sys_sels, ARRAY_SIZE(sys_sels)); - clk[VF610_CLK_DDR_SEL] = imx_clk_mux("ddr_sel", CCM_CCSR, 6, 1, ddr_sels, ARRAY_SIZE(ddr_sels)); - clk[VF610_CLK_SYS_BUS] = imx_clk_divider("sys_bus", "sys_sel", CCM_CACRR, 0, 3); - clk[VF610_CLK_PLATFORM_BUS] = imx_clk_divider("platform_bus", "sys_bus", CCM_CACRR, 3, 3); - clk[VF610_CLK_IPG_BUS] = imx_clk_divider("ipg_bus", "platform_bus", CCM_CACRR, 11, 2); - - clk[VF610_CLK_PLL3_MAIN_DIV] = imx_clk_divider("pll3_usb_otg_div", "pll3_usb_otg", CCM_CACRR, 20, 1); - clk[VF610_CLK_PLL4_MAIN_DIV] = clk_register_divider_table(NULL, "pll4_audio_div", "pll4_audio", 0, CCM_CACRR, 6, 3, 0, pll4_audio_div_table, &imx_ccm_lock); - clk[VF610_CLK_PLL6_MAIN_DIV] = imx_clk_divider("pll6_video_div", "pll6_video", CCM_CACRR, 21, 1); - - clk[VF610_CLK_USBPHY0] = imx_clk_gate("usbphy0", "pll3_usb_otg", PLL3_CTRL, 6); - clk[VF610_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll7_usb_host", PLL7_CTRL, 6); - - clk[VF610_CLK_USBC0] = imx_clk_gate2("usbc0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(4)); - clk[VF610_CLK_USBC1] = imx_clk_gate2("usbc1", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(4)); - - clk[VF610_CLK_QSPI0_SEL] = imx_clk_mux("qspi0_sel", CCM_CSCMR1, 22, 2, qspi_sels, 4); - clk[VF610_CLK_QSPI0_EN] = imx_clk_gate("qspi0_en", "qspi0_sel", CCM_CSCDR3, 4); - clk[VF610_CLK_QSPI0_X4_DIV] = imx_clk_divider("qspi0_x4", "qspi0_en", CCM_CSCDR3, 0, 2); - clk[VF610_CLK_QSPI0_X2_DIV] = imx_clk_divider("qspi0_x2", "qspi0_x4", CCM_CSCDR3, 2, 1); - clk[VF610_CLK_QSPI0_X1_DIV] = imx_clk_divider("qspi0_x1", "qspi0_x2", CCM_CSCDR3, 3, 1); - clk[VF610_CLK_QSPI0] = imx_clk_gate2("qspi0", "qspi0_x1", CCM_CCGR2, CCM_CCGRx_CGn(4)); - - clk[VF610_CLK_QSPI1_SEL] = imx_clk_mux("qspi1_sel", CCM_CSCMR1, 24, 2, qspi_sels, 4); - clk[VF610_CLK_QSPI1_EN] = imx_clk_gate("qspi1_en", "qspi1_sel", CCM_CSCDR3, 12); - clk[VF610_CLK_QSPI1_X4_DIV] = imx_clk_divider("qspi1_x4", "qspi1_en", CCM_CSCDR3, 8, 2); - clk[VF610_CLK_QSPI1_X2_DIV] = imx_clk_divider("qspi1_x2", "qspi1_x4", CCM_CSCDR3, 10, 1); - clk[VF610_CLK_QSPI1_X1_DIV] = imx_clk_divider("qspi1_x1", "qspi1_x2", CCM_CSCDR3, 11, 1); - clk[VF610_CLK_QSPI1] = imx_clk_gate2("qspi1", "qspi1_x1", CCM_CCGR8, CCM_CCGRx_CGn(4)); - - clk[VF610_CLK_ENET_50M] = imx_clk_fixed_factor("enet_50m", "pll5_enet", 1, 10); - clk[VF610_CLK_ENET_25M] = imx_clk_fixed_factor("enet_25m", "pll5_enet", 1, 20); - clk[VF610_CLK_ENET_SEL] = imx_clk_mux("enet_sel", CCM_CSCMR2, 4, 2, rmii_sels, 4); - clk[VF610_CLK_ENET_TS_SEL] = imx_clk_mux("enet_ts_sel", CCM_CSCMR2, 0, 3, enet_ts_sels, 7); - clk[VF610_CLK_ENET] = imx_clk_gate("enet", "enet_sel", CCM_CSCDR1, 24); - clk[VF610_CLK_ENET_TS] = imx_clk_gate("enet_ts", "enet_ts_sel", CCM_CSCDR1, 23); - clk[VF610_CLK_ENET0] = imx_clk_gate2("enet0", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(0)); - clk[VF610_CLK_ENET1] = imx_clk_gate2("enet1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(1)); - - clk[VF610_CLK_PIT] = imx_clk_gate2("pit", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(7)); - - clk[VF610_CLK_UART0] = imx_clk_gate2("uart0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(7)); - clk[VF610_CLK_UART1] = imx_clk_gate2("uart1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(8)); - clk[VF610_CLK_UART2] = imx_clk_gate2("uart2", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(9)); - clk[VF610_CLK_UART3] = imx_clk_gate2("uart3", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(10)); - clk[VF610_CLK_UART4] = imx_clk_gate2("uart4", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(9)); - clk[VF610_CLK_UART5] = imx_clk_gate2("uart5", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(10)); - - clk[VF610_CLK_I2C0] = imx_clk_gate2("i2c0", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(6)); - clk[VF610_CLK_I2C1] = imx_clk_gate2("i2c1", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(7)); - - clk[VF610_CLK_DSPI0] = imx_clk_gate2("dspi0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(12)); - clk[VF610_CLK_DSPI1] = imx_clk_gate2("dspi1", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(13)); - clk[VF610_CLK_DSPI2] = imx_clk_gate2("dspi2", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(12)); - clk[VF610_CLK_DSPI3] = imx_clk_gate2("dspi3", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(13)); - - clk[VF610_CLK_WDT] = imx_clk_gate2("wdt", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(14)); - - clk[VF610_CLK_ESDHC0_SEL] = imx_clk_mux("esdhc0_sel", CCM_CSCMR1, 16, 2, esdhc_sels, 4); - clk[VF610_CLK_ESDHC0_EN] = imx_clk_gate("esdhc0_en", "esdhc0_sel", CCM_CSCDR2, 28); - clk[VF610_CLK_ESDHC0_DIV] = imx_clk_divider("esdhc0_div", "esdhc0_en", CCM_CSCDR2, 16, 4); - clk[VF610_CLK_ESDHC0] = imx_clk_gate2("eshc0", "esdhc0_div", CCM_CCGR7, CCM_CCGRx_CGn(1)); - - clk[VF610_CLK_ESDHC1_SEL] = imx_clk_mux("esdhc1_sel", CCM_CSCMR1, 18, 2, esdhc_sels, 4); - clk[VF610_CLK_ESDHC1_EN] = imx_clk_gate("esdhc1_en", "esdhc1_sel", CCM_CSCDR2, 29); - clk[VF610_CLK_ESDHC1_DIV] = imx_clk_divider("esdhc1_div", "esdhc1_en", CCM_CSCDR2, 20, 4); - clk[VF610_CLK_ESDHC1] = imx_clk_gate2("eshc1", "esdhc1_div", CCM_CCGR7, CCM_CCGRx_CGn(2)); - - /* - * ftm_ext_clk and ftm_fix_clk are FTM timer counter's - * selectable clock sources, both use a common enable bit - * in CCM_CSCDR1, selecting "dummy" clock as parent of - * "ftm0_ext_fix" make it serve only for enable/disable. - */ - clk[VF610_CLK_FTM0_EXT_SEL] = imx_clk_mux("ftm0_ext_sel", CCM_CSCMR2, 6, 2, ftm_ext_sels, 4); - clk[VF610_CLK_FTM0_FIX_SEL] = imx_clk_mux("ftm0_fix_sel", CCM_CSCMR2, 14, 1, ftm_fix_sels, 2); - clk[VF610_CLK_FTM0_EXT_FIX_EN] = imx_clk_gate("ftm0_ext_fix_en", "dummy", CCM_CSCDR1, 25); - clk[VF610_CLK_FTM1_EXT_SEL] = imx_clk_mux("ftm1_ext_sel", CCM_CSCMR2, 8, 2, ftm_ext_sels, 4); - clk[VF610_CLK_FTM1_FIX_SEL] = imx_clk_mux("ftm1_fix_sel", CCM_CSCMR2, 15, 1, ftm_fix_sels, 2); - clk[VF610_CLK_FTM1_EXT_FIX_EN] = imx_clk_gate("ftm1_ext_fix_en", "dummy", CCM_CSCDR1, 26); - clk[VF610_CLK_FTM2_EXT_SEL] = imx_clk_mux("ftm2_ext_sel", CCM_CSCMR2, 10, 2, ftm_ext_sels, 4); - clk[VF610_CLK_FTM2_FIX_SEL] = imx_clk_mux("ftm2_fix_sel", CCM_CSCMR2, 16, 1, ftm_fix_sels, 2); - clk[VF610_CLK_FTM2_EXT_FIX_EN] = imx_clk_gate("ftm2_ext_fix_en", "dummy", CCM_CSCDR1, 27); - clk[VF610_CLK_FTM3_EXT_SEL] = imx_clk_mux("ftm3_ext_sel", CCM_CSCMR2, 12, 2, ftm_ext_sels, 4); - clk[VF610_CLK_FTM3_FIX_SEL] = imx_clk_mux("ftm3_fix_sel", CCM_CSCMR2, 17, 1, ftm_fix_sels, 2); - clk[VF610_CLK_FTM3_EXT_FIX_EN] = imx_clk_gate("ftm3_ext_fix_en", "dummy", CCM_CSCDR1, 28); - - /* ftm(n)_clk are FTM module operation clock */ - clk[VF610_CLK_FTM0] = imx_clk_gate2("ftm0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(8)); - clk[VF610_CLK_FTM1] = imx_clk_gate2("ftm1", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(9)); - clk[VF610_CLK_FTM2] = imx_clk_gate2("ftm2", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(8)); - clk[VF610_CLK_FTM3] = imx_clk_gate2("ftm3", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(9)); - - clk[VF610_CLK_DCU0_SEL] = imx_clk_mux("dcu0_sel", CCM_CSCMR1, 28, 1, dcu_sels, 2); - clk[VF610_CLK_DCU0_EN] = imx_clk_gate("dcu0_en", "dcu0_sel", CCM_CSCDR3, 19); - clk[VF610_CLK_DCU0_DIV] = imx_clk_divider("dcu0_div", "dcu0_en", CCM_CSCDR3, 16, 3); - clk[VF610_CLK_DCU0] = imx_clk_gate2("dcu0", "dcu0_div", CCM_CCGR3, CCM_CCGRx_CGn(8)); - clk[VF610_CLK_DCU1_SEL] = imx_clk_mux("dcu1_sel", CCM_CSCMR1, 29, 1, dcu_sels, 2); - clk[VF610_CLK_DCU1_EN] = imx_clk_gate("dcu1_en", "dcu1_sel", CCM_CSCDR3, 23); - clk[VF610_CLK_DCU1_DIV] = imx_clk_divider("dcu1_div", "dcu1_en", CCM_CSCDR3, 20, 3); - clk[VF610_CLK_DCU1] = imx_clk_gate2("dcu1", "dcu1_div", CCM_CCGR9, CCM_CCGRx_CGn(8)); - - clk[VF610_CLK_ESAI_SEL] = imx_clk_mux("esai_sel", CCM_CSCMR1, 20, 2, esai_sels, 4); - clk[VF610_CLK_ESAI_EN] = imx_clk_gate("esai_en", "esai_sel", CCM_CSCDR2, 30); - clk[VF610_CLK_ESAI_DIV] = imx_clk_divider("esai_div", "esai_en", CCM_CSCDR2, 24, 4); - clk[VF610_CLK_ESAI] = imx_clk_gate2("esai", "esai_div", CCM_CCGR4, CCM_CCGRx_CGn(2)); - - clk[VF610_CLK_SAI0_SEL] = imx_clk_mux("sai0_sel", CCM_CSCMR1, 0, 2, sai_sels, 4); - clk[VF610_CLK_SAI0_EN] = imx_clk_gate("sai0_en", "sai0_sel", CCM_CSCDR1, 16); - clk[VF610_CLK_SAI0_DIV] = imx_clk_divider("sai0_div", "sai0_en", CCM_CSCDR1, 0, 4); - clk[VF610_CLK_SAI0] = imx_clk_gate2("sai0", "sai0_div", CCM_CCGR0, CCM_CCGRx_CGn(15)); - - clk[VF610_CLK_SAI1_SEL] = imx_clk_mux("sai1_sel", CCM_CSCMR1, 2, 2, sai_sels, 4); - clk[VF610_CLK_SAI1_EN] = imx_clk_gate("sai1_en", "sai1_sel", CCM_CSCDR1, 17); - clk[VF610_CLK_SAI1_DIV] = imx_clk_divider("sai1_div", "sai1_en", CCM_CSCDR1, 4, 4); - clk[VF610_CLK_SAI1] = imx_clk_gate2("sai1", "sai1_div", CCM_CCGR1, CCM_CCGRx_CGn(0)); - - clk[VF610_CLK_SAI2_SEL] = imx_clk_mux("sai2_sel", CCM_CSCMR1, 4, 2, sai_sels, 4); - clk[VF610_CLK_SAI2_EN] = imx_clk_gate("sai2_en", "sai2_sel", CCM_CSCDR1, 18); - clk[VF610_CLK_SAI2_DIV] = imx_clk_divider("sai2_div", "sai2_en", CCM_CSCDR1, 8, 4); - clk[VF610_CLK_SAI2] = imx_clk_gate2("sai2", "sai2_div", CCM_CCGR1, CCM_CCGRx_CGn(1)); - - clk[VF610_CLK_SAI3_SEL] = imx_clk_mux("sai3_sel", CCM_CSCMR1, 6, 2, sai_sels, 4); - clk[VF610_CLK_SAI3_EN] = imx_clk_gate("sai3_en", "sai3_sel", CCM_CSCDR1, 19); - clk[VF610_CLK_SAI3_DIV] = imx_clk_divider("sai3_div", "sai3_en", CCM_CSCDR1, 12, 4); - clk[VF610_CLK_SAI3] = imx_clk_gate2("sai3", "sai3_div", CCM_CCGR1, CCM_CCGRx_CGn(2)); - - clk[VF610_CLK_NFC_SEL] = imx_clk_mux("nfc_sel", CCM_CSCMR1, 12, 2, nfc_sels, 4); - clk[VF610_CLK_NFC_EN] = imx_clk_gate("nfc_en", "nfc_sel", CCM_CSCDR2, 9); - clk[VF610_CLK_NFC_PRE_DIV] = imx_clk_divider("nfc_pre_div", "nfc_en", CCM_CSCDR3, 13, 3); - clk[VF610_CLK_NFC_FRAC_DIV] = imx_clk_divider("nfc_frac_div", "nfc_pre_div", CCM_CSCDR2, 4, 4); - clk[VF610_CLK_NFC] = imx_clk_gate2("nfc", "nfc_frac_div", CCM_CCGR10, CCM_CCGRx_CGn(0)); - - clk[VF610_CLK_GPU_SEL] = imx_clk_mux("gpu_sel", CCM_CSCMR1, 14, 1, gpu_sels, 2); - clk[VF610_CLK_GPU_EN] = imx_clk_gate("gpu_en", "gpu_sel", CCM_CSCDR2, 10); - clk[VF610_CLK_GPU2D] = imx_clk_gate2("gpu", "gpu_en", CCM_CCGR8, CCM_CCGRx_CGn(15)); - - clk[VF610_CLK_VADC_SEL] = imx_clk_mux("vadc_sel", CCM_CSCMR1, 8, 2, vadc_sels, 3); - clk[VF610_CLK_VADC_EN] = imx_clk_gate("vadc_en", "vadc_sel", CCM_CSCDR1, 22); - clk[VF610_CLK_VADC_DIV] = imx_clk_divider("vadc_div", "vadc_en", CCM_CSCDR1, 20, 2); - clk[VF610_CLK_VADC_DIV_HALF] = imx_clk_fixed_factor("vadc_div_half", "vadc_div", 1, 2); - clk[VF610_CLK_VADC] = imx_clk_gate2("vadc", "vadc_div", CCM_CCGR8, CCM_CCGRx_CGn(7)); - - clk[VF610_CLK_ADC0] = imx_clk_gate2("adc0", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(11)); - clk[VF610_CLK_ADC1] = imx_clk_gate2("adc1", "ipg_bus", CCM_CCGR7, CCM_CCGRx_CGn(11)); - clk[VF610_CLK_DAC0] = imx_clk_gate2("dac0", "ipg_bus", CCM_CCGR8, CCM_CCGRx_CGn(12)); - clk[VF610_CLK_DAC1] = imx_clk_gate2("dac1", "ipg_bus", CCM_CCGR8, CCM_CCGRx_CGn(13)); - - clk[VF610_CLK_ASRC] = imx_clk_gate2("asrc", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(1)); - - clk[VF610_CLK_FLEXCAN0_EN] = imx_clk_gate("flexcan0_en", "ipg_bus", CCM_CSCDR2, 11); - clk[VF610_CLK_FLEXCAN0] = imx_clk_gate2("flexcan0", "flexcan0_en", CCM_CCGR0, CCM_CCGRx_CGn(0)); - clk[VF610_CLK_FLEXCAN1_EN] = imx_clk_gate("flexcan1_en", "ipg_bus", CCM_CSCDR2, 12); - clk[VF610_CLK_FLEXCAN1] = imx_clk_gate2("flexcan1", "flexcan1_en", CCM_CCGR9, CCM_CCGRx_CGn(4)); - - clk[VF610_CLK_DMAMUX0] = imx_clk_gate2("dmamux0", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(4)); - clk[VF610_CLK_DMAMUX1] = imx_clk_gate2("dmamux1", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(5)); - clk[VF610_CLK_DMAMUX2] = imx_clk_gate2("dmamux2", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(1)); - clk[VF610_CLK_DMAMUX3] = imx_clk_gate2("dmamux3", "platform_bus", CCM_CCGR6, CCM_CCGRx_CGn(2)); - - clk[VF610_CLK_SNVS] = imx_clk_gate2("snvs-rtc", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(7)); - - imx_check_clocks(clk, ARRAY_SIZE(clk)); - - clk_set_parent(clk[VF610_CLK_QSPI0_SEL], clk[VF610_CLK_PLL1_PFD4]); - clk_set_rate(clk[VF610_CLK_QSPI0_X4_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_SEL]) / 2); - clk_set_rate(clk[VF610_CLK_QSPI0_X2_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_X4_DIV]) / 2); - clk_set_rate(clk[VF610_CLK_QSPI0_X1_DIV], clk_get_rate(clk[VF610_CLK_QSPI0_X2_DIV]) / 2); - - clk_set_parent(clk[VF610_CLK_QSPI1_SEL], clk[VF610_CLK_PLL1_PFD4]); - clk_set_rate(clk[VF610_CLK_QSPI1_X4_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_SEL]) / 2); - clk_set_rate(clk[VF610_CLK_QSPI1_X2_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_X4_DIV]) / 2); - clk_set_rate(clk[VF610_CLK_QSPI1_X1_DIV], clk_get_rate(clk[VF610_CLK_QSPI1_X2_DIV]) / 2); - - clk_set_parent(clk[VF610_CLK_SAI0_SEL], clk[VF610_CLK_AUDIO_EXT]); - clk_set_parent(clk[VF610_CLK_SAI1_SEL], clk[VF610_CLK_AUDIO_EXT]); - clk_set_parent(clk[VF610_CLK_SAI2_SEL], clk[VF610_CLK_AUDIO_EXT]); - clk_set_parent(clk[VF610_CLK_SAI3_SEL], clk[VF610_CLK_AUDIO_EXT]); - - for (i = 0; i < ARRAY_SIZE(clks_init_on); i++) - clk_prepare_enable(clk[clks_init_on[i]]); - - /* Add the clocks to provider list */ - clk_data.clks = clk; - clk_data.clk_num = ARRAY_SIZE(clk); - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); -} -CLK_OF_DECLARE(vf610, "fsl,vf610-ccm", vf610_clocks_init); diff --git a/arch/arm/mach-imx/clk.c b/arch/arm/mach-imx/clk.c deleted file mode 100644 index df12b5307175..000000000000 --- a/arch/arm/mach-imx/clk.c +++ /dev/null @@ -1,75 +0,0 @@ -#include <linux/clk.h> -#include <linux/err.h> -#include <linux/of.h> -#include <linux/slab.h> -#include <linux/spinlock.h> -#include "clk.h" - -DEFINE_SPINLOCK(imx_ccm_lock); - -void __init imx_check_clocks(struct clk *clks[], unsigned int count) -{ - unsigned i; - - for (i = 0; i < count; i++) - if (IS_ERR(clks[i])) - pr_err("i.MX clk %u: register failed with %ld\n", - i, PTR_ERR(clks[i])); -} - -static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name) -{ - struct of_phandle_args phandle; - struct clk *clk = ERR_PTR(-ENODEV); - char *path; - - path = kasprintf(GFP_KERNEL, "/clocks/%s", name); - if (!path) - return ERR_PTR(-ENOMEM); - - phandle.np = of_find_node_by_path(path); - kfree(path); - - if (phandle.np) { - clk = of_clk_get_from_provider(&phandle); - of_node_put(phandle.np); - } - return clk; -} - -struct clk * __init imx_obtain_fixed_clock( - const char *name, unsigned long rate) -{ - struct clk *clk; - - clk = imx_obtain_fixed_clock_from_dt(name); - if (IS_ERR(clk)) - clk = imx_clk_fixed(name, rate); - return clk; -} - -/* - * This fixups the register CCM_CSCMR1 write value. - * The write/read/divider values of the aclk_podf field - * of that register have the relationship described by - * the following table: - * - * write value read value divider - * 3b'000 3b'110 7 - * 3b'001 3b'111 8 - * 3b'010 3b'100 5 - * 3b'011 3b'101 6 - * 3b'100 3b'010 3 - * 3b'101 3b'011 4 - * 3b'110 3b'000 1 - * 3b'111 3b'001 2(default) - * - * That's why we do the xor operation below. - */ -#define CSCMR1_FIXUP 0x00600000 - -void imx_cscmr1_fixup(u32 *val) -{ - *val ^= CSCMR1_FIXUP; - return; -} diff --git a/arch/arm/mach-imx/clk.h b/arch/arm/mach-imx/clk.h deleted file mode 100644 index 6a07903a28bc..000000000000 --- a/arch/arm/mach-imx/clk.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef __MACH_IMX_CLK_H -#define __MACH_IMX_CLK_H - -#include <linux/spinlock.h> -#include <linux/clk-provider.h> - -extern spinlock_t imx_ccm_lock; - -void imx_check_clocks(struct clk *clks[], unsigned int count); - -extern void imx_cscmr1_fixup(u32 *val); - -struct clk *imx_clk_pllv1(const char *name, const char *parent, - void __iomem *base); - -struct clk *imx_clk_pllv2(const char *name, const char *parent, - void __iomem *base); - -enum imx_pllv3_type { - IMX_PLLV3_GENERIC, - IMX_PLLV3_SYS, - IMX_PLLV3_USB, - IMX_PLLV3_USB_VF610, - IMX_PLLV3_AV, - IMX_PLLV3_ENET, -}; - -struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name, - const char *parent_name, void __iomem *base, u32 div_mask); - -struct clk *clk_register_gate2(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, - unsigned int *share_count); - -struct clk * imx_obtain_fixed_clock( - const char *name, unsigned long rate); - -struct clk *imx_clk_gate_exclusive(const char *name, const char *parent, - void __iomem *reg, u8 shift, u32 exclusive_mask); - -static inline struct clk *imx_clk_gate2(const char *name, const char *parent, - void __iomem *reg, u8 shift) -{ - return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, - shift, 0, &imx_ccm_lock, NULL); -} - -static inline struct clk *imx_clk_gate2_shared(const char *name, - const char *parent, void __iomem *reg, u8 shift, - unsigned int *share_count) -{ - return clk_register_gate2(NULL, name, parent, CLK_SET_RATE_PARENT, reg, - shift, 0, &imx_ccm_lock, share_count); -} - -struct clk *imx_clk_pfd(const char *name, const char *parent_name, - void __iomem *reg, u8 idx); - -struct clk *imx_clk_busy_divider(const char *name, const char *parent_name, - void __iomem *reg, u8 shift, u8 width, - void __iomem *busy_reg, u8 busy_shift); - -struct clk *imx_clk_busy_mux(const char *name, void __iomem *reg, u8 shift, - u8 width, void __iomem *busy_reg, u8 busy_shift, - const char **parent_names, int num_parents); - -struct clk *imx_clk_fixup_divider(const char *name, const char *parent, - void __iomem *reg, u8 shift, u8 width, - void (*fixup)(u32 *val)); - -struct clk *imx_clk_fixup_mux(const char *name, void __iomem *reg, - u8 shift, u8 width, const char **parents, - int num_parents, void (*fixup)(u32 *val)); - -static inline struct clk *imx_clk_fixed(const char *name, int rate) -{ - return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate); -} - -static inline struct clk *imx_clk_divider(const char *name, const char *parent, - void __iomem *reg, u8 shift, u8 width) -{ - return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT, - reg, shift, width, 0, &imx_ccm_lock); -} - -static inline struct clk *imx_clk_divider_flags(const char *name, - const char *parent, void __iomem *reg, u8 shift, u8 width, - unsigned long flags) -{ - return clk_register_divider(NULL, name, parent, flags, - reg, shift, width, 0, &imx_ccm_lock); -} - -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_gate_dis(const char *name, const char *parent, - void __iomem *reg, u8 shift) -{ - return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg, - shift, CLK_GATE_SET_TO_DISABLE, &imx_ccm_lock); -} - -static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg, - u8 shift, u8 width, const char **parents, int num_parents) -{ - return clk_register_mux(NULL, name, parents, num_parents, - CLK_SET_RATE_NO_REPARENT, reg, shift, - width, 0, &imx_ccm_lock); -} - -static inline struct clk *imx_clk_mux_flags(const char *name, - void __iomem *reg, u8 shift, u8 width, const char **parents, - int num_parents, unsigned long flags) -{ - return clk_register_mux(NULL, name, parents, num_parents, - flags | CLK_SET_RATE_NO_REPARENT, reg, shift, width, 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); -} - -struct clk *imx_clk_cpu(const char *name, const char *parent_name, - struct clk *div, struct clk *mux, struct clk *pll, - struct clk *step); - -#endif diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h index 0f04e30b726d..21e4e8697a58 100644 --- a/arch/arm/mach-imx/common.h +++ b/arch/arm/mach-imx/common.h @@ -44,7 +44,6 @@ void imx27_soc_init(void); void imx31_soc_init(void); void imx35_soc_init(void); void epit_timer_init(void __iomem *base, int irq); -void mxc_timer_init(void __iomem *, int); int mx1_clocks_init(unsigned long fref); int mx21_clocks_init(unsigned long lref, unsigned long fref); int mx27_clocks_init(unsigned long fref); @@ -56,13 +55,10 @@ struct platform_device *mxc_register_gpio(char *name, int id, void mxc_set_cpu_type(unsigned int type); void mxc_restart(enum reboot_mode, const char *); void mxc_arch_reset_init(void __iomem *); -int mx51_revision(void); -int mx53_revision(void); void imx_set_aips(void __iomem *); void imx_aips_allow_unprivileged_access(const char *compat); int mxc_device_init(void); void imx_set_soc_revision(unsigned int rev); -unsigned int imx_get_soc_revision(void); void imx_init_revision_from_anatop(void); struct device *imx_soc_device_init(void); void imx6_enable_rbc(bool enable); @@ -87,7 +83,6 @@ enum mx3_cpu_pwr_mode { }; void mx3_cpu_lp_set(enum mx3_cpu_pwr_mode mode); -void imx_print_silicon_rev(const char *cpu, int srev); void imx_enable_cpu(int cpu, bool enable); void imx_set_cpu_jump(int cpu, void *jump_addr); @@ -111,7 +106,7 @@ void imx_gpc_hwirq_unmask(unsigned int hwirq); void imx_anatop_init(void); void imx_anatop_pre_suspend(void); void imx_anatop_post_resume(void); -int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode); +int imx6_set_lpm(enum mxc_cpu_pwr_mode mode); void imx6q_set_int_mem_clk_lpm(bool enable); void imx6sl_set_wait_clk(bool enter); int imx_mmdc_get_ddr_type(void); @@ -121,26 +116,28 @@ int imx_cpu_kill(unsigned int cpu); #ifdef CONFIG_SUSPEND void v7_cpu_resume(void); +void imx53_suspend(void __iomem *ocram_vbase); +extern const u32 imx53_suspend_sz; void imx6_suspend(void __iomem *ocram_vbase); #else static inline void v7_cpu_resume(void) {} +static inline void imx53_suspend(void __iomem *ocram_vbase) {} +static const u32 imx53_suspend_sz; static inline void imx6_suspend(void __iomem *ocram_vbase) {} #endif +void imx6_pm_ccm_init(const char *ccm_compat); void imx6q_pm_init(void); void imx6dl_pm_init(void); void imx6sl_pm_init(void); void imx6sx_pm_init(void); -void imx6q_pm_set_ccm_base(void __iomem *base); #ifdef CONFIG_PM void imx51_pm_init(void); void imx53_pm_init(void); -void imx5_pm_set_ccm_base(void __iomem *base); #else static inline void imx51_pm_init(void) {} static inline void imx53_pm_init(void) {} -static inline void imx5_pm_set_ccm_base(void __iomem *base) {} #endif #ifdef CONFIG_NEON diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index df42c14ff749..a7fa92a7b1d7 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -130,6 +130,9 @@ struct device * __init imx_soc_device_init(void) case MXC_CPU_IMX6Q: soc_id = "i.MX6Q"; break; + case MXC_CPU_IMX7D: + soc_id = "i.MX7D"; + break; default: soc_id = "Unknown"; } diff --git a/arch/arm/mach-imx/cpuidle-imx6q.c b/arch/arm/mach-imx/cpuidle-imx6q.c index 8e21ccc1eda2..353bb8774112 100644 --- a/arch/arm/mach-imx/cpuidle-imx6q.c +++ b/arch/arm/mach-imx/cpuidle-imx6q.c @@ -27,9 +27,9 @@ static int imx6q_enter_wait(struct cpuidle_device *dev, */ if (!spin_trylock(&master_lock)) goto idle; - imx6q_set_lpm(WAIT_UNCLOCKED); + imx6_set_lpm(WAIT_UNCLOCKED); cpu_do_idle(); - imx6q_set_lpm(WAIT_CLOCKED); + imx6_set_lpm(WAIT_CLOCKED); spin_unlock(&master_lock); goto done; } diff --git a/arch/arm/mach-imx/cpuidle-imx6sl.c b/arch/arm/mach-imx/cpuidle-imx6sl.c index 5742a9fd1ef2..8d866fb674a8 100644 --- a/arch/arm/mach-imx/cpuidle-imx6sl.c +++ b/arch/arm/mach-imx/cpuidle-imx6sl.c @@ -16,7 +16,7 @@ static int imx6sl_enter_wait(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - imx6q_set_lpm(WAIT_UNCLOCKED); + imx6_set_lpm(WAIT_UNCLOCKED); /* * Software workaround for ERR005311, see function * description for details. @@ -24,7 +24,7 @@ static int imx6sl_enter_wait(struct cpuidle_device *dev, imx6sl_set_wait_clk(true); cpu_do_idle(); imx6sl_set_wait_clk(false); - imx6q_set_lpm(WAIT_CLOCKED); + imx6_set_lpm(WAIT_CLOCKED); return index; } diff --git a/arch/arm/mach-imx/cpuidle-imx6sx.c b/arch/arm/mach-imx/cpuidle-imx6sx.c index 2c9f1a8bf245..3c6672b3796b 100644 --- a/arch/arm/mach-imx/cpuidle-imx6sx.c +++ b/arch/arm/mach-imx/cpuidle-imx6sx.c @@ -25,7 +25,7 @@ static int imx6sx_idle_finish(unsigned long val) static int imx6sx_enter_wait(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index) { - imx6q_set_lpm(WAIT_UNCLOCKED); + imx6_set_lpm(WAIT_UNCLOCKED); switch (index) { case 1: @@ -50,7 +50,7 @@ static int imx6sx_enter_wait(struct cpuidle_device *dev, break; } - imx6q_set_lpm(WAIT_CLOCKED); + imx6_set_lpm(WAIT_CLOCKED); return index; } diff --git a/arch/arm/mach-imx/gpc.c b/arch/arm/mach-imx/gpc.c index 0ea77ed25b25..80bad29d609a 100644 --- a/arch/arm/mach-imx/gpc.c +++ b/arch/arm/mach-imx/gpc.c @@ -227,7 +227,7 @@ static int imx_gpc_domain_alloc(struct irq_domain *domain, return irq_domain_alloc_irqs_parent(domain, irq, nr_irqs, &parent_args); } -static struct irq_domain_ops imx_gpc_domain_ops = { +static const struct irq_domain_ops imx_gpc_domain_ops = { .xlate = imx_gpc_domain_xlate, .alloc = imx_gpc_domain_alloc, .free = irq_domain_free_irqs_common, diff --git a/arch/arm/mach-imx/hardware.h b/arch/arm/mach-imx/hardware.h index 76af2c03c241..d737f95ebb07 100644 --- a/arch/arm/mach-imx/hardware.h +++ b/arch/arm/mach-imx/hardware.h @@ -22,6 +22,7 @@ #ifndef __ASSEMBLY__ #include <asm/io.h> +#include <soc/imx/revision.h> #endif #include <asm/sizes.h> diff --git a/arch/arm/mach-imx/iomux-imx31.c b/arch/arm/mach-imx/iomux-imx31.c index d6a30753ca7c..6dd22cabf4d3 100644 --- a/arch/arm/mach-imx/iomux-imx31.c +++ b/arch/arm/mach-imx/iomux-imx31.c @@ -40,7 +40,7 @@ static DEFINE_SPINLOCK(gpio_mux_lock); #define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3) -static unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG]; +static DECLARE_BITMAP(mxc_pin_alloc_map, NB_PORTS * 32); /* * set the mode for a IOMUX pin. */ diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 3ab61549ce0f..9602cc12d2f1 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c @@ -393,6 +393,7 @@ static void __init imx6q_init_irq(void) imx_init_l2cache(); imx_src_init(); irqchip_init(); + imx6_pm_ccm_init("fsl,imx6q-ccm"); } static const char * const imx6q_dt_compat[] __initconst = { diff --git a/arch/arm/mach-imx/mach-imx6sl.c b/arch/arm/mach-imx/mach-imx6sl.c index 12a1b098fc6a..300326373166 100644 --- a/arch/arm/mach-imx/mach-imx6sl.c +++ b/arch/arm/mach-imx/mach-imx6sl.c @@ -66,6 +66,7 @@ static void __init imx6sl_init_irq(void) imx_init_l2cache(); imx_src_init(); irqchip_init(); + imx6_pm_ccm_init("fsl,imx6sl-ccm"); } static const char * const imx6sl_dt_compat[] __initconst = { diff --git a/arch/arm/mach-imx/mach-imx6sx.c b/arch/arm/mach-imx/mach-imx6sx.c index f17b7004c24b..6a0b0614de29 100644 --- a/arch/arm/mach-imx/mach-imx6sx.c +++ b/arch/arm/mach-imx/mach-imx6sx.c @@ -86,6 +86,7 @@ static void __init imx6sx_init_irq(void) imx_init_l2cache(); imx_src_init(); irqchip_init(); + imx6_pm_ccm_init("fsl,imx6sx-ccm"); } static void __init imx6sx_init_late(void) diff --git a/arch/arm/mach-imx/mach-imx7d.c b/arch/arm/mach-imx/mach-imx7d.c new file mode 100644 index 000000000000..4d4a19099a43 --- /dev/null +++ b/arch/arm/mach-imx/mach-imx7d.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/irqchip.h> +#include <linux/of_platform.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> + +#include "common.h" + +static void __init imx7d_init_machine(void) +{ + struct device *parent; + + parent = imx_soc_device_init(); + if (parent == NULL) + pr_warn("failed to initialize soc device\n"); + + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + imx_anatop_init(); +} + +static void __init imx7d_init_irq(void) +{ + imx_init_revision_from_anatop(); + imx_src_init(); + irqchip_init(); +} + +static const char *imx7d_dt_compat[] __initconst = { + "fsl,imx7d", + NULL, +}; + +DT_MACHINE_START(IMX7D, "Freescale i.MX7 Dual (Device Tree)") + .init_irq = imx7d_init_irq, + .init_machine = imx7d_init_machine, + .dt_compat = imx7d_dt_compat, +MACHINE_END diff --git a/arch/arm/mach-imx/mach-vf610.c b/arch/arm/mach-imx/mach-vf610.c index 2e7c75b66fe0..b20f6c14eda5 100644 --- a/arch/arm/mach-imx/mach-vf610.c +++ b/arch/arm/mach-imx/mach-vf610.c @@ -17,6 +17,7 @@ static const char * const vf610_dt_compat[] __initconst = { "fsl,vf510", "fsl,vf600", "fsl,vf610", + "fsl,vf610m4", NULL, }; diff --git a/arch/arm/mach-imx/mmdc.c b/arch/arm/mach-imx/mmdc.c index 0411f0664c15..db9621c718ec 100644 --- a/arch/arm/mach-imx/mmdc.c +++ b/arch/arm/mach-imx/mmdc.c @@ -17,6 +17,8 @@ #include <linux/of_address.h> #include <linux/of_device.h> +#include "common.h" + #define MMDC_MAPSR 0x404 #define BP_MMDC_MAPSR_PSD 0 #define BP_MMDC_MAPSR_PSS 4 diff --git a/arch/arm/mach-imx/mx27.h b/arch/arm/mach-imx/mx27.h index 8a65f192e7f3..f96bb2642677 100644 --- a/arch/arm/mach-imx/mx27.h +++ b/arch/arm/mach-imx/mx27.h @@ -231,8 +231,4 @@ #define MX27_DMA_REQ_SDHC3 36 #define MX27_DMA_REQ_NFC 37 -#ifndef __ASSEMBLY__ -extern int mx27_revision(void); -#endif - #endif /* ifndef __MACH_MX27_H__ */ diff --git a/arch/arm/mach-imx/mx3x.h b/arch/arm/mach-imx/mx3x.h index 96fb4fbc8ad7..6fec6114c2f1 100644 --- a/arch/arm/mach-imx/mx3x.h +++ b/arch/arm/mach-imx/mx3x.h @@ -185,11 +185,4 @@ #define MX3x_PROD_SIGNATURE 0x1 /* For MX31 */ -/* Mandatory defines used globally */ - -#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) -extern int mx35_revision(void); -extern int mx31_revision(void); -#endif - #endif /* ifndef __MACH_MX3x_H__ */ diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index 4c1343df2ba4..c4436d4fd6fd 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h @@ -1,5 +1,5 @@ /* - * Copyright 2004-2007, 2010 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2004-2007, 2010-2015 Freescale Semiconductor, Inc. * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) * * This program is free software; you can redistribute it and/or @@ -38,22 +38,7 @@ #define MXC_CPU_IMX6DL 0x61 #define MXC_CPU_IMX6SX 0x62 #define MXC_CPU_IMX6Q 0x63 - -#define IMX_CHIP_REVISION_1_0 0x10 -#define IMX_CHIP_REVISION_1_1 0x11 -#define IMX_CHIP_REVISION_1_2 0x12 -#define IMX_CHIP_REVISION_1_3 0x13 -#define IMX_CHIP_REVISION_1_4 0x14 -#define IMX_CHIP_REVISION_1_5 0x15 -#define IMX_CHIP_REVISION_2_0 0x20 -#define IMX_CHIP_REVISION_2_1 0x21 -#define IMX_CHIP_REVISION_2_2 0x22 -#define IMX_CHIP_REVISION_2_3 0x23 -#define IMX_CHIP_REVISION_3_0 0x30 -#define IMX_CHIP_REVISION_3_1 0x31 -#define IMX_CHIP_REVISION_3_2 0x32 -#define IMX_CHIP_REVISION_3_3 0x33 -#define IMX_CHIP_REVISION_UNKNOWN 0xff +#define MXC_CPU_IMX7D 0x72 #define IMX_DDR_TYPE_LPDDR2 1 @@ -185,6 +170,11 @@ static inline bool cpu_is_imx6q(void) return __mxc_cpu_type == MXC_CPU_IMX6Q; } +static inline bool cpu_is_imx7d(void) +{ + return __mxc_cpu_type == MXC_CPU_IMX7D; +} + struct cpu_op { u32 cpu_rate; }; diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c index f1f80ab73e69..0309ccda36a9 100644 --- a/arch/arm/mach-imx/pm-imx5.c +++ b/arch/arm/mach-imx/pm-imx5.c @@ -13,7 +13,14 @@ #include <linux/io.h> #include <linux/err.h> #include <linux/export.h> + +#include <linux/genalloc.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/of_platform.h> + #include <asm/cacheflush.h> +#include <asm/fncpy.h> #include <asm/system_misc.h> #include <asm/tlbflush.h> @@ -49,29 +56,91 @@ */ #define IMX5_DEFAULT_CPU_IDLE_STATE WAIT_UNCLOCKED_POWER_OFF +struct imx5_suspend_io_state { + u32 offset; + u32 clear; + u32 set; + u32 saved_value; +}; + struct imx5_pm_data { + phys_addr_t ccm_addr; phys_addr_t cortex_addr; phys_addr_t gpc_addr; + phys_addr_t m4if_addr; + phys_addr_t iomuxc_addr; + void (*suspend_asm)(void __iomem *ocram_vbase); + const u32 *suspend_asm_sz; + const struct imx5_suspend_io_state *suspend_io_config; + int suspend_io_count; +}; + +static const struct imx5_suspend_io_state imx53_suspend_io_config[] = { +#define MX53_DSE_HIGHZ_MASK (0x7 << 19) + {.offset = 0x584, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM0 */ + {.offset = 0x594, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM1 */ + {.offset = 0x560, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM2 */ + {.offset = 0x554, .clear = MX53_DSE_HIGHZ_MASK}, /* DQM3 */ + {.offset = 0x574, .clear = MX53_DSE_HIGHZ_MASK}, /* CAS */ + {.offset = 0x588, .clear = MX53_DSE_HIGHZ_MASK}, /* RAS */ + {.offset = 0x578, .clear = MX53_DSE_HIGHZ_MASK}, /* SDCLK_0 */ + {.offset = 0x570, .clear = MX53_DSE_HIGHZ_MASK}, /* SDCLK_1 */ + + {.offset = 0x580, .clear = MX53_DSE_HIGHZ_MASK}, /* SDODT0 */ + {.offset = 0x564, .clear = MX53_DSE_HIGHZ_MASK}, /* SDODT1 */ + {.offset = 0x57c, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS0 */ + {.offset = 0x590, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS1 */ + {.offset = 0x568, .clear = MX53_DSE_HIGHZ_MASK}, /* SDQS2 */ + {.offset = 0x558, .clear = MX53_DSE_HIGHZ_MASK}, /* SDSQ3 */ + {.offset = 0x6f0, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_ADDS */ + {.offset = 0x718, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_BODS */ + {.offset = 0x71c, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B1DS */ + {.offset = 0x728, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B2DS */ + {.offset = 0x72c, .clear = MX53_DSE_HIGHZ_MASK}, /* GRP_B3DS */ + + /* Controls the CKE signal which is required to leave self refresh */ + {.offset = 0x720, .clear = MX53_DSE_HIGHZ_MASK, .set = 1 << 19}, /* CTLDS */ }; static const struct imx5_pm_data imx51_pm_data __initconst = { + .ccm_addr = 0x73fd4000, .cortex_addr = 0x83fa0000, .gpc_addr = 0x73fd8000, }; static const struct imx5_pm_data imx53_pm_data __initconst = { + .ccm_addr = 0x53fd4000, .cortex_addr = 0x63fa0000, .gpc_addr = 0x53fd8000, + .m4if_addr = 0x63fd8000, + .iomuxc_addr = 0x53fa8000, + .suspend_asm = &imx53_suspend, + .suspend_asm_sz = &imx53_suspend_sz, + .suspend_io_config = imx53_suspend_io_config, + .suspend_io_count = ARRAY_SIZE(imx53_suspend_io_config), }; +#define MX5_MAX_SUSPEND_IOSTATE ARRAY_SIZE(imx53_suspend_io_config) + +/* + * This structure is for passing necessary data for low level ocram + * suspend code(arch/arm/mach-imx/suspend-imx53.S), if this struct + * definition is changed, the offset definition in that file + * must be also changed accordingly otherwise, the suspend to ocram + * function will be broken! + */ +struct imx5_cpu_suspend_info { + void __iomem *m4if_base; + void __iomem *iomuxc_base; + u32 io_count; + struct imx5_suspend_io_state io_state[MX5_MAX_SUSPEND_IOSTATE]; +} __aligned(8); + static void __iomem *ccm_base; static void __iomem *cortex_base; static void __iomem *gpc_base; - -void __init imx5_pm_set_ccm_base(void __iomem *base) -{ - ccm_base = base; -} +static void __iomem *suspend_ocram_base; +static void (*imx5_suspend_in_ocram_fn)(void __iomem *ocram_vbase); /* * set cpu low power mode before WFI instruction. This function is called @@ -161,8 +230,15 @@ static int mx5_suspend_enter(suspend_state_t state) /*clear the EMPGC0/1 bits */ __raw_writel(0, gpc_base + MXC_SRPG_EMPGC0_SRPGCR); __raw_writel(0, gpc_base + MXC_SRPG_EMPGC1_SRPGCR); + + if (imx5_suspend_in_ocram_fn) + imx5_suspend_in_ocram_fn(suspend_ocram_base); + else + cpu_do_idle(); + + } else { + cpu_do_idle(); } - cpu_do_idle(); /* return registers to default idle state */ mx5_cpu_lp_set(IMX5_DEFAULT_CPU_IDLE_STATE); @@ -194,6 +270,111 @@ static void imx5_pm_idle(void) imx5_cpu_do_idle(); } +static int __init imx_suspend_alloc_ocram( + size_t size, + void __iomem **virt_out, + phys_addr_t *phys_out) +{ + struct device_node *node; + struct platform_device *pdev; + struct gen_pool *ocram_pool; + unsigned long ocram_base; + void __iomem *virt; + phys_addr_t phys; + int ret = 0; + + /* Copied from imx6: TODO factorize */ + node = of_find_compatible_node(NULL, NULL, "mmio-sram"); + if (!node) { + pr_warn("%s: failed to find ocram node!\n", __func__); + return -ENODEV; + } + + pdev = of_find_device_by_node(node); + if (!pdev) { + pr_warn("%s: failed to find ocram device!\n", __func__); + ret = -ENODEV; + goto put_node; + } + + ocram_pool = dev_get_gen_pool(&pdev->dev); + if (!ocram_pool) { + pr_warn("%s: ocram pool unavailable!\n", __func__); + ret = -ENODEV; + goto put_node; + } + + ocram_base = gen_pool_alloc(ocram_pool, size); + if (!ocram_base) { + pr_warn("%s: unable to alloc ocram!\n", __func__); + ret = -ENOMEM; + goto put_node; + } + + phys = gen_pool_virt_to_phys(ocram_pool, ocram_base); + virt = __arm_ioremap_exec(phys, size, false); + if (phys_out) + *phys_out = phys; + if (virt_out) + *virt_out = virt; + +put_node: + of_node_put(node); + + return ret; +} + +static int __init imx5_suspend_init(const struct imx5_pm_data *soc_data) +{ + struct imx5_cpu_suspend_info *suspend_info; + int ret; + /* Need this to avoid compile error due to const typeof in fncpy.h */ + void (*suspend_asm)(void __iomem *) = soc_data->suspend_asm; + + if (!suspend_asm) + return 0; + + if (!soc_data->suspend_asm_sz || !*soc_data->suspend_asm_sz) + return -EINVAL; + + ret = imx_suspend_alloc_ocram( + *soc_data->suspend_asm_sz + sizeof(*suspend_info), + &suspend_ocram_base, NULL); + if (ret) + return ret; + + suspend_info = suspend_ocram_base; + + suspend_info->io_count = soc_data->suspend_io_count; + memcpy(suspend_info->io_state, soc_data->suspend_io_config, + sizeof(*suspend_info->io_state) * soc_data->suspend_io_count); + + suspend_info->m4if_base = ioremap(soc_data->m4if_addr, SZ_16K); + if (!suspend_info->m4if_base) { + ret = -ENOMEM; + goto failed_map_m4if; + } + + suspend_info->iomuxc_base = ioremap(soc_data->iomuxc_addr, SZ_16K); + if (!suspend_info->iomuxc_base) { + ret = -ENOMEM; + goto failed_map_iomuxc; + } + + imx5_suspend_in_ocram_fn = fncpy( + suspend_ocram_base + sizeof(*suspend_info), + suspend_asm, + *soc_data->suspend_asm_sz); + + return 0; + +failed_map_iomuxc: + iounmap(suspend_info->m4if_base); + +failed_map_m4if: + return ret; +} + static int __init imx5_pm_common_init(const struct imx5_pm_data *data) { int ret; @@ -208,6 +389,7 @@ static int __init imx5_pm_common_init(const struct imx5_pm_data *data) arm_pm_idle = imx5_pm_idle; + ccm_base = ioremap(data->ccm_addr, SZ_16K); cortex_base = ioremap(data->cortex_addr, SZ_16K); gpc_base = ioremap(data->gpc_addr, SZ_16K); WARN_ON(!ccm_base || !cortex_base || !gpc_base); @@ -219,6 +401,11 @@ static int __init imx5_pm_common_init(const struct imx5_pm_data *data) if (ret) pr_warn("%s: cpuidle init failed %d\n", __func__, ret); + ret = imx5_suspend_init(data); + if (ret) + pr_warn("%s: No DDR LPM support with suspend %d!\n", + __func__, ret); + suspend_set_ops(&mx5_suspend_ops); return 0; @@ -226,10 +413,12 @@ static int __init imx5_pm_common_init(const struct imx5_pm_data *data) void __init imx51_pm_init(void) { - imx5_pm_common_init(&imx51_pm_data); + if (IS_ENABLED(CONFIG_SOC_IMX51)) + imx5_pm_common_init(&imx51_pm_data); } void __init imx53_pm_init(void) { - imx5_pm_common_init(&imx53_pm_data); + if (IS_ENABLED(CONFIG_SOC_IMX53)) + imx5_pm_common_init(&imx53_pm_data); } diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index 6a7c6fc780cc..b01650d94f91 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -255,7 +255,7 @@ static void imx6q_enable_wb(bool enable) writel_relaxed(val, ccm_base + CCR); } -int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode) +int imx6_set_lpm(enum mxc_cpu_pwr_mode mode) { u32 val = readl_relaxed(ccm_base + CLPCR); @@ -340,7 +340,7 @@ static int imx6q_pm_enter(suspend_state_t state) { switch (state) { case PM_SUSPEND_STANDBY: - imx6q_set_lpm(STOP_POWER_ON); + imx6_set_lpm(STOP_POWER_ON); imx6q_set_int_mem_clk_lpm(true); imx_gpc_pre_suspend(false); if (cpu_is_imx6sl()) @@ -350,10 +350,10 @@ static int imx6q_pm_enter(suspend_state_t state) if (cpu_is_imx6sl()) imx6sl_set_wait_clk(false); imx_gpc_post_resume(); - imx6q_set_lpm(WAIT_CLOCKED); + imx6_set_lpm(WAIT_CLOCKED); break; case PM_SUSPEND_MEM: - imx6q_set_lpm(STOP_POWER_OFF); + imx6_set_lpm(STOP_POWER_OFF); imx6q_set_int_mem_clk_lpm(false); imx6q_enable_wb(true); /* @@ -373,7 +373,7 @@ static int imx6q_pm_enter(suspend_state_t state) imx6_enable_rbc(false); imx6q_enable_wb(false); imx6q_set_int_mem_clk_lpm(true); - imx6q_set_lpm(WAIT_CLOCKED); + imx6_set_lpm(WAIT_CLOCKED); break; default: return -EINVAL; @@ -392,11 +392,6 @@ static const struct platform_suspend_ops imx6q_pm_ops = { .valid = imx6q_pm_valid, }; -void __init imx6q_pm_set_ccm_base(void __iomem *base) -{ - ccm_base = base; -} - static int __init imx6_pm_get_base(struct imx6_pm_base *base, const char *compat) { @@ -482,8 +477,7 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata) /* * ccm physical address is not used by asm code currently, - * so get ccm virtual address directly, as we already have - * it from ccm driver. + * so get ccm virtual address directly. */ pm_info->ccm_base.vbase = ccm_base; @@ -568,7 +562,7 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata /* * This is for SW workaround step #1 of ERR007265, see comments - * in imx6q_set_lpm for details of this errata. + * in imx6_set_lpm for details of this errata. * Force IOMUXC irq pending, so that the interrupt to GPC can be * used to deassert dsm_request signal when the signal gets * asserted unexpectedly. @@ -579,6 +573,24 @@ static void __init imx6_pm_common_init(const struct imx6_pm_socdata IMX6Q_GPR1_GINT); } +void __init imx6_pm_ccm_init(const char *ccm_compat) +{ + struct device_node *np; + u32 val; + + np = of_find_compatible_node(NULL, NULL, ccm_compat); + ccm_base = of_iomap(np, 0); + BUG_ON(!ccm_base); + + /* + * Initialize CCM_CLPCR_LPM into RUN mode to avoid ARM core + * clock being shut down unexpectedly by WAIT mode. + */ + val = readl_relaxed(ccm_base + CLPCR); + val &= ~BM_CLPCR_LPM; + writel_relaxed(val, ccm_base + CLPCR); +} + void __init imx6q_pm_init(void) { imx6_pm_common_init(&imx6q_pm_data); diff --git a/arch/arm/mach-imx/suspend-imx53.S b/arch/arm/mach-imx/suspend-imx53.S new file mode 100644 index 000000000000..5ed078ad110a --- /dev/null +++ b/arch/arm/mach-imx/suspend-imx53.S @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2008-2011 Freescale Semiconductor, Inc. + */ +/* + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include <linux/linkage.h> + +#define M4IF_MCR0_OFFSET (0x008C) +#define M4IF_MCR0_FDVFS (0x1 << 11) +#define M4IF_MCR0_FDVACK (0x1 << 27) + + .align 3 + +/* + * ==================== low level suspend ==================== + * + * On entry + * r0: pm_info structure address; + * + * suspend ocram space layout: + * ======================== high address ====================== + * . + * . + * . + * ^ + * ^ + * ^ + * imx53_suspend code + * PM_INFO structure(imx53_suspend_info) + * ======================== low address ======================= + */ + +/* Offsets of members of struct imx53_suspend_info */ +#define SUSPEND_INFO_MX53_M4IF_V_OFFSET 0x0 +#define SUSPEND_INFO_MX53_IOMUXC_V_OFFSET 0x4 +#define SUSPEND_INFO_MX53_IO_COUNT_OFFSET 0x8 +#define SUSPEND_INFO_MX53_IO_STATE_OFFSET 0xc + +ENTRY(imx53_suspend) + stmfd sp!, {r4,r5,r6,r7} + + /* Save pad config */ + ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] + cmp r1, #0 + beq skip_pad_conf_1 + + add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET + ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] + +1: + ldr r5, [r2], #12 /* IOMUXC register offset */ + ldr r6, [r3, r5] /* current value */ + str r6, [r2], #4 /* save area */ + subs r1, r1, #1 + bne 1b + +skip_pad_conf_1: + /* Set FDVFS bit of M4IF_MCR0 to request DDR to enter self-refresh */ + ldr r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET] + ldr r2,[r1, #M4IF_MCR0_OFFSET] + orr r2, r2, #M4IF_MCR0_FDVFS + str r2,[r1, #M4IF_MCR0_OFFSET] + + /* Poll FDVACK bit of M4IF_MCR to wait for DDR to enter self-refresh */ +wait_sr_ack: + ldr r2,[r1, #M4IF_MCR0_OFFSET] + ands r2, r2, #M4IF_MCR0_FDVACK + beq wait_sr_ack + + /* Set pad config */ + ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] + cmp r1, #0 + beq skip_pad_conf_2 + + add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET + ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] + +2: + ldr r5, [r2], #4 /* IOMUXC register offset */ + ldr r6, [r2], #4 /* clear */ + ldr r7, [r3, r5] + bic r7, r7, r6 + ldr r6, [r2], #8 /* set */ + orr r7, r7, r6 + str r7, [r3, r5] + subs r1, r1, #1 + bne 2b + +skip_pad_conf_2: + /* Zzz, enter stop mode */ + wfi + nop + nop + nop + nop + + /* Restore pad config */ + ldr r1, [r0, #SUSPEND_INFO_MX53_IO_COUNT_OFFSET] + cmp r1, #0 + beq skip_pad_conf_3 + + add r2, r0, #SUSPEND_INFO_MX53_IO_STATE_OFFSET + ldr r3, [r0, #SUSPEND_INFO_MX53_IOMUXC_V_OFFSET] + +3: + ldr r5, [r2], #12 /* IOMUXC register offset */ + ldr r6, [r2], #4 /* saved value */ + str r6, [r3, r5] + subs r1, r1, #1 + bne 3b + +skip_pad_conf_3: + /* Clear FDVFS bit of M4IF_MCR0 to request DDR to exit self-refresh */ + ldr r1, [r0, #SUSPEND_INFO_MX53_M4IF_V_OFFSET] + ldr r2,[r1, #M4IF_MCR0_OFFSET] + bic r2, r2, #M4IF_MCR0_FDVFS + str r2,[r1, #M4IF_MCR0_OFFSET] + + /* Poll FDVACK bit of M4IF_MCR to wait for DDR to exit self-refresh */ +wait_ar_ack: + ldr r2,[r1, #M4IF_MCR0_OFFSET] + ands r2, r2, #M4IF_MCR0_FDVACK + bne wait_ar_ack + + /* Restore registers */ + ldmfd sp!, {r4,r5,r6,r7} + mov pc, lr + +ENDPROC(imx53_suspend) + +ENTRY(imx53_suspend_sz) + .word . - imx53_suspend diff --git a/arch/arm/mach-imx/time.c b/arch/arm/mach-imx/time.c deleted file mode 100644 index 15d18e198303..000000000000 --- a/arch/arm/mach-imx/time.c +++ /dev/null @@ -1,385 +0,0 @@ -/* - * linux/arch/arm/plat-mxc/time.c - * - * Copyright (C) 2000-2001 Deep Blue Solutions - * Copyright (C) 2002 Shane Nay (shane@minirl.com) - * Copyright (C) 2006-2007 Pavel Pisa (ppisa@pikron.com) - * Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de) - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/clockchips.h> -#include <linux/clk.h> -#include <linux/delay.h> -#include <linux/err.h> -#include <linux/sched_clock.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_irq.h> - -#include <asm/mach/time.h> - -#include "common.h" -#include "hardware.h" - -/* - * There are 2 versions of the timer hardware on Freescale MXC hardware. - * Version 1: MX1/MXL, MX21, MX27. - * Version 2: MX25, MX31, MX35, MX37, MX51 - */ - -/* defines common for all i.MX */ -#define MXC_TCTL 0x00 -#define MXC_TCTL_TEN (1 << 0) /* Enable module */ -#define MXC_TPRER 0x04 - -/* MX1, MX21, MX27 */ -#define MX1_2_TCTL_CLK_PCLK1 (1 << 1) -#define MX1_2_TCTL_IRQEN (1 << 4) -#define MX1_2_TCTL_FRR (1 << 8) -#define MX1_2_TCMP 0x08 -#define MX1_2_TCN 0x10 -#define MX1_2_TSTAT 0x14 - -/* MX21, MX27 */ -#define MX2_TSTAT_CAPT (1 << 1) -#define MX2_TSTAT_COMP (1 << 0) - -/* MX31, MX35, MX25, MX5, MX6 */ -#define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */ -#define V2_TCTL_CLK_IPG (1 << 6) -#define V2_TCTL_CLK_PER (2 << 6) -#define V2_TCTL_CLK_OSC_DIV8 (5 << 6) -#define V2_TCTL_FRR (1 << 9) -#define V2_TCTL_24MEN (1 << 10) -#define V2_TPRER_PRE24M 12 -#define V2_IR 0x0c -#define V2_TSTAT 0x08 -#define V2_TSTAT_OF1 (1 << 0) -#define V2_TCN 0x24 -#define V2_TCMP 0x10 - -#define V2_TIMER_RATE_OSC_DIV8 3000000 - -#define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) -#define timer_is_v2() (!timer_is_v1()) - -static struct clock_event_device clockevent_mxc; -static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED; - -static void __iomem *timer_base; - -static inline void gpt_irq_disable(void) -{ - unsigned int tmp; - - if (timer_is_v2()) - __raw_writel(0, timer_base + V2_IR); - else { - tmp = __raw_readl(timer_base + MXC_TCTL); - __raw_writel(tmp & ~MX1_2_TCTL_IRQEN, timer_base + MXC_TCTL); - } -} - -static inline void gpt_irq_enable(void) -{ - if (timer_is_v2()) - __raw_writel(1<<0, timer_base + V2_IR); - else { - __raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN, - timer_base + MXC_TCTL); - } -} - -static void gpt_irq_acknowledge(void) -{ - if (timer_is_v1()) { - if (cpu_is_mx1()) - __raw_writel(0, timer_base + MX1_2_TSTAT); - else - __raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, - timer_base + MX1_2_TSTAT); - } else if (timer_is_v2()) - __raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT); -} - -static void __iomem *sched_clock_reg; - -static u64 notrace mxc_read_sched_clock(void) -{ - return sched_clock_reg ? __raw_readl(sched_clock_reg) : 0; -} - -static struct delay_timer imx_delay_timer; - -static unsigned long imx_read_current_timer(void) -{ - return __raw_readl(sched_clock_reg); -} - -static int __init mxc_clocksource_init(struct clk *timer_clk) -{ - unsigned int c = clk_get_rate(timer_clk); - void __iomem *reg = timer_base + (timer_is_v2() ? V2_TCN : MX1_2_TCN); - - imx_delay_timer.read_current_timer = &imx_read_current_timer; - imx_delay_timer.freq = c; - register_current_timer_delay(&imx_delay_timer); - - sched_clock_reg = reg; - - sched_clock_register(mxc_read_sched_clock, 32, c); - return clocksource_mmio_init(reg, "mxc_timer1", c, 200, 32, - clocksource_mmio_readl_up); -} - -/* clock event */ - -static int mx1_2_set_next_event(unsigned long evt, - struct clock_event_device *unused) -{ - unsigned long tcmp; - - tcmp = __raw_readl(timer_base + MX1_2_TCN) + evt; - - __raw_writel(tcmp, timer_base + MX1_2_TCMP); - - return (int)(tcmp - __raw_readl(timer_base + MX1_2_TCN)) < 0 ? - -ETIME : 0; -} - -static int v2_set_next_event(unsigned long evt, - struct clock_event_device *unused) -{ - unsigned long tcmp; - - tcmp = __raw_readl(timer_base + V2_TCN) + evt; - - __raw_writel(tcmp, timer_base + V2_TCMP); - - return evt < 0x7fffffff && - (int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ? - -ETIME : 0; -} - -#ifdef DEBUG -static const char *clock_event_mode_label[] = { - [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC", - [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT", - [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN", - [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED", - [CLOCK_EVT_MODE_RESUME] = "CLOCK_EVT_MODE_RESUME", -}; -#endif /* DEBUG */ - -static void mxc_set_mode(enum clock_event_mode mode, - struct clock_event_device *evt) -{ - unsigned long flags; - - /* - * The timer interrupt generation is disabled at least - * for enough time to call mxc_set_next_event() - */ - local_irq_save(flags); - - /* Disable interrupt in GPT module */ - gpt_irq_disable(); - - if (mode != clockevent_mode) { - /* Set event time into far-far future */ - if (timer_is_v2()) - __raw_writel(__raw_readl(timer_base + V2_TCN) - 3, - timer_base + V2_TCMP); - else - __raw_writel(__raw_readl(timer_base + MX1_2_TCN) - 3, - timer_base + MX1_2_TCMP); - - /* Clear pending interrupt */ - gpt_irq_acknowledge(); - } - -#ifdef DEBUG - printk(KERN_INFO "mxc_set_mode: changing mode from %s to %s\n", - clock_event_mode_label[clockevent_mode], - clock_event_mode_label[mode]); -#endif /* DEBUG */ - - /* Remember timer mode */ - clockevent_mode = mode; - local_irq_restore(flags); - - switch (mode) { - case CLOCK_EVT_MODE_PERIODIC: - printk(KERN_ERR"mxc_set_mode: Periodic mode is not " - "supported for i.MX\n"); - break; - case CLOCK_EVT_MODE_ONESHOT: - /* - * Do not put overhead of interrupt enable/disable into - * mxc_set_next_event(), the core has about 4 minutes - * to call mxc_set_next_event() or shutdown clock after - * mode switching - */ - local_irq_save(flags); - gpt_irq_enable(); - local_irq_restore(flags); - break; - case CLOCK_EVT_MODE_SHUTDOWN: - case CLOCK_EVT_MODE_UNUSED: - case CLOCK_EVT_MODE_RESUME: - /* Left event sources disabled, no more interrupts appear */ - break; - } -} - -/* - * IRQ handler for the timer - */ -static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) -{ - struct clock_event_device *evt = &clockevent_mxc; - uint32_t tstat; - - if (timer_is_v2()) - tstat = __raw_readl(timer_base + V2_TSTAT); - else - tstat = __raw_readl(timer_base + MX1_2_TSTAT); - - gpt_irq_acknowledge(); - - evt->event_handler(evt); - - return IRQ_HANDLED; -} - -static struct irqaction mxc_timer_irq = { - .name = "i.MX Timer Tick", - .flags = IRQF_TIMER | IRQF_IRQPOLL, - .handler = mxc_timer_interrupt, -}; - -static struct clock_event_device clockevent_mxc = { - .name = "mxc_timer1", - .features = CLOCK_EVT_FEAT_ONESHOT, - .set_mode = mxc_set_mode, - .set_next_event = mx1_2_set_next_event, - .rating = 200, -}; - -static int __init mxc_clockevent_init(struct clk *timer_clk) -{ - if (timer_is_v2()) - clockevent_mxc.set_next_event = v2_set_next_event; - - clockevent_mxc.cpumask = cpumask_of(0); - clockevents_config_and_register(&clockevent_mxc, - clk_get_rate(timer_clk), - 0xff, 0xfffffffe); - - return 0; -} - -static void __init _mxc_timer_init(int irq, - struct clk *clk_per, struct clk *clk_ipg) -{ - uint32_t tctl_val; - - if (IS_ERR(clk_per)) { - pr_err("i.MX timer: unable to get clk\n"); - return; - } - - if (!IS_ERR(clk_ipg)) - clk_prepare_enable(clk_ipg); - - clk_prepare_enable(clk_per); - - /* - * Initialise to a known state (all timers off, and timing reset) - */ - - __raw_writel(0, timer_base + MXC_TCTL); - __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */ - - if (timer_is_v2()) { - tctl_val = V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN; - if (clk_get_rate(clk_per) == V2_TIMER_RATE_OSC_DIV8) { - tctl_val |= V2_TCTL_CLK_OSC_DIV8; - if (cpu_is_imx6dl() || cpu_is_imx6sx()) { - /* 24 / 8 = 3 MHz */ - __raw_writel(7 << V2_TPRER_PRE24M, - timer_base + MXC_TPRER); - tctl_val |= V2_TCTL_24MEN; - } - } else { - tctl_val |= V2_TCTL_CLK_PER; - } - } else { - tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; - } - - __raw_writel(tctl_val, timer_base + MXC_TCTL); - - /* init and register the timer to the framework */ - mxc_clocksource_init(clk_per); - mxc_clockevent_init(clk_per); - - /* Make irqs happen */ - setup_irq(irq, &mxc_timer_irq); -} - -void __init mxc_timer_init(void __iomem *base, int irq) -{ - struct clk *clk_per = clk_get_sys("imx-gpt.0", "per"); - struct clk *clk_ipg = clk_get_sys("imx-gpt.0", "ipg"); - - timer_base = base; - - _mxc_timer_init(irq, clk_per, clk_ipg); -} - -static void __init mxc_timer_init_dt(struct device_node *np) -{ - struct clk *clk_per, *clk_ipg; - int irq; - - if (timer_base) - return; - - timer_base = of_iomap(np, 0); - WARN_ON(!timer_base); - irq = irq_of_parse_and_map(np, 0); - - clk_ipg = of_clk_get_by_name(np, "ipg"); - - /* Try osc_per first, and fall back to per otherwise */ - clk_per = of_clk_get_by_name(np, "osc_per"); - if (IS_ERR(clk_per)) - clk_per = of_clk_get_by_name(np, "per"); - - _mxc_timer_init(irq, clk_per, clk_ipg); -} -CLOCKSOURCE_OF_DECLARE(mx1_timer, "fsl,imx1-gpt", mxc_timer_init_dt); -CLOCKSOURCE_OF_DECLARE(mx25_timer, "fsl,imx25-gpt", mxc_timer_init_dt); -CLOCKSOURCE_OF_DECLARE(mx50_timer, "fsl,imx50-gpt", mxc_timer_init_dt); -CLOCKSOURCE_OF_DECLARE(mx51_timer, "fsl,imx51-gpt", mxc_timer_init_dt); -CLOCKSOURCE_OF_DECLARE(mx53_timer, "fsl,imx53-gpt", mxc_timer_init_dt); -CLOCKSOURCE_OF_DECLARE(mx6q_timer, "fsl,imx6q-gpt", mxc_timer_init_dt); -CLOCKSOURCE_OF_DECLARE(mx6sl_timer, "fsl,imx6sl-gpt", mxc_timer_init_dt); -CLOCKSOURCE_OF_DECLARE(mx6sx_timer, "fsl,imx6sx-gpt", mxc_timer_init_dt); |