From patchwork Sat Mar 14 11:49:45 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jun Nie X-Patchwork-Id: 45818 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f69.google.com (mail-la0-f69.google.com [209.85.215.69]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 2CE96214BF for ; Sat, 14 Mar 2015 11:56:35 +0000 (UTC) Received: by labgq15 with SMTP id gq15sf20461808lab.0 for ; Sat, 14 Mar 2015 04:56:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:subject:date:message-id :in-reply-to:references:precedence:list-id:list-unsubscribe :list-archive:list-post:list-help:list-subscribe:mime-version :content-type:content-transfer-encoding:sender:errors-to :x-original-sender:x-original-authentication-results:mailing-list; bh=CCZTzyzjIpwVm25JTScJJN++aWD+QP7fMBoZ8xQc93Y=; b=CuHEXyPO5v/OAa2bKmIupVC1+B99uI6hS9+PKwFF6ulQdvl8Bw919nEJ3Gw1mRpk0y Bl66kIL+KAiS0QDz6MRoE98LyzhpKqjfBOFOCGFiUP7i3vfmoiUrNdh0/o2gPhJUAkGu jf3IyIVN25o3vdsosAj7DMyPOdAyCwax9NaMosA1YvGM6s7XWBV5ZxLhEPWpXkKZ45tX JqtzfkWSXPcPZqZ26lvgdWHCUn0WeNthduzApVZMCkSRMgErLsFI6Tgpl/3YIa6/svxb BFi0HLBjugcfO4xRBGDpxSJo5jim9XELrGL/BLYCBx5LtF+86Takggi0/yWh2fykB+jW Dp3w== X-Gm-Message-State: ALoCoQnozxXryWTxbquqNRGEzrz37UClCjhm8XUve7sZcQcfpVtW/XLuBns/6fC0F2Dp/KuoCK6v X-Received: by 10.180.75.232 with SMTP id f8mr11143414wiw.0.1426334193439; Sat, 14 Mar 2015 04:56:33 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.4.131 with SMTP id k3ls514517lak.21.gmail; Sat, 14 Mar 2015 04:56:33 -0700 (PDT) X-Received: by 10.152.120.202 with SMTP id le10mr32957852lab.115.1426334193141; Sat, 14 Mar 2015 04:56:33 -0700 (PDT) Received: from mail-lb0-f172.google.com (mail-lb0-f172.google.com. [209.85.217.172]) by mx.google.com with ESMTPS id a2si3371281lah.96.2015.03.14.04.56.33 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 14 Mar 2015 04:56:33 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.172 as permitted sender) client-ip=209.85.217.172; Received: by lbbsy1 with SMTP id sy1so5311062lbb.1 for ; Sat, 14 Mar 2015 04:56:33 -0700 (PDT) X-Received: by 10.152.116.11 with SMTP id js11mr25212117lab.106.1426334193013; Sat, 14 Mar 2015 04:56:33 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.35.133 with SMTP id h5csp1479004lbj; Sat, 14 Mar 2015 04:56:31 -0700 (PDT) X-Received: by 10.70.102.236 with SMTP id fr12mr41779788pdb.79.1426334190504; Sat, 14 Mar 2015 04:56:30 -0700 (PDT) Received: from bombadil.infradead.org (bombadil.infradead.org. [2001:1868:205::9]) by mx.google.com with ESMTPS id fj8si9444729pad.135.2015.03.14.04.56.29 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 14 Mar 2015 04:56:30 -0700 (PDT) Received-SPF: none (google.com: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org does not designate permitted sender hosts) client-ip=2001:1868:205::9; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YWkeE-00067t-VY; Sat, 14 Mar 2015 11:54:30 +0000 Received: from mail-pd0-f175.google.com ([209.85.192.175]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YWkaz-0003F6-2P for linux-arm-kernel@lists.infradead.org; Sat, 14 Mar 2015 11:51:12 +0000 Received: by pdbni2 with SMTP id ni2so10888911pdb.1 for ; Sat, 14 Mar 2015 04:50:48 -0700 (PDT) X-Received: by 10.66.161.161 with SMTP id xt1mr113545014pab.35.1426333848331; Sat, 14 Mar 2015 04:50:48 -0700 (PDT) Received: from localhost.localdomain ([107.6.112.156]) by mx.google.com with ESMTPSA id ov5sm7365488pdb.91.2015.03.14.04.50.44 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 14 Mar 2015 04:50:47 -0700 (PDT) From: Jun Nie To: linux-arm-kernel@lists.infradead.org, mturquette@linaro.org, linux@arm.linux.org.uk, shawn.guo@linaro.org, jun.nie@linaro.org, zte-lt@lists.linaro.org Subject: [PATCH 10/10] clk: zx: add zx296702 clock support Date: Sat, 14 Mar 2015 19:49:45 +0800 Message-Id: <1426333785-3952-11-git-send-email-jun.nie@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1426333785-3952-1-git-send-email-jun.nie@linaro.org> References: <1426333785-3952-1-git-send-email-jun.nie@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150314_045109_237234_CA9EED86 X-CRM114-Status: GOOD ( 19.91 ) X-Spam-Score: -0.7 (/) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (-0.7 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.192.175 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.192.175 listed in wl.mailspike.net] -0.0 SPF_PASS SPF: sender matches SPF record X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patch=linaro.org@lists.infradead.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: jun.nie@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.172 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 It adds a clock driver for zx296702 SoC to register the clock tree to Common Clock Framework. All the clocks of bus topology and some the peripheral clocks are ready with this commit. Some missing leaf clocks for peripherals will be added later when needed. Signed-off-by: Shawn Guo Signed-off-by: Jun Nie --- drivers/clk/Makefile | 1 + drivers/clk/zte/Makefile | 2 + drivers/clk/zte/clk-pll.c | 211 ++++++++++ drivers/clk/zte/clk-zx296702.c | 611 +++++++++++++++++++++++++++++ drivers/clk/zte/clk.h | 30 ++ include/dt-bindings/clock/zx296702-clock.h | 158 ++++++++ 6 files changed, 1013 insertions(+) create mode 100644 drivers/clk/zte/Makefile create mode 100644 drivers/clk/zte/clk-pll.c create mode 100644 drivers/clk/zte/clk-zx296702.c create mode 100644 drivers/clk/zte/clk.h create mode 100644 include/dt-bindings/clock/zx296702-clock.h diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index d478ceb..3b428bf 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -69,4 +69,5 @@ obj-$(CONFIG_ARCH_OMAP2PLUS) += ti/ obj-$(CONFIG_ARCH_U8500) += ux500/ obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/ obj-$(CONFIG_X86) += x86/ +obj-$(CONFIG_ARCH_ZX) += zte/ obj-$(CONFIG_ARCH_ZYNQ) += zynq/ diff --git a/drivers/clk/zte/Makefile b/drivers/clk/zte/Makefile new file mode 100644 index 0000000..95b707c --- /dev/null +++ b/drivers/clk/zte/Makefile @@ -0,0 +1,2 @@ +obj-y := clk-pll.o +obj-$(CONFIG_SOC_ZX296702) += clk-zx296702.o diff --git a/drivers/clk/zte/clk-pll.c b/drivers/clk/zte/clk-pll.c new file mode 100644 index 0000000..b8c6935 --- /dev/null +++ b/drivers/clk/zte/clk-pll.c @@ -0,0 +1,211 @@ +/* + * Copyright 2014 Linaro Ltd. + * Copyright (C) 2014 ZTE Corporation. + * + * 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 +#include +#include +#include +#include +#include + +#include "clk.h" + +#define to_clk_zx_pll(_hw) container_of(_hw, struct clk_zx_pll, hw) + +static int rate_to_idx(struct clk_zx_pll *zx_pll, unsigned long rate) +{ + const struct zx_pll_config *config = zx_pll->lookup_table; + int i; + + for (i = 0; i < zx_pll->count; i++) { + if (config[i].rate > rate) + return i > 0 ? i - 1 : 0; + + if (config[i].rate == rate) + return i; + } + + return i - 1; +} + +static int hw_to_idx(struct clk_zx_pll *zx_pll) +{ + const struct zx_pll_config *config = zx_pll->lookup_table; + u32 hw_cfg0, hw_cfg1; + unsigned long flags = 0; + int i; + + if (zx_pll->lock) + spin_lock_irqsave(zx_pll->lock, flags); + + hw_cfg0 = readl(zx_pll->reg_base); + hw_cfg1 = readl(zx_pll->reg_base + 4); + + if (zx_pll->lock) + spin_unlock_irqrestore(zx_pll->lock, flags); + + /* For matching the value in lookup table */ + hw_cfg0 &= ~BIT(30); /* clear lock bit */ + hw_cfg0 |= BIT(31); /* set PD bit */ + + for (i = 0; i < zx_pll->count; i++) { + if (hw_cfg0 == config[i].cfg0 && hw_cfg1 == config[i].cfg1) + return i; + } + + return -1; +} + +static unsigned long zx_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw); + int idx; + + idx = hw_to_idx(zx_pll); + if (unlikely(idx == -1)) + return 0; + + return zx_pll->lookup_table[idx].rate; +} + +static long zx_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw); + int idx; + + idx = rate_to_idx(zx_pll, rate); + + return zx_pll->lookup_table[idx].rate; +} + +static int zx_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + /* Assume current cpu is not running on current PLL */ + struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw); + const struct zx_pll_config *config; + unsigned long flags = 0; + int idx; + u32 reg; + + idx = rate_to_idx(zx_pll, rate); + config = &zx_pll->lookup_table[idx]; + + if (zx_pll->lock) + spin_lock_irqsave(zx_pll->lock, flags); + + writel(config->cfg0, zx_pll->reg_base); + writel(config->cfg1, zx_pll->reg_base + 4); + reg = readl(zx_pll->reg_base); + reg &= ~BIT(31); + writel(reg, zx_pll->reg_base); + while (!(readl(zx_pll->reg_base) & BIT(30))) + cpu_relax(); + + if (zx_pll->lock) + spin_unlock_irqrestore(zx_pll->lock, flags); + + return 0; +} + +static int zx_pll_enable(struct clk_hw *hw) +{ + struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw); + unsigned long flags = 0; + u32 reg; + + if (zx_pll->lock) + spin_lock_irqsave(zx_pll->lock, flags); + + reg = readl(zx_pll->reg_base); + writel(reg & ~BIT(31), zx_pll->reg_base); + while (!(readl(zx_pll->reg_base) & BIT(30))) + cpu_relax(); + + if (zx_pll->lock) + spin_unlock_irqrestore(zx_pll->lock, flags); + + return 0; +} + +static void zx_pll_disable(struct clk_hw *hw) +{ + struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw); + unsigned long flags = 0; + u32 reg; + + if (zx_pll->lock) + spin_lock_irqsave(zx_pll->lock, flags); + + reg = readl(zx_pll->reg_base); + writel(reg | BIT(31), zx_pll->reg_base); + + if (zx_pll->lock) + spin_unlock_irqrestore(zx_pll->lock, flags); +} + +static int zx_pll_is_enabled(struct clk_hw *hw) +{ + struct clk_zx_pll *zx_pll = to_clk_zx_pll(hw); + unsigned long flags = 0; + u32 reg; + + if (zx_pll->lock) + spin_lock_irqsave(zx_pll->lock, flags); + + reg = readl(zx_pll->reg_base); + + if (zx_pll->lock) + spin_unlock_irqrestore(zx_pll->lock, flags); + + return !(reg & BIT(31)); +} + +static const struct clk_ops zx_pll_ops = { + .recalc_rate = zx_pll_recalc_rate, + .round_rate = zx_pll_round_rate, + .set_rate = zx_pll_set_rate, + .enable = zx_pll_enable, + .disable = zx_pll_disable, + .is_enabled = zx_pll_is_enabled, +}; + +struct clk *clk_register_zx_pll(const char *name, const char *parent_name, + unsigned long flags, void __iomem *reg_base, + const struct zx_pll_config *lookup_table, int count, spinlock_t *lock) +{ + struct clk_zx_pll *zx_pll; + struct clk *clk; + struct clk_init_data init; + + zx_pll = kzalloc(sizeof(*zx_pll), GFP_KERNEL); + if (!zx_pll) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &zx_pll_ops; + init.flags = flags; + init.parent_names = (parent_name ? &parent_name : NULL); + init.num_parents = (parent_name ? 1 : 0); + + zx_pll->reg_base = reg_base; + zx_pll->lookup_table = lookup_table; + zx_pll->count = count; + zx_pll->lock = lock; + zx_pll->hw.init = &init; + + clk = clk_register(NULL, &zx_pll->hw); + + if (IS_ERR(clk)) + kfree(zx_pll); + + return clk; +} diff --git a/drivers/clk/zte/clk-zx296702.c b/drivers/clk/zte/clk-zx296702.c new file mode 100644 index 0000000..b76a6e8 --- /dev/null +++ b/drivers/clk/zte/clk-zx296702.c @@ -0,0 +1,611 @@ +/* + * Copyright 2014 Linaro Ltd. + * Copyright (C) 2014 ZTE Corporation. + * + * 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 +#include +#include +#include +#include "clk.h" + +static DEFINE_SPINLOCK(reg_lock); + +static void __iomem *topcrm_base; +static void __iomem *lsp0crpm_base; +static void __iomem *lsp1crpm_base; + +static struct clk *clk[ZX296702_CLK_END]; +static struct clk_onecell_data clk_data; + +#define CLK_MUX (topcrm_base + 0x04) +#define CLK_DIV (topcrm_base + 0x08) +#define CLK_EN0 (topcrm_base + 0x0c) +#define CLK_EN1 (topcrm_base + 0x10) +#define VOU_LOCAL_CLKEN (topcrm_base + 0x68) +#define VOU_LOCAL_CLKSEL (topcrm_base + 0x70) +#define VOU_LOCAL_DIV2_SET (topcrm_base + 0x74) +#define CLK_MUX1 (topcrm_base + 0x8c) + +#define CLK_UART0 (lsp1crpm_base + 0x20) +#define CLK_UART1 (lsp1crpm_base + 0x24) +#define CLK_SDMMC0 (lsp1crpm_base + 0x2c) +#define CLK_SDMMC1 (lsp0crpm_base + 0x0c) + +static const struct zx_pll_config pll_a9_config[] = { + { .rate = 700000000, .cfg0 = 0x800405d1, .cfg1 = 0x04555555 }, + { .rate = 800000000, .cfg0 = 0x80040691, .cfg1 = 0x04aaaaaa }, + { .rate = 900000000, .cfg0 = 0x80040791, .cfg1 = 0x04000000 }, + { .rate = 1000000000, .cfg0 = 0x80040851, .cfg1 = 0x04555555 }, + { .rate = 1100000000, .cfg0 = 0x80040911, .cfg1 = 0x04aaaaaa }, + { .rate = 1200000000, .cfg0 = 0x80040a11, .cfg1 = 0x04000000 }, +}; + +static const struct clk_div_table main_hlk_div[] = { + { .val = 1, .div = 2, }, + { .val = 3, .div = 4, }, + { /* sentinel */ } +}; + +static const struct clk_div_table a9_as1_aclk_divider[] = { + { .val = 0, .div = 1, }, + { .val = 1, .div = 2, }, + { .val = 3, .div = 4, }, + { /* sentinel */ } +}; + +static const struct clk_div_table sec_wclk_divider[] = { + { .val = 0, .div = 1, }, + { .val = 1, .div = 2, }, + { .val = 3, .div = 4, }, + { .val = 5, .div = 6, }, + { .val = 7, .div = 8, }, + { /* sentinel */ } +}; + +static const char const *matrix_aclk_sel[] = { + "pll_mm0_198M", + "osc", + "clk_148M5", + "pll_lsp_104M", +}; + +static const char const *a9_wclk_sel[] = { + "pll_a9", + "osc", + "clk_500", + "clk_250", +}; + +static const char const *a9_as1_aclk_sel[] = { + "clk_250", + "osc", + "pll_mm0_396M", + "pll_mac_333M", +}; + +static const char const *a9_trace_clkin_sel[] = { + "clk_74M25", + "pll_mm1_108M", + "clk_125", + "clk_148M5", +}; + +static const char const *decppu_aclk_sel[] = { + "clk_250", + "pll_mm0_198M", + "pll_lsp_104M", + "pll_audio_294M912", +}; + +static const char const *vou_main_wclk_sel[] = { + "clk_148M5", + "clk_74M25", + "clk_27", + "pll_mm1_54M", +}; + +static const char const *vou_scaler_wclk_sel[] = { + "clk_250", + "pll_mac_333M", + "pll_audio_294M912", + "pll_mm0_198M", +}; + +static const char const *r2d_wclk_sel[] = { + "pll_audio_294M912", + "pll_mac_333M", + "pll_a9_350M", + "pll_mm0_396M", +}; + +static const char const *ddr_wclk_sel[] = { + "pll_mac_333M", + "pll_ddr_266M", + "pll_audio_294M912", + "pll_mm0_198M", +}; + +static const char const *nand_wclk_sel[] = { + "pll_lsp_104M", + "osc", +}; + +static const char const *lsp_26_wclk_sel[] = { + "pll_lsp_26M", + "osc", +}; + +static const char const *vl0_sel[] = { + "vou_main_channel_div", + "vou_aux_channel_div", +}; + +static const char const *hdmi_sel[] = { + "vou_main_channel_wclk", + "vou_aux_channel_wclk", +}; + +static const char const *sdmmc0_wclk_sel[] = { + "lsp1_104M_wclk", + "lsp1_26M_wclk", +}; + +static const char const *sdmmc1_wclk_sel[] = { + "lsp0_104M_wclk", + "lsp0_26M_wclk", +}; + +static const char const *uart_wclk_sel[] = { + "lsp1_104M_wclk", + "lsp1_26M_wclk", +}; + +static inline struct clk *zx_divtbl(const char *name, const char *parent, + void __iomem *reg, u8 shift, u8 width, + const struct clk_div_table *table) +{ + return clk_register_divider_table(NULL, name, parent, 0, reg, shift, + width, 0, table, ®_lock); +} + +static inline struct clk *zx_div(const char *name, const char *parent, + void __iomem *reg, u8 shift, u8 width) +{ + return clk_register_divider(NULL, name, parent, 0, + reg, shift, width, 0, ®_lock); +} + +static inline struct clk *zx_mux(const char *name, const char **parents, + int num_parents, void __iomem *reg, u8 shift, u8 width) +{ + return clk_register_mux(NULL, name, parents, num_parents, + 0, reg, shift, width, 0, ®_lock); +} + +static inline struct clk *zx_gate(const char *name, const char *parent, + void __iomem *reg, u8 shift) +{ + return clk_register_gate(NULL, name, parent, CLK_IGNORE_UNUSED, + reg, shift, 0, ®_lock); +} + +static void __init zx296702_clocks_init(struct device_node *np) +{ + struct device_node *node; + int i; + + topcrm_base = of_iomap(np, 0); + WARN_ON(!topcrm_base); + + node = of_find_compatible_node(NULL, NULL, "zte,zx296702-lsp0crpm"); + lsp0crpm_base = of_iomap(node, 0); + WARN_ON(!lsp0crpm_base); + + node = of_find_compatible_node(NULL, NULL, "zte,zx296702-lsp1crpm"); + lsp1crpm_base = of_iomap(node, 0); + WARN_ON(!lsp1crpm_base); + + clk[ZX296702_OSC] = + clk_register_fixed_rate(NULL, "osc", NULL, CLK_IS_ROOT, + 30000000); + clk[ZX296702_PLL_A9] = + clk_register_zx_pll("pll_a9", "osc", 0, topcrm_base + + 0x01c, pll_a9_config, + ARRAY_SIZE(pll_a9_config), ®_lock); + + /* TODO: pll_a9_350M look like changeble follow a9 pll */ + clk[ZX296702_PLL_A9_350M] = + clk_register_fixed_rate(NULL, "pll_a9_350M", "osc", 0, + 350000000); + clk[ZX296702_PLL_MAC_1000M] = + clk_register_fixed_rate(NULL, "pll_mac_1000M", "osc", 0, + 1000000000); + clk[ZX296702_PLL_MAC_333M] = + clk_register_fixed_rate(NULL, "pll_mac_333M", "osc", 0, + 333000000); + clk[ZX296702_PLL_MM0_1188M] = + clk_register_fixed_rate(NULL, "pll_mm0_1188M", "osc", 0, + 1188000000); + clk[ZX296702_PLL_MM0_396M] = + clk_register_fixed_rate(NULL, "pll_mm0_396M", "osc", 0, + 396000000); + clk[ZX296702_PLL_MM0_198M] = + clk_register_fixed_rate(NULL, "pll_mm0_198M", "osc", 0, + 198000000); + clk[ZX296702_PLL_MM1_108M] = + clk_register_fixed_rate(NULL, "pll_mm1_108M", "osc", 0, + 108000000); + clk[ZX296702_PLL_MM1_72M] = + clk_register_fixed_rate(NULL, "pll_mm1_72M", "osc", 0, + 72000000); + clk[ZX296702_PLL_MM1_54M] = + clk_register_fixed_rate(NULL, "pll_mm1_54M", "osc", 0, + 54000000); + clk[ZX296702_PLL_LSP_104M] = + clk_register_fixed_rate(NULL, "pll_lsp_104M", "osc", 0, + 104000000); + clk[ZX296702_PLL_LSP_26M] = + clk_register_fixed_rate(NULL, "pll_lsp_26M", "osc", 0, + 26000000); + clk[ZX296702_PLL_DDR_266M] = + clk_register_fixed_rate(NULL, "pll_ddr_266M", "osc", 0, + 266000000); + clk[ZX296702_PLL_AUDIO_294M912] = + clk_register_fixed_rate(NULL, "pll_audio_294M912", "osc", 0, + 294912000); + + /* bus clock */ + clk[ZX296702_MATRIX_ACLK] = + zx_mux("matrix_aclk", matrix_aclk_sel, + ARRAY_SIZE(matrix_aclk_sel), CLK_MUX, 2, 2); + clk[ZX296702_MAIN_HCLK] = + zx_divtbl("main_hclk", "matrix_aclk", CLK_DIV, 0, 2, + main_hlk_div); + clk[ZX296702_MAIN_PCLK] = + zx_divtbl("main_pclk", "matrix_aclk", CLK_DIV, 2, 2, + main_hlk_div); + + /* cpu clock */ + clk[ZX296702_CLK_500] = + clk_register_fixed_factor(NULL, "clk_500", "pll_mac_1000M", 0, + 1, 2); + clk[ZX296702_CLK_250] = + clk_register_fixed_factor(NULL, "clk_250", "pll_mac_1000M", 0, + 1, 4); + clk[ZX296702_CLK_125] = + clk_register_fixed_factor(NULL, "clk_125", "clk_250", 0, 1, 2); + clk[ZX296702_CLK_148M5] = + clk_register_fixed_factor(NULL, "clk_148M5", "pll_mm0_1188M", 0, + 1, 8); + clk[ZX296702_CLK_74M25] = + clk_register_fixed_factor(NULL, "clk_74M25", "pll_mm0_1188M", 0, + 1, 16); + clk[ZX296702_A9_WCLK] = + zx_mux("a9_wclk", a9_wclk_sel, ARRAY_SIZE(a9_wclk_sel), CLK_MUX, + 0, 2); + clk[ZX296702_A9_AS1_ACLK_MUX] = + zx_mux("a9_as1_aclk_mux", a9_as1_aclk_sel, + ARRAY_SIZE(a9_as1_aclk_sel), CLK_MUX, 4, 2); + clk[ZX296702_A9_TRACE_CLKIN_MUX] = + zx_mux("a9_trace_clkin_mux", a9_trace_clkin_sel, + ARRAY_SIZE(a9_trace_clkin_sel), CLK_MUX1, 0, 2); + clk[ZX296702_A9_AS1_ACLK_DIV] = + zx_divtbl("a9_as1_aclk_div", "a9_as1_aclk_mux", CLK_DIV, 4, 2, + a9_as1_aclk_divider); + + /* multi-media clock */ + clk[ZX296702_CLK_2] = + clk_register_fixed_factor(NULL, "clk_2", "pll_mm1_72M", 0, + 1, 36); + clk[ZX296702_CLK_27] = + clk_register_fixed_factor(NULL, "clk_27", "pll_mm1_54M", 0, + 1, 2); + clk[ZX296702_DECPPU_ACLK_MUX] = + zx_mux("decppu_aclk_mux", decppu_aclk_sel, + ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 6, 2); + clk[ZX296702_PPU_ACLK_MUX] = + zx_mux("ppu_aclk_mux", decppu_aclk_sel, + ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 8, 2); + clk[ZX296702_MALI400_ACLK_MUX] = + zx_mux("mali400_aclk_mux", decppu_aclk_sel, + ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 12, 2); + clk[ZX296702_VOU_ACLK_MUX] = + zx_mux("vou_aclk_mux", decppu_aclk_sel, + ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 10, 2); + clk[ZX296702_VOU_MAIN_WCLK_MUX] = + zx_mux("vou_main_wclk_mux", vou_main_wclk_sel, + ARRAY_SIZE(vou_main_wclk_sel), CLK_MUX, 14, 2); + clk[ZX296702_VOU_AUX_WCLK_MUX] = + zx_mux("vou_aux_wclk_mux", vou_main_wclk_sel, + ARRAY_SIZE(vou_main_wclk_sel), CLK_MUX, 16, 2); + clk[ZX296702_VOU_SCALER_WCLK_MUX] = + zx_mux("vou_scaler_wclk_mux", vou_scaler_wclk_sel, + ARRAY_SIZE(vou_scaler_wclk_sel), CLK_MUX, + 18, 2); + clk[ZX296702_R2D_ACLK_MUX] = + zx_mux("r2d_aclk_mux", decppu_aclk_sel, + ARRAY_SIZE(decppu_aclk_sel), CLK_MUX, 20, 2); + clk[ZX296702_R2D_WCLK_MUX] = + zx_mux("r2d_wclk_mux", r2d_wclk_sel, + ARRAY_SIZE(r2d_wclk_sel), CLK_MUX, 22, 2); + + /* other clock */ + clk[ZX296702_CLK_50] = + clk_register_fixed_factor(NULL, "clk_50", "pll_mac_1000M", + 0, 1, 20); + clk[ZX296702_CLK_25] = + clk_register_fixed_factor(NULL, "clk_25", "pll_mac_1000M", + 0, 1, 40); + clk[ZX296702_CLK_12] = + clk_register_fixed_factor(NULL, "clk_12", "pll_mm1_72M", + 0, 1, 6); + clk[ZX296702_CLK_16M384] = + clk_register_fixed_factor(NULL, "clk_16M384", + "pll_audio_294M912", 0, 1, 18); + clk[ZX296702_CLK_32K768] = + clk_register_fixed_factor(NULL, "clk_32K768", "clk_16M384", + 0, 1, 500); + clk[ZX296702_SEC_WCLK_DIV] = + zx_divtbl("sec_wclk_div", "pll_lsp_104M", CLK_DIV, 6, 3, + sec_wclk_divider); + clk[ZX296702_DDR_WCLK_MUX] = + zx_mux("ddr_wclk_mux", ddr_wclk_sel, + ARRAY_SIZE(ddr_wclk_sel), CLK_MUX, 24, 2); + clk[ZX296702_NAND_WCLK_MUX] = + zx_mux("nand_wclk_mux", nand_wclk_sel, + ARRAY_SIZE(nand_wclk_sel), CLK_MUX, 24, 2); + clk[ZX296702_LSP_26_WCLK_MUX] = + zx_mux("lsp_26_wclk_mux", lsp_26_wclk_sel, + ARRAY_SIZE(lsp_26_wclk_sel), CLK_MUX, 27, 1); + + /* gates */ + clk[ZX296702_A9_AS0_ACLK] = + zx_gate("a9_as0_aclk", "matrix_aclk", CLK_EN0, 0); + clk[ZX296702_A9_AS1_ACLK] = + zx_gate("a9_as1_aclk", "a9_as1_aclk_div", CLK_EN0, 1); + clk[ZX296702_A9_TRACE_CLKIN] = + zx_gate("a9_trace_clkin", "a9_trace_clkin_mux", CLK_EN0, 2); + clk[ZX296702_DECPPU_AXI_M_ACLK] = + zx_gate("decppu_axi_m_aclk", "decppu_aclk_mux", CLK_EN0, 3); + clk[ZX296702_DECPPU_AHB_S_HCLK] = + zx_gate("decppu_ahb_s_hclk", "main_hclk", CLK_EN0, 4); + clk[ZX296702_PPU_AXI_M_ACLK] = + zx_gate("ppu_axi_m_aclk", "ppu_aclk_mux", CLK_EN0, 5); + clk[ZX296702_PPU_AHB_S_HCLK] = + zx_gate("ppu_ahb_s_hclk", "main_hclk", CLK_EN0, 6); + clk[ZX296702_VOU_AXI_M_ACLK] = + zx_gate("vou_axi_m_aclk", "vou_aclk_mux", CLK_EN0, 7); + clk[ZX296702_VOU_APB_PCLK] = + zx_gate("vou_apb_pclk", "main_pclk", CLK_EN0, 8); + clk[ZX296702_VOU_MAIN_CHANNEL_WCLK] = + zx_gate("vou_main_channel_wclk", "vou_main_wclk_mux", + CLK_EN0, 9); + clk[ZX296702_VOU_AUX_CHANNEL_WCLK] = + zx_gate("vou_aux_channel_wclk", "vou_aux_wclk_mux", + CLK_EN0, 10); + clk[ZX296702_VOU_HDMI_OSCLK_CEC] = + zx_gate("vou_hdmi_osclk_cec", "clk_2", CLK_EN0, 11); + clk[ZX296702_VOU_SCALER_WCLK] = + zx_gate("vou_scaler_wclk", "vou_scaler_wclk_mux", CLK_EN0, 12); + clk[ZX296702_MALI400_AXI_M_ACLK] = + zx_gate("mali400_axi_m_aclk", "mali400_aclk_mux", CLK_EN0, 13); + clk[ZX296702_MALI400_APB_PCLK] = + zx_gate("mali400_apb_pclk", "main_pclk", CLK_EN0, 14); + clk[ZX296702_R2D_WCLK] = + zx_gate("r2d_wclk", "r2d_wclk_mux", CLK_EN0, 15); + clk[ZX296702_R2D_AXI_M_ACLK] = + zx_gate("r2d_axi_m_aclk", "r2d_aclk_mux", CLK_EN0, 16); + clk[ZX296702_R2D_AHB_HCLK] = + zx_gate("r2d_ahb_hclk", "main_hclk", CLK_EN0, 17); + clk[ZX296702_DDR3_AXI_S0_ACLK] = + zx_gate("ddr3_axi_s0_aclk", "matrix_aclk", CLK_EN0, 18); + clk[ZX296702_DDR3_APB_PCLK] = + zx_gate("ddr3_apb_pclk", "main_pclk", CLK_EN0, 19); + clk[ZX296702_DDR3_WCLK] = + zx_gate("ddr3_wclk", "ddr_wclk_mux", CLK_EN0, 20); + clk[ZX296702_USB20_0_AHB_HCLK] = + zx_gate("usb20_0_ahb_hclk", "main_hclk", CLK_EN0, 21); + clk[ZX296702_USB20_0_EXTREFCLK] = + zx_gate("usb20_0_extrefclk", "clk_12", CLK_EN0, 22); + clk[ZX296702_USB20_1_AHB_HCLK] = + zx_gate("usb20_1_ahb_hclk", "main_hclk", CLK_EN0, 23); + clk[ZX296702_USB20_1_EXTREFCLK] = + zx_gate("usb20_1_extrefclk", "clk_12", CLK_EN0, 24); + clk[ZX296702_USB20_2_AHB_HCLK] = + zx_gate("usb20_2_ahb_hclk", "main_hclk", CLK_EN0, 25); + clk[ZX296702_USB20_2_EXTREFCLK] = + zx_gate("usb20_2_extrefclk", "clk_12", CLK_EN0, 26); + clk[ZX296702_GMAC_AXI_M_ACLK] = + zx_gate("gmac_axi_m_aclk", "matrix_aclk", CLK_EN0, 27); + clk[ZX296702_GMAC_APB_PCLK] = + zx_gate("gmac_apb_pclk", "main_pclk", CLK_EN0, 28); + clk[ZX296702_GMAC_125_CLKIN] = + zx_gate("gmac_125_clkin", "clk_125", CLK_EN0, 29); + clk[ZX296702_GMAC_RMII_CLKIN] = + zx_gate("gmac_rmii_clkin", "clk_50", CLK_EN0, 30); + clk[ZX296702_GMAC_25M_CLK] = + zx_gate("gmac_25M_clk", "clk_25", CLK_EN0, 31); + clk[ZX296702_NANDFLASH_AHB_HCLK] = + zx_gate("nandflash_ahb_hclk", "main_hclk", CLK_EN1, 0); + clk[ZX296702_NANDFLASH_WCLK] = + zx_gate("nandflash_wclk", "nand_wclk_mux", CLK_EN1, 1); + clk[ZX296702_LSP0_APB_PCLK] = + zx_gate("lsp0_apb_pclk", "main_pclk", CLK_EN1, 2); + clk[ZX296702_LSP0_AHB_HCLK] = + zx_gate("lsp0_ahb_hclk", "main_hclk", CLK_EN1, 3); + clk[ZX296702_LSP0_26M_WCLK] = + zx_gate("lsp0_26M_wclk", "lsp_26_wclk_mux", CLK_EN1, 4); + clk[ZX296702_LSP0_104M_WCLK] = + zx_gate("lsp0_104M_wclk", "pll_lsp_104M", CLK_EN1, 5); + clk[ZX296702_LSP0_16M384_WCLK] = + zx_gate("lsp0_16M384_wclk", "clk_16M384", CLK_EN1, 6); + /* FIXME: apb_pclk enable bit is bit7. We hack it as reserved 31 for + * UART does not work after parent clk is disabled/enabled */ + clk[ZX296702_LSP1_APB_PCLK] = + zx_gate("lsp1_apb_pclk", "main_pclk", CLK_EN1, 31); + clk[ZX296702_LSP1_26M_WCLK] = + zx_gate("lsp1_26M_wclk", "lsp_26_wclk_mux", CLK_EN1, 8); + clk[ZX296702_LSP1_104M_WCLK] = + zx_gate("lsp1_104M_wclk", "pll_lsp_104M", CLK_EN1, 9); + clk[ZX296702_LSP1_32K_CLK] = + zx_gate("lsp1_32K_clk", "clk_32K768", CLK_EN1, 10); + clk[ZX296702_AON_HCLK] = + zx_gate("aon_hclk", "main_hclk", CLK_EN1, 11); + clk[ZX296702_SYS_CTRL_PCLK] = + zx_gate("sys_ctrl_pclk", "main_pclk", CLK_EN1, 12); + clk[ZX296702_DMA_PCLK] = + zx_gate("dma_pclk", "main_pclk", CLK_EN1, 13); + clk[ZX296702_DMA_ACLK] = + zx_gate("dma_aclk", "matrix_aclk", CLK_EN1, 14); + clk[ZX296702_SEC_HCLK] = + zx_gate("sec_hclk", "main_hclk", CLK_EN1, 15); + clk[ZX296702_AES_WCLK] = + zx_gate("aes_wclk", "sec_wclk_div", CLK_EN1, 16); + clk[ZX296702_DES_WCLK] = + zx_gate("des_wclk", "sec_wclk_div", CLK_EN1, 17); + clk[ZX296702_IRAM_ACLK] = + zx_gate("iram_aclk", "matrix_aclk", CLK_EN1, 18); + clk[ZX296702_IROM_ACLK] = + zx_gate("irom_aclk", "matrix_aclk", CLK_EN1, 19); + clk[ZX296702_BOOT_CTRL_HCLK] = + zx_gate("boot_ctrl_hclk", "main_hclk", CLK_EN1, 20); + clk[ZX296702_EFUSE_CLK_30] = + zx_gate("efuse_clk_30", "osc", CLK_EN1, 21); + + /* TODO: add VOU Local clocks */ + clk[ZX296702_VOU_MAIN_CHANNEL_DIV] = + zx_div("vou_main_channel_div", "vou_main_channel_wclk", + VOU_LOCAL_DIV2_SET, 1, 1); + clk[ZX296702_VOU_AUX_CHANNEL_DIV] = + zx_div("vou_aux_channel_div", "vou_aux_channel_wclk", + VOU_LOCAL_DIV2_SET, 0, 1); + clk[ZX296702_VOU_TV_ENC_HD_DIV] = + zx_div("vou_tv_enc_hd_div", "vou_tv_enc_hd_mux", + VOU_LOCAL_DIV2_SET, 3, 1); + clk[ZX296702_VOU_TV_ENC_SD_DIV] = + zx_div("vou_tv_enc_sd_div", "vou_tv_enc_sd_mux", + VOU_LOCAL_DIV2_SET, 2, 1); + clk[ZX296702_VL0_MUX] = + zx_mux("vl0_mux", vl0_sel, ARRAY_SIZE(vl0_sel), + VOU_LOCAL_CLKSEL, 8, 1); + clk[ZX296702_VL1_MUX] = + zx_mux("vl1_mux", vl0_sel, ARRAY_SIZE(vl0_sel), + VOU_LOCAL_CLKSEL, 9, 1); + clk[ZX296702_VL2_MUX] = + zx_mux("vl2_mux", vl0_sel, ARRAY_SIZE(vl0_sel), + VOU_LOCAL_CLKSEL, 10, 1); + clk[ZX296702_GL0_MUX] = + zx_mux("gl0_mux", vl0_sel, ARRAY_SIZE(vl0_sel), + VOU_LOCAL_CLKSEL, 5, 1); + clk[ZX296702_GL1_MUX] = + zx_mux("gl1_mux", vl0_sel, ARRAY_SIZE(vl0_sel), + VOU_LOCAL_CLKSEL, 6, 1); + clk[ZX296702_GL2_MUX] = + zx_mux("gl2_mux", vl0_sel, ARRAY_SIZE(vl0_sel), + VOU_LOCAL_CLKSEL, 7, 1); + clk[ZX296702_WB_MUX] = + zx_mux("wb_mux", vl0_sel, ARRAY_SIZE(vl0_sel), + VOU_LOCAL_CLKSEL, 11, 1); + clk[ZX296702_HDMI_MUX] = + zx_mux("hdmi_mux", hdmi_sel, ARRAY_SIZE(hdmi_sel), + VOU_LOCAL_CLKSEL, 4, 1); + clk[ZX296702_VOU_TV_ENC_HD_MUX] = + zx_mux("vou_tv_enc_hd_mux", hdmi_sel, ARRAY_SIZE(hdmi_sel), + VOU_LOCAL_CLKSEL, 3, 1); + clk[ZX296702_VOU_TV_ENC_SD_MUX] = + zx_mux("vou_tv_enc_sd_mux", hdmi_sel, ARRAY_SIZE(hdmi_sel), + VOU_LOCAL_CLKSEL, 2, 1); + clk[ZX296702_VL0_CLK] = + zx_gate("vl0_clk", "vl0_mux", VOU_LOCAL_CLKEN, 8); + clk[ZX296702_VL1_CLK] = + zx_gate("vl1_clk", "vl1_mux", VOU_LOCAL_CLKEN, 9); + clk[ZX296702_VL2_CLK] = + zx_gate("vl2_clk", "vl2_mux", VOU_LOCAL_CLKEN, 10); + clk[ZX296702_GL0_CLK] = + zx_gate("gl0_clk", "gl0_mux", VOU_LOCAL_CLKEN, 5); + clk[ZX296702_GL1_CLK] = + zx_gate("gl1_clk", "gl1_mux", VOU_LOCAL_CLKEN, 6); + clk[ZX296702_GL2_CLK] = + zx_gate("gl2_clk", "gl2_mux", VOU_LOCAL_CLKEN, 7); + clk[ZX296702_WB_CLK] = + zx_gate("wb_clk", "wb_mux", VOU_LOCAL_CLKEN, 11); + clk[ZX296702_CL_CLK] = + zx_gate("cl_clk", "vou_main_channel_div", VOU_LOCAL_CLKEN, 12); + clk[ZX296702_MAIN_MIX_CLK] = + zx_gate("main_mix_clk", "vou_main_channel_div", + VOU_LOCAL_CLKEN, 4); + clk[ZX296702_AUX_MIX_CLK] = + zx_gate("aux_mix_clk", "vou_aux_channel_div", + VOU_LOCAL_CLKEN, 3); + clk[ZX296702_HDMI_CLK] = + zx_gate("hdmi_clk", "hdmi_mux", VOU_LOCAL_CLKEN, 2); + clk[ZX296702_VOU_TV_ENC_HD_DAC_CLK] = + zx_gate("vou_tv_enc_hd_dac_clk", "vou_tv_enc_hd_div", + VOU_LOCAL_CLKEN, 1); + clk[ZX296702_VOU_TV_ENC_SD_DAC_CLK] = + zx_gate("vou_tv_enc_sd_dac_clk", "vou_tv_enc_sd_div", + VOU_LOCAL_CLKEN, 0); + + /* UART0 */ + clk[ZX296702_UART0_WCLK_MUX] = + zx_mux("uart0_wclk_mux", uart_wclk_sel, + ARRAY_SIZE(uart_wclk_sel), CLK_UART0, 4, 1); + clk[ZX296702_UART0_WCLK] = + zx_gate("uart0_wclk", "uart0_wclk_mux", CLK_UART0, 1); + clk[ZX296702_UART0_PCLK] = + zx_gate("uart0_pclk", "lsp1_apb_pclk", CLK_UART0, 0); + + /* UART1 */ + clk[ZX296702_UART1_WCLK_MUX] = + zx_mux("uart1_wclk_mux", uart_wclk_sel, + ARRAY_SIZE(uart_wclk_sel), CLK_UART1, 4, 1); + clk[ZX296702_UART1_WCLK] = + zx_gate("uart1_wclk", "uart1_wclk_mux", CLK_UART1, 1); + clk[ZX296702_UART1_PCLK] = + zx_gate("uart1_pclk", "lsp1_apb_pclk", CLK_UART1, 0); + + /* SDMMC0 */ + clk[ZX296702_SDMMC0_WCLK_MUX] = + zx_mux("sdmmc0_wclk_mux", sdmmc0_wclk_sel, + ARRAY_SIZE(sdmmc0_wclk_sel), CLK_SDMMC0, 4, 1); + clk[ZX296702_SDMMC0_WCLK_DIV] = + zx_div("sdmmc0_wclk_div", "sdmmc0_wclk_mux", CLK_SDMMC0, 12, 4); + clk[ZX296702_SDMMC0_WCLK] = + zx_gate("sdmmc0_wclk", "sdmmc0_wclk_div", CLK_SDMMC0, 1); + clk[ZX296702_SDMMC0_PCLK] = + zx_gate("sdmmc0_pclk", "lsp1_apb_pclk", CLK_SDMMC0, 0); + + /* SDMMC1 */ + clk[ZX296702_SDMMC1_WCLK_MUX] = + zx_mux("sdmmc1_wclk_mux", sdmmc1_wclk_sel, + ARRAY_SIZE(sdmmc1_wclk_sel), CLK_SDMMC1, 4, 1); + clk[ZX296702_SDMMC1_WCLK_DIV] = + zx_div("sdmmc1_wclk_div", "sdmmc1_wclk_mux", CLK_SDMMC1, 12, 4); + clk[ZX296702_SDMMC1_WCLK] = + zx_gate("sdmmc1_wclk", "sdmmc1_wclk_div", CLK_SDMMC1, 1); + clk[ZX296702_SDMMC1_PCLK] = + zx_gate("sdmmc1_pclk", "lsp1_apb_pclk", CLK_SDMMC1, 0); + + /* CA9 PERIPHCLK = a9_wclk / 2 */ + clk[ZX296702_A9_PERIPHCLK] = + clk_register_fixed_factor(NULL, "a9_periphclk", "a9_wclk", + 0, 1, 2); + + for (i = 0; i < ARRAY_SIZE(clk); i++) { + if (IS_ERR(clk[i])) { + pr_err("zx296702 clk %d: register failed with %ld\n", + i, PTR_ERR(clk[i])); + return; + } + } + + 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(zx296702_clock, "zte,zx296702-topcrm", zx296702_clocks_init); diff --git a/drivers/clk/zte/clk.h b/drivers/clk/zte/clk.h new file mode 100644 index 0000000..419d93b --- /dev/null +++ b/drivers/clk/zte/clk.h @@ -0,0 +1,30 @@ +/* + * Copyright 2014 Linaro Ltd. + * Copyright (C) 2014 ZTE Corporation. + * + * 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. + */ + +#ifndef __ZTE_CLK_H +#define __ZTE_CLK_H + +struct zx_pll_config { + unsigned long rate; + u32 cfg0; + u32 cfg1; +}; + +struct clk_zx_pll { + struct clk_hw hw; + void __iomem *reg_base; + const struct zx_pll_config *lookup_table; /* order by rate asc */ + int count; + spinlock_t *lock; +}; + +struct clk *clk_register_zx_pll(const char *name, const char *parent_name, + unsigned long flags, void __iomem *reg_base, + const struct zx_pll_config *lookup_table, int count, spinlock_t *lock); +#endif diff --git a/include/dt-bindings/clock/zx296702-clock.h b/include/dt-bindings/clock/zx296702-clock.h new file mode 100644 index 0000000..c9a304b --- /dev/null +++ b/include/dt-bindings/clock/zx296702-clock.h @@ -0,0 +1,158 @@ +/* + * Copyright 2014 Linaro Ltd. + * Copyright (C) 2014 ZTE Corporation. + * + * 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. + */ + +#ifndef __DT_BINDINGS_CLOCK_ZX296702_H +#define __DT_BINDINGS_CLOCK_ZX296702_H + +#define ZX296702_OSC 0 +#define ZX296702_PLL_A9 1 +#define ZX296702_PLL_A9_350M 2 +#define ZX296702_PLL_MAC_1000M 3 +#define ZX296702_PLL_MAC_333M 4 +#define ZX296702_PLL_MM0_1188M 5 +#define ZX296702_PLL_MM0_396M 6 +#define ZX296702_PLL_MM0_198M 7 +#define ZX296702_PLL_MM1_108M 8 +#define ZX296702_PLL_MM1_72M 9 +#define ZX296702_PLL_MM1_54M 10 +#define ZX296702_PLL_LSP_104M 11 +#define ZX296702_PLL_LSP_26M 12 +#define ZX296702_PLL_AUDIO_294M912 13 +#define ZX296702_PLL_DDR_266M 14 +#define ZX296702_CLK_148M5 15 +#define ZX296702_MATRIX_ACLK 16 +#define ZX296702_MAIN_HCLK 17 +#define ZX296702_MAIN_PCLK 18 +#define ZX296702_CLK_500 19 +#define ZX296702_CLK_250 20 +#define ZX296702_CLK_125 21 +#define ZX296702_CLK_74M25 22 +#define ZX296702_A9_WCLK 23 +#define ZX296702_A9_AS1_ACLK_MUX 24 +#define ZX296702_A9_TRACE_CLKIN_MUX 25 +#define ZX296702_A9_AS1_ACLK_DIV 26 +#define ZX296702_CLK_2 27 +#define ZX296702_CLK_27 28 +#define ZX296702_DECPPU_ACLK_MUX 29 +#define ZX296702_PPU_ACLK_MUX 30 +#define ZX296702_MALI400_ACLK_MUX 31 +#define ZX296702_VOU_ACLK_MUX 32 +#define ZX296702_VOU_MAIN_WCLK_MUX 33 +#define ZX296702_VOU_AUX_WCLK_MUX 34 +#define ZX296702_VOU_SCALER_WCLK_MUX 35 +#define ZX296702_R2D_ACLK_MUX 36 +#define ZX296702_R2D_WCLK_MUX 37 +#define ZX296702_CLK_50 38 +#define ZX296702_CLK_25 39 +#define ZX296702_CLK_12 40 +#define ZX296702_CLK_16M384 41 +#define ZX296702_CLK_32K768 42 +#define ZX296702_SEC_WCLK_DIV 43 +#define ZX296702_DDR_WCLK_MUX 44 +#define ZX296702_NAND_WCLK_MUX 45 +#define ZX296702_LSP_26_WCLK_MUX 46 +#define ZX296702_A9_AS0_ACLK 47 +#define ZX296702_A9_AS1_ACLK 48 +#define ZX296702_A9_TRACE_CLKIN 49 +#define ZX296702_DECPPU_AXI_M_ACLK 50 +#define ZX296702_DECPPU_AHB_S_HCLK 51 +#define ZX296702_PPU_AXI_M_ACLK 52 +#define ZX296702_PPU_AHB_S_HCLK 53 +#define ZX296702_VOU_AXI_M_ACLK 54 +#define ZX296702_VOU_APB_PCLK 55 +#define ZX296702_VOU_MAIN_CHANNEL_WCLK 56 +#define ZX296702_VOU_AUX_CHANNEL_WCLK 57 +#define ZX296702_VOU_HDMI_OSCLK_CEC 58 +#define ZX296702_VOU_SCALER_WCLK 59 +#define ZX296702_MALI400_AXI_M_ACLK 60 +#define ZX296702_MALI400_APB_PCLK 61 +#define ZX296702_R2D_WCLK 62 +#define ZX296702_R2D_AXI_M_ACLK 63 +#define ZX296702_R2D_AHB_HCLK 64 +#define ZX296702_DDR3_AXI_S0_ACLK 65 +#define ZX296702_DDR3_APB_PCLK 66 +#define ZX296702_DDR3_WCLK 67 +#define ZX296702_USB20_0_AHB_HCLK 68 +#define ZX296702_USB20_0_EXTREFCLK 69 +#define ZX296702_USB20_1_AHB_HCLK 70 +#define ZX296702_USB20_1_EXTREFCLK 71 +#define ZX296702_USB20_2_AHB_HCLK 72 +#define ZX296702_USB20_2_EXTREFCLK 73 +#define ZX296702_GMAC_AXI_M_ACLK 74 +#define ZX296702_GMAC_APB_PCLK 75 +#define ZX296702_GMAC_125_CLKIN 76 +#define ZX296702_GMAC_RMII_CLKIN 77 +#define ZX296702_GMAC_25M_CLK 78 +#define ZX296702_NANDFLASH_AHB_HCLK 79 +#define ZX296702_NANDFLASH_WCLK 80 +#define ZX296702_LSP0_APB_PCLK 81 +#define ZX296702_LSP0_AHB_HCLK 82 +#define ZX296702_LSP0_26M_WCLK 83 +#define ZX296702_LSP0_104M_WCLK 84 +#define ZX296702_LSP0_16M384_WCLK 85 +#define ZX296702_LSP1_APB_PCLK 86 +#define ZX296702_LSP1_26M_WCLK 87 +#define ZX296702_LSP1_104M_WCLK 88 +#define ZX296702_LSP1_32K_CLK 89 +#define ZX296702_AON_HCLK 90 +#define ZX296702_SYS_CTRL_PCLK 91 +#define ZX296702_DMA_PCLK 92 +#define ZX296702_DMA_ACLK 93 +#define ZX296702_SEC_HCLK 94 +#define ZX296702_AES_WCLK 95 +#define ZX296702_DES_WCLK 96 +#define ZX296702_IRAM_ACLK 97 +#define ZX296702_IROM_ACLK 98 +#define ZX296702_BOOT_CTRL_HCLK 99 +#define ZX296702_EFUSE_CLK_30 100 +#define ZX296702_VOU_MAIN_CHANNEL_DIV 101 +#define ZX296702_VOU_AUX_CHANNEL_DIV 102 +#define ZX296702_VOU_TV_ENC_HD_DIV 103 +#define ZX296702_VOU_TV_ENC_SD_DIV 104 +#define ZX296702_VL0_MUX 105 +#define ZX296702_VL1_MUX 106 +#define ZX296702_VL2_MUX 107 +#define ZX296702_GL0_MUX 108 +#define ZX296702_GL1_MUX 109 +#define ZX296702_GL2_MUX 110 +#define ZX296702_WB_MUX 111 +#define ZX296702_HDMI_MUX 112 +#define ZX296702_VOU_TV_ENC_HD_MUX 113 +#define ZX296702_VOU_TV_ENC_SD_MUX 114 +#define ZX296702_VL0_CLK 115 +#define ZX296702_VL1_CLK 116 +#define ZX296702_VL2_CLK 117 +#define ZX296702_GL0_CLK 118 +#define ZX296702_GL1_CLK 119 +#define ZX296702_GL2_CLK 120 +#define ZX296702_WB_CLK 121 +#define ZX296702_CL_CLK 122 +#define ZX296702_MAIN_MIX_CLK 123 +#define ZX296702_AUX_MIX_CLK 124 +#define ZX296702_HDMI_CLK 125 +#define ZX296702_VOU_TV_ENC_HD_DAC_CLK 126 +#define ZX296702_VOU_TV_ENC_SD_DAC_CLK 127 +#define ZX296702_UART0_WCLK_MUX 128 +#define ZX296702_UART0_WCLK 129 +#define ZX296702_UART0_PCLK 130 +#define ZX296702_UART1_WCLK_MUX 131 +#define ZX296702_UART1_WCLK 132 +#define ZX296702_UART1_PCLK 133 +#define ZX296702_SDMMC0_WCLK_MUX 134 +#define ZX296702_SDMMC0_WCLK_DIV 135 +#define ZX296702_SDMMC0_WCLK 136 +#define ZX296702_SDMMC0_PCLK 137 +#define ZX296702_SDMMC1_WCLK_MUX 138 +#define ZX296702_SDMMC1_WCLK_DIV 139 +#define ZX296702_SDMMC1_WCLK 140 +#define ZX296702_SDMMC1_PCLK 141 +#define ZX296702_A9_PERIPHCLK 142 +#define ZX296702_CLK_END 143 + +#endif /* __DT_BINDINGS_CLOCK_ZX296702_H */