From patchwork Sun Oct 7 17:10:52 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Abraham X-Patchwork-Id: 1561851 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 62D18DFF71 for ; Sun, 7 Oct 2012 17:16:58 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TKuRF-0007Tj-ID; Sun, 07 Oct 2012 17:14:49 +0000 Received: from mail-pb0-f49.google.com ([209.85.160.49]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1TKuQT-0007IC-2p for linux-arm-kernel@lists.infradead.org; Sun, 07 Oct 2012 17:14:11 +0000 Received: by mail-pb0-f49.google.com with SMTP id xa7so3639009pbc.36 for ; Sun, 07 Oct 2012 10:13:59 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=u+XWYK4MOKK/Q/XgO9AUPobmfiUyIKSljVUKOs2vxTE=; b=LwR2kQQq6PolVdET9F5I4cTChTxHVIL0QQosg7HZ4FQC1zdZ7TE0fMtFLreXZMA5sj LZxBeX8DeKVNakOPaBLrgE+n4QMV9vVkd8sXLelAH49JegBRnqPYRDuqVk2wVhz8PhHE xdQNZV9H4C15TTOqlc4XFAXoFkNrmx4D4TbIV+pMSzd5F7+B68WN6BXK6QjnjiKgPGLw AGjBOgecUqB7f4sQIUnLvhPRCy57khVaN8i46mJXXN7IZS57EKxac05BhXnZWD2e1UiL GDRXQL0ru3QPIivAYTLkhduDIL7pRkLtHmTuWRyn9nCKKqladt6tcTsraacSbpjKfq/S aWLA== Received: by 10.68.225.3 with SMTP id rg3mr47122953pbc.27.1349630039400; Sun, 07 Oct 2012 10:13:59 -0700 (PDT) Received: from localhost.localdomain ([121.168.7.175]) by mx.google.com with ESMTPS id ky6sm9351514pbc.18.2012.10.07.10.13.56 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 07 Oct 2012 10:13:58 -0700 (PDT) From: Thomas Abraham To: linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org Subject: [PATCH v2 2/5] clk: exynos4: register clocks using common clock framework Date: Mon, 8 Oct 2012 02:10:52 +0900 Message-Id: <1349629855-4962-3-git-send-email-thomas.abraham@linaro.org> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1349629855-4962-1-git-send-email-thomas.abraham@linaro.org> References: <1349629855-4962-1-git-send-email-thomas.abraham@linaro.org> X-Gm-Message-State: ALoCoQmLy9Q7BCeHi07LrNHLEBjB2c5EWDsZ877S6SNm3Iblcx52EzXxiqkMhGas/e5ygAJ8jv3z X-Spam-Note: CRM114 invocation failed X-Spam-Score: -2.6 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.160.49 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: kgene.kim@samsung.com, mturquette@linaro.org, devicetree-discuss@lists.ozlabs.org, sylvester.nawrocki@gmail.com, t.figa@samsung.com, mturquette@ti.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org For legacy Exynos4 platforms, the available clocks are statically listed and then registered using the common clock framework. On device tree enabled exynos platfotms, the device tree is searched and all clock nodes found are registered. Support for Exynos4210 and Exynos4x12 platforms is included. Cc: Mike Turquette Cc: Kukjin Kim Signed-off-by: Thomas Abraham --- drivers/clk/samsung/Makefile | 1 + drivers/clk/samsung/clk-exynos4.c | 647 +++++++++++++++++++++++++++++++++++++ 2 files changed, 648 insertions(+), 0 deletions(-) create mode 100644 drivers/clk/samsung/clk-exynos4.c diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index 3f926b0..69487f7 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_PLAT_SAMSUNG) += clk.o +obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c new file mode 100644 index 0000000..e74b004 --- /dev/null +++ b/drivers/clk/samsung/clk-exynos4.c @@ -0,0 +1,647 @@ +/* + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * Copyright (c) 2012 Linaro Ltd. + * + * 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. + * + * Common Clock Framework support for all Exynos4 platforms + * ToDo: Remove all static instantiation of clocks after migrating all Exynos4 + * based boards to use device tree support. +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "clk.h" + +#define EXYNOS4_OP_MODE (S5P_VA_CHIPID + 8) + +/* base address of io remapped clock controller register space */ +static void __iomem *clk_base; + +static const char *pll_parent_names[] __initdata = { "fin_pll" }; +static const char *fin_pll_parents[] __initdata = { "xxti", "xusbxti" }; +static const char *mout_apll_parents[] __initdata = { "fin_pll", "fout_apll", }; +static const char *mout_mpll_parents[] __initdata = { "fin_pll", "fout_mpll", }; +static const char *mout_epll_parents[] __initdata = { "fin_pll", "fout_epll", }; + +static const char *sclk_ampll_parents[] __initdata = { + "mout_mpll", "sclk_apll", }; + +static const char *sclk_evpll_parents[] __initdata = { + "mout_epll", "mout_vpll", }; + +static const char *mout_core_parents[] __initdata = { + "mout_apll", "mout_mpll", }; + +static const char *mout_mfc_parents[] __initdata = { + "mout_mfc0", "mout_mfc1", }; + +static const char *mout_dac_parents[] __initdata = { + "mout_vpll", "sclk_hdmiphy", }; + +static const char *mout_hdmi_parents[] __initdata = { + "sclk_pixel", "sclk_hdmiphy", }; + +static const char *mout_mixer_parents[] __initdata = { + "sclk_dac", "sclk_hdmi", }; + +static const char *group1_parents[] __initdata = { + "xxti", "xusbxti", "sclk_hdmi24m", "sclk_usbphy0", + "none", "sclk_hdmiphy", "mout_mpll", "mout_epll", + "mout_vpll" }; + +static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] = { + FRATE_CLK(NULL, "xxti", NULL, CLK_IS_ROOT, 24000000), + FRATE_CLK(NULL, "xusbxti", NULL, CLK_IS_ROOT, 24000000), + FRATE_CLK(NULL, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000), + FRATE_CLK(NULL, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000), + FRATE_CLK(NULL, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000), +}; + +static struct samsung_mux_clock exynos4_mux_clks[] = { + MUXCLK(NULL, "fin_pll", fin_pll_parents, 0, + EXYNOS4_OP_MODE, 0, 1, 0), + MUXCLK(NULL, "mout_apll", mout_apll_parents, 0, + EXYNOS4_CLKSRC_CPU, 0, 1, 0), + MUXCLK(NULL, "mout_epll", mout_epll_parents, 0, + EXYNOS4_CLKSRC_TOP0, 4, 1, 0), + MUXCLK(NULL, "mout_core", mout_core_parents, 0, + EXYNOS4_CLKSRC_CPU, 16, 1, 0), + MUXCLK(NULL, "mout_aclk_200", sclk_ampll_parents, 0, + EXYNOS4_CLKSRC_TOP0, 12, 1, 0), + MUXCLK(NULL, "mout_aclk_100", sclk_ampll_parents, 0, + EXYNOS4_CLKSRC_TOP0, 16, 1, 0), + MUXCLK(NULL, "mout_aclk_160", sclk_ampll_parents, 0, + EXYNOS4_CLKSRC_TOP0, 20, 1, 0), + MUXCLK(NULL, "mout_aclk_133", sclk_ampll_parents, 0, + EXYNOS4_CLKSRC_TOP0, 24, 1, 0), + MUXCLK("exynos4210-uart.0", "mout_uart0", group1_parents, 0, + EXYNOS4_CLKSRC_PERIL0, 0, 4, 0), + MUXCLK("exynos4210-uart.1", "mout_uart1", group1_parents, 0, + EXYNOS4_CLKSRC_PERIL0, 4, 4, 0), + MUXCLK("exynos4210-uart.2", "mout_uart2", group1_parents, 0, + EXYNOS4_CLKSRC_PERIL0, 8, 4, 0), + MUXCLK("exynos4210-uart.3", "mout_uart3", group1_parents, 0, + EXYNOS4_CLKSRC_PERIL0, 12, 4, 0), + MUXCLK("exynos4-sdhci.0", "mout_mmc0", group1_parents, 0, + EXYNOS4_CLKSRC_FSYS, 0, 4, 0), + MUXCLK("exynos4-sdhci.1", "mout_mmc1", group1_parents, 0, + EXYNOS4_CLKSRC_FSYS, 4, 4, 0), + MUXCLK("exynos4-sdhci.1", "mout_mmc2", group1_parents, 0, + EXYNOS4_CLKSRC_FSYS, 8, 4, 0), + MUXCLK("exynos4-sdhci.1", "mout_mmc3", group1_parents, 0, + EXYNOS4_CLKSRC_FSYS, 12, 4, 0), + MUXCLK("exynos4210-spi.0", "mout_spi0", group1_parents, 0, + EXYNOS4_CLKSRC_PERIL1, 16, 4, 0), + MUXCLK("exynos4210-spi.1", "mout_spi1", group1_parents, 0, + EXYNOS4_CLKSRC_PERIL1, 20, 4, 0), + MUXCLK("exynos4210-spi.2", "mout_spi2", group1_parents, 0, + EXYNOS4_CLKSRC_PERIL1, 24, 4, 0), + MUXCLK(NULL, "mout_sata", sclk_ampll_parents, 0, + EXYNOS4_CLKSRC_FSYS, 24, 1, 0), + MUXCLK(NULL, "mout_mfc0", sclk_ampll_parents, 0, + EXYNOS4_CLKSRC_MFC, 0, 1, 0), + MUXCLK(NULL, "mout_mfc1", sclk_evpll_parents, 0, + EXYNOS4_CLKSRC_MFC, 4, 1, 0), + MUXCLK("s5p-mfc", "mout_mfc", mout_mfc_parents, 0, + EXYNOS4_CLKSRC_MFC, 8, 1, 0), + MUXCLK("s5p-mipi-csis.0", "mout_csis0", group1_parents, 0, + EXYNOS4_CLKSRC_CAM, 24, 4, 0), + MUXCLK("s5p-mipi-csis.1", "mout_csis1", group1_parents, 0, + EXYNOS4_CLKSRC_CAM, 28, 4, 0), + MUXCLK(NULL, "mout_cam0", group1_parents, 0, + EXYNOS4_CLKSRC_CAM, 16, 4, 0), + MUXCLK(NULL, "mout_cam1", group1_parents, 0, + EXYNOS4_CLKSRC_CAM, 20, 4, 0), + MUXCLK("exynos4-fimc.0", "mout_fimc0", group1_parents, 0, + EXYNOS4_CLKSRC_CAM, 0, 4, 0), + MUXCLK("exynos4-fimc.1", "mout_fimc1", group1_parents, 0, + EXYNOS4_CLKSRC_CAM, 4, 4, 0), + MUXCLK("exynos4-fimc.2", "mout_fimc2", group1_parents, 0, + EXYNOS4_CLKSRC_CAM, 8, 4, 0), + MUXCLK("exynos4-fimc.3", "mout_fimc3", group1_parents, 0, + EXYNOS4_CLKSRC_CAM, 12, 4, 0), + MUXCLK("exynos4-fb.0", "mout_fimd0", group1_parents, 0, + EXYNOS4_CLKSRC_LCD0, 0, 4, 0), + MUXCLK(NULL, "sclk_dac", mout_dac_parents, 0, + EXYNOS4_CLKSRC_TV, 8, 1, 0), + MUXCLK(NULL, "sclk_hdmi", mout_hdmi_parents, 0, + EXYNOS4_CLKSRC_TV, 0, 1, 0), + MUXCLK(NULL, "sclk_mixer", mout_mixer_parents, 0, + EXYNOS4_CLKSRC_TV, 4, 1, 0), +}; + +static struct samsung_div_clock exynos4_div_clks[] = { + DIVCLK(NULL, "sclk_apll", "mout_apll", 0, + EXYNOS4_CLKDIV_CPU, 24, 3, 0), + DIVCLK(NULL, "div_core", "mout_core", 0, + EXYNOS4_CLKDIV_CPU, 0, 3, 0), + DIVCLK(NULL, "armclk", "div_core", 0, + EXYNOS4_CLKDIV_CPU, 28, 3, 0), + DIVCLK(NULL, "aclk_200", "mout_aclk_200", 0, + EXYNOS4_CLKDIV_TOP, 0, 3, 0), + DIVCLK(NULL, "aclk_100", "mout_aclk_100", 0, + EXYNOS4_CLKDIV_TOP, 4, 4, 0), + DIVCLK(NULL, "aclk_160", "mout_aclk_160", 0, + EXYNOS4_CLKDIV_TOP, 8, 3, 0), + DIVCLK(NULL, "aclk_133", "mout_aclk_133", 0, + EXYNOS4_CLKDIV_TOP, 12, 3, 0), + DIVCLK("exynos4210-uart.0", "div_uart0", "mout_uart0", 0, + EXYNOS4_CLKDIV_PERIL0, 0, 4, 0), + DIVCLK("exynos4210-uart.1", "div_uart1", "mout_uart1", 0, + EXYNOS4_CLKDIV_PERIL0, 4, 4, 0), + DIVCLK("exynos4210-uart.2", "div_uart2", "mout_uart2", 0, + EXYNOS4_CLKDIV_PERIL0, 8, 4, 0), + DIVCLK("exynos4210-uart.3", "div_uart3", "mout_uart3", 0, + EXYNOS4_CLKDIV_PERIL0, 12, 4, 0), + DIVCLK("exynos4-sdhci.0", "div_mmc0", "mout_mmc0", 0, + EXYNOS4_CLKDIV_FSYS1, 0, 4, 0), + DIVCLK("exynos4-sdhci.0", "div_mmc0_pre", "div_mmc0", 0, + EXYNOS4_CLKDIV_FSYS1, 8, 8, 0), + DIVCLK("exynos4-sdhci.1", "div_mmc1", "mout_mmc1", 0, + EXYNOS4_CLKDIV_FSYS1, 16, 4, 0), + DIVCLK("exynos4-sdhci.1", "div_mmc1_pre", "div_mmc1", 0, + EXYNOS4_CLKDIV_FSYS1, 24, 8, 0), + DIVCLK("exynos4-sdhci.2", "div_mmc2", "mout_mmc2", 0, + EXYNOS4_CLKDIV_FSYS2, 0, 4, 0), + DIVCLK("exynos4-sdhci.2", "div_mmc2_pre", "div_mmc2", 0, + EXYNOS4_CLKDIV_FSYS2, 8, 8, 0), + DIVCLK("exynos4-sdhci.3", "div_mmc3", "mout_mmc3", 0, + EXYNOS4_CLKDIV_FSYS2, 16, 4, 0), + DIVCLK("exynos4-sdhci.3", "div_mmc3_pre", "div_mmc3", 0, + EXYNOS4_CLKDIV_FSYS2, 24, 8, 0), + DIVCLK("exynos4210-spi.0", "div_spi0", "mout_spi0", 0, + EXYNOS4_CLKDIV_PERIL1, 0, 4, 0), + DIVCLK("exynos4210-spi.1", "div_spi1", "mout_spi1", 0, + EXYNOS4_CLKDIV_PERIL1, 16, 4, 0), + DIVCLK("exynos4210-spi.2", "div_spi2", "mout_spi2", 0, + EXYNOS4_CLKDIV_PERIL2, 0, 4, 0), + DIVCLK("exynos4210-spi.0", "div_spi0_pre", "div_spi0", 0, + EXYNOS4_CLKDIV_PERIL1, 8, 8, 0), + DIVCLK("exynos4210-spi.1", "div_spi1_pre", "div_spi1", 0, + EXYNOS4_CLKDIV_PERIL1, 24, 8, 0), + DIVCLK("exynos4210-spi.2", "div_spi2_pre", "div_spi2", 0, + EXYNOS4_CLKDIV_PERIL2, 8, 8, 0), + DIVCLK(NULL, "div_sata", "mout_sata", 0, + EXYNOS4_CLKDIV_FSYS0, 20, 4, 0), + DIVCLK("s5p-mfc", "div_mfc", "mout_mfc", 0, + EXYNOS4_CLKDIV_MFC, 0, 4, 0), + DIVCLK("s5p-mipi-csis.0", "div_csis0", "mout_csis0", 0, + EXYNOS4_CLKDIV_CAM, 24, 4, 0), + DIVCLK("s5p-mipi-csis.1", "div_csis1", "mout_csis1", 0, + EXYNOS4_CLKDIV_CAM, 28, 4, 0), + DIVCLK(NULL, "div_cam0", "mout_cam0", 0, + EXYNOS4_CLKDIV_CAM, 16, 4, 0), + DIVCLK(NULL, "div_cam1", "mout_cam1", 0, + EXYNOS4_CLKDIV_CAM, 20, 4, 0), + DIVCLK("exynos4-fimc.0", "div_fimc0", "mout_fimc0", 0, + EXYNOS4_CLKDIV_CAM, 0, 4, 0), + DIVCLK("exynos4-fimc.1", "div_fimc1", "mout_fimc1", 0, + EXYNOS4_CLKDIV_CAM, 4, 4, 0), + DIVCLK("exynos4-fimc.2", "div_fimc2", "mout_fimc2", 0, + EXYNOS4_CLKDIV_CAM, 4, 4, 0), + DIVCLK("exynos4-fimc.3", "div_fimc3", "mout_fimc3", 0, + EXYNOS4_CLKDIV_CAM, 4, 4, 0), + DIVCLK("exynos4-fb.0", "div_fimd0", "mout_fimd0", 0, + EXYNOS4_CLKDIV_LCD0, 0, 4, 0), + DIVCLK(NULL, "sclk_pixel", "mout_vpll", 0, + EXYNOS4_CLKDIV_TV, 0, 4, 0), +}; + +struct samsung_gate_clock exynos4_gate_clks[] = { + GATECLK("exynos4210-uart.0", "uart0", "aclk_100", CLK_SET_RATE_PARENT, + EXYNOS4_CLKGATE_IP_PERIL, 0, "uart"), + GATECLK("exynos4210-uart.1", "uart1", "aclk_100", CLK_SET_RATE_PARENT, + EXYNOS4_CLKGATE_IP_PERIL, 1, "uart"), + GATECLK("exynos4210-uart.2", "uart2", "aclk_100", CLK_SET_RATE_PARENT, + EXYNOS4_CLKGATE_IP_PERIL, 2, "uart"), + GATECLK("exynos4210-uart.3", "uart3", "aclk_100", CLK_SET_RATE_PARENT, + EXYNOS4_CLKGATE_IP_PERIL, 3, "uart"), + GATECLK("exynos4210-uart.4", "uart4", "aclk_100", CLK_SET_RATE_PARENT, + EXYNOS4_CLKGATE_IP_PERIL, 4, "uart"), + GATECLK("exynos4210-uart.5", "uart5", "aclk_100", CLK_SET_RATE_PARENT, + EXYNOS4_CLKGATE_IP_PERIL, 5, "uart"), + GATECLK("exynos4210-uart.0", "uclk0", "div_uart0", CLK_SET_RATE_PARENT, + EXYNOS4_CLKSRC_MASK_PERIL0, 0, "clk_uart_baud0"), + GATECLK("exynos4210-uart.1", "uclk1", "div_uart1", CLK_SET_RATE_PARENT, + EXYNOS4_CLKSRC_MASK_PERIL0, 4, "clk_uart_baud0"), + GATECLK("exynos4210-uart.2", "uclk2", "div_uart2", CLK_SET_RATE_PARENT, + EXYNOS4_CLKSRC_MASK_PERIL0, 8, "clk_uart_baud0"), + GATECLK("exynos4210-uart.3", "uclk3", "div_uart3", CLK_SET_RATE_PARENT, + EXYNOS4_CLKSRC_MASK_PERIL0, 12, "clk_uart_baud0"), + GATECLK(NULL, "timers", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 24, NULL), + GATECLK("s5p-mipi-csis.0", "csis", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_CAM, 5, NULL), + GATECLK(NULL, "jpeg", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_CAM, 6, NULL), + GATECLK("exynos4-fimc.0", "fimc0", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_CAM, 0, "fimc"), + GATECLK("exynos4-fimc.1", "fimc1", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_CAM, 1, "fimc"), + GATECLK("exynos4-fimc.2", "fimc2", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_CAM, 2, "fimc"), + GATECLK("exynos4-fimc.3", "fimc3", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_CAM, 3, "fimc"), + GATECLK("exynos4-sdhci.0", "hsmmc0", "aclk_133", 0, + EXYNOS4_CLKGATE_IP_FSYS, 5, "hsmmc"), + GATECLK("exynos4-sdhci.1", "hsmmc1", "aclk_133", 0, + EXYNOS4_CLKGATE_IP_FSYS, 6, "hsmmc"), + GATECLK("exynos4-sdhci.2", "hsmmc2", "aclk_133", 0, + EXYNOS4_CLKGATE_IP_FSYS, 7, "hsmmc"), + GATECLK("exynos4-sdhci.3", "hsmmc3", "aclk_133", 0, + EXYNOS4_CLKGATE_IP_FSYS, 8, "hsmmc"), + GATECLK(NULL, "dwmmc", "aclk_133", 0, + EXYNOS4_CLKGATE_IP_FSYS, 9, NULL), + GATECLK("s5p-sdo", "dac", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_TV, 2, NULL), + GATECLK("s5p-mixer", "mixer", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_TV, 1, NULL), + GATECLK("s5p-mixer", "vp", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_TV, 0, NULL), + GATECLK("exynos4-hdmi", "hdmi", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_TV, 3, NULL), + GATECLK("exynos4-hdmi", "hdmiphy", "aclk_160", 0, + S5P_HDMI_PHY_CONTROL, 0, NULL), + GATECLK("s5p-sdo", "dacphy", "aclk_160", 0, + S5P_DAC_PHY_CONTROL, 0, NULL), + GATECLK(NULL, "adc", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 15, NULL), + GATECLK(NULL, "keypad", "aclk_100", 0, + EXYNOS4210_CLKGATE_IP_PERIR, 16, NULL), + GATECLK(NULL, "rtc", "aclk_100", 0, + EXYNOS4210_CLKGATE_IP_PERIR, 15, NULL), + GATECLK(NULL, "watchdog", "aclk_100", 0, + EXYNOS4210_CLKGATE_IP_PERIR, 14, NULL), + GATECLK(NULL, "usbhost", "aclk_133", 0, + EXYNOS4_CLKGATE_IP_FSYS, 12, NULL), + GATECLK(NULL, "otg", "aclk_133", 0, + EXYNOS4_CLKGATE_IP_FSYS, 13, NULL), + GATECLK("exynos4210-spi.0", "spi0", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 16, "spi"), + GATECLK("exynos4210-spi.1", "spi1", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 17, "spi"), + GATECLK("exynos4210-spi.2", "spi2", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 18, "spi"), + GATECLK("samsung-i2s.0", "iis0", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 19, "iis"), + GATECLK("samsung-i2s.1", "iis1", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 20, "iis"), + GATECLK("samsung-i2s.2", "iis2", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 21, "iis"), + GATECLK("samsung-ac97", "ac97", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 27, NULL), + GATECLK("s5p-mfc", "mfc", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_MFC, 0, NULL), + GATECLK("s3c2440-i2c.0", "i2c0", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 6, "i2c"), + GATECLK("s3c2440-i2c.1", "i2c1", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 7, "i2c"), + GATECLK("s3c2440-i2c.2", "i2c2", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 8, "i2c"), + GATECLK("s3c2440-i2c.3", "i2c3", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 9, "i2c"), + GATECLK("s3c2440-i2c.4", "i2c4", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 10, "i2c"), + GATECLK("s3c2440-i2c.5", "i2c5", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 11, "i2c"), + GATECLK("s3c2440-i2c.6", "i2c6", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 12, "i2c"), + GATECLK("s3c2440-i2c.7", "i2c7", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 13, "i2c"), + GATECLK("s3c2440-hdmiphy-i2c", "i2c", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_PERIL, 14, NULL), + GATECLK(SYSMMU_CLOCK_DEVNAME(mfc_l, 0), "sysmmu0", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_MFC, 1, "sysmmu"), + GATECLK(SYSMMU_CLOCK_DEVNAME(mfc_r, 1), "sysmmu1", "aclk_100", 0, + EXYNOS4_CLKGATE_IP_MFC, 2, "sysmmu"), + GATECLK(SYSMMU_CLOCK_DEVNAME(tv, 2), "sysmmu2", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_TV, 4, "sysmmu"), + GATECLK(SYSMMU_CLOCK_DEVNAME(jpeg, 3), "sysmmu3", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_CAM, 11, "sysmmu"), + GATECLK(SYSMMU_CLOCK_DEVNAME(rot, 4), "sysmmu4", "aclk_200", 0, + EXYNOS4210_CLKGATE_IP_IMAGE, 4, "sysmmu"), + GATECLK(SYSMMU_CLOCK_DEVNAME(fimc0, 5), "sysmmu5", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_CAM, 7, "sysmmu"), + GATECLK(SYSMMU_CLOCK_DEVNAME(fimc1, 6), "sysmmu6", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_CAM, 8, "sysmmu"), + GATECLK(SYSMMU_CLOCK_DEVNAME(fimc2, 7), "sysmmu7", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_CAM, 9, "sysmmu"), + GATECLK(SYSMMU_CLOCK_DEVNAME(fimc3, 8), "sysmmu8", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_CAM, 10, "sysmmu"), + GATECLK(SYSMMU_CLOCK_DEVNAME(fimd, 10), "sysmmu10", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_LCD0, 4, "sysmmu"), + GATECLK("dma-pl330.0", "dma0", "aclk_133", 0, + EXYNOS4_CLKGATE_IP_FSYS, 0, "dma"), + GATECLK("dma-pl330.1", "dma1", "aclk_133", 0, + EXYNOS4_CLKGATE_IP_FSYS, 1, "dma"), + GATECLK("exynos4-fb.0", "fimd", "aclk_160", 0, + EXYNOS4_CLKGATE_IP_LCD0, 0, "lcd"), + GATECLK("exynos4210-spi.0", "sclk_spi0", "div_spi0_pre", 0, + EXYNOS4_CLKSRC_MASK_PERIL1, 16, "spi_busclk0"), + GATECLK("exynos4210-spi.1", "sclk_spi1", "div_spi1_pre", 0, + EXYNOS4_CLKSRC_MASK_PERIL1, 20, "spi_busclk0"), + GATECLK("exynos4210-spi.2", "sclk_spi2", "div_spi2_pre", 0, + EXYNOS4_CLKSRC_MASK_PERIL1, 24, "spi_busclk0"), + GATECLK("exynos4-sdhci.0", "sclk_mmc0", "div_mmc0_pre", 0, + EXYNOS4_CLKSRC_MASK_FSYS, 0, "mmc_busclk.2"), + GATECLK("exynos4-sdhci.1", "sclk_mmc1", "div_mmc1_pre", 0, + EXYNOS4_CLKSRC_MASK_FSYS, 4, "mmc_busclk.2"), + GATECLK("exynos4-sdhci.2", "sclk_mmc2", "div_mmc2_pre", 0, + EXYNOS4_CLKSRC_MASK_FSYS, 8, "mmc_busclk.2"), + GATECLK("exynos4-sdhci.3", "sclk_mmc3", "div_mmc3_pre", 0, + EXYNOS4_CLKSRC_MASK_FSYS, 12, "mmc_busclk.2"), + GATECLK("s5p-mipi-csis.0", "sclk_csis0", "div_csis0", 0, + EXYNOS4_CLKSRC_MASK_CAM, 24, "sclk_csis"), + GATECLK("s5p-mipi-csis.1", "sclk_csis1", "div_csis1", 0, + EXYNOS4_CLKSRC_MASK_CAM, 28, "sclk_csis"), + GATECLK(NULL, "sclk_cam0", "div_cam0", 0, + EXYNOS4_CLKSRC_MASK_CAM, 16, NULL), + GATECLK(NULL, "sclk_cam1", "div_cam1", 0, + EXYNOS4_CLKSRC_MASK_CAM, 20, NULL), + GATECLK("exynos4-fimc.0", "sclk_fimc", "div_fimc0", 0, + EXYNOS4_CLKSRC_MASK_CAM, 0, "sclk_fimc"), + GATECLK("exynos4-fimc.1", "sclk_fimc", "div_fimc1", 0, + EXYNOS4_CLKSRC_MASK_CAM, 4, "sclk_fimc"), + GATECLK("exynos4-fimc.2", "sclk_fimc", "div_fimc2", 0, + EXYNOS4_CLKSRC_MASK_CAM, 8, "sclk_fimc"), + GATECLK("exynos4-fimc.3", "sclk_fimc", "div_fimc3", 0, + EXYNOS4_CLKSRC_MASK_CAM, 12, "sclk_fimc"), + GATECLK("exynos4-fb.0", "sclk_fimd", "div_fimd0", 0, + EXYNOS4_CLKSRC_MASK_LCD0, 0, "sclk_fimd"), +}; + +/* register clock common to all Exynos4 platforms */ +void __init exynos4_clk_init(void) +{ + samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks, + ARRAY_SIZE(exynos4_fixed_rate_clks)); + samsung_clk_register_mux(exynos4_mux_clks, + ARRAY_SIZE(exynos4_mux_clks)); + samsung_clk_register_div(exynos4_div_clks, + ARRAY_SIZE(exynos4_div_clks)); + samsung_clk_register_gate(exynos4_gate_clks, + ARRAY_SIZE(exynos4_gate_clks)); +} + +/* + * Exynos4210 Specific Clocks + */ + +static const char *exynos4210_vpll_parent_names[] __initdata = { + "mout_vpll_src" }; +static const char *mout_vpll_src_parents[] __initdata = { + "fin_pll", "sclk_hdmi24m" }; +static const char *exynos4210_mout_vpll_parents[] __initdata = { + "mout_vpll_src", "fout_vpll", }; + +/* Exynos4210 specific fixed rate clocks */ +static struct samsung_fixed_rate_clock exynos4210_fixed_rate_clks[] = { + FRATE_CLK(NULL, "sclk_usbphy1", NULL, CLK_IS_ROOT, 48000000), +}; + +/* Exynos4210 specific mux-type clocks */ +static struct samsung_mux_clock exynos4210_mux_clks[] = { + MUXCLK(NULL, "mout_vpll_src", mout_vpll_src_parents, 0, + EXYNOS4_CLKSRC_TOP1, 0, 1, 0), + MUXCLK(NULL, "mout_vpll", exynos4210_mout_vpll_parents, 0, + EXYNOS4_CLKSRC_TOP0, 8, 1, 0), + MUXCLK(NULL, "mout_mpll", mout_mpll_parents, 0, + EXYNOS4_CLKSRC_CPU, 8, 1, 0), +}; + +static unsigned long exynos4210_get_rate_apll(unsigned long xtal_rate) +{ + return s5p_get_pll45xx(xtal_rate, + __raw_readl(EXYNOS4_APLL_CON0), pll_4508); +} + +static unsigned long exynos4210_get_rate_mpll(unsigned long xtal_rate) +{ + return s5p_get_pll45xx(xtal_rate, + __raw_readl(EXYNOS4_MPLL_CON0), pll_4508); +} + +static unsigned long exynos4210_get_rate_epll(unsigned long xtal_rate) +{ + return s5p_get_pll46xx(xtal_rate, __raw_readl(EXYNOS4_EPLL_CON0), + __raw_readl(EXYNOS4_EPLL_CON1), pll_4600); +} + +static unsigned long exynos4210_get_rate_vpll(unsigned long vpllsrc_rate) +{ + return s5p_get_pll46xx(vpllsrc_rate, __raw_readl(EXYNOS4_VPLL_CON0), + __raw_readl(EXYNOS4_VPLL_CON1), pll_4650c); +} + +static u32 exynos4_vpll_div[][8] = { + { 54000000, 3, 53, 3, 1024, 0, 17, 0 }, + { 108000000, 3, 53, 2, 1024, 0, 17, 0 }, +}; + +static int exynos4210_vpll_set_rate(unsigned long rate) +{ + unsigned int vpll_con0, vpll_con1 = 0; + unsigned int i; + + vpll_con0 = __raw_readl(EXYNOS4_VPLL_CON0); + vpll_con0 &= ~(0x1 << 27 | \ + PLL90XX_MDIV_MASK << PLL46XX_MDIV_SHIFT | \ + PLL90XX_PDIV_MASK << PLL46XX_PDIV_SHIFT | \ + PLL90XX_SDIV_MASK << PLL46XX_SDIV_SHIFT); + + vpll_con1 = __raw_readl(EXYNOS4_VPLL_CON1); + vpll_con1 &= ~(PLL46XX_MRR_MASK << PLL46XX_MRR_SHIFT | \ + PLL46XX_MFR_MASK << PLL46XX_MFR_SHIFT | \ + PLL4650C_KDIV_MASK << PLL46XX_KDIV_SHIFT); + + for (i = 0; i < ARRAY_SIZE(exynos4_vpll_div); i++) { + if (exynos4_vpll_div[i][0] == rate) { + vpll_con0 |= exynos4_vpll_div[i][1] << PLL46XX_PDIV_SHIFT; + vpll_con0 |= exynos4_vpll_div[i][2] << PLL46XX_MDIV_SHIFT; + vpll_con0 |= exynos4_vpll_div[i][3] << PLL46XX_SDIV_SHIFT; + vpll_con1 |= exynos4_vpll_div[i][4] << PLL46XX_KDIV_SHIFT; + vpll_con1 |= exynos4_vpll_div[i][5] << PLL46XX_MFR_SHIFT; + vpll_con1 |= exynos4_vpll_div[i][6] << PLL46XX_MRR_SHIFT; + vpll_con0 |= exynos4_vpll_div[i][7] << 27; + break; + } + } + + if (i == ARRAY_SIZE(exynos4_vpll_div)) { + pr_err("%s: Invalid Clock VPLL Frequency\n", __func__); + return -EINVAL; + } + + __raw_writel(vpll_con0, EXYNOS4_VPLL_CON0); + __raw_writel(vpll_con1, EXYNOS4_VPLL_CON1); + + /* Wait for VPLL lock */ + while (!(__raw_readl(EXYNOS4_VPLL_CON0) & (1 << PLL46XX_LOCKED_SHIFT))) + continue; + + return 0; +} + +static const __initconst struct of_device_id clk_match[] = { + { .compatible = "fixed-clock", + .data = of_fixed_clk_setup, }, + { .compatible = "samsung,clock-mux", + .data = samsung_of_clk_register_mux, }, + { .compatible = "samsung,clock-pll", + .data = samsung_of_clk_register_pll, }, + { .compatible = "samsung,clock-div", + .data = samsung_of_clk_register_div, }, + { .compatible = "samsung,clock-gate", + .data = samsung_of_clk_register_gate, }, + {}, +}; + +#ifdef CONFIG_OF +void __init exynos4_of_clk_init(void) +{ + struct device_node *np; + struct clk *clk; + + np = of_find_compatible_node(NULL, NULL, "samsung,exynos4-clock-ctrl"); + if (!np) { + pr_err("%s: clock controller node not found\n", __func__); + return; + } + + clk_base = of_iomap(np, 0); + WARN(!clk_base, "unable to map clocks registers\n"); + + samsung_clk_set_ctrl_base(clk_base); + samsung_clk_set_finpll_reg(EXYNOS4_OP_MODE); + of_clk_init(clk_match); + + clk = clk_get(NULL, "fout_apll"); + samsung_pll_clk_set_cb(clk, NULL, exynos4210_get_rate_apll); + clk = clk_get(NULL, "fout_mpll"); + samsung_pll_clk_set_cb(clk, NULL, exynos4210_get_rate_mpll); + clk = clk_get(NULL, "fout_epll"); + samsung_pll_clk_set_cb(clk, NULL, exynos4210_get_rate_epll); + clk = clk_get(NULL, "fout_vpll"); + samsung_pll_clk_set_cb(clk, exynos4210_vpll_set_rate, + exynos4210_get_rate_mpll); +} +#else +void __init exynos4_of_clk_init(void) +{ +} +#endif + +/* Exynos4210 specific clock registration */ +void __init exynos4210_clk_init(void) +{ + if (of_have_populated_dt()) { + exynos4_of_clk_init(); + goto disp_rates; + } + + /* exynos4210 specific fix up for group1_parents */ + group1_parents[4] = "sclk_usbphy1"; + + samsung_clk_set_ctrl_base(S5P_VA_CMU); + exynos4_clk_init(); + samsung_clk_register_pll("fout_apll", pll_parent_names, NULL, + NULL, exynos4210_get_rate_apll); + samsung_clk_register_pll("fout_mpll", pll_parent_names, NULL, + NULL, exynos4210_get_rate_mpll); + samsung_clk_register_pll("fout_epll", pll_parent_names, NULL, + NULL, exynos4210_get_rate_epll); + samsung_clk_register_pll("fout_vpll", exynos4210_vpll_parent_names, + NULL, exynos4210_vpll_set_rate, exynos4210_get_rate_vpll); + + samsung_clk_register_fixed_rate(exynos4210_fixed_rate_clks, + ARRAY_SIZE(exynos4210_fixed_rate_clks)); + samsung_clk_register_mux(exynos4210_mux_clks, + ARRAY_SIZE(exynos4210_mux_clks)); + +disp_rates: + pr_info("EXYNOS4210: PLL settings: A=%ld, M=%ld, E=%ld, V=%ld\n", + _get_rate("fout_apll"), _get_rate("fout_mpll"), + _get_rate("fout_epll"), _get_rate("fout_vpll")); + + pr_info("EXYNOS4210: ARMCLK=%ld, ACLK200=%ld, ACLK100=%ld\n" + " ACLK160=%ld, ACLK133=%ld\n", _get_rate("armclk"), + _get_rate("aclk_200"), _get_rate("aclk_100"), + _get_rate("aclk_160"), _get_rate("aclk_133")); +} + +/* + * Exynos4x12 Specific Clocks + */ + +static const char *exynos4x12_mout_vpll_parents[] __initdata = { + "fin_pll", "fout_vpll", }; + +/* Exynos4x12 specific mux clocks */ +static struct samsung_mux_clock exynos4x12_mux_clks[] = { + MUXCLK(NULL, "mout_mpll", mout_mpll_parents, 0, + EXYNOS4_CLKSRC_DMC, 12, 1, 0), + MUXCLK(NULL, "mout_vpll", exynos4x12_mout_vpll_parents, 0, + EXYNOS4_CLKSRC_TOP0, 8, 1, 0), +}; + +static unsigned long exynos4x12_get_rate_apll(unsigned long xtal_rate) +{ + return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS4_APLL_CON0)); +} + +static unsigned long exynos4x12_get_rate_mpll(unsigned long xtal_rate) +{ + return s5p_get_pll35xx(xtal_rate, __raw_readl(EXYNOS4_MPLL_CON0)); +} + +static unsigned long exynos4x12_get_rate_epll(unsigned long xtal_rate) +{ + return s5p_get_pll36xx(xtal_rate, __raw_readl(EXYNOS4_EPLL_CON0), + __raw_readl(EXYNOS4_EPLL_CON1)); +} + +static unsigned long exynos4x12_get_rate_vpll(unsigned long vpllsrc_rate) +{ + return s5p_get_pll36xx(vpllsrc_rate, __raw_readl(EXYNOS4_VPLL_CON0), + __raw_readl(EXYNOS4_VPLL_CON1)); +} + +/* Exynos4x12 specific clock registeration */ +void __init exynos4x12_clk_init(void) +{ + exynos4_clk_init(); + + samsung_clk_register_pll("fout_apll", pll_parent_names, NULL, + NULL, exynos4x12_get_rate_apll); + samsung_clk_register_pll("fout_mpll", pll_parent_names, NULL, + NULL, exynos4x12_get_rate_mpll); + samsung_clk_register_pll("fout_epll", pll_parent_names, NULL, + NULL, exynos4x12_get_rate_epll); + samsung_clk_register_pll("fout_vpll", pll_parent_names, NULL, + NULL, exynos4x12_get_rate_vpll); + + samsung_clk_register_mux(exynos4x12_mux_clks, + ARRAY_SIZE(exynos4x12_mux_clks)); + + pr_info("EXYNOS4210: PLL settings: A=%ld, M=%ld, E=%ld, V=%ld\n", + _get_rate("fout_apll"), _get_rate("fout_mpll"), + _get_rate("fout_epll"), _get_rate("fout_vpll")); + + pr_info("EXYNOS4210: ARMCLK=%ld, ACLK200=%ld, ACLK100=%ld\n" + " ACLK160=%ld, ACLK133=%ld\n", _get_rate("armclk"), + _get_rate("aclk_200"), _get_rate("aclk_100"), + _get_rate("aclk_160"), _get_rate("aclk_133")); +}