From patchwork Wed Feb 20 11:25:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Belloni X-Patchwork-Id: 10821911 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 2078D14E1 for ; Wed, 20 Feb 2019 11:27:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 052922DFDC for ; Wed, 20 Feb 2019 11:27:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EC6E12DFEC; Wed, 20 Feb 2019 11:27:13 +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=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 35E362DFDC for ; Wed, 20 Feb 2019 11:27:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=PrAoA2tH5+QaT1p2LgCEdDtKsc3WM86O0Vx73rFz9c8=; b=EdRMWM/Tq4zAA9 w88LnZaZayfdUBSPjFqR64XQ4GC0ZJh6YPVSWR1NR7GQ2Jp7dY1sUs9ugtlNjp45GC96m0KYAvBVf Fq9GWFBu/YIWs80itiC7TR+Bdb2LDv+oC7Vihb3UX+SfHp3Zo6IEdmaGtP5nT6m774c8dIG5iINC+ VqhK+9YA5cIf5kBmf9MUa2MRUcL3NHRRtBaeB91wOZ9tBfSY9vT04V+aL15ljuSOfxEcDx+EVyp7r zy5pwxpMgJAw8EqOyVuY94wjVvxK5U1wW2rnOQXUwYnvcEKFk0VHvaDBGwjfVFoK/J0Sy3ulCBtLI RkYE762WAcgmw3R49Q3w==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gwQ1p-00066w-Cp; Wed, 20 Feb 2019 11:27:05 +0000 Received: from relay12.mail.gandi.net ([217.70.178.232]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gwQ1A-0005Bv-1g for linux-arm-kernel@lists.infradead.org; Wed, 20 Feb 2019 11:26:30 +0000 Received: from localhost (alyon-652-1-153-126.w109-212.abo.wanadoo.fr [109.212.12.126]) (Authenticated sender: alexandre.belloni@bootlin.com) by relay12.mail.gandi.net (Postfix) with ESMTPSA id 10E4C200016; Wed, 20 Feb 2019 11:26:14 +0000 (UTC) From: Alexandre Belloni To: Stephen Boyd Subject: [PATCH 1/7] clk: at91: allow configuring peripheral PCR layout Date: Wed, 20 Feb 2019 12:25:59 +0100 Message-Id: <20190220112605.23095-2-alexandre.belloni@bootlin.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190220112605.23095-1-alexandre.belloni@bootlin.com> References: <20190220112605.23095-1-alexandre.belloni@bootlin.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190220_032624_785549_88EE571E X-CRM114-Status: GOOD ( 13.48 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Alexandre Belloni , linux-kernel@vger.kernel.org, Michael Turquette , Claudiu Beznea , linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The PCR register actually changed layout for each SoC. By chance, this didn't have impact on sama5d[2-4] support but since sama5d3, PID is seven bits wide and sama5d4 and sama5d2 don't have DIV. For the DT backward compatibility, keep the layout as is. Signed-off-by: Alexandre Belloni --- drivers/clk/at91/at91sam9x5.c | 9 ++++++ drivers/clk/at91/clk-peripheral.c | 46 ++++++++++++++++--------------- drivers/clk/at91/dt-compat.c | 9 ++++++ drivers/clk/at91/pmc.h | 12 ++++++++ drivers/clk/at91/sama5d2.c | 9 ++++++ drivers/clk/at91/sama5d4.c | 8 ++++++ include/linux/clk/at91_pmc.h | 3 -- 7 files changed, 71 insertions(+), 25 deletions(-) diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c index 3487e03d4bc6..f5cfcbd85f10 100644 --- a/drivers/clk/at91/at91sam9x5.c +++ b/drivers/clk/at91/at91sam9x5.c @@ -49,6 +49,13 @@ static const struct { { .n = "pck1", .p = "prog1", .id = 9 }, }; +static const struct clk_pcr_layout at91sam9x5_pcr_layout = { + .offset = 0x10c, + .cmd = BIT(12), + .pid_mask = GENMASK(5, 0), + .div_mask = GENMASK(17, 16), +}; + struct pck { char *n; u8 id; @@ -242,6 +249,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, for (i = 0; i < ARRAY_SIZE(at91sam9x5_periphck); i++) { hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &at91sam9x5_pcr_layout, at91sam9x5_periphck[i].n, "masterck", at91sam9x5_periphck[i].id, @@ -254,6 +262,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, for (i = 0; extra_pcks[i].id; i++) { hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &at91sam9x5_pcr_layout, extra_pcks[i].n, "masterck", extra_pcks[i].id, diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c index 65c1defa78e4..6b7748b9588a 100644 --- a/drivers/clk/at91/clk-peripheral.c +++ b/drivers/clk/at91/clk-peripheral.c @@ -8,6 +8,7 @@ * */ +#include #include #include #include @@ -23,9 +24,6 @@ DEFINE_SPINLOCK(pmc_pcr_lock); #define PERIPHERAL_ID_MAX 31 #define PERIPHERAL_MASK(id) (1 << ((id) & PERIPHERAL_ID_MAX)) -#define PERIPHERAL_RSHIFT_MASK 0x3 -#define PERIPHERAL_RSHIFT(val) (((val) >> 16) & PERIPHERAL_RSHIFT_MASK) - #define PERIPHERAL_MAX_SHIFT 3 struct clk_peripheral { @@ -43,6 +41,7 @@ struct clk_sam9x5_peripheral { spinlock_t *lock; u32 id; u32 div; + const struct clk_pcr_layout *layout; bool auto_div; }; @@ -169,13 +168,13 @@ static int clk_sam9x5_peripheral_enable(struct clk_hw *hw) return 0; spin_lock_irqsave(periph->lock, flags); - regmap_write(periph->regmap, AT91_PMC_PCR, - (periph->id & AT91_PMC_PCR_PID_MASK)); - regmap_update_bits(periph->regmap, AT91_PMC_PCR, - AT91_PMC_PCR_DIV_MASK | AT91_PMC_PCR_CMD | + regmap_write(periph->regmap, periph->layout->offset, + (periph->id & periph->layout->pid_mask)); + regmap_update_bits(periph->regmap, periph->layout->offset, + periph->layout->div_mask | periph->layout->cmd | AT91_PMC_PCR_EN, - AT91_PMC_PCR_DIV(periph->div) | - AT91_PMC_PCR_CMD | + field_prep(periph->layout->div_mask, periph->div) | + periph->layout->cmd | AT91_PMC_PCR_EN); spin_unlock_irqrestore(periph->lock, flags); @@ -191,11 +190,11 @@ static void clk_sam9x5_peripheral_disable(struct clk_hw *hw) return; spin_lock_irqsave(periph->lock, flags); - regmap_write(periph->regmap, AT91_PMC_PCR, - (periph->id & AT91_PMC_PCR_PID_MASK)); - regmap_update_bits(periph->regmap, AT91_PMC_PCR, - AT91_PMC_PCR_EN | AT91_PMC_PCR_CMD, - AT91_PMC_PCR_CMD); + regmap_write(periph->regmap, periph->layout->offset, + (periph->id & periph->layout->pid_mask)); + regmap_update_bits(periph->regmap, periph->layout->offset, + AT91_PMC_PCR_EN | periph->layout->cmd, + periph->layout->cmd); spin_unlock_irqrestore(periph->lock, flags); } @@ -209,9 +208,9 @@ static int clk_sam9x5_peripheral_is_enabled(struct clk_hw *hw) return 1; spin_lock_irqsave(periph->lock, flags); - regmap_write(periph->regmap, AT91_PMC_PCR, - (periph->id & AT91_PMC_PCR_PID_MASK)); - regmap_read(periph->regmap, AT91_PMC_PCR, &status); + regmap_write(periph->regmap, periph->layout->offset, + (periph->id & periph->layout->pid_mask)); + regmap_read(periph->regmap, periph->layout->offset, &status); spin_unlock_irqrestore(periph->lock, flags); return status & AT91_PMC_PCR_EN ? 1 : 0; @@ -229,13 +228,13 @@ clk_sam9x5_peripheral_recalc_rate(struct clk_hw *hw, return parent_rate; spin_lock_irqsave(periph->lock, flags); - regmap_write(periph->regmap, AT91_PMC_PCR, - (periph->id & AT91_PMC_PCR_PID_MASK)); - regmap_read(periph->regmap, AT91_PMC_PCR, &status); + regmap_write(periph->regmap, periph->layout->offset, + (periph->id & periph->layout->pid_mask)); + regmap_read(periph->regmap, periph->layout->offset, &status); spin_unlock_irqrestore(periph->lock, flags); if (status & AT91_PMC_PCR_EN) { - periph->div = PERIPHERAL_RSHIFT(status); + periph->div = field_get(periph->layout->div_mask, status); periph->auto_div = false; } else { clk_sam9x5_peripheral_autodiv(periph); @@ -328,6 +327,7 @@ static const struct clk_ops sam9x5_peripheral_ops = { struct clk_hw * __init at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, + const struct clk_pcr_layout *layout, const char *name, const char *parent_name, u32 id, const struct clk_range *range) { @@ -354,7 +354,9 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, periph->div = 0; periph->regmap = regmap; periph->lock = lock; - periph->auto_div = true; + if (layout->div_mask) + periph->auto_div = true; + periph->layout = layout; periph->range = *range; hw = &periph->hw; diff --git a/drivers/clk/at91/dt-compat.c b/drivers/clk/at91/dt-compat.c index b95bb4e2a927..aa09072f36db 100644 --- a/drivers/clk/at91/dt-compat.c +++ b/drivers/clk/at91/dt-compat.c @@ -93,6 +93,14 @@ CLK_OF_DECLARE(of_sama5d2_clk_audio_pll_pmc_setup, of_sama5d2_clk_audio_pll_pmc_setup); #endif /* CONFIG_HAVE_AT91_AUDIO_PLL */ +static const struct clk_pcr_layout dt_pcr_layout = { + .offset = 0x10c, + .cmd = BIT(12), + .pid_mask = GENMASK(5, 0), + .div_mask = GENMASK(17, 16), + .gckcss_mask = GENMASK(10, 8), +}; + #ifdef CONFIG_HAVE_AT91_GENERATED_CLK #define GENERATED_SOURCE_MAX 6 @@ -448,6 +456,7 @@ of_at91_clk_periph_setup(struct device_node *np, u8 type) hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &dt_pcr_layout, name, parent_name, id, &range); diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 672a79bda88c..616c04588093 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -80,6 +80,17 @@ extern const struct clk_programmable_layout at91rm9200_programmable_layout; extern const struct clk_programmable_layout at91sam9g45_programmable_layout; extern const struct clk_programmable_layout at91sam9x5_programmable_layout; +struct clk_pcr_layout { + u32 offset; + u32 cmd; + u32 div_mask; + u32 gckcss_mask; + u32 pid_mask; +}; + +#define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1)) +#define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask)) + #define ndck(a, s) (a[s - 1].id + 1) #define nck(a) (a[ARRAY_SIZE(a) - 1].id + 1) struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem, @@ -143,6 +154,7 @@ at91_clk_register_peripheral(struct regmap *regmap, const char *name, const char *parent_name, u32 id); struct clk_hw * __init at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, + const struct clk_pcr_layout *layout, const char *name, const char *parent_name, u32 id, const struct clk_range *range); diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c index cd0ef7274fdb..f3f1ce2013d4 100644 --- a/drivers/clk/at91/sama5d2.c +++ b/drivers/clk/at91/sama5d2.c @@ -28,6 +28,13 @@ static const struct clk_pll_characteristics plla_characteristics = { .out = plla_out, }; +static const struct clk_pcr_layout sama5d2_pcr_layout = { + .offset = 0x10c, + .cmd = BIT(12), + .gckcss_mask = GENMASK(10, 8), + .pid_mask = GENMASK(6, 0), +}; + static const struct { char *n; char *p; @@ -265,6 +272,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np) for (i = 0; i < ARRAY_SIZE(sama5d2_periphck); i++) { hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &sama5d2_pcr_layout, sama5d2_periphck[i].n, "masterck", sama5d2_periphck[i].id, @@ -277,6 +285,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np) for (i = 0; i < ARRAY_SIZE(sama5d2_periph32ck); i++) { hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &sama5d2_pcr_layout, sama5d2_periph32ck[i].n, "h32mxck", sama5d2_periph32ck[i].id, diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c index b645a9d59cdb..840edca77821 100644 --- a/drivers/clk/at91/sama5d4.c +++ b/drivers/clk/at91/sama5d4.c @@ -28,6 +28,12 @@ static const struct clk_pll_characteristics plla_characteristics = { .out = plla_out, }; +static const struct clk_pcr_layout sama5d4_pcr_layout = { + .offset = 0x10c, + .cmd = BIT(12), + .pid_mask = GENMASK(6, 0), +}; + static const struct { char *n; char *p; @@ -232,6 +238,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np) for (i = 0; i < ARRAY_SIZE(sama5d4_periphck); i++) { hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &sama5d4_pcr_layout, sama5d4_periphck[i].n, "masterck", sama5d4_periphck[i].id, @@ -244,6 +251,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np) for (i = 0; i < ARRAY_SIZE(sama5d4_periph32ck); i++) { hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &sama5d4_pcr_layout, sama5d4_periph32ck[i].n, "h32mxck", sama5d4_periph32ck[i].id, diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h index 931ab05f771d..b97b8dcbffe6 100644 --- a/include/linux/clk/at91_pmc.h +++ b/include/linux/clk/at91_pmc.h @@ -191,9 +191,6 @@ #define AT91_PMC_PCR_GCKCSS_MASK (0x7 << AT91_PMC_PCR_GCKCSS_OFFSET) #define AT91_PMC_PCR_GCKCSS(n) ((n) << AT91_PMC_PCR_GCKCSS_OFFSET) /* GCK Clock Source Selection */ #define AT91_PMC_PCR_CMD (0x1 << 12) /* Command (read=0, write=1) */ -#define AT91_PMC_PCR_DIV_OFFSET 16 -#define AT91_PMC_PCR_DIV_MASK (0x3 << AT91_PMC_PCR_DIV_OFFSET) -#define AT91_PMC_PCR_DIV(n) ((n) << AT91_PMC_PCR_DIV_OFFSET) /* Divisor Value */ #define AT91_PMC_PCR_GCKDIV_OFFSET 20 #define AT91_PMC_PCR_GCKDIV_MASK (0xff << AT91_PMC_PCR_GCKDIV_OFFSET) #define AT91_PMC_PCR_GCKDIV(n) ((n) << AT91_PMC_PCR_GCKDIV_OFFSET) /* Generated Clock Divisor Value */ From patchwork Wed Feb 20 11:26:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Belloni X-Patchwork-Id: 10821909 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 D96D81575 for ; Wed, 20 Feb 2019 11:26:55 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id BE6772DFDC for ; Wed, 20 Feb 2019 11:26:55 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id B2A712DFEC; Wed, 20 Feb 2019 11:26:55 +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=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2059F2DFDC for ; Wed, 20 Feb 2019 11:26:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=roa0t33fdwkrmO6UWvRaBEJ0xGWZtIS+l6K7MUUuGFA=; b=FBOXgTJfK6C00V LzyxfWHHTA7as+TsSwA1l/Ch0CfOfrnIRfhLIL77VA1G2xKvs6v8J+HnrxiCw6+sXIv43LO2k3DRW OYBHCHCKxGkwprZKBB01aRA8XB+QJxoQaxhD0cugMRIXJjpepUbqik1LzAXZvcGQAcARXAnOGTEZs Fh/bYM3tNX37kqJYUFZgwQ+CJxMhQxnoFQvigM2G3sn1ytVq5B8Nek4MCwQpPG2R9Ah93NEIj5y4c Z3p/T3vNaxO7EAsWia1y0tBfq/urUsJ/YDiNymZ0k3bO2+/+kza/JrVN72cSoTMUIwTn1MT0Gnwpp 1w6uUatgP+BOKYNJQxFQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gwQ1d-0005sb-Jf; Wed, 20 Feb 2019 11:26:53 +0000 Received: from relay10.mail.gandi.net ([217.70.178.230]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gwQ17-00059r-HJ for linux-arm-kernel@lists.infradead.org; Wed, 20 Feb 2019 11:26:30 +0000 Received: from localhost (alyon-652-1-153-126.w109-212.abo.wanadoo.fr [109.212.12.126]) (Authenticated sender: alexandre.belloni@bootlin.com) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 00B49240004; Wed, 20 Feb 2019 11:26:17 +0000 (UTC) From: Alexandre Belloni To: Stephen Boyd Subject: [PATCH 2/7] clk: at91: allow configuring generated PCR layout Date: Wed, 20 Feb 2019 12:26:00 +0100 Message-Id: <20190220112605.23095-3-alexandre.belloni@bootlin.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190220112605.23095-1-alexandre.belloni@bootlin.com> References: <20190220112605.23095-1-alexandre.belloni@bootlin.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190220_032622_139418_94BD3419 X-CRM114-Status: GOOD ( 12.10 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Alexandre Belloni , linux-kernel@vger.kernel.org, Michael Turquette , Claudiu Beznea , linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The PCR register layout for GCLKCSS is changing for the future SoCs, allow configuring it. Signed-off-by: Alexandre Belloni --- drivers/clk/at91/clk-generated.c | 48 +++++++++++++++++--------------- drivers/clk/at91/dt-compat.c | 3 +- drivers/clk/at91/pmc.h | 1 + drivers/clk/at91/sama5d2.c | 1 + include/linux/clk/at91_pmc.h | 7 +---- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c index 66e7f7baf958..5f18847965c1 100644 --- a/drivers/clk/at91/clk-generated.c +++ b/drivers/clk/at91/clk-generated.c @@ -11,6 +11,7 @@ * */ +#include #include #include #include @@ -31,6 +32,7 @@ struct clk_generated { spinlock_t *lock; u32 id; u32 gckdiv; + const struct clk_pcr_layout *layout; u8 parent_id; bool audio_pll_allowed; }; @@ -47,14 +49,14 @@ static int clk_generated_enable(struct clk_hw *hw) __func__, gck->gckdiv, gck->parent_id); spin_lock_irqsave(gck->lock, flags); - regmap_write(gck->regmap, AT91_PMC_PCR, - (gck->id & AT91_PMC_PCR_PID_MASK)); - regmap_update_bits(gck->regmap, AT91_PMC_PCR, - AT91_PMC_PCR_GCKDIV_MASK | AT91_PMC_PCR_GCKCSS_MASK | - AT91_PMC_PCR_CMD | AT91_PMC_PCR_GCKEN, - AT91_PMC_PCR_GCKCSS(gck->parent_id) | - AT91_PMC_PCR_CMD | - AT91_PMC_PCR_GCKDIV(gck->gckdiv) | + regmap_write(gck->regmap, gck->layout->offset, + (gck->id & gck->layout->pid_mask)); + regmap_update_bits(gck->regmap, gck->layout->offset, + AT91_PMC_PCR_GCKDIV_MASK | gck->layout->gckcss_mask | + gck->layout->cmd | AT91_PMC_PCR_GCKEN, + field_prep(gck->layout->gckcss_mask, gck->parent_id) | + gck->layout->cmd | + FIELD_PREP(AT91_PMC_PCR_GCKDIV_MASK, gck->gckdiv) | AT91_PMC_PCR_GCKEN); spin_unlock_irqrestore(gck->lock, flags); return 0; @@ -66,11 +68,11 @@ static void clk_generated_disable(struct clk_hw *hw) unsigned long flags; spin_lock_irqsave(gck->lock, flags); - regmap_write(gck->regmap, AT91_PMC_PCR, - (gck->id & AT91_PMC_PCR_PID_MASK)); - regmap_update_bits(gck->regmap, AT91_PMC_PCR, - AT91_PMC_PCR_CMD | AT91_PMC_PCR_GCKEN, - AT91_PMC_PCR_CMD); + regmap_write(gck->regmap, gck->layout->offset, + (gck->id & gck->layout->pid_mask)); + regmap_update_bits(gck->regmap, gck->layout->offset, + gck->layout->cmd | AT91_PMC_PCR_GCKEN, + gck->layout->cmd); spin_unlock_irqrestore(gck->lock, flags); } @@ -81,9 +83,9 @@ static int clk_generated_is_enabled(struct clk_hw *hw) unsigned int status; spin_lock_irqsave(gck->lock, flags); - regmap_write(gck->regmap, AT91_PMC_PCR, - (gck->id & AT91_PMC_PCR_PID_MASK)); - regmap_read(gck->regmap, AT91_PMC_PCR, &status); + regmap_write(gck->regmap, gck->layout->offset, + (gck->id & gck->layout->pid_mask)); + regmap_read(gck->regmap, gck->layout->offset, &status); spin_unlock_irqrestore(gck->lock, flags); return status & AT91_PMC_PCR_GCKEN ? 1 : 0; @@ -259,19 +261,18 @@ static void clk_generated_startup(struct clk_generated *gck) unsigned long flags; spin_lock_irqsave(gck->lock, flags); - regmap_write(gck->regmap, AT91_PMC_PCR, - (gck->id & AT91_PMC_PCR_PID_MASK)); - regmap_read(gck->regmap, AT91_PMC_PCR, &tmp); + regmap_write(gck->regmap, gck->layout->offset, + (gck->id & gck->layout->pid_mask)); + regmap_read(gck->regmap, gck->layout->offset, &tmp); spin_unlock_irqrestore(gck->lock, flags); - gck->parent_id = (tmp & AT91_PMC_PCR_GCKCSS_MASK) - >> AT91_PMC_PCR_GCKCSS_OFFSET; - gck->gckdiv = (tmp & AT91_PMC_PCR_GCKDIV_MASK) - >> AT91_PMC_PCR_GCKDIV_OFFSET; + gck->parent_id = field_get(gck->layout->gckcss_mask, tmp); + gck->gckdiv = FIELD_GET(AT91_PMC_PCR_GCKDIV_MASK, tmp); } struct clk_hw * __init at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, + const struct clk_pcr_layout *layout, const char *name, const char **parent_names, u8 num_parents, u8 id, bool pll_audio, const struct clk_range *range) @@ -298,6 +299,7 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, gck->lock = lock; gck->range = *range; gck->audio_pll_allowed = pll_audio; + gck->layout = layout; clk_generated_startup(gck); hw = &gck->hw; diff --git a/drivers/clk/at91/dt-compat.c b/drivers/clk/at91/dt-compat.c index aa09072f36db..aa1754eac59f 100644 --- a/drivers/clk/at91/dt-compat.c +++ b/drivers/clk/at91/dt-compat.c @@ -154,7 +154,8 @@ static void __init of_sama5d2_clk_generated_setup(struct device_node *np) id == GCK_ID_CLASSD)) pll_audio = true; - hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, name, + hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, + &dt_pcr_layout, name, parent_names, num_parents, id, pll_audio, &range); if (IS_ERR(hw)) diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 616c04588093..4027306b904c 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -116,6 +116,7 @@ at91_clk_register_audio_pll_pmc(struct regmap *regmap, const char *name, struct clk_hw * __init at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, + const struct clk_pcr_layout *layout, const char *name, const char **parent_names, u8 num_parents, u8 id, bool pll_audio, const struct clk_range *range); diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c index f3f1ce2013d4..8f301a517b9d 100644 --- a/drivers/clk/at91/sama5d2.c +++ b/drivers/clk/at91/sama5d2.c @@ -304,6 +304,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np) parent_names[5] = "audiopll_pmcck"; for (i = 0; i < ARRAY_SIZE(sama5d2_gck); i++) { hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, + &sama5d2_pcr_layout, sama5d2_gck[i].n, parent_names, 6, sama5d2_gck[i].id, diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h index b97b8dcbffe6..31f00ebf1315 100644 --- a/include/linux/clk/at91_pmc.h +++ b/include/linux/clk/at91_pmc.h @@ -187,13 +187,8 @@ #define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9 and SAMA5] */ #define AT91_PMC_PCR_PID_MASK 0x3f -#define AT91_PMC_PCR_GCKCSS_OFFSET 8 -#define AT91_PMC_PCR_GCKCSS_MASK (0x7 << AT91_PMC_PCR_GCKCSS_OFFSET) -#define AT91_PMC_PCR_GCKCSS(n) ((n) << AT91_PMC_PCR_GCKCSS_OFFSET) /* GCK Clock Source Selection */ #define AT91_PMC_PCR_CMD (0x1 << 12) /* Command (read=0, write=1) */ -#define AT91_PMC_PCR_GCKDIV_OFFSET 20 -#define AT91_PMC_PCR_GCKDIV_MASK (0xff << AT91_PMC_PCR_GCKDIV_OFFSET) -#define AT91_PMC_PCR_GCKDIV(n) ((n) << AT91_PMC_PCR_GCKDIV_OFFSET) /* Generated Clock Divisor Value */ +#define AT91_PMC_PCR_GCKDIV_MASK GENMASK(27, 20) #define AT91_PMC_PCR_EN (0x1 << 28) /* Enable */ #define AT91_PMC_PCR_GCKEN (0x1 << 29) /* GCK Enable */ From patchwork Wed Feb 20 11:26:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Belloni X-Patchwork-Id: 10821903 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 6DFC61575 for ; Wed, 20 Feb 2019 11:26:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 53C232DFDC for ; Wed, 20 Feb 2019 11:26:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 483E92DFEC; Wed, 20 Feb 2019 11:26:34 +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=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E96102DFDC for ; Wed, 20 Feb 2019 11:26:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=VUnV1rWq+izq7t9PBMrbibP3yjstCOywJY0OiVol8xI=; b=AAWPtRjN/hPDeL 3+Uak4P0XWfDphTL73un1nfSeHBKNoF33AcOTcDX1cOrDHxhDThj8BKEFkeJEVMH9Ngj7cUgKEagf gxLCue6I2gOpDA+Lt0LKX+S7g91bUedaYjfWsJJb4ATfMQKKir6jyOfWR7pMm73zK8GjW5DNC1Vzc YAZ4EEdHDkjXSXEk1HQ/7sfhqrLRD9X5+oyFHFa+xRKuNKr1AUVPHhPqHv8gKXpayp5E3vU/Q/Ind dY9QYtDYYZaH4VH3XBmuQZOsyynfRd/sPf3pi2kuk+yc2YMF82EYYuffSyp83R6LS26/dgegFxzeH 1XLRoCSqxLUw5rSjROQQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gwQ1I-0005Ps-Kf; Wed, 20 Feb 2019 11:26:32 +0000 Received: from relay10.mail.gandi.net ([217.70.178.230]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gwQ19-0005D1-Ef for linux-arm-kernel@lists.infradead.org; Wed, 20 Feb 2019 11:26:30 +0000 Received: from localhost (alyon-652-1-153-126.w109-212.abo.wanadoo.fr [109.212.12.126]) (Authenticated sender: alexandre.belloni@bootlin.com) by relay10.mail.gandi.net (Postfix) with ESMTPSA id 4FB70240009; Wed, 20 Feb 2019 11:26:20 +0000 (UTC) From: Alexandre Belloni To: Stephen Boyd Subject: [PATCH 3/7] clk: at91: usb: Add sam9x60 support Date: Wed, 20 Feb 2019 12:26:01 +0100 Message-Id: <20190220112605.23095-4-alexandre.belloni@bootlin.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190220112605.23095-1-alexandre.belloni@bootlin.com> References: <20190220112605.23095-1-alexandre.belloni@bootlin.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190220_032624_399995_C0DB6ADE X-CRM114-Status: GOOD ( 10.96 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Alexandre Belloni , linux-kernel@vger.kernel.org, Michael Turquette , Claudiu Beznea , linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The sam9x60 USB clock supports four different parents, ensure they can be selected. Signed-off-by: Alexandre Belloni --- drivers/clk/at91/clk-usb.c | 33 +++++++++++++++++++++++++++------ drivers/clk/at91/pmc.h | 3 +++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c index 79ee1c760f2a..ebc37ee33518 100644 --- a/drivers/clk/at91/clk-usb.c +++ b/drivers/clk/at91/clk-usb.c @@ -23,9 +23,13 @@ #define RM9200_USB_DIV_SHIFT 28 #define RM9200_USB_DIV_TAB_SIZE 4 +#define SAM9X5_USBS_MASK GENMASK(0, 0) +#define SAM9X60_USBS_MASK GENMASK(1, 0) + struct at91sam9x5_clk_usb { struct clk_hw hw; struct regmap *regmap; + u32 usbs_mask; }; #define to_at91sam9x5_clk_usb(hw) \ @@ -111,8 +115,7 @@ static int at91sam9x5_clk_usb_set_parent(struct clk_hw *hw, u8 index) if (index > 1) return -EINVAL; - regmap_update_bits(usb->regmap, AT91_PMC_USB, AT91_PMC_USBS, - index ? AT91_PMC_USBS : 0); + regmap_update_bits(usb->regmap, AT91_PMC_USB, usb->usbs_mask, index); return 0; } @@ -124,7 +127,7 @@ static u8 at91sam9x5_clk_usb_get_parent(struct clk_hw *hw) regmap_read(usb->regmap, AT91_PMC_USB, &usbr); - return usbr & AT91_PMC_USBS; + return usbr & usb->usbs_mask; } static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, @@ -190,9 +193,10 @@ static const struct clk_ops at91sam9n12_usb_ops = { .set_rate = at91sam9x5_clk_usb_set_rate, }; -struct clk_hw * __init -at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, - const char **parent_names, u8 num_parents) +static struct clk_hw * __init +_at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, + const char **parent_names, u8 num_parents, + u32 usbs_mask) { struct at91sam9x5_clk_usb *usb; struct clk_hw *hw; @@ -212,6 +216,7 @@ at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, usb->hw.init = &init; usb->regmap = regmap; + usb->usbs_mask = SAM9X5_USBS_MASK; hw = &usb->hw; ret = clk_hw_register(NULL, &usb->hw); @@ -223,6 +228,22 @@ at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, return hw; } +struct clk_hw * __init +at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name, + const char **parent_names, u8 num_parents) +{ + return _at91sam9x5_clk_register_usb(regmap, name, parent_names, + num_parents, SAM9X5_USBS_MASK); +} + +struct clk_hw * __init +sam9x60_clk_register_usb(struct regmap *regmap, const char *name, + const char **parent_names, u8 num_parents) +{ + return _at91sam9x5_clk_register_usb(regmap, name, parent_names, + num_parents, SAM9X60_USBS_MASK); +} + struct clk_hw * __init at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name, const char *parent_name) diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 4027306b904c..44345e4ab1c9 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -194,6 +194,9 @@ struct clk_hw * __init at91sam9n12_clk_register_usb(struct regmap *regmap, const char *name, const char *parent_name); struct clk_hw * __init +sam9x60_clk_register_usb(struct regmap *regmap, const char *name, + const char **parent_names, u8 num_parents); +struct clk_hw * __init at91rm9200_clk_register_usb(struct regmap *regmap, const char *name, const char *parent_name, const u32 *divisors); From patchwork Wed Feb 20 11:26:02 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Belloni X-Patchwork-Id: 10821907 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 3E9E214E1 for ; Wed, 20 Feb 2019 11:26:44 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 21F782DFDC for ; Wed, 20 Feb 2019 11:26:44 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 132DC2DFEC; Wed, 20 Feb 2019 11:26:44 +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=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9CE162DFDC for ; Wed, 20 Feb 2019 11:26:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Rv0E8oHw/TQIrgEavxnKj+/jahmMAEth+Tk4pn/Zak8=; b=nHSEiGG/AV6tqz gxO6oIUGbQyX82cK4ly7imb+8w7ELB18+m8qKdsfDcD3b4qtGIKmX8FPKCXfkwjx2GQiZMF36CS1p zPJg6EX6xThRyjif0CMfI61VwRzUH4+3hvGMBbZanIkW1DHCKpPoPX2o0LYx178tSdDktr9K/mhmM TIKNz0kvowcplH02jbIuKQWuA6caAxC8KOzOAluQrLBsTjn8cJh8sTp2A3TtiAqEEH0SIizGTINjb SAn1nzJIHyA8uXglZ1ys4Cac5DYeeBtFRYy9Yf+ZDqe/0we612W6sxOEfhpqqo4X+15sCVgFmFSKR xJbq5X7m219gKLV7zIxw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gwQ1R-0005br-RE; Wed, 20 Feb 2019 11:26:41 +0000 Received: from relay12.mail.gandi.net ([217.70.178.232]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gwQ1B-0005Fz-G4 for linux-arm-kernel@lists.infradead.org; Wed, 20 Feb 2019 11:26:30 +0000 Received: from localhost (alyon-652-1-153-126.w109-212.abo.wanadoo.fr [109.212.12.126]) (Authenticated sender: alexandre.belloni@bootlin.com) by relay12.mail.gandi.net (Postfix) with ESMTPSA id C143F200007; Wed, 20 Feb 2019 11:26:22 +0000 (UTC) From: Alexandre Belloni To: Stephen Boyd Subject: [PATCH 4/7] clk: at91: master: Add sam9x60 support Date: Wed, 20 Feb 2019 12:26:02 +0100 Message-Id: <20190220112605.23095-5-alexandre.belloni@bootlin.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190220112605.23095-1-alexandre.belloni@bootlin.com> References: <20190220112605.23095-1-alexandre.belloni@bootlin.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190220_032625_934413_45D8064E X-CRM114-Status: GOOD ( 12.10 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Alexandre Belloni , linux-kernel@vger.kernel.org, Michael Turquette , Claudiu Beznea , linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The sam9x60 cpu clock is located at a different offset but is otherwise similar to the master clock. Signed-off-by: Alexandre Belloni --- drivers/clk/at91/clk-master.c | 8 +++++--- drivers/clk/at91/pmc.h | 1 + include/linux/clk/at91_pmc.h | 2 ++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c index eb53b4a8fab6..12b5bf4cc7bb 100644 --- a/drivers/clk/at91/clk-master.c +++ b/drivers/clk/at91/clk-master.c @@ -29,6 +29,7 @@ struct clk_master { struct regmap *regmap; const struct clk_master_layout *layout; const struct clk_master_characteristics *characteristics; + u32 mckr; }; static inline bool clk_master_ready(struct regmap *regmap) @@ -69,7 +70,7 @@ static unsigned long clk_master_recalc_rate(struct clk_hw *hw, master->characteristics; unsigned int mckr; - regmap_read(master->regmap, AT91_PMC_MCKR, &mckr); + regmap_read(master->regmap, master->layout->offset, &mckr); mckr &= layout->mask; pres = (mckr >> layout->pres_shift) & MASTER_PRES_MASK; @@ -95,7 +96,7 @@ static u8 clk_master_get_parent(struct clk_hw *hw) struct clk_master *master = to_clk_master(hw); unsigned int mckr; - regmap_read(master->regmap, AT91_PMC_MCKR, &mckr); + regmap_read(master->regmap, master->layout->offset, &mckr); return mckr & AT91_PMC_CSS; } @@ -147,13 +148,14 @@ at91_clk_register_master(struct regmap *regmap, return hw; } - const struct clk_master_layout at91rm9200_master_layout = { .mask = 0x31F, .pres_shift = 2, + .offset = AT91_PMC_MCKR, }; const struct clk_master_layout at91sam9x5_master_layout = { .mask = 0x373, .pres_shift = 4, + .offset = AT91_PMC_MCKR, }; diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 44345e4ab1c9..4a30c20f17f1 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -38,6 +38,7 @@ struct clk_range { #define CLK_RANGE(MIN, MAX) {.min = MIN, .max = MAX,} struct clk_master_layout { + u32 offset; u32 mask; u8 pres_shift; }; diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h index 31f00ebf1315..0c53f26ae3d3 100644 --- a/include/linux/clk/at91_pmc.h +++ b/include/linux/clk/at91_pmc.h @@ -74,6 +74,8 @@ #define AT91_PMC_USBDIV_4 (2 << 28) #define AT91_PMC_USB96M (1 << 28) /* Divider by 2 Enable (PLLB only) */ +#define AT91_PMC_CPU_CKR 0x28 /* CPU Clock Register */ + #define AT91_PMC_MCKR 0x30 /* Master Clock Register */ #define AT91_PMC_CSS (3 << 0) /* Master Clock Selection */ #define AT91_PMC_CSS_SLOW (0 << 0) From patchwork Wed Feb 20 11:26:03 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Belloni X-Patchwork-Id: 10821917 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 577E714E1 for ; Wed, 20 Feb 2019 11:28:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2CEBC2DFEC for ; Wed, 20 Feb 2019 11:28:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1A7702E002; Wed, 20 Feb 2019 11:28:01 +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=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3948C2DFEC for ; Wed, 20 Feb 2019 11:28:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=S0c8BWJTmCEtYGz1DRHtqWIhudwoll3N1yrI7gsGaAU=; b=Emuh1ac+ULm524 TUtkCGYAsjrOQbMoRtX+fgifbI0LYVZTRE4jwjD1atxE0MdoC0Kh+o5nyzD1ARZzfy6Et3FquPB7/ 7xoOV69bjTNcK7FUDY1y+ENycy04QaEh91cA84gjOlNmSG6rDJO0iWTc2Z6oRSmENwFuDBgd38epJ jJfLDixdP4xw+zd9Ha4Uzih6I4ylX28mMFfLFDgs3UJ+H+ARZiD7VjEMB2JrHtOAjqYPBhRtrVGnC d0WU3ryrPaBMpxBUdMinT5CIwkgFYap27uqFD6hER1Jr8jgvfTW6b2Tlv6c8ecJBRdCrW69IzHBYz /jbziSKnnu3HUWCt0RVA==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gwQ2g-00079k-9e; Wed, 20 Feb 2019 11:27:58 +0000 Received: from relay9-d.mail.gandi.net ([217.70.183.199]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gwQ1J-0005Pg-TG for linux-arm-kernel@lists.infradead.org; Wed, 20 Feb 2019 11:26:44 +0000 X-Originating-IP: 109.212.12.126 Received: from localhost (alyon-652-1-153-126.w109-212.abo.wanadoo.fr [109.212.12.126]) (Authenticated sender: alexandre.belloni@bootlin.com) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 4CF72FF80A; Wed, 20 Feb 2019 11:26:25 +0000 (UTC) From: Alexandre Belloni To: Stephen Boyd Subject: [PATCH 5/7] clk: at91: add sam9x60 PLL driver Date: Wed, 20 Feb 2019 12:26:03 +0100 Message-Id: <20190220112605.23095-6-alexandre.belloni@bootlin.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190220112605.23095-1-alexandre.belloni@bootlin.com> References: <20190220112605.23095-1-alexandre.belloni@bootlin.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190220_032634_844307_1161F861 X-CRM114-Status: GOOD ( 19.91 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Alexandre Belloni , linux-kernel@vger.kernel.org, Michael Turquette , Claudiu Beznea , linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP The PLLs on the sam9x60 (PLLA and USB PLL) use a different register set and programming model than the previous SoCs. Signed-off-by: Alexandre Belloni --- drivers/clk/at91/Makefile | 1 + drivers/clk/at91/clk-sam9x60-pll.c | 329 +++++++++++++++++++++++++++++ drivers/clk/at91/pmc.h | 6 + 3 files changed, 336 insertions(+) create mode 100644 drivers/clk/at91/clk-sam9x60-pll.c diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile index c75df1cad60e..0a30fc8dfcb0 100644 --- a/drivers/clk/at91/Makefile +++ b/drivers/clk/at91/Makefile @@ -14,6 +14,7 @@ obj-$(CONFIG_HAVE_AT91_SMD) += clk-smd.o obj-$(CONFIG_HAVE_AT91_H32MX) += clk-h32mx.o obj-$(CONFIG_HAVE_AT91_GENERATED_CLK) += clk-generated.o obj-$(CONFIG_HAVE_AT91_I2S_MUX_CLK) += clk-i2s-mux.o +obj-$(CONFIG_HAVE_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o obj-$(CONFIG_SOC_AT91SAM9) += at91sam9260.o at91sam9rl.o at91sam9x5.o obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c new file mode 100644 index 000000000000..a3d5c729e8b6 --- /dev/null +++ b/drivers/clk/at91/clk-sam9x60-pll.c @@ -0,0 +1,329 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2019 Microchip Technology Inc. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "pmc.h" + +#define PMC_PLL_CTRL0 0xc +#define PMC_PLL_CTRL0_DIV_MSK GENMASK(7, 0) +#define PMC_PLL_CTRL0_ENPLL BIT(28) +#define PMC_PLL_CTRL0_ENPLLCK BIT(29) +#define PMC_PLL_CTRL0_ENLOCK BIT(31) + +#define PMC_PLL_CTRL1 0x10 +#define PMC_PLL_CTRL1_FRACR_MSK GENMASK(21, 0) +#define PMC_PLL_CTRL1_MUL_MSK GENMASK(30, 24) + +#define PMC_PLL_ACR 0x18 +#define PMC_PLL_ACR_UTMIVR BIT(12) +#define PMC_PLL_ACR_UTMIBG BIT(13) +#define PMC_PLL_ACR_LOOP_FILTER_MSK GENMASK(31, 24) + +#define PMC_PLL_UPDT 0x1c +#define PMC_PLL_UPDT_UPDATE BIT(8) + +#define PMC_PLL_ISR0 0xec + +#define PLL_DIV_MAX (FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1) +#define UPLL_DIV 2 +#define PLL_MUL_MAX (FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1) + +#define PLL_MAX_ID 1 + +struct sam9x60_pll { + struct clk_hw hw; + struct regmap *regmap; + spinlock_t *lock; + const struct clk_pll_characteristics *characteristics; + u32 frac; + u8 id; + u8 div; + u16 mul; +}; + +#define to_sam9x60_pll(hw) container_of(hw, struct sam9x60_pll, hw) + +static inline bool sam9x60_pll_ready(struct regmap *regmap, int id) +{ + unsigned int status; + + regmap_read(regmap, PMC_PLL_ISR0, &status); + + return !!(status & BIT(id)); +} + +static int sam9x60_pll_prepare(struct clk_hw *hw) +{ + struct sam9x60_pll *pll = to_sam9x60_pll(hw); + struct regmap *regmap = pll->regmap; + unsigned long flags; + u8 div; + u16 mul; + u32 val; + + spin_lock_irqsave(pll->lock, flags); + regmap_write(regmap, PMC_PLL_UPDT, pll->id); + + regmap_read(regmap, PMC_PLL_CTRL0, &val); + div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val); + + regmap_read(regmap, PMC_PLL_CTRL1, &val); + mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, val); + + if (sam9x60_pll_ready(regmap, pll->id) && + (div == pll->div && mul == pll->mul)) { + spin_unlock_irqrestore(pll->lock, flags); + return 0; + } + + /* Recommended value for PMC_PLL_ACR.LOOP_FILTER is 0x9 */ + regmap_update_bits(regmap, PMC_PLL_ACR, + PMC_PLL_ACR_LOOP_FILTER_MSK, 0x9); + + regmap_write(regmap, PMC_PLL_CTRL1, + FIELD_PREP(PMC_PLL_CTRL1_MUL_MSK, pll->mul)); + + if (pll->characteristics->upll) { + /* Enable the UTMI internal bandgap */ + regmap_update_bits(regmap, PMC_PLL_ACR, + PMC_PLL_ACR_UTMIBG, PMC_PLL_ACR_UTMIBG); + + udelay(10); + + /* Enable the UTMI internal regulator */ + regmap_update_bits(regmap, PMC_PLL_ACR, + PMC_PLL_ACR_UTMIVR, PMC_PLL_ACR_UTMIVR); + + udelay(10); + } + + regmap_update_bits(regmap, PMC_PLL_UPDT, + PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE); + + regmap_write(regmap, PMC_PLL_CTRL0, + PMC_PLL_CTRL0_ENLOCK | PMC_PLL_CTRL0_ENPLL | + PMC_PLL_CTRL0_ENPLLCK | pll->div); + + regmap_update_bits(regmap, PMC_PLL_UPDT, + PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE); + + while (!sam9x60_pll_ready(regmap, pll->id)) + cpu_relax(); + + spin_unlock_irqrestore(pll->lock, flags); + + return 0; +} + +static int sam9x60_pll_is_prepared(struct clk_hw *hw) +{ + struct sam9x60_pll *pll = to_sam9x60_pll(hw); + + return sam9x60_pll_ready(pll->regmap, pll->id); +} + +static void sam9x60_pll_unprepare(struct clk_hw *hw) +{ + struct sam9x60_pll *pll = to_sam9x60_pll(hw); + unsigned long flags; + + spin_lock_irqsave(pll->lock, flags); + + regmap_write(pll->regmap, PMC_PLL_UPDT, pll->id); + + regmap_update_bits(pll->regmap, PMC_PLL_CTRL0, + PMC_PLL_CTRL0_ENPLLCK, 0); + + regmap_update_bits(pll->regmap, PMC_PLL_UPDT, + PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE); + + regmap_update_bits(pll->regmap, PMC_PLL_CTRL0, PMC_PLL_CTRL0_ENPLL, 0); + + if (pll->characteristics->upll) + regmap_update_bits(pll->regmap, PMC_PLL_ACR, + PMC_PLL_ACR_UTMIBG | PMC_PLL_ACR_UTMIVR, 0); + + regmap_update_bits(pll->regmap, PMC_PLL_UPDT, + PMC_PLL_UPDT_UPDATE, PMC_PLL_UPDT_UPDATE); + + spin_unlock_irqrestore(pll->lock, flags); +} + +static unsigned long sam9x60_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct sam9x60_pll *pll = to_sam9x60_pll(hw); + + return (parent_rate * (pll->mul + 1)) / (pll->div + 1); +} + +static long sam9x60_pll_get_best_div_mul(struct sam9x60_pll *pll, + unsigned long rate, + unsigned long parent_rate, + bool update) +{ + const struct clk_pll_characteristics *characteristics = + pll->characteristics; + unsigned long bestremainder = ULONG_MAX; + unsigned long maxdiv, mindiv, tmpdiv; + long bestrate = -ERANGE; + unsigned long bestdiv = 0; + unsigned long bestmul = 0; + unsigned long bestfrac = 0; + + if (rate < characteristics->output[0].min || + rate > characteristics->output[0].max) + return -ERANGE; + + if (!pll->characteristics->upll) { + mindiv = parent_rate / rate; + if (mindiv < 2) + mindiv = 2; + + maxdiv = DIV_ROUND_UP(parent_rate * PLL_MUL_MAX, rate); + if (maxdiv > PLL_DIV_MAX) + maxdiv = PLL_DIV_MAX; + } else { + mindiv = maxdiv = UPLL_DIV; + } + + for (tmpdiv = mindiv; tmpdiv <= maxdiv; tmpdiv++) { + unsigned long remainder; + unsigned long tmprate; + unsigned long tmpmul; + unsigned long tmpfrac = 0; + + /* + * Calculate the multiplier associated with the current + * divider that provide the closest rate to the requested one. + */ + tmpmul = mult_frac(rate, tmpdiv, parent_rate); + tmprate = mult_frac(parent_rate, tmpmul, tmpdiv); + remainder = rate - tmprate; + + if (remainder) { + tmpfrac = DIV_ROUND_CLOSEST_ULL((u64)remainder * tmpdiv * (1 << 22), + parent_rate); + + tmprate += DIV_ROUND_CLOSEST_ULL((u64)tmpfrac * parent_rate, + tmpdiv * (1 << 22)); + + if (tmprate > rate) + remainder = tmprate - rate; + else + remainder = rate - tmprate; + } + + /* + * Compare the remainder with the best remainder found until + * now and elect a new best multiplier/divider pair if the + * current remainder is smaller than the best one. + */ + if (remainder < bestremainder) { + bestremainder = remainder; + bestdiv = tmpdiv; + bestmul = tmpmul; + bestrate = tmprate; + bestfrac = tmpfrac; + } + + /* We've found a perfect match! */ + if (!remainder) + break; + } + + /* Check if bestrate is a valid output rate */ + if (bestrate < characteristics->output[0].min && + bestrate > characteristics->output[0].max) + return -ERANGE; + + if (update) { + pll->div = bestdiv - 1; + pll->mul = bestmul - 1; + pll->frac = bestfrac; + } + + return bestrate; +} + +static long sam9x60_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + struct sam9x60_pll *pll = to_sam9x60_pll(hw); + + return sam9x60_pll_get_best_div_mul(pll, rate, *parent_rate, false); +} + +static int sam9x60_pll_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct sam9x60_pll *pll = to_sam9x60_pll(hw); + + return sam9x60_pll_get_best_div_mul(pll, rate, parent_rate, true); +} + +static const struct clk_ops pll_ops = { + .prepare = sam9x60_pll_prepare, + .unprepare = sam9x60_pll_unprepare, + .is_prepared = sam9x60_pll_is_prepared, + .recalc_rate = sam9x60_pll_recalc_rate, + .round_rate = sam9x60_pll_round_rate, + .set_rate = sam9x60_pll_set_rate, +}; + +struct clk_hw * __init +sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock, + const char *name, const char *parent_name, u8 id, + const struct clk_pll_characteristics *characteristics) +{ + struct sam9x60_pll *pll; + struct clk_hw *hw; + struct clk_init_data init; + unsigned int pllr; + int ret; + + if (id > PLL_MAX_ID) + return ERR_PTR(-EINVAL); + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &pll_ops; + init.parent_names = &parent_name; + init.num_parents = 1; + init.flags = CLK_SET_RATE_GATE; + + pll->id = id; + pll->hw.init = &init; + pll->characteristics = characteristics; + pll->regmap = regmap; + pll->lock = lock; + + regmap_write(regmap, PMC_PLL_UPDT, id); + regmap_read(regmap, PMC_PLL_CTRL0, &pllr); + pll->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, pllr); + regmap_read(regmap, PMC_PLL_CTRL1, &pllr); + pll->mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, pllr); + + hw = &pll->hw; + ret = clk_hw_register(NULL, hw); + if (ret) { + kfree(pll); + hw = ERR_PTR(ret); + } + + return hw; +} + diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 4a30c20f17f1..fb9e9c4cdc8d 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -69,6 +69,7 @@ struct clk_pll_characteristics { struct clk_range *output; u16 *icpll; u8 *out; + u8 upll : 1; }; struct clk_programmable_layout { @@ -169,6 +170,11 @@ struct clk_hw * __init at91_clk_register_plldiv(struct regmap *regmap, const char *name, const char *parent_name); +struct clk_hw * __init +sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock, + const char *name, const char *parent_name, u8 id, + const struct clk_pll_characteristics *characteristics); + struct clk_hw * __init at91_clk_register_programmable(struct regmap *regmap, const char *name, const char **parent_names, u8 num_parents, u8 id, From patchwork Wed Feb 20 11:26:04 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Belloni X-Patchwork-Id: 10821915 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 1266B14E1 for ; Wed, 20 Feb 2019 11:27:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EB1FC2DFEC for ; Wed, 20 Feb 2019 11:27:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DA2592E002; Wed, 20 Feb 2019 11:27:53 +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=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 897D12DFEC for ; Wed, 20 Feb 2019 11:27:53 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=4gpHBRP0DonAZaZARMmrlmvB0hQw0IXjstabjZryvC4=; b=EfJtRFVuz1FrUn nEfmIOWwLquXSl/k5QzGuo5Qj3VpKQoMDF0e6d/WnzDMg/JpSSMGsJ0czIEB7ZqRWlqsx9ZLyaJUW +ZEFqeW1r2OX9exXLlJpKH0e6/7IDH2k/0xLyF3fHpZvFVP4sODNfHjB7KDYpyRp1wdfYQnnt47yM WGsWpQCAT5ZQJvvWH0ZGz+ohzUFsAbkhChBRuREE7vo514v4/E928i28Z8UdGmGh9wL8kIbvJJsJs S4/pMe7cHrgrwtLc8LXqUG2+evgqIC6FZ9UQJEfC2ptSp38z1UeYEr+JR9gpbmTM/TUQSAPYISCPP CuVuTjYVzYaEO+xjYCnw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gwQ2V-0006rO-5x; Wed, 20 Feb 2019 11:27:47 +0000 Received: from relay9-d.mail.gandi.net ([217.70.183.199]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gwQ1J-0005Pf-TB for linux-arm-kernel@lists.infradead.org; Wed, 20 Feb 2019 11:26:37 +0000 X-Originating-IP: 109.212.12.126 Received: from localhost (alyon-652-1-153-126.w109-212.abo.wanadoo.fr [109.212.12.126]) (Authenticated sender: alexandre.belloni@bootlin.com) by relay9-d.mail.gandi.net (Postfix) with ESMTPSA id 64D0DFF809; Wed, 20 Feb 2019 11:26:28 +0000 (UTC) From: Alexandre Belloni To: Stephen Boyd Subject: [PATCH 6/7] dt-bindings: clk: at91: add bindings for SAM9X60 pmc Date: Wed, 20 Feb 2019 12:26:04 +0100 Message-Id: <20190220112605.23095-7-alexandre.belloni@bootlin.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190220112605.23095-1-alexandre.belloni@bootlin.com> References: <20190220112605.23095-1-alexandre.belloni@bootlin.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190220_032634_834820_2B53B126 X-CRM114-Status: UNSURE ( 9.77 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Alexandre Belloni , linux-kernel@vger.kernel.org, Michael Turquette , Claudiu Beznea , Rob Herring , linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Add SAM9X60 PMC compatible string. Cc: Rob Herring Signed-off-by: Alexandre Belloni Reviewed-by: Rob Herring --- Documentation/devicetree/bindings/clock/at91-clock.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/at91-clock.txt b/Documentation/devicetree/bindings/clock/at91-clock.txt index ce1d21102428..e0e4fa67716f 100644 --- a/Documentation/devicetree/bindings/clock/at91-clock.txt +++ b/Documentation/devicetree/bindings/clock/at91-clock.txt @@ -37,7 +37,8 @@ For example: Power Management Controller (PMC): Required properties: -- compatible : shall be "atmel,-pmc", "syscon": +- compatible : shall be "atmel,-pmc", "syscon" or + "microchip,sam9x60-pmc" can be: at91rm9200, at91sam9260, at91sam9261, at91sam9263, at91sam9g45, at91sam9n12, at91sam9rl, at91sam9g15, at91sam9g25, at91sam9g35, at91sam9x25, at91sam9x35, at91sam9x5, From patchwork Wed Feb 20 11:26:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandre Belloni X-Patchwork-Id: 10821913 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 116041575 for ; Wed, 20 Feb 2019 11:27:42 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EA5FE2DFDC for ; Wed, 20 Feb 2019 11:27:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DE9602DFEC; Wed, 20 Feb 2019 11:27:41 +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=-5.2 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 38B072DFDC for ; Wed, 20 Feb 2019 11:27:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=5xMbTSY7Ajez3wRY2Cz8VjCJyRZZYOHtn1WZ7eSNUWE=; b=kuwezUwwPE/hV7 ssZpTPlAabZeykGAIFuLOIEt8RYW5q6GXA3R9i4fClzMPIApPFGPb81rowYKYkKJSfvZVcRZzLlFM fOVqxlGgOFhqm+DUcZfhvN8pfVP7PhAiDsPQwZtBGIJbUz5IDQgRDDrbN/XKyK92nHRhjsdoE+gSQ QBDogxQOVONpEfmVpaK28yhWQaR+8+es9xxBkgQk7uZR4dGRjjHTU/XxsIGWkzxQ13gpAwvU9EIU/ Kg+f9UkDMZfTUvHIUv4OkfA4QeWs5utR5NhM31P6TbnjpjXCk91i1IrWWhOZ/w7CY/MWBXiCLu471 pv7RiwV3AhoarDTd1jqQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gwQ2L-0006es-Us; Wed, 20 Feb 2019 11:27:37 +0000 Received: from relay6-d.mail.gandi.net ([217.70.183.198]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gwQ1S-0005cA-Vt for linux-arm-kernel@lists.infradead.org; Wed, 20 Feb 2019 11:27:00 +0000 X-Originating-IP: 109.212.12.126 Received: from localhost (alyon-652-1-153-126.w109-212.abo.wanadoo.fr [109.212.12.126]) (Authenticated sender: alexandre.belloni@bootlin.com) by relay6-d.mail.gandi.net (Postfix) with ESMTPSA id C267FC0006; Wed, 20 Feb 2019 11:26:30 +0000 (UTC) From: Alexandre Belloni To: Stephen Boyd Subject: [PATCH 7/7] clk: at91: add sam9x60 pmc driver Date: Wed, 20 Feb 2019 12:26:05 +0100 Message-Id: <20190220112605.23095-8-alexandre.belloni@bootlin.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190220112605.23095-1-alexandre.belloni@bootlin.com> References: <20190220112605.23095-1-alexandre.belloni@bootlin.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20190220_032644_394194_4A0E4034 X-CRM114-Status: GOOD ( 13.71 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, Alexandre Belloni , linux-kernel@vger.kernel.org, Michael Turquette , Claudiu Beznea , linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Add a driver for the PMC clocks of the sam9c60. Signed-off-by: Alexandre Belloni --- drivers/clk/at91/Makefile | 1 + drivers/clk/at91/sam9x60.c | 307 +++++++++++++++++++++++++++++++++++++ 2 files changed, 308 insertions(+) create mode 100644 drivers/clk/at91/sam9x60.c diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile index 0a30fc8dfcb0..3732241352ce 100644 --- a/drivers/clk/at91/Makefile +++ b/drivers/clk/at91/Makefile @@ -16,5 +16,6 @@ obj-$(CONFIG_HAVE_AT91_GENERATED_CLK) += clk-generated.o obj-$(CONFIG_HAVE_AT91_I2S_MUX_CLK) += clk-i2s-mux.o obj-$(CONFIG_HAVE_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o obj-$(CONFIG_SOC_AT91SAM9) += at91sam9260.o at91sam9rl.o at91sam9x5.o +obj-$(CONFIG_SOC_SAM9X60) += sam9x60.o obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c new file mode 100644 index 000000000000..22bf51c55bdc --- /dev/null +++ b/drivers/clk/at91/sam9x60.c @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include + +#include + +#include "pmc.h" + +DEFINE_SPINLOCK(pmc_pll_lock); + +static const struct clk_master_characteristics mck_characteristics = { + .output = { .min = 140000000, .max = 200000000 }, + .divisors = { 1, 2, 4, 3 }, + .have_div3_pres = 1, +}; + +static const struct clk_master_layout sam9x60_master_layout = { + .mask = 0x373, + .pres_shift = 4, + .offset = 0x28, +}; + +static struct clk_range plla_outputs[] = { + { .min = 300000000, .max = 600000000 }, +}; + +static const struct clk_pll_characteristics plla_characteristics = { + .input = { .min = 12000000, .max = 48000000 }, + .num_output = ARRAY_SIZE(plla_outputs), + .output = plla_outputs, +}; + +static struct clk_range upll_outputs[] = { + { .min = 300000000, .max = 500000000 }, +}; + +static const struct clk_pll_characteristics upll_characteristics = { + .input = { .min = 12000000, .max = 48000000 }, + .num_output = ARRAY_SIZE(upll_outputs), + .output = upll_outputs, + .upll = true, +}; + +static const struct clk_programmable_layout sam9x60_programmable_layout = { + .pres_shift = 8, + .css_mask = 0x1f, + .have_slck_mck = 0, +}; + +static const struct clk_pcr_layout sam9x60_pcr_layout = { + .offset = 0x88, + .cmd = BIT(31), + .gckcss_mask = GENMASK(12, 8), + .pid_mask = GENMASK(6, 0), +}; + +static const struct { + char *n; + char *p; + u8 id; +} sam9x60_systemck[] = { + { .n = "ddrck", .p = "masterck", .id = 2 }, + { .n = "uhpck", .p = "usbck", .id = 6 }, + { .n = "pck0", .p = "prog0", .id = 8 }, + { .n = "pck1", .p = "prog1", .id = 9 }, + { .n = "qspick", .p = "masterck", .id = 19 }, +}; + +static const struct { + char *n; + u8 id; +} sam9x60_periphck[] = { + { .n = "pioA_clk", .id = 2, }, + { .n = "pioB_clk", .id = 3, }, + { .n = "pioC_clk", .id = 4, }, + { .n = "flex0_clk", .id = 5, }, + { .n = "flex1_clk", .id = 6, }, + { .n = "flex2_clk", .id = 7, }, + { .n = "flex3_clk", .id = 8, }, + { .n = "flex6_clk", .id = 9, }, + { .n = "flex7_clk", .id = 10, }, + { .n = "flex8_clk", .id = 11, }, + { .n = "sdmmc0_clk", .id = 12, }, + { .n = "flex4_clk", .id = 13, }, + { .n = "flex5_clk", .id = 14, }, + { .n = "flex9_clk", .id = 15, }, + { .n = "flex10_clk", .id = 16, }, + { .n = "tcb0_clk", .id = 17, }, + { .n = "pwm_clk", .id = 18, }, + { .n = "adc_clk", .id = 19, }, + { .n = "dma0_clk", .id = 20, }, + { .n = "matrix_clk", .id = 21, }, + { .n = "uhphs_clk", .id = 22, }, + { .n = "udphs_clk", .id = 23, }, + { .n = "macb0_clk", .id = 24, }, + { .n = "lcd_clk", .id = 25, }, + { .n = "sdmmc1_clk", .id = 26, }, + { .n = "macb1_clk", .id = 27, }, + { .n = "ssc_clk", .id = 28, }, + { .n = "can0_clk", .id = 29, }, + { .n = "can1_clk", .id = 30, }, + { .n = "flex11_clk", .id = 32, }, + { .n = "flex12_clk", .id = 33, }, + { .n = "i2s_clk", .id = 34, }, + { .n = "qspi_clk", .id = 35, }, + { .n = "gfx2d_clk", .id = 36, }, + { .n = "pit64b_clk", .id = 37, }, + { .n = "trng_clk", .id = 38, }, + { .n = "aes_clk", .id = 39, }, + { .n = "tdes_clk", .id = 40, }, + { .n = "sha_clk", .id = 41, }, + { .n = "classd_clk", .id = 42, }, + { .n = "isi_clk", .id = 43, }, + { .n = "pioD_clk", .id = 44, }, + { .n = "tcb1_clk", .id = 45, }, + { .n = "dbgu_clk", .id = 47, }, + { .n = "mpddr_clk", .id = 49, }, +}; + +static const struct { + char *n; + u8 id; + struct clk_range r; + bool pll; +} sam9x60_gck[] = { + { .n = "flex0_gclk", .id = 5, }, + { .n = "flex1_gclk", .id = 6, }, + { .n = "flex2_gclk", .id = 7, }, + { .n = "flex3_gclk", .id = 8, }, + { .n = "flex6_gclk", .id = 9, }, + { .n = "flex7_gclk", .id = 10, }, + { .n = "flex8_gclk", .id = 11, }, + { .n = "sdmmc0_gclk", .id = 12, .r = { .min = 0, .max = 105000000 }, }, + { .n = "flex4_gclk", .id = 13, }, + { .n = "flex5_gclk", .id = 14, }, + { .n = "flex9_gclk", .id = 15, }, + { .n = "flex10_gclk", .id = 16, }, + { .n = "tcb0_gclk", .id = 17, }, + { .n = "adc_gclk", .id = 19, }, + { .n = "lcd_gclk", .id = 25, .r = { .min = 0, .max = 140000000 }, }, + { .n = "sdmmc1_gclk", .id = 26, .r = { .min = 0, .max = 105000000 }, }, + { .n = "flex11_gclk", .id = 32, }, + { .n = "flex12_gclk", .id = 33, }, + { .n = "i2s_gclk", .id = 34, .r = { .min = 0, .max = 105000000 }, + .pll = true, }, + { .n = "pit64b_gclk", .id = 37, }, + { .n = "classd_gclk", .id = 42, .r = { .min = 0, .max = 100000000 }, + .pll = true, }, + { .n = "tcb1_gclk", .id = 45, }, + { .n = "dbgu_gclk", .id = 47, }, +}; + +static void __init sam9x60_pmc_setup(struct device_node *np) +{ + struct clk_range range = CLK_RANGE(0, 0); + const char *td_slck_name, *md_slck_name, *mainxtal_name; + struct pmc_data *sam9x60_pmc; + const char *parent_names[6]; + struct regmap *regmap; + struct clk_hw *hw; + int i; + bool bypass; + + i = of_property_match_string(np, "clock-names", "td_slck"); + if (i < 0) + return; + + td_slck_name = of_clk_get_parent_name(np, i); + + i = of_property_match_string(np, "clock-names", "md_slck"); + if (i < 0) + return; + + md_slck_name = of_clk_get_parent_name(np, i); + + i = of_property_match_string(np, "clock-names", "main_xtal"); + if (i < 0) + return; + mainxtal_name = of_clk_get_parent_name(np, i); + + regmap = syscon_node_to_regmap(np); + if (IS_ERR(regmap)) + return; + + sam9x60_pmc = pmc_data_allocate(PMC_MAIN + 1, + nck(sam9x60_systemck), + nck(sam9x60_periphck), + nck(sam9x60_gck)); + if (!sam9x60_pmc) + return; + + hw = at91_clk_register_main_rc_osc(regmap, "main_rc_osc", 24000000, + 50000000); + if (IS_ERR(hw)) + goto err_free; + + bypass = of_property_read_bool(np, "atmel,osc-bypass"); + + hw = at91_clk_register_main_osc(regmap, "main_osc", mainxtal_name, + bypass); + if (IS_ERR(hw)) + goto err_free; + + parent_names[0] = "main_rc_osc"; + parent_names[1] = "main_osc"; + hw = at91_clk_register_sam9x5_main(regmap, "mainck", parent_names, 2); + if (IS_ERR(hw)) + goto err_free; + + sam9x60_pmc->chws[PMC_MAIN] = hw; + + hw = sam9x60_clk_register_pll(regmap, &pmc_pll_lock, "pllack", + "mainck", 0, &plla_characteristics); + if (IS_ERR(hw)) + goto err_free; + + hw = sam9x60_clk_register_pll(regmap, &pmc_pll_lock, "upllck", + "main_osc", 1, &upll_characteristics); + if (IS_ERR(hw)) + goto err_free; + + sam9x60_pmc->chws[PMC_UTMI] = hw; + + parent_names[0] = md_slck_name; + parent_names[1] = "mainck"; + parent_names[2] = "pllack"; + hw = at91_clk_register_master(regmap, "masterck", 3, parent_names, + &sam9x60_master_layout, + &mck_characteristics); + if (IS_ERR(hw)) + goto err_free; + + sam9x60_pmc->chws[PMC_MCK] = hw; + + parent_names[0] = "pllack"; + parent_names[1] = "upllck"; + parent_names[2] = "mainck"; + parent_names[3] = "mainck"; + hw = sam9x60_clk_register_usb(regmap, "usbck", parent_names, 4); + if (IS_ERR(hw)) + goto err_free; + + parent_names[0] = md_slck_name; + parent_names[1] = td_slck_name; + parent_names[2] = "mainck"; + parent_names[3] = "masterck"; + parent_names[4] = "pllack"; + parent_names[5] = "upllck"; + for (i = 0; i < 8; i++) { + char name[6]; + + snprintf(name, sizeof(name), "prog%d", i); + + hw = at91_clk_register_programmable(regmap, name, + parent_names, 6, i, + &sam9x60_programmable_layout); + if (IS_ERR(hw)) + goto err_free; + } + + for (i = 0; i < ARRAY_SIZE(sam9x60_systemck); i++) { + hw = at91_clk_register_system(regmap, sam9x60_systemck[i].n, + sam9x60_systemck[i].p, + sam9x60_systemck[i].id); + if (IS_ERR(hw)) + goto err_free; + + sam9x60_pmc->shws[sam9x60_systemck[i].id] = hw; + } + + for (i = 0; i < ARRAY_SIZE(sam9x60_periphck); i++) { + hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &sam9x60_pcr_layout, + sam9x60_periphck[i].n, + "masterck", + sam9x60_periphck[i].id, + &range); + if (IS_ERR(hw)) + goto err_free; + + sam9x60_pmc->phws[sam9x60_periphck[i].id] = hw; + } + + for (i = 0; i < ARRAY_SIZE(sam9x60_gck); i++) { + hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, + &sam9x60_pcr_layout, + sam9x60_gck[i].n, + parent_names, 6, + sam9x60_gck[i].id, + sam9x60_gck[i].pll, + &sam9x60_gck[i].r); + if (IS_ERR(hw)) + goto err_free; + + sam9x60_pmc->ghws[sam9x60_gck[i].id] = hw; + } + + of_clk_add_hw_provider(np, of_clk_hw_pmc_get, sam9x60_pmc); + + return; + +err_free: + pmc_data_free(sam9x60_pmc); +} + +CLK_OF_DECLARE_DRIVER(sam9x60_pmc, "microchip,sam9x60-pmc", sam9x60_pmc_setup);