From patchwork Fri Feb 1 06:35:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiaxun Yang X-Patchwork-Id: 10791855 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3FCA013B5 for ; Fri, 1 Feb 2019 06:36:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 334B430DC0 for ; Fri, 1 Feb 2019 06:36:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 27127318CA; Fri, 1 Feb 2019 06:36:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C663A30DC0 for ; Fri, 1 Feb 2019 06:36:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727204AbfBAGgN (ORCPT ); Fri, 1 Feb 2019 01:36:13 -0500 Received: from forward100p.mail.yandex.net ([77.88.28.100]:43452 "EHLO forward100p.mail.yandex.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725876AbfBAGgM (ORCPT ); Fri, 1 Feb 2019 01:36:12 -0500 Received: from mxback5o.mail.yandex.net (mxback5o.mail.yandex.net [IPv6:2a02:6b8:0:1a2d::1f]) by forward100p.mail.yandex.net (Yandex) with ESMTP id 8E68E598299C; Fri, 1 Feb 2019 09:36:08 +0300 (MSK) Received: from smtp3o.mail.yandex.net (smtp3o.mail.yandex.net [2a02:6b8:0:1a2d::27]) by mxback5o.mail.yandex.net (nwsmtp/Yandex) with ESMTP id D5wPg38RU2-a8xiqL3W; Fri, 01 Feb 2019 09:36:08 +0300 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=flygoat.com; s=mail; t=1549002968; bh=2wiqs9zxe3W64theQBSX1Wi8qaLxM4kryOcr6IFsFbg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=KL7Mx/DNeZeaDpKmm1rZ9lOGyFc62Osl2YZUKjT9Sw9yeY7zSblcPthMAQVt87MjR Sdomyur9gDVKn8Z3MLVs3x8wt7W5746KHUgSyr1DDf/Gimdg7jAlw/Oc8YhuIKfAlF DFDjzrbqzS3egQ0uHRbRYOR1i87X4ckcgmNeC+Wo= Authentication-Results: mxback5o.mail.yandex.net; dkim=pass header.i=@flygoat.com Received: by smtp3o.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id 5VfXSCstdQ-a1VOTSbl; Fri, 01 Feb 2019 09:36:06 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client certificate not present) From: Jiaxun Yang To: linux-mips@vger.kernel.org Cc: mturquette@baylibre.com, sboyd@kernel.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, robh+dt@kernel.org, mark.rutland@arm.com, devicetree@vger.kernel.org, Jiaxun Yang Subject: [PATCH v3 1/3] clk: loongson1: add configuration option for loongson1 clks Date: Fri, 1 Feb 2019 14:35:38 +0800 Message-Id: <20190201063540.19636-2-jiaxun.yang@flygoat.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190201063540.19636-1-jiaxun.yang@flygoat.com> References: <20190128152052.3047-1-jiaxun.yang@flygoat.com> <20190201063540.19636-1-jiaxun.yang@flygoat.com> MIME-Version: 1.0 Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The patch introduces options for loongson1 clocks so we can select the driver we need. Signed-off-by: Jiaxun Yang --- drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 2 +- drivers/clk/loongson1/Kconfig | 27 +++++++++++++++++++++++++++ drivers/clk/loongson1/Makefile | 7 ++++--- 4 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 drivers/clk/loongson1/Kconfig diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index e5b2fe80eab4..136d3d73c6df 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -298,6 +298,7 @@ source "drivers/clk/imgtec/Kconfig" source "drivers/clk/imx/Kconfig" source "drivers/clk/ingenic/Kconfig" source "drivers/clk/keystone/Kconfig" +source "drivers/clk/loongson1/Kconfig" source "drivers/clk/mediatek/Kconfig" source "drivers/clk/meson/Kconfig" source "drivers/clk/mvebu/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 8a9440a97500..7d29e545caf0 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -76,7 +76,7 @@ obj-y += imx/ obj-y += ingenic/ obj-$(CONFIG_ARCH_K3) += keystone/ obj-$(CONFIG_ARCH_KEYSTONE) += keystone/ -obj-$(CONFIG_MACH_LOONGSON32) += loongson1/ +obj-y += loongson1/ obj-y += mediatek/ obj-$(CONFIG_COMMON_CLK_AMLOGIC) += meson/ obj-$(CONFIG_MACH_PIC32) += microchip/ diff --git a/drivers/clk/loongson1/Kconfig b/drivers/clk/loongson1/Kconfig new file mode 100644 index 000000000000..e2220332d797 --- /dev/null +++ b/drivers/clk/loongson1/Kconfig @@ -0,0 +1,27 @@ +menu "Loongson-1 Clock drivers" + depends on MACH_LOONGSON32 + +config LOONGSON1_CLOCK_COMMON + bool + +config LOONGSON1_CLOCK_LS1B + bool "Loongson 1B driver" + default y + select LOONGSON1_CLOCK_COMMON + help + Support the clocks provided by the clock hardware on Loongson-1B + and compatible SoCs. + + If building for a Loongson-1B SoC, you want to say Y here. + +config LOONGSON1_CLOCK_LS1C + bool "Loongson 1C driver" + default y + select LOONGSON1_CLOCK_COMMON + help + Support the clocks provided by the clock hardware on Loongson-1C + and compatible SoCs. + + If building for a Loongson-1C SoC, you want to say Y here. + +endmenu diff --git a/drivers/clk/loongson1/Makefile b/drivers/clk/loongson1/Makefile index b7f6a16390e0..9240189183ff 100644 --- a/drivers/clk/loongson1/Makefile +++ b/drivers/clk/loongson1/Makefile @@ -1,3 +1,4 @@ -obj-y += clk.o -obj-$(CONFIG_LOONGSON1_LS1B) += clk-loongson1b.o -obj-$(CONFIG_LOONGSON1_LS1C) += clk-loongson1c.o +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_LOONGSON1_CLOCK_COMMON) += clk.o +obj-$(CONFIG_LOONGSON1_CLOCK_LS1B) += clk-loongson1b.o +obj-$(CONFIG_LOONGSON1_CLOCK_LS1C) += clk-loongson1c.o From patchwork Fri Feb 1 06:35:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiaxun Yang X-Patchwork-Id: 10791857 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1438913B5 for ; Fri, 1 Feb 2019 06:36:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 011AF30DC0 for ; Fri, 1 Feb 2019 06:36:23 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E46C2318D0; Fri, 1 Feb 2019 06:36:23 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B228130DC0 for ; Fri, 1 Feb 2019 06:36:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727574AbfBAGgW (ORCPT ); Fri, 1 Feb 2019 01:36:22 -0500 Received: from forward101o.mail.yandex.net ([37.140.190.181]:47223 "EHLO forward101o.mail.yandex.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725876AbfBAGgW (ORCPT ); Fri, 1 Feb 2019 01:36:22 -0500 Received: from mxback23g.mail.yandex.net (mxback23g.mail.yandex.net [IPv6:2a02:6b8:0:1472:2741:0:8b7:323]) by forward101o.mail.yandex.net (Yandex) with ESMTP id EF7183C018E5; Fri, 1 Feb 2019 09:36:16 +0300 (MSK) Received: from smtp3o.mail.yandex.net (smtp3o.mail.yandex.net [2a02:6b8:0:1a2d::27]) by mxback23g.mail.yandex.net (nwsmtp/Yandex) with ESMTP id v0pvFYIGtX-aGS01h9u; Fri, 01 Feb 2019 09:36:16 +0300 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=flygoat.com; s=mail; t=1549002976; bh=vKyFdvgXMOy7XUNRn+kBFtSzywE4LMaWer9HOdvwdrM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=CeXwZIBt+PSQW/AkY9XmJMdScWX+mN1yBc84uRau/NTvpbnX1g0zigO3Vkbzi2i/E uNhUTLxx/eNvSFTs8uLKA01XcQAG6GU42YZtgrC5eETC9izPoaK3OvWwDGSoqyEvU9 OdQSp9BdsXwapk0btcIKQ63Uug5jJu/lT7XQXL1k= Authentication-Results: mxback23g.mail.yandex.net; dkim=pass header.i=@flygoat.com Received: by smtp3o.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id 5VfXSCstdQ-a8VOl154; Fri, 01 Feb 2019 09:36:13 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client certificate not present) From: Jiaxun Yang To: linux-mips@vger.kernel.org Cc: mturquette@baylibre.com, sboyd@kernel.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, robh+dt@kernel.org, mark.rutland@arm.com, devicetree@vger.kernel.org, Jiaxun Yang Subject: [PATCH v3 2/3] clk: loongson1: add of support Date: Fri, 1 Feb 2019 14:35:39 +0800 Message-Id: <20190201063540.19636-3-jiaxun.yang@flygoat.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190201063540.19636-1-jiaxun.yang@flygoat.com> References: <20190128152052.3047-1-jiaxun.yang@flygoat.com> <20190201063540.19636-1-jiaxun.yang@flygoat.com> MIME-Version: 1.0 Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch add of support by split the clk_hw register and clkdev register, then handle the of clk_hw via of_clk_hw_onecell_get. Signed-off-by: Jiaxun Yang --- drivers/clk/loongson1/clk-loongson1b.c | 197 ++++++++++++++++++++----- drivers/clk/loongson1/clk-loongson1c.c | 164 +++++++++++++++----- drivers/clk/loongson1/clk.c | 47 +++++- drivers/clk/loongson1/clk.h | 18 ++- 4 files changed, 343 insertions(+), 83 deletions(-) diff --git a/drivers/clk/loongson1/clk-loongson1b.c b/drivers/clk/loongson1/clk-loongson1b.c index f36a97e993c0..2148df31db15 100644 --- a/drivers/clk/loongson1/clk-loongson1b.c +++ b/drivers/clk/loongson1/clk-loongson1b.c @@ -1,10 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2012-2016 Zhang, Keguang - * - * 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. + * Copyright (c) 2019 Jiaxun Yang */ #include @@ -12,11 +9,41 @@ #include #include -#include #include "clk.h" +#include + +#define LS1B_CLK_COUNT 9 -#define OSC (33 * 1000000) #define DIV_APB 2 +/* Clock PLL Divisor Register Bits */ +#define DIV_DC_EN BIT(31) +#define DIV_DC_RST BIT(30) +#define DIV_CPU_EN BIT(25) +#define DIV_CPU_RST BIT(24) +#define DIV_DDR_EN BIT(19) +#define DIV_DDR_RST BIT(18) +#define RST_DC_EN BIT(5) +#define RST_DC BIT(4) +#define RST_DDR_EN BIT(3) +#define RST_DDR BIT(2) +#define RST_CPU_EN BIT(1) +#define RST_CPU BIT(0) + +#define DIV_DC_SHIFT 26 +#define DIV_CPU_SHIFT 20 +#define DIV_DDR_SHIFT 14 + +#define DIV_DC_WIDTH 4 +#define DIV_CPU_WIDTH 4 +#define DIV_DDR_WIDTH 4 + +#define BYPASS_DC_SHIFT 12 +#define BYPASS_DDR_SHIFT 10 +#define BYPASS_CPU_SHIFT 8 + +#define BYPASS_DC_WIDTH 1 +#define BYPASS_DDR_WIDTH 1 +#define BYPASS_CPU_WIDTH 1 static DEFINE_SPINLOCK(_lock); @@ -25,9 +52,9 @@ static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw, { u32 pll, rate; - pll = __raw_readl(LS1X_CLK_PLL_FREQ); + pll = __raw_readl(CLK_PLL_FREQ_ADDR); rate = 12 + (pll & GENMASK(5, 0)); - rate *= OSC; + rate *= parent_rate; rate >>= 1; return rate; @@ -37,21 +64,29 @@ static const struct clk_ops ls1x_pll_clk_ops = { .recalc_rate = ls1x_pll_recalc_rate, }; -static const char *const cpu_parents[] = { "cpu_clk_div", "osc_clk", }; -static const char *const ahb_parents[] = { "ahb_clk_div", "osc_clk", }; -static const char *const dc_parents[] = { "dc_clk_div", "osc_clk", }; -void __init ls1x_clk_init(void) +struct clk_hw_onecell_data __init *ls1b_clk_init_hw(const char *osc_name) { struct clk_hw *hw; + struct clk_hw_onecell_data *onecell; + const char *parents[2]; + + onecell = kzalloc(sizeof(*onecell) + + (LS1B_CLK_COUNT * sizeof(struct clk_hw *)), + GFP_KERNEL); + + if (!onecell) + return NULL; - hw = clk_hw_register_fixed_rate(NULL, "osc_clk", NULL, 0, OSC); - clk_hw_register_clkdev(hw, "osc_clk", NULL); + onecell->num = LS1B_CLK_COUNT; + parents[1] = osc_name; /* clock derived from 33 MHz OSC clk */ - hw = clk_hw_register_pll(NULL, "pll_clk", "osc_clk", + hw = clk_hw_register_pll(NULL, "pll_clk", osc_name, &ls1x_pll_clk_ops, 0); - clk_hw_register_clkdev(hw, "pll_clk", NULL); + if (!hw) + goto err; + onecell->hws[LS1B_CLK_PLL] = hw; /* clock derived from PLL clk */ /* _____ @@ -61,16 +96,22 @@ void __init ls1x_clk_init(void) * |_____| */ hw = clk_hw_register_divider(NULL, "cpu_clk_div", "pll_clk", - CLK_GET_RATE_NOCACHE, LS1X_CLK_PLL_DIV, + CLK_GET_RATE_NOCACHE, CLK_PLL_DIV_ADDR, DIV_CPU_SHIFT, DIV_CPU_WIDTH, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ROUND_CLOSEST, &_lock); - clk_hw_register_clkdev(hw, "cpu_clk_div", NULL); - hw = clk_hw_register_mux(NULL, "cpu_clk", cpu_parents, - ARRAY_SIZE(cpu_parents), - CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV, + if (!hw) + goto err; + onecell->hws[LS1B_CLK_CPU_DIV] = hw; + + parents[0] = "cpu_clk_div"; + hw = clk_hw_register_mux(NULL, "cpu_clk", parents, + ARRAY_SIZE(parents), + CLK_SET_RATE_NO_REPARENT, CLK_PLL_DIV_ADDR, BYPASS_CPU_SHIFT, BYPASS_CPU_WIDTH, 0, &_lock); - clk_hw_register_clkdev(hw, "cpu_clk", NULL); + if (!hw) + goto err; + onecell->hws[LS1B_CLK_CPU] = hw; /* _____ * _______________________| | @@ -79,14 +120,20 @@ void __init ls1x_clk_init(void) * |_____| */ hw = clk_hw_register_divider(NULL, "dc_clk_div", "pll_clk", - 0, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT, + 0, CLK_PLL_DIV_ADDR, DIV_DC_SHIFT, DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock); - clk_hw_register_clkdev(hw, "dc_clk_div", NULL); - hw = clk_hw_register_mux(NULL, "dc_clk", dc_parents, - ARRAY_SIZE(dc_parents), - CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV, + if (!hw) + goto err; + onecell->hws[LS1B_CLK_DC_DIV] = hw; + + parents[0] = "dc_clk_div"; + hw = clk_hw_register_mux(NULL, "dc_clk", parents, + ARRAY_SIZE(parents), + CLK_SET_RATE_NO_REPARENT, CLK_PLL_DIV_ADDR, BYPASS_DC_SHIFT, BYPASS_DC_WIDTH, 0, &_lock); - clk_hw_register_clkdev(hw, "dc_clk", NULL); + if (!hw) + goto err; + onecell->hws[LS1B_CLK_DC] = hw; /* _____ * _______________________| | @@ -94,23 +141,76 @@ void __init ls1x_clk_init(void) * \___ PLL ___ DDR DIV ___| | * |_____| */ - hw = clk_hw_register_divider(NULL, "ahb_clk_div", "pll_clk", - 0, LS1X_CLK_PLL_DIV, DIV_DDR_SHIFT, + hw = clk_hw_register_divider(NULL, "ddr_clk_div", "pll_clk", + 0, CLK_PLL_DIV_ADDR, DIV_DDR_SHIFT, DIV_DDR_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock); - clk_hw_register_clkdev(hw, "ahb_clk_div", NULL); - hw = clk_hw_register_mux(NULL, "ahb_clk", ahb_parents, - ARRAY_SIZE(ahb_parents), - CLK_SET_RATE_NO_REPARENT, LS1X_CLK_PLL_DIV, + if (!hw) + goto err; + onecell->hws[LS1B_CLK_DDR_DIV] = hw; + + parents[0] = "ddr_clk_div"; + hw = clk_hw_register_mux(NULL, "ddr_clk", parents, + ARRAY_SIZE(parents), + CLK_SET_RATE_NO_REPARENT, CLK_PLL_DIV_ADDR, BYPASS_DDR_SHIFT, BYPASS_DDR_WIDTH, 0, &_lock); - clk_hw_register_clkdev(hw, "ahb_clk", NULL); - clk_hw_register_clkdev(hw, "ls1x-dma", NULL); - clk_hw_register_clkdev(hw, "stmmaceth", NULL); + if (!hw) + goto err; + onecell->hws[LS1B_CLK_DDR] = hw; + + hw = clk_hw_register_fixed_factor(NULL, "ahb_clk", "ddr_clk", 0, 1, + 1); + if (!hw) + goto err; + onecell->hws[LS1B_CLK_AHB] = hw; /* clock derived from AHB clk */ /* APB clk is always half of the AHB clk */ hw = clk_hw_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1, DIV_APB); + if (!hw) + goto err; + onecell->hws[LS1B_CLK_APB] = hw; + + return onecell; + +err: + kfree(onecell); + return NULL; +} + +void __maybe_unused __init ls1b_register_clkdev(struct clk_hw_onecell_data *onecell) +{ + struct clk_hw *hw; + + hw = onecell->hws[LS1B_CLK_PLL]; + clk_hw_register_clkdev(hw, "pll_clk", NULL); + + hw = onecell->hws[LS1B_CLK_CPU_DIV]; + clk_hw_register_clkdev(hw, "cpu_clk_div", NULL); + + hw = onecell->hws[LS1B_CLK_CPU]; + clk_hw_register_clkdev(hw, "cpu_clk", NULL); + + + hw = onecell->hws[LS1B_CLK_DC_DIV]; + clk_hw_register_clkdev(hw, "dc_clk_div", NULL); + + hw = onecell->hws[LS1B_CLK_DC]; + clk_hw_register_clkdev(hw, "dc_clk", NULL); + + hw = onecell->hws[LS1B_CLK_DDR_DIV]; + clk_hw_register_clkdev(hw, "ddr_clk_div", NULL); + + hw = onecell->hws[LS1B_CLK_DDR]; + clk_hw_register_clkdev(hw, "ddr_clk_div", NULL); + + hw = onecell->hws[LS1B_CLK_AHB]; + clk_hw_register_clkdev(hw, "ahb_clk", NULL); + clk_hw_register_clkdev(hw, "ls1x-dma", NULL); + clk_hw_register_clkdev(hw, "stmmaceth", NULL); + + hw = onecell->hws[LS1B_CLK_APB]; clk_hw_register_clkdev(hw, "apb_clk", NULL); clk_hw_register_clkdev(hw, "ls1x-ac97", NULL); clk_hw_register_clkdev(hw, "ls1x-i2c", NULL); @@ -120,3 +220,24 @@ void __init ls1x_clk_init(void) clk_hw_register_clkdev(hw, "ls1x-wdt", NULL); clk_hw_register_clkdev(hw, "serial8250", NULL); } + +static void __init ls1b_clk_of_setup(struct device_node *np) +{ + struct clk_hw_onecell_data *onecell; + int err; + const char *parent = of_clk_get_parent_name(np, 0); + + clk_base = of_iomap(np, 0); + + onecell = ls1b_clk_init_hw(parent); + if (!onecell) + pr_err("ls1b-clk: unable to register clk_hw"); + + err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, onecell); + if (err) + pr_err("ls1b-clk: failed to add DT provider: %d\n", err); + + pr_info("ls1b-clk: driver registered"); +} + +CLK_OF_DECLARE(clk_ls1b, "loongson,ls1b-clock", ls1b_clk_of_setup); diff --git a/drivers/clk/loongson1/clk-loongson1c.c b/drivers/clk/loongson1/clk-loongson1c.c index 3466f7320b40..076a2e1d5df9 100644 --- a/drivers/clk/loongson1/clk-loongson1c.c +++ b/drivers/clk/loongson1/clk-loongson1c.c @@ -1,21 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0 /* - * Copyright (c) 2016 Yang Ling - * - * 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. + * Copyright (c) 2012-2016 Zhang, Keguang + * Copyright (c) 2019 Jiaxun Yang */ #include #include -#include #include "clk.h" -#define OSC (24 * 1000000) +#include + +#define LS1C_CLK_COUNT 6 + #define DIV_APB 1 +/* PLL/SDRAM Frequency configuration register Bits */ +#define PLL_VALID BIT(31) +#define FRAC_N GENMASK(23, 16) +#define RST_TIME GENMASK(3, 2) +#define SDRAM_DIV GENMASK(1, 0) + +/* CPU/CAMERA/DC Frequency configuration register Bits */ +#define DIV_DC_EN BIT(31) +#define DIV_DC GENMASK(30, 24) +#define DIV_CAM_EN BIT(23) +#define DIV_CAM GENMASK(22, 16) +#define DIV_CPU_EN BIT(15) +#define DIV_CPU GENMASK(14, 8) +#define DIV_DC_SEL_EN BIT(5) +#define DIV_DC_SEL BIT(4) +#define DIV_CAM_SEL_EN BIT(3) +#define DIV_CAM_SEL BIT(2) +#define DIV_CPU_SEL_EN BIT(1) +#define DIV_CPU_SEL BIT(0) + +#define DIV_DC_SHIFT 24 +#define DIV_CAM_SHIFT 16 +#define DIV_CPU_SHIFT 8 +#define DIV_DDR_SHIFT 0 + +#define DIV_DC_WIDTH 7 +#define DIV_CAM_WIDTH 7 +#define DIV_CPU_WIDTH 7 +#define DIV_DDR_WIDTH 2 + static DEFINE_SPINLOCK(_lock); static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw, @@ -23,9 +52,9 @@ static unsigned long ls1x_pll_recalc_rate(struct clk_hw *hw, { u32 pll, rate; - pll = __raw_readl(LS1X_CLK_PLL_FREQ); + pll = __raw_readl(CLK_PLL_FREQ_ADDR); rate = ((pll >> 8) & 0xff) + ((pll >> 16) & 0xff); - rate *= OSC; + rate *= parent_rate; rate >>= 2; return rate; @@ -42,50 +71,95 @@ static const struct clk_div_table ahb_div_table[] = { [3] = { .val = 3, .div = 3 }, }; -void __init ls1x_clk_init(void) +struct clk_hw_onecell_data __init *ls1c_clk_init_hw(const char *osc_name) { struct clk_hw *hw; + struct clk_hw_onecell_data *onecell; + + onecell = kzalloc(sizeof(*onecell) + + (LS1C_CLK_COUNT * sizeof(struct clk_hw *)), + GFP_KERNEL); + + if (!onecell) + return NULL; - hw = clk_hw_register_fixed_rate(NULL, "osc_clk", NULL, 0, OSC); - clk_hw_register_clkdev(hw, "osc_clk", NULL); + onecell->num = LS1C_CLK_COUNT; - /* clock derived from 24 MHz OSC clk */ - hw = clk_hw_register_pll(NULL, "pll_clk", "osc_clk", + /* clock derived from OSC clk */ + hw = clk_hw_register_pll(NULL, "pll_clk", osc_name, &ls1x_pll_clk_ops, 0); - clk_hw_register_clkdev(hw, "pll_clk", NULL); + if (!hw) + goto err; + onecell->hws[LS1C_CLK_PLL] = hw; - hw = clk_hw_register_divider(NULL, "cpu_clk_div", "pll_clk", - CLK_GET_RATE_NOCACHE, LS1X_CLK_PLL_DIV, + hw = clk_hw_register_divider(NULL, "cpu_clk", "pll_clk", + CLK_GET_RATE_NOCACHE, CLK_PLL_DIV_ADDR, DIV_CPU_SHIFT, DIV_CPU_WIDTH, CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ROUND_CLOSEST, &_lock); - clk_hw_register_clkdev(hw, "cpu_clk_div", NULL); - hw = clk_hw_register_fixed_factor(NULL, "cpu_clk", "cpu_clk_div", - 0, 1, 1); - clk_hw_register_clkdev(hw, "cpu_clk", NULL); + if (!hw) + goto err; + onecell->hws[LS1C_CLK_CPU] = hw; - hw = clk_hw_register_divider(NULL, "dc_clk_div", "pll_clk", - 0, LS1X_CLK_PLL_DIV, DIV_DC_SHIFT, + + hw = clk_hw_register_divider(NULL, "dc_clk", "pll_clk", + 0, CLK_PLL_DIV_ADDR, DIV_DC_SHIFT, DIV_DC_WIDTH, CLK_DIVIDER_ONE_BASED, &_lock); - clk_hw_register_clkdev(hw, "dc_clk_div", NULL); - hw = clk_hw_register_fixed_factor(NULL, "dc_clk", "dc_clk_div", - 0, 1, 1); - clk_hw_register_clkdev(hw, "dc_clk", NULL); + if (!hw) + goto err; + onecell->hws[LS1C_CLK_DC] = hw; - hw = clk_hw_register_divider_table(NULL, "ahb_clk_div", "cpu_clk_div", - 0, LS1X_CLK_PLL_FREQ, DIV_DDR_SHIFT, + hw = clk_hw_register_divider_table(NULL, "ddr_clk", "cpu_clk", + 0, CLK_PLL_FREQ_ADDR, DIV_DDR_SHIFT, DIV_DDR_WIDTH, CLK_DIVIDER_ALLOW_ZERO, ahb_div_table, &_lock); - clk_hw_register_clkdev(hw, "ahb_clk_div", NULL); - hw = clk_hw_register_fixed_factor(NULL, "ahb_clk", "ahb_clk_div", + if (!hw) + goto err; + onecell->hws[LS1C_CLK_DDR] = hw; + + + hw = clk_hw_register_fixed_factor(NULL, "ahb_clk", "ddr_clk", 0, 1, 1); + if (!hw) + goto err; + onecell->hws[LS1C_CLK_AHB] = hw; + + + hw = clk_hw_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1, + DIV_APB); + if (!hw) + goto err; + onecell->hws[LS1C_CLK_APB] = hw; + + return onecell; + +err: + kfree(onecell); + return NULL; +} + +void __maybe_unused __init ls1c_register_clkdev(struct clk_hw_onecell_data *onecell) +{ + struct clk_hw *hw; + + hw = onecell->hws[LS1C_CLK_PLL]; + clk_hw_register_clkdev(hw, "pll_clk", NULL); + + hw = onecell->hws[LS1C_CLK_CPU]; + clk_hw_register_clkdev(hw, "cpu_clk", NULL); + + hw = onecell->hws[LS1C_CLK_DC]; + clk_hw_register_clkdev(hw, "dc_clk", NULL); + + hw = onecell->hws[LS1C_CLK_DDR]; + clk_hw_register_clkdev(hw, "ddr_clk", NULL); + + hw = onecell->hws[LS1C_CLK_AHB]; clk_hw_register_clkdev(hw, "ahb_clk", NULL); clk_hw_register_clkdev(hw, "ls1x-dma", NULL); clk_hw_register_clkdev(hw, "stmmaceth", NULL); - /* clock derived from AHB clk */ - hw = clk_hw_register_fixed_factor(NULL, "apb_clk", "ahb_clk", 0, 1, - DIV_APB); + hw = onecell->hws[LS1C_CLK_APB]; clk_hw_register_clkdev(hw, "apb_clk", NULL); clk_hw_register_clkdev(hw, "ls1x-ac97", NULL); clk_hw_register_clkdev(hw, "ls1x-i2c", NULL); @@ -95,3 +169,23 @@ void __init ls1x_clk_init(void) clk_hw_register_clkdev(hw, "ls1x-wdt", NULL); clk_hw_register_clkdev(hw, "serial8250", NULL); } + +static void __init ls1c_clk_of_setup(struct device_node *np) +{ + struct clk_hw_onecell_data *onecell; + int err; + const char *parent = of_clk_get_parent_name(np, 0); + + clk_base = of_iomap(np, 0); + + onecell = ls1c_clk_init_hw(parent); + if (!onecell) + pr_err("ls1c-clk: unable to register clk_hw"); + + err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, onecell); + if (err) + pr_err("ls1c-clk: failed to add DT provider: %d\n", err); + + pr_info("ls1c-clk: driver registered"); +} +CLK_OF_DECLARE(clk_ls1c, "loongson,ls1c-clock", ls1c_clk_of_setup); diff --git a/drivers/clk/loongson1/clk.c b/drivers/clk/loongson1/clk.c index 983ce9f6edbb..b4dc7dd8e0cd 100644 --- a/drivers/clk/loongson1/clk.c +++ b/drivers/clk/loongson1/clk.c @@ -1,14 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2012-2016 Zhang, Keguang - * - * 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. + * Copyright (c) 2019 Jiaxun Yang */ +#include + #include #include +#include +#include + +#include + +void __iomem *clk_base; + +#define LS1C_OSC (24 * 1000000) +#define LS1B_OSC (33 * 1000000) + +#define LS1X_CLK_BASE 0x1fe78030 #include "clk.h" @@ -43,3 +53,30 @@ struct clk_hw *__init clk_hw_register_pll(struct device *dev, return hw; } + +void __init ls1x_clk_init(void) +{ + struct clk_hw *hw; + struct clk_hw_onecell_data *onecell; + + clk_base = (void __iomem *)KSEG1ADDR(LS1X_CLK_BASE); +#ifdef CONFIG_LOONGSON1_LS1B + hw = clk_hw_register_fixed_rate(NULL, "osc_clk", NULL, 0, LS1B_OSC); + clk_hw_register_clkdev(hw, "osc_clk", NULL); + onecell = ls1c_clk_init_hw("osc_clk"); + if (!onecell) + panic("ls1x-clk: unable to register clk_hw"); + + ls1c_register_clkdev(onecell); +#elif defined(CONFIG_LOONGSON1_LS1C) + hw = clk_hw_register_fixed_rate(NULL, "osc_clk", NULL, 0, LS1C_OSC); + clk_hw_register_clkdev(hw, "osc_clk", NULL); + onecell = ls1c_clk_init_hw("osc_clk"); + if (!onecell) + panic("ls1x-clk: unable to register clk_hw"); + + ls1c_register_clkdev(onecell); +#else + panic("ls1x-clk: not loongson platform"); +#endif +} diff --git a/drivers/clk/loongson1/clk.h b/drivers/clk/loongson1/clk.h index 085d74b5d496..be7cc72c0ea3 100644 --- a/drivers/clk/loongson1/clk.h +++ b/drivers/clk/loongson1/clk.h @@ -1,10 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2012-2016 Zhang, Keguang - * - * 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. + * Copyright (c) 2019 Jiaxun Yang */ #ifndef __LOONGSON1_CLK_H @@ -16,4 +13,15 @@ struct clk_hw *clk_hw_register_pll(struct device *dev, const struct clk_ops *ops, unsigned long flags); +struct clk_hw_onecell_data __init *ls1c_clk_init_hw(const char *osc_name); +struct clk_hw_onecell_data __init *ls1b_clk_init_hw(const char *osc_name); + +void __maybe_unused __init ls1c_register_clkdev(struct clk_hw_onecell_data *onecell); +void __maybe_unused __init ls1b_register_clkdev(struct clk_hw_onecell_data *onecell); + +extern void __iomem *clk_base; + +#define CLK_PLL_FREQ_ADDR clk_base +#define CLK_PLL_DIV_ADDR (clk_base + 0x4) + #endif /* __LOONGSON1_CLK_H */ From patchwork Fri Feb 1 06:35:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiaxun Yang X-Patchwork-Id: 10791863 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8753A13B5 for ; Fri, 1 Feb 2019 06:36:47 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7BC3330DC0 for ; Fri, 1 Feb 2019 06:36:47 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 70532318CA; Fri, 1 Feb 2019 06:36:47 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4C9AB30DC0 for ; Fri, 1 Feb 2019 06:36:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726460AbfBAGg1 (ORCPT ); Fri, 1 Feb 2019 01:36:27 -0500 Received: from forward100o.mail.yandex.net ([37.140.190.180]:41639 "EHLO forward100o.mail.yandex.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725876AbfBAGg0 (ORCPT ); Fri, 1 Feb 2019 01:36:26 -0500 Received: from mxback20j.mail.yandex.net (mxback20j.mail.yandex.net [IPv6:2a02:6b8:0:1619::114]) by forward100o.mail.yandex.net (Yandex) with ESMTP id 3C9004AC2A57; Fri, 1 Feb 2019 09:36:22 +0300 (MSK) Received: from smtp3o.mail.yandex.net (smtp3o.mail.yandex.net [2a02:6b8:0:1a2d::27]) by mxback20j.mail.yandex.net (nwsmtp/Yandex) with ESMTP id qJCCBI1Fap-aLPKoXau; Fri, 01 Feb 2019 09:36:22 +0300 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=flygoat.com; s=mail; t=1549002982; bh=bw8o9PbShB3Y6hhdn7ifBb3eYe95FLWeMK5ModEQ+Iw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=Ca8nSz3CbmINCn7RK5K7HSShpGhLu1UfjHmNCg/xD3WRYwKnROipuIPZpFTlOvL/H pLwpjg8rccTAeo6ib5ve3zzA9SvXNUJJxifcZSNH3AfeuSvmUM8aQ+ZNd9y58ovFS8 47kedHdd+RIR+YFmhfbzl0z0YrruuC/D57IEOl8Y= Authentication-Results: mxback20j.mail.yandex.net; dkim=pass header.i=@flygoat.com Received: by smtp3o.mail.yandex.net (nwsmtp/Yandex) with ESMTPSA id 5VfXSCstdQ-aHVCPGMI; Fri, 01 Feb 2019 09:36:20 +0300 (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client certificate not present) From: Jiaxun Yang To: linux-mips@vger.kernel.org Cc: mturquette@baylibre.com, sboyd@kernel.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, robh+dt@kernel.org, mark.rutland@arm.com, devicetree@vger.kernel.org, Jiaxun Yang Subject: [PATCH v3 3/3] dt-bindings: clock: Add loongson-1 clock bindings Date: Fri, 1 Feb 2019 14:35:40 +0800 Message-Id: <20190201063540.19636-4-jiaxun.yang@flygoat.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190201063540.19636-1-jiaxun.yang@flygoat.com> References: <20190128152052.3047-1-jiaxun.yang@flygoat.com> <20190201063540.19636-1-jiaxun.yang@flygoat.com> MIME-Version: 1.0 Sender: linux-mips-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mips@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Loongson-1 is a series of MIPS MCUs. This patch add the clock bindings for loongson-1b and loongson-1c clock subsystem. Signed-off-by: Jiaxun Yang Reviewed-by: Rob Herring --- .../bindings/clock/loongson1-clock.txt | 14 ++++++++++++++ include/dt-bindings/clock/ls1b-clock.h | 17 +++++++++++++++++ include/dt-bindings/clock/ls1c-clock.h | 14 ++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/loongson1-clock.txt create mode 100644 include/dt-bindings/clock/ls1b-clock.h create mode 100644 include/dt-bindings/clock/ls1c-clock.h diff --git a/Documentation/devicetree/bindings/clock/loongson1-clock.txt b/Documentation/devicetree/bindings/clock/loongson1-clock.txt new file mode 100644 index 000000000000..5afd13a98eaa --- /dev/null +++ b/Documentation/devicetree/bindings/clock/loongson1-clock.txt @@ -0,0 +1,14 @@ +* Clock bindings for Loongson-1 MCUs + +Required properties: +- compatible: must contain one of the following compatibles: + - "loongson,ls1b-clock" + - "loongson,ls1c-clock" + +- reg: Address and length of the register set +- #clock-cells: Should be <1> +- clocks: list of input clocks + +The clock consumer should specify the desired clock by having the clock +ID in its "clocks" phandle cell. See include/dt-bindings/clock/ls1c-clock.h +or include/dt-bindings/clock/ls1b-clock.h for the full list of clocks. diff --git a/include/dt-bindings/clock/ls1b-clock.h b/include/dt-bindings/clock/ls1b-clock.h new file mode 100644 index 000000000000..c7ae85bb4583 --- /dev/null +++ b/include/dt-bindings/clock/ls1b-clock.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2019 Jiaxun Yang */ + +#ifndef __DT_BINDINGS_CLOCK_LS1B_CLOCK_H__ +#define __DT_BINDINGS_CLOCK_LS1B_CLOCK_H__ + +#define LS1B_CLK_PLL 0 +#define LS1B_CLK_CPU_DIV 1 +#define LS1B_CLK_CPU 2 +#define LS1B_CLK_DC_DIV 3 +#define LS1B_CLK_DC 4 +#define LS1B_CLK_DDR_DIV 5 +#define LS1B_CLK_DDR 6 +#define LS1B_CLK_AHB 7 +#define LS1B_CLK_APB 8 + +#endif /* __DT_BINDINGS_CLOCK_LS1B_CLOCK_H__ */ diff --git a/include/dt-bindings/clock/ls1c-clock.h b/include/dt-bindings/clock/ls1c-clock.h new file mode 100644 index 000000000000..9d01914f374e --- /dev/null +++ b/include/dt-bindings/clock/ls1c-clock.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2019 Jiaxun Yang */ + +#ifndef __DT_BINDINGS_CLOCK_LS1C_CLOCK_H__ +#define __DT_BINDINGS_CLOCK_LS1C_CLOCK_H__ + +#define LS1C_CLK_PLL 0 +#define LS1C_CLK_CPU 1 +#define LS1C_CLK_DC 2 +#define LS1C_CLK_DDR 3 +#define LS1C_CLK_AHB 4 +#define LS1C_CLK_APB 5 + +#endif /* __DT_BINDINGS_CLOCK_LS1C_CLOCK_H__ */