From patchwork Sun Mar 14 15:12:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 400870 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8A8F0C433E0 for ; Sun, 14 Mar 2021 15:14:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 59A0864EE2 for ; Sun, 14 Mar 2021 15:14:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229539AbhCNPNt (ORCPT ); Sun, 14 Mar 2021 11:13:49 -0400 Received: from smtp-17.italiaonline.it ([213.209.10.17]:53955 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S233897AbhCNPNp (ORCPT ); Sun, 14 Mar 2021 11:13:45 -0400 Received: from passgat-Modern-14-A10M.homenet.telecomitalia.it ([87.20.116.197]) by smtp-17.iol.local with ESMTPA id LSPzlDn2etpGHLSQ6lAQ8I; Sun, 14 Mar 2021 16:12:42 +0100 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2021; t=1615734762; bh=5x+SnMXXNl5lP1MlTpZHetc5S5OURdo5+CO/FZksj9Q=; h=From; b=PmUqJleccBTDLsFKSoMoklJ0dQHj5QDOqWY7nWWoVAob+eLdnVjVJWRiyZogzztUP fKlsjiuMOfPcdXwo0Z/7jYyXEVQWs7+RUGmvRwkuwpj09UBn0So3Wj5I6hfehYobZ9 FN8xa/Ta03RtjX49zgjNX457NwNp2gzlDPiRiwJo6t5/C1DKF+JHxYCtAxpb7kYncp zqyhz7VrOJcm+80vD3HozBm6tTiCVDRsVkCrB7Tt9pUsI7pEFNXxdrxT1qb8FOp0ef 0jFy4UFG9qZG24VwW1orgvI3I5EIrA64GbE+ZCXEQ9NpcvapxOFqSLdZKXr+t0rf8U iDjFCRzLxZe7Q== X-CNFS-Analysis: v=2.4 cv=Q7IXX66a c=1 sm=1 tr=0 ts=604e27ea cx=a_exe a=AVqmXbCQpuNSdJmApS5GbQ==:117 a=AVqmXbCQpuNSdJmApS5GbQ==:17 a=Bl6OLPU8nqzXNm5YYFQA:9 From: Dario Binacchi To: linux-kernel@vger.kernel.org Cc: Dario Binacchi , Lee Jones , Michael Turquette , Stephen Boyd , Tero Kristo , linux-clk@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH 1/4] clk: ti: fix typo in routine description Date: Sun, 14 Mar 2021 16:12:30 +0100 Message-Id: <20210314151233.23243-2-dariobin@libero.it> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210314151233.23243-1-dariobin@libero.it> References: <20210314151233.23243-1-dariobin@libero.it> X-CMAE-Envelope: MS4xfN6fGTPEh5gLyghbn1eIfsPmGzVXQ4yPJN4J8eWOvCIqGJParrQEOl8NkmMBDQDwIa5sOlkRZdxhbuiSdvWALn0NBqdWNbqUZuJxJVP0MMsp+m4E+4Wc CeD8l4VH6m1a3BGwbhZC7iqzILXBK1q5/pDivY/mY0Ro1L+r3vZDd6UdTdRJGvzbfrlsiqPiR/0cmE4+31PfWxGAllrryyQ4QANy9uQI8SvP2wVqvkmaZmU2 SIBGD9IGTYvOWKrW4QcJl4YmJnBUsgPbHdeW/HYaZCRi8alZGmjWzmu7dMGyXVyFVMN0SG6mEmVQSgdKcNNMmaefrMz05yzAhq6du5vmXSuK3UQDLFqQVcdB 9OfaXOtE0vhQS2SnQhBTHOm7b6YwHARms3I+bDnU8IwBQ3Hd4r67Ps4Pbr9GmDPVIhMLJ7OFyjJgfAYvCkGlc7JWvWrO5GE9AZEx5WADQkIE8AnS1piGCK6s 3U7a4jmO51rBtHez Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org Replace _omap3_noncore_dpll_program with omap3_noncore_dpll_program. Signed-off-by: Dario Binacchi --- drivers/clk/ti/dpll3xxx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/clk/ti/dpll3xxx.c b/drivers/clk/ti/dpll3xxx.c index 6097b099a5df..94d5b5fe9a2b 100644 --- a/drivers/clk/ti/dpll3xxx.c +++ b/drivers/clk/ti/dpll3xxx.c @@ -292,7 +292,7 @@ static void _lookup_sddiv(struct clk_hw_omap *clk, u8 *sd_div, u16 m, u8 n) } /** - * _omap3_noncore_dpll_program - set non-core DPLL M,N values directly + * omap3_noncore_dpll_program - set non-core DPLL M,N values directly * @clk: struct clk * of DPLL to set * @freqsel: FREQSEL value to set * From patchwork Sun Mar 14 15:12:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 400269 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90A19C433DB for ; Sun, 14 Mar 2021 15:21:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5074964EE2 for ; Sun, 14 Mar 2021 15:21:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233389AbhCNPVZ (ORCPT ); Sun, 14 Mar 2021 11:21:25 -0400 Received: from smtp-17-i2.italiaonline.it ([213.209.12.17]:53204 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S229539AbhCNPUx (ORCPT ); Sun, 14 Mar 2021 11:20:53 -0400 X-Greylist: delayed 339 seconds by postgrey-1.27 at vger.kernel.org; Sun, 14 Mar 2021 11:20:53 EDT Received: from passgat-Modern-14-A10M.homenet.telecomitalia.it ([87.20.116.197]) by smtp-17.iol.local with ESMTPA id LSPzlDn2etpGHLSQ7lAQ8p; Sun, 14 Mar 2021 16:12:43 +0100 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2021; t=1615734763; bh=+FWtNBr6F5ufPynCRXYCrnqtuCpk2dKlZtIc6FJngYI=; h=From; b=AyMixakPjkjBZeMA6WGIqlBsoVZPs4zRjLnJYkGVL4Y0KbXDVAQ9/A9xSqDzDof5/ Ag2cWtKtfFJaUxPSPaL2yjJgxoAa8WikCXbFFlqo1ZIQroR/nzxyiUqJqSEjYDKEkL g3f6KK0BeOTTvuHDel86ONE6cqWwOavRfzan0XDBibVBYhDqRhS1MASYVr4itJsnBT 84gIxaCTHkorkWFTpFF6qdPLG84k/3WGsG8mmKALw1PDtd3CsmHtxnPJWheg4VioHu 2djCPPkV8lGM/moJip/4gIAkXtl1Jy+yhEznoQBVp168c2vlavvQPqnmdzNkbW2jVU bUdQt6aw/Okhg== X-CNFS-Analysis: v=2.4 cv=Q7IXX66a c=1 sm=1 tr=0 ts=604e27eb cx=a_exe a=AVqmXbCQpuNSdJmApS5GbQ==:117 a=AVqmXbCQpuNSdJmApS5GbQ==:17 a=jCmRPZ0w5czJu0AXxT0A:9 From: Dario Binacchi To: linux-kernel@vger.kernel.org Cc: Dario Binacchi , =?utf-8?q?Beno=C3=AEt_Cousson?= , Rob Herring , Tony Lindgren , devicetree@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH 3/4] ARM: dts: am33xx-clocks: add spread spectrum support Date: Sun, 14 Mar 2021 16:12:32 +0100 Message-Id: <20210314151233.23243-4-dariobin@libero.it> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210314151233.23243-1-dariobin@libero.it> References: <20210314151233.23243-1-dariobin@libero.it> X-CMAE-Envelope: MS4xfDCcah2L8AiZCR5ZNO4FJMg4iLk9zRZZUojTuqIoj2FZ6RtybJAp3t7FPpY9nlLSe0KSZhldj17oQtRdGxJ6QMFSxI68/CtX0wWkyugPmaxEmuyrSxCK 3ycIPrgQBC4i/FV9M8O1q2i50lsk9tbh4Q4JVn+tWGzn7JnqEqiC3odweimA9BzDAhSDzLFOis0b7dgOaUkBspI37obPqPhoZOLg1ir7ZjLLVBoGtrPnaHZb FYPEvBbLAWNY93lKArMDLK9vwzfZAv2OfXcs8tX1WShk2atDqIip5N+bB+VAKmJOnihW5ZTIGuJK7oeUhulIzD7ph0O4tQLaLMnDIH3LI5w0Lzp1Y9lHt2om LYCQLe83apLIIXcos2keulSCyfbuihrsAwaOmLxMg4ZApqn3oscfFE5xspCu/kOf6Xzw49GXwCAqbmxrY9d6vL2PAX/qEA== Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org Registers for adjusting the spread spectrum clocking (SSC) have been added. As reported by the TI spruh73x RM, SSC is supported only for LCD and MPU PLLs. Signed-off-by: Dario Binacchi --- arch/arm/boot/dts/am33xx-clocks.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/am33xx-clocks.dtsi b/arch/arm/boot/dts/am33xx-clocks.dtsi index dced92a8970e..e7bbbf536a8c 100644 --- a/arch/arm/boot/dts/am33xx-clocks.dtsi +++ b/arch/arm/boot/dts/am33xx-clocks.dtsi @@ -164,7 +164,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-core-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x0490>, <0x045c>, <0x0468>; + reg = <0x0490>, <0x045c>, <0x0468>, <0x0460>, <0x0464>; }; dpll_core_x2_ck: dpll_core_x2_ck { @@ -244,7 +244,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-no-gate-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x0498>, <0x0448>, <0x0454>; + reg = <0x0498>, <0x0448>, <0x0454>, <0x044c>, <0x0450>; }; dpll_disp_m2_ck: dpll_disp_m2_ck@4a4 { From patchwork Sun Mar 14 15:12:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dario Binacchi X-Patchwork-Id: 400268 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 214F2C4332E for ; Sun, 14 Mar 2021 15:21:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CCE7C64EEF for ; Sun, 14 Mar 2021 15:21:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229495AbhCNPV0 (ORCPT ); Sun, 14 Mar 2021 11:21:26 -0400 Received: from smtp-17-i2.italiaonline.it ([213.209.12.17]:48330 "EHLO libero.it" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S231205AbhCNPVA (ORCPT ); Sun, 14 Mar 2021 11:21:00 -0400 Received: from passgat-Modern-14-A10M.homenet.telecomitalia.it ([87.20.116.197]) by smtp-17.iol.local with ESMTPA id LSPzlDn2etpGHLSQ7lAQ8z; Sun, 14 Mar 2021 16:12:44 +0100 x-libjamoibt: 1601 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=libero.it; s=s2021; t=1615734764; bh=OJexXQyYRFXRNDZK+nCiQVD7b1nhegx+74zGaKuvGxY=; h=From; b=Z5gWsyk/13lq+bJRI3LPPWFB/HDKqQ3WuK0bCNZO5vIEin0waMZMH8EDKmERlnHE9 4I1eat4xi9K5GF4x01t7sAm/LIURGV9aOwcDcbp6sL2J25Jg/3mfMCSYYfhygzHaL0 KohSM/qoTdS2nt+YwjAZlAboSEH/iiorZNfQBvcV/sx/RAQoguWlB30fZ3OkQG1/cZ 1EY5qa0D51Pm3A7oie8uDjOvQwm/FpavoL6CQrP7Dg0g1UpZOtba7CHJcRVZg02m71 R/61heMqk5Z6flpMX0ot6hs166oj6LDLRMS4spqQUqFXczNn5DGvBneQi4GT6DBTVK lEwbXhd5m1vEQ== X-CNFS-Analysis: v=2.4 cv=Q7IXX66a c=1 sm=1 tr=0 ts=604e27ec cx=a_exe a=AVqmXbCQpuNSdJmApS5GbQ==:117 a=AVqmXbCQpuNSdJmApS5GbQ==:17 a=IkcTkHD0fZMA:10 a=lv3YbdnuOFW5EWC_AkUA:9 a=QEXdDO2ut3YA:10 From: Dario Binacchi To: linux-kernel@vger.kernel.org Cc: Dario Binacchi , =?utf-8?q?Beno=C3=AEt_Cousson?= , Lee Jones , Michael Turquette , Rob Herring , Stephen Boyd , Tero Kristo , Tony Lindgren , devicetree@vger.kernel.org, linux-clk@vger.kernel.org, linux-omap@vger.kernel.org Subject: [PATCH 4/4] clk: ti: add am33xx spread spectrum clock support Date: Sun, 14 Mar 2021 16:12:33 +0100 Message-Id: <20210314151233.23243-5-dariobin@libero.it> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210314151233.23243-1-dariobin@libero.it> References: <20210314151233.23243-1-dariobin@libero.it> MIME-Version: 1.0 X-CMAE-Envelope: MS4xfFYu7+Zt+PPO7dSWSZFo1QYRwh0MVcVpc+2sxdqWYF0vFnwFQT0vF4W25cqoidEUgj7FteLrYvJBKAsazRuf8qnR+CrVIbMW3qqyijEv8uM/ZerTOvyG ZUXZbzT+ykVMVyyoZgWDJN/Np5w2OEc2KxIZ0Ay0rH6z3VLN/jzX5tbBAoOi3nfpS07I04iGmKmErD/kSUOFtE8VlnqLHXOlMuGyjKJernKeS2HiDKth743D /wSHeSdE2+CQuTbu9L6GhX2XNOgyYd8gwiV5t43UARmKN8W496NoQ+D2JOqDpg9KGBrVvNqfy3BquM4p/eTYBgT1ApOiXedUg3YP8tvzWXhY1lEyxtW7Wi+7 QyKdCTXpILjtBKcBfupFmFvdFiEIq0r0gu565MNy4YcH4EXXZNRbmtP2gszaNc/eGGncMxYuTTZ7ciYrNDL6dW7RP2h3f4HiGnboZXUz544y6dPyDVkcUiAE PCxOUAL7RF+9uC/S+4wRptkccB+VHxxk72YKn+ThlZROoCvFj/peKVQ61AfAGb01EwBPP5oKc+VhJeoG0igmsCECjiEzGLPr7JRzXwy33LqEU3tO1xW4UDqW gk+MHR3tDKpRPYL+JIeM+T4d Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org The patch enables spread spectrum clocking (SSC) for MPU and LCD PLLs. As reported by the TI spruh73x RM, SSC is only supported for the DISP/LCD and MPU PLLs on am33xx device. SSC is not supported for DDR, PER, and CORE PLLs. Calculating the required values and setting the registers accordingly was taken from the set_mpu_spreadspectrum routine contained in the arch/arm/mach-omap2/am33xx/clock_am33xx.c file of the u-boot project. In locked condition, DPLL output clock = CLKINP *[M/N]. In case of SSC enabled, the AM335x reference manual explains that there is a restriction of range of M values. Since the omap2_dpll_round_rate routine attempts to select the minimum possible N, the value of M obtained is not guaranteed to be within the range required. With the new "ti,min-div" parameter it is possible to increase N and consequently M to satisfy the constraint imposed by SSC. Signed-off-by: Dario Binacchi --- arch/arm/boot/dts/am33xx-clocks.dtsi | 4 +- drivers/clk/ti/dpll.c | 41 ++++++++++++++ drivers/clk/ti/dpll3xxx.c | 85 ++++++++++++++++++++++++++++ include/linux/clk/ti.h | 24 ++++++++ 4 files changed, 152 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/am33xx-clocks.dtsi b/arch/arm/boot/dts/am33xx-clocks.dtsi index e7bbbf536a8c..a02e0b1229a4 100644 --- a/arch/arm/boot/dts/am33xx-clocks.dtsi +++ b/arch/arm/boot/dts/am33xx-clocks.dtsi @@ -164,7 +164,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-core-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x0490>, <0x045c>, <0x0468>, <0x0460>, <0x0464>; + reg = <0x0490>, <0x045c>, <0x0468>; }; dpll_core_x2_ck: dpll_core_x2_ck { @@ -204,7 +204,7 @@ #clock-cells = <0>; compatible = "ti,am3-dpll-clock"; clocks = <&sys_clkin_ck>, <&sys_clkin_ck>; - reg = <0x0488>, <0x0420>, <0x042c>; + reg = <0x0488>, <0x0420>, <0x042c>, <0x0424>, <0x0428>; }; dpll_mpu_m2_ck: dpll_mpu_m2_ck@4a8 { diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index d6f1ac5b53e1..2738417a47b7 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c @@ -290,7 +290,9 @@ static void __init of_ti_dpll_setup(struct device_node *node, struct clk_init_data *init = NULL; const char **parent_names = NULL; struct dpll_data *dd = NULL; + int ssc_clk_index; u8 dpll_mode = 0; + u32 min_div; dd = kmemdup(ddt, sizeof(*dd), GFP_KERNEL); clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); @@ -345,6 +347,27 @@ static void __init of_ti_dpll_setup(struct device_node *node, if (dd->autoidle_mask) { if (ti_clk_get_reg_addr(node, 3, &dd->autoidle_reg)) goto cleanup; + + ssc_clk_index = 4; + } else { + ssc_clk_index = 3; + } + + if (dd->ssc_deltam_int_mask && dd->ssc_deltam_frac_mask && + dd->ssc_modfreq_mant_mask && dd->ssc_modfreq_exp_mask) { + if (ti_clk_get_reg_addr(node, ssc_clk_index++, + &dd->ssc_deltam_reg)) + goto cleanup; + + if (ti_clk_get_reg_addr(node, ssc_clk_index++, + &dd->ssc_modfreq_reg)) + goto cleanup; + + of_property_read_u32(node, "ti,ssc-modfreq", &dd->ssc_modfreq); + of_property_read_u32(node, "ti,ssc-deltam", &dd->ssc_deltam); + if (of_property_read_bool(node, "ti,ssc-downspread")) + dd->ssc_downspread = 1; + } if (of_property_read_bool(node, "ti,low-power-stop")) @@ -356,6 +379,10 @@ static void __init of_ti_dpll_setup(struct device_node *node, if (of_property_read_bool(node, "ti,lock")) dpll_mode |= 1 << DPLL_LOCKED; + if (!of_property_read_u32(node, "ti,min-div", &min_div) && + min_div > dd->min_divider) + dd->min_divider = min_div; + if (dpll_mode) dd->modes = dpll_mode; @@ -585,8 +612,15 @@ static void __init of_ti_am3_no_gate_dpll_setup(struct device_node *node) const struct dpll_data dd = { .idlest_mask = 0x1, .enable_mask = 0x7, + .ssc_enable_mask = 0x1 << 12, + .ssc_ack_mask = 0x1 << 13, + .ssc_downspread_mask = 0x1 << 14, .mult_mask = 0x7ff << 8, .div1_mask = 0x7f, + .ssc_deltam_int_mask = 0x3 << 18, + .ssc_deltam_frac_mask = 0x3ffff, + .ssc_modfreq_mant_mask = 0x7f, + .ssc_modfreq_exp_mask = 0x7 << 8, .max_multiplier = 2047, .max_divider = 128, .min_divider = 1, @@ -645,8 +679,15 @@ static void __init of_ti_am3_dpll_setup(struct device_node *node) const struct dpll_data dd = { .idlest_mask = 0x1, .enable_mask = 0x7, + .ssc_enable_mask = 0x1 << 12, + .ssc_ack_mask = 0x1 << 13, + .ssc_downspread_mask = 0x1 << 14, .mult_mask = 0x7ff << 8, .div1_mask = 0x7f, + .ssc_deltam_int_mask = 0x3 << 18, + .ssc_deltam_frac_mask = 0x3ffff, + .ssc_modfreq_mant_mask = 0x7f, + .ssc_modfreq_exp_mask = 0x7 << 8, .max_multiplier = 2047, .max_divider = 128, .min_divider = 1, diff --git a/drivers/clk/ti/dpll3xxx.c b/drivers/clk/ti/dpll3xxx.c index 94d5b5fe9a2b..e32b3515f9e7 100644 --- a/drivers/clk/ti/dpll3xxx.c +++ b/drivers/clk/ti/dpll3xxx.c @@ -291,6 +291,88 @@ static void _lookup_sddiv(struct clk_hw_omap *clk, u8 *sd_div, u16 m, u8 n) *sd_div = sd; } +/** + * omap3_noncore_dpll_ssc_program - set spread-spectrum clocking registers + * @clk: struct clk * of DPLL to set + * + * Enable the DPLL spread spectrum clocking if frequency modulation and + * frequency spreading have been set, otherwise disable it. + */ +static void omap3_noncore_dpll_ssc_program(struct clk_hw_omap *clk) +{ + struct dpll_data *dd = clk->dpll_data; + unsigned long ref_rate; + u32 v, ctrl, mod_freq_divider, exponent, mantissa; + u32 deltam_step, deltam_ceil; + + ctrl = ti_clk_ll_ops->clk_readl(&dd->control_reg); + + if (dd->ssc_modfreq && dd->ssc_deltam) { + ctrl |= dd->ssc_enable_mask; + + if (dd->ssc_downspread) + ctrl |= dd->ssc_downspread_mask; + else + ctrl &= ~dd->ssc_downspread_mask; + + ref_rate = clk_hw_get_rate(dd->clk_ref); + mod_freq_divider = + (ref_rate / dd->last_rounded_n) / (4 * dd->ssc_modfreq); + if (dd->ssc_modfreq > (ref_rate / 70)) + pr_warn("clock: SSC modulation frequency of DPLL %s greater than %ld\n", + __clk_get_name(clk->hw.clk), ref_rate / 70); + + exponent = 0; + mantissa = mod_freq_divider; + while ((mantissa > 127) && (exponent < 7)) { + exponent++; + mantissa /= 2; + } + if (mantissa > 127) + mantissa = 127; + + v = ti_clk_ll_ops->clk_readl(&dd->ssc_modfreq_reg); + v &= ~(dd->ssc_modfreq_mant_mask | dd->ssc_modfreq_exp_mask); + v |= mantissa << __ffs(dd->ssc_modfreq_mant_mask); + v |= exponent << __ffs(dd->ssc_modfreq_exp_mask); + ti_clk_ll_ops->clk_writel(v, &dd->ssc_modfreq_reg); + + deltam_step = dd->last_rounded_m * dd->ssc_deltam; + deltam_step /= 10; + if (dd->ssc_downspread) + deltam_step /= 2; + + deltam_step <<= __ffs(dd->ssc_deltam_int_mask); + deltam_step /= 100; + deltam_step /= mod_freq_divider; + if (deltam_step > 0xFFFFF) + deltam_step = 0xFFFFF; + + deltam_ceil = (deltam_step & dd->ssc_deltam_int_mask) >> + __ffs(dd->ssc_deltam_int_mask); + if (deltam_step & dd->ssc_deltam_frac_mask) + deltam_ceil++; + + if ((dd->ssc_downspread && + ((dd->last_rounded_m - (2 * deltam_ceil)) < 20 || + dd->last_rounded_m > 2045)) || + ((dd->last_rounded_m - deltam_ceil) < 20 || + (dd->last_rounded_m + deltam_ceil) > 2045)) + pr_warn("clock: SSC multiplier of DPLL %s is out of range\n", + __clk_get_name(clk->hw.clk)); + + v = ti_clk_ll_ops->clk_readl(&dd->ssc_deltam_reg); + v &= ~(dd->ssc_deltam_int_mask | dd->ssc_deltam_frac_mask); + v |= deltam_step << __ffs(dd->ssc_deltam_int_mask | + dd->ssc_deltam_frac_mask); + ti_clk_ll_ops->clk_writel(v, &dd->ssc_deltam_reg); + } else { + ctrl &= ~dd->ssc_enable_mask; + } + + ti_clk_ll_ops->clk_writel(ctrl, &dd->control_reg); +} + /** * omap3_noncore_dpll_program - set non-core DPLL M,N values directly * @clk: struct clk * of DPLL to set @@ -390,6 +472,9 @@ static int omap3_noncore_dpll_program(struct clk_hw_omap *clk, u16 freqsel) ti_clk_ll_ops->clk_writel(v, &dd->control_reg); } + if (dd->ssc_enable_mask) + omap3_noncore_dpll_ssc_program(clk); + /* We let the clock framework set the other output dividers later */ /* REVISIT: Set ramp-up delay? */ diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index c62f6fa6763d..cba093de62d8 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h @@ -63,6 +63,18 @@ struct clk_omap_reg { * @auto_recal_bit: bitshift of the driftguard enable bit in @control_reg * @recal_en_bit: bitshift of the PRM_IRQENABLE_* bit for recalibration IRQs * @recal_st_bit: bitshift of the PRM_IRQSTATUS_* bit for recalibration IRQs + * @ssc_deltam_reg: register containing the DPLL SSC frequency spreading + * @ssc_modfreq_reg: register containing the DPLL SSC modulation frequency + * @ssc_modfreq_mant_mask: mask of the mantissa component in @ssc_modfreq_reg + * @ssc_modfreq_exp_mask: mask of the exponent component in @ssc_modfreq_reg + * @ssc_enable_mask: mask of the DPLL SSC enable bit in @control_reg + * @ssc_ack_mask: mask of the DPLL SSC turned on/off bit in @control_reg + * @ssc_downspread_mask: mask of the DPLL SSC low frequency only bit in + * @control_reg + * @ssc_modfreq: the DPLL SSC frequency modulation in kHz + * @ssc_deltam: the DPLL SSC frequency spreading in permille (10th of percent) + * @ssc_downspread: require the only low frequency spread of the DPLL in SSC + * mode * @flags: DPLL type/features (see below) * * Possible values for @flags: @@ -110,6 +122,18 @@ struct dpll_data { u8 auto_recal_bit; u8 recal_en_bit; u8 recal_st_bit; + struct clk_omap_reg ssc_deltam_reg; + struct clk_omap_reg ssc_modfreq_reg; + u32 ssc_deltam_int_mask; + u32 ssc_deltam_frac_mask; + u32 ssc_modfreq_mant_mask; + u32 ssc_modfreq_exp_mask; + u32 ssc_enable_mask; + u32 ssc_ack_mask; + u32 ssc_downspread_mask; + u32 ssc_modfreq; + u32 ssc_deltam; + u8 ssc_downspread; u8 flags; };