From patchwork Thu Nov 24 14:45:44 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gabriel FERNANDEZ X-Patchwork-Id: 9445643 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B8B7260235 for ; Thu, 24 Nov 2016 14:51:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A597D27FA7 for ; Thu, 24 Nov 2016 14:51:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9A1D327FAE; Thu, 24 Nov 2016 14:51:06 +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=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 1755F27FA7 for ; Thu, 24 Nov 2016 14:51:06 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1c9vLF-00044p-VT; Thu, 24 Nov 2016 14:49:37 +0000 Received: from mx08-00178001.pphosted.com ([91.207.212.93] helo=mx07-00178001.pphosted.com) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1c9vJ2-0002Uy-4j for linux-arm-kernel@lists.infradead.org; Thu, 24 Nov 2016 14:47:27 +0000 Received: from pps.filterd (m0046660.ppops.net [127.0.0.1]) by mx08-00178001.pphosted.com (8.16.0.11/8.16.0.11) with SMTP id uAOEf4YZ003677; Thu, 24 Nov 2016 15:46:31 +0100 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx08-.pphosted.com with ESMTP id 26tcracp38-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Thu, 24 Nov 2016 15:46:31 +0100 Received: from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id B94A531; Thu, 24 Nov 2016 14:46:30 +0000 (GMT) Received: from Webmail-eu.st.com (Safex1hubcas21.st.com [10.75.90.44]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 8E5CE2C2D; Thu, 24 Nov 2016 14:46:30 +0000 (GMT) Received: from localhost (10.48.1.80) by Webmail-ga.st.com (10.75.90.48) with Microsoft SMTP Server (TLS) id 14.3.294.0; Thu, 24 Nov 2016 15:46:30 +0100 From: To: Rob Herring , Mark Rutland , Russell King , Maxime Coquelin , Alexandre Torgue , Michael Turquette , Stephen Boyd , Nicolas Pitre , Arnd Bergmann , , , Subject: [PATCH v2 4/9] clk: stm32f4: Add lcd-tft clock Date: Thu, 24 Nov 2016 15:45:44 +0100 Message-ID: <1479998749-20358-5-git-send-email-gabriel.fernandez@st.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1479998749-20358-1-git-send-email-gabriel.fernandez@st.com> References: <1479998749-20358-1-git-send-email-gabriel.fernandez@st.com> MIME-Version: 1.0 X-Originating-IP: [10.48.1.80] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2016-11-24_04:, , signatures=0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20161124_064720_601964_0913EAED X-CRM114-Status: GOOD ( 17.09 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, amelie.delaunay@st.com, kernel@stlinux.com, olivier.bideau@st.com, linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org, ludovic.barre@st.com, gabriel.fernandez@st.com, 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 From: Gabriel Fernandez This patch introduces lcd-tft clock for stm32f4 soc. Signed-off-by: Gabriel Fernandez --- .../devicetree/bindings/clock/st,stm32-rcc.txt | 1 + drivers/clk/clk-stm32f4.c | 118 +++++++++++++++++++++ include/dt-bindings/clock/stm32f4-clock.h | 3 +- 3 files changed, 121 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/clock/st,stm32-rcc.txt b/Documentation/devicetree/bindings/clock/st,stm32-rcc.txt index eb6733c..4cd08da6 100644 --- a/Documentation/devicetree/bindings/clock/st,stm32-rcc.txt +++ b/Documentation/devicetree/bindings/clock/st,stm32-rcc.txt @@ -76,6 +76,7 @@ The secondary index is bound with the following magic numbers: 5 CLK_RTC (real-time clock) 6 PLL_VCO_I2S (vco frequency of I2S pll) 7 PLL_VCO_SAI (vco frequency of SAI pll) + 8 CLK_LCD (LCD-TFT) Example: diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c index 3918305..86244fc 100644 --- a/drivers/clk/clk-stm32f4.c +++ b/drivers/clk/clk-stm32f4.c @@ -47,6 +47,7 @@ #define STM32F4_RCC_CSR 0x74 #define STM32F4_RCC_PLLI2SCFGR 0x84 #define STM32F4_RCC_PLLSAICFGR 0x88 +#define STM32F4_RCC_DCKCFGR 0x8c struct stm32f4_gate_data { u8 offset; @@ -932,11 +933,42 @@ static struct clk_hw *stm32_register_cclk(struct device *dev, const char *name, "no-clock", "lse", "lsi", "hse-rtc" }; +static const char *lcd_parent[1] = { "pllsai-r-div" }; + +struct stm32_aux_clk { + int idx; + const char *name; + const char * const *parent_names; + int num_parents; + int offset_mux; + u8 shift; + u8 mask; + int offset_gate; + u8 bit_idx; + unsigned long flags; +}; + struct stm32f4_clk_data { const struct stm32f4_gate_data *gates_data; const u64 *gates_map; int gates_num; const struct stm32f4_pll_data *pll_data; + const struct stm32_aux_clk *aux_clk; + int aux_clk_num; +}; + +#define NONE -1 +#define NO_IDX NONE +#define NO_MUX NONE +#define NO_GATE NONE + +static const struct stm32_aux_clk stm32f429_aux_clk[] = { + { + CLK_LCD, "lcd-tft", lcd_parent, ARRAY_SIZE(lcd_parent), + NO_MUX, 0, 0, + STM32F4_RCC_APB2ENR, 26, + CLK_SET_RATE_PARENT + }, }; static const struct stm32f4_clk_data stm32f429_clk_data = { @@ -944,6 +976,8 @@ struct stm32f4_clk_data { .gates_map = stm32f42xx_gate_map, .gates_num = ARRAY_SIZE(stm32f429_gates), .pll_data = stm32f429_pll, + .aux_clk = stm32f429_aux_clk, + .aux_clk_num = ARRAY_SIZE(stm32f429_aux_clk), }; static const struct stm32f4_clk_data stm32f469_clk_data = { @@ -951,6 +985,8 @@ struct stm32f4_clk_data { .gates_map = stm32f46xx_gate_map, .gates_num = ARRAY_SIZE(stm32f469_gates), .pll_data = stm32f469_pll, + .aux_clk = stm32f429_aux_clk, + .aux_clk_num = ARRAY_SIZE(stm32f429_aux_clk), }; static const struct of_device_id stm32f4_of_match[] = { @@ -965,6 +1001,66 @@ struct stm32f4_clk_data { {} }; +static struct clk_hw *stm32_register_aux_clk(const char *name, + const char * const *parent_names, int num_parents, + int offset_mux, u8 shift, u8 mask, + int offset_gate, u8 bit_idx, + unsigned long flags, spinlock_t *lock) +{ + struct clk_hw *hw; + struct clk_gate *gate; + struct clk_mux *mux = NULL; + struct clk_hw *mux_hw = NULL, *gate_hw = NULL; + const struct clk_ops *mux_ops = NULL, *gate_ops = NULL; + + if (offset_gate != NO_GATE) { + gate = kzalloc(sizeof(*gate), GFP_KERNEL); + if (!gate) { + hw = ERR_PTR(-EINVAL); + goto fail; + } + + gate->reg = base + offset_gate; + gate->bit_idx = bit_idx; + gate->flags = 0; + gate->lock = lock; + gate_hw = &gate->hw; + gate_ops = &clk_gate_ops; + } + + if (offset_mux != NO_MUX) { + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) { + kfree(gate); + hw = ERR_PTR(-EINVAL); + goto fail; + } + + mux->reg = base + offset_mux; + mux->shift = shift; + mux->mask = mask; + mux->flags = 0; + mux_hw = &mux->hw; + mux_ops = &clk_mux_ops; + } + + if (mux_hw == NULL && gate_hw == NULL) + return ERR_PTR(-EINVAL); + + hw = clk_hw_register_composite(NULL, name, parent_names, num_parents, + mux_hw, mux_ops, + NULL, NULL, + gate_hw, gate_ops, + flags); + + if (IS_ERR(hw)) { + kfree(gate); + kfree(mux); + } +fail: + return hw; +} + static void __init stm32f4_rcc_init(struct device_node *np) { const char *hse_clk; @@ -1120,6 +1216,28 @@ static void __init stm32f4_rcc_init(struct device_node *np) goto fail; } + for (n = 0; n < data->aux_clk_num; n++) { + const struct stm32_aux_clk *aux_clk; + struct clk_hw *hw; + + aux_clk = &data->aux_clk[n]; + + hw = stm32_register_aux_clk(aux_clk->name, + aux_clk->parent_names, aux_clk->num_parents, + aux_clk->offset_mux, aux_clk->shift, + aux_clk->mask, aux_clk->offset_gate, + aux_clk->bit_idx, aux_clk->flags, + &stm32f4_clk_lock); + + if (IS_ERR(hw)) { + pr_warn("Unable to register %s clk\n", aux_clk->name); + continue; + } + + if (aux_clk->idx != NO_IDX) + clks[aux_clk->idx] = hw; + } + of_clk_add_hw_provider(np, stm32f4_rcc_lookup_clk, NULL); return; fail: diff --git a/include/dt-bindings/clock/stm32f4-clock.h b/include/dt-bindings/clock/stm32f4-clock.h index 56b8e10..1be4a3a 100644 --- a/include/dt-bindings/clock/stm32f4-clock.h +++ b/include/dt-bindings/clock/stm32f4-clock.h @@ -27,7 +27,8 @@ #define CLK_RTC 5 #define PLL_VCO_I2S 6 #define PLL_VCO_SAI 7 +#define CLK_LCD 8 -#define END_PRIMARY_CLK 8 +#define END_PRIMARY_CLK 9 #endif