From patchwork Mon Jul 16 08:41:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick DELAUNAY X-Patchwork-Id: 944239 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=st.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41TcQ44xySz9rvt for ; Mon, 16 Jul 2018 18:43:40 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 48148C21DB6; Mon, 16 Jul 2018 08:42:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=none autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id EA6A3C220BA; Mon, 16 Jul 2018 08:42:14 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 5DE03C22088; Mon, 16 Jul 2018 08:42:05 +0000 (UTC) Received: from mx07-00178001.pphosted.com (mx08-00178001.pphosted.com [91.207.212.93]) by lists.denx.de (Postfix) with ESMTPS id 171ECC220A2 for ; Mon, 16 Jul 2018 08:42:02 +0000 (UTC) Received: from pps.filterd (m0046660.ppops.net [127.0.0.1]) by mx08-.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id w6G8dJYN020173; Mon, 16 Jul 2018 10:42:01 +0200 Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx08-00178001.pphosted.com with ESMTP id 2k85reb8th-1 (version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT); Mon, 16 Jul 2018 10:42:01 +0200 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 F200038; Mon, 16 Jul 2018 08:42:00 +0000 (GMT) Received: from Webmail-eu.st.com (Safex1hubcas23.st.com [10.75.90.46]) by zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id DB4C8AC6D; Mon, 16 Jul 2018 08:42:00 +0000 (GMT) Received: from SAFEX1HUBCAS24.st.com (10.75.90.95) by SAFEX1HUBCAS23.st.com (10.75.90.46) with Microsoft SMTP Server (TLS) id 14.3.361.1; Mon, 16 Jul 2018 10:42:01 +0200 Received: from localhost (10.201.23.85) by webmail-ga.st.com (10.75.90.48) with Microsoft SMTP Server (TLS) id 14.3.361.1; Mon, 16 Jul 2018 10:42:00 +0200 From: Patrick Delaunay To: Date: Mon, 16 Jul 2018 10:41:43 +0200 Message-ID: <1531730506-18633-3-git-send-email-patrick.delaunay@st.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1531730506-18633-1-git-send-email-patrick.delaunay@st.com> References: <1531730506-18633-1-git-send-email-patrick.delaunay@st.com> MIME-Version: 1.0 X-Originating-IP: [10.201.23.85] X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:, , definitions=2018-07-16_03:, , signatures=0 Cc: Tom Rini , Benjamin GAIGNARD Subject: [U-Boot] [PATCH 3/6] stm32mp1: clk: add LDTC and DSI clock support X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This patch add clk_enable/clk_disable/clk_get_rate support for - DSI_PX - LTDC_PX - DSI_K (only get rate) These clocks are needed for LTDC and DSI drivers with latest device tree. Signed-off-by: Patrick Delaunay --- drivers/clk/clk_stm32mp1.c | 96 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c index 710633f..6202ebe 100644 --- a/drivers/clk/clk_stm32mp1.c +++ b/drivers/clk/clk_stm32mp1.c @@ -98,6 +98,7 @@ #define RCC_QSPICKSELR 0x900 #define RCC_FMCCKSELR 0x904 #define RCC_USBCKSELR 0x91C +#define RCC_DSICKSELR 0x924 #define RCC_MP_APB1ENSETR 0xA00 #define RCC_MP_APB2ENSETR 0XA08 #define RCC_MP_APB3ENSETR 0xA10 @@ -267,6 +268,7 @@ enum stm32mp1_parent_id { _CK_PER, _CK_MPU, _CK_MCU, + _DSI_PHY, _PARENT_NB, _UNKNOWN_ID = 0xff, }; @@ -287,6 +289,7 @@ enum stm32mp1_parent_sel { _USBPHY_SEL, _USBO_SEL, _STGEN_SEL, + _DSI_SEL, _PARENT_SEL_NB, _UNKNOWN_SEL = 0xff, }; @@ -512,6 +515,9 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = { STM32MP1_CLK_SET_CLR_F(RCC_MP_APB3ENSETR, 13, VREF, _PCLK3), + STM32MP1_CLK_SET_CLR_F(RCC_MP_APB4ENSETR, 0, LTDC_PX, _PLL4_Q), + STM32MP1_CLK_SET_CLR_F(RCC_MP_APB4ENSETR, 4, DSI_PX, _PLL4_Q), + STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 4, DSI_K, _DSI_SEL), STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 8, DDRPERFM, _UNKNOWN_SEL), STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 15, IWDG2, _UNKNOWN_SEL), STM32MP1_CLK_SET_CLR(RCC_MP_APB4ENSETR, 16, USBPHY_K, _USBPHY_SEL), @@ -569,6 +575,7 @@ static const u8 fmc_parents[] = {_ACLK, _PLL3_R, _PLL4_P, _CK_PER}; static const u8 usbphy_parents[] = {_HSE_KER, _PLL4_R, _HSE_KER_DIV2}; static const u8 usbo_parents[] = {_PLL4_R, _USB_PHY_48}; static const u8 stgen_parents[] = {_HSI_KER, _HSE_KER}; +static const u8 dsi_parents[] = {_DSI_PHY, _PLL4_P}; static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { STM32MP1_CLK_PARENT(_I2C12_SEL, RCC_I2C12CKSELR, 0, 0x7, i2c12_parents), @@ -591,6 +598,7 @@ static const struct stm32mp1_clk_sel stm32mp1_clk_sel[_PARENT_SEL_NB] = { STM32MP1_CLK_PARENT(_USBPHY_SEL, RCC_USBCKSELR, 0, 0x3, usbphy_parents), STM32MP1_CLK_PARENT(_USBO_SEL, RCC_USBCKSELR, 4, 0x1, usbo_parents), STM32MP1_CLK_PARENT(_STGEN_SEL, RCC_STGENCKSELR, 0, 0x3, stgen_parents), + STM32MP1_CLK_PARENT(_DSI_SEL, RCC_DSICKSELR, 0, 0x1, dsi_parents), }; #ifdef STM32MP1_CLOCK_TREE_INIT @@ -682,7 +690,8 @@ char * const stm32mp1_clk_parent_name[_PARENT_NB] = { [_CK_PER] = "CK_PER", [_CK_MPU] = "CK_MPU", [_CK_MCU] = "CK_MCU", - [_USB_PHY_48] = "USB_PHY_48" + [_USB_PHY_48] = "USB_PHY_48", + [_DSI_PHY] = "DSI_PHY_PLL", }; static const __maybe_unused @@ -701,7 +710,8 @@ char * const stm32mp1_clk_parent_sel_name[_PARENT_SEL_NB] = { [_FMC_SEL] = "FMC", [_USBPHY_SEL] = "USBPHY", [_USBO_SEL] = "USBO", - [_STGEN_SEL] = "STGEN" + [_STGEN_SEL] = "STGEN", + [_DSI_SEL] = "DSI", }; static const struct stm32mp1_clk_data stm32mp1_data = { @@ -1060,7 +1070,22 @@ static ulong stm32mp1_clk_get(struct stm32mp1_clk_priv *priv, int p) case _USB_PHY_48: clock = stm32mp1_clk_get_fixed(priv, _USB_PHY_48); break; - + case _DSI_PHY: + { + struct clk clk; + struct udevice *dev = NULL; + + if (!uclass_get_device_by_name(UCLASS_CLK, "ck_dsi_phy", + &dev)) { + if (clk_request(dev, &clk)) { + pr_err("ck_dsi_phy request"); + } else { + clk.id = 0; + clock = clk_get_rate(&clk); + } + } + break; + } default: break; } @@ -1723,6 +1748,70 @@ static int stm32mp1_clktree(struct udevice *dev) } #endif /* STM32MP1_CLOCK_TREE_INIT */ +static int pll_set_output_rate(struct udevice *dev, + int pll_id, + int div_id, + unsigned long clk_rate) +{ + struct stm32mp1_clk_priv *priv = dev_get_priv(dev); + const struct stm32mp1_clk_pll *pll = priv->data->pll; + u32 pllxcr = priv->base + pll[pll_id].pllxcr; + int div; + ulong fvco; + + if (div_id > _DIV_NB) + return -EINVAL; + + fvco = pll_get_fvco(priv, pll_id); + + if (fvco <= clk_rate) + div = 1; + else + div = DIV_ROUND_UP(fvco, clk_rate); + + if (div > 128) + div = 128; + + debug("fvco = %ld, clk_rate = %ld, div=%d\n", fvco, clk_rate, div); + /* stop the requested output */ + clrbits_le32(pllxcr, 0x1 << div_id << RCC_PLLNCR_DIVEN_SHIFT); + /* change divider */ + clrsetbits_le32(priv->base + pll[pll_id].pllxcfgr2, + RCC_PLLNCFGR2_DIVX_MASK << RCC_PLLNCFGR2_SHIFT(div_id), + (div - 1) << RCC_PLLNCFGR2_SHIFT(div_id)); + /* start the requested output */ + setbits_le32(pllxcr, 0x1 << div_id << RCC_PLLNCR_DIVEN_SHIFT); + + return 0; +} + +static ulong stm32mp1_clk_set_rate(struct clk *clk, unsigned long clk_rate) +{ + struct stm32mp1_clk_priv *priv = dev_get_priv(clk->dev); + int p; + + switch (clk->id) { + case LTDC_PX: + case DSI_PX: + break; + default: + pr_err("not supported"); + return -EINVAL; + } + + p = stm32mp1_clk_get_parent(priv, clk->id); + if (p < 0) + return -EINVAL; + + switch (p) { + case _PLL4_Q: + /* for LTDC_PX and DSI_PX case */ + return pll_set_output_rate(clk->dev, _PLL4, _DIV_Q, clk_rate); + } + + return -EINVAL; +} + static void stm32mp1_osc_clk_init(const char *name, struct stm32mp1_clk_priv *priv, int index) @@ -1846,6 +1935,7 @@ static const struct clk_ops stm32mp1_clk_ops = { .enable = stm32mp1_clk_enable, .disable = stm32mp1_clk_disable, .get_rate = stm32mp1_clk_get_rate, + .set_rate = stm32mp1_clk_set_rate, }; U_BOOT_DRIVER(stm32mp1_clock) = {