get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/813497/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 813497,
    "url": "http://patchwork.ozlabs.org/api/patches/813497/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/1505318412-27121-4-git-send-email-patrice.chotard@st.com/",
    "project": {
        "id": 18,
        "url": "http://patchwork.ozlabs.org/api/projects/18/?format=api",
        "name": "U-Boot",
        "link_name": "uboot",
        "list_id": "u-boot.lists.denx.de",
        "list_email": "u-boot@lists.denx.de",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<1505318412-27121-4-git-send-email-patrice.chotard@st.com>",
    "list_archive_url": null,
    "date": "2017-09-13T16:00:06",
    "name": "[U-Boot,v2,3/9] dm: clk: add clk driver support for stm32h7 SoCs",
    "commit_ref": "4c3aebd56a035740f04fce44ce6c398afbb5ad86",
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "3a963f0b3ecfc42ce14adc187f7103dadb9b134b",
    "submitter": {
        "id": 63958,
        "url": "http://patchwork.ozlabs.org/api/people/63958/?format=api",
        "name": "Patrice CHOTARD",
        "email": "patrice.chotard@st.com"
    },
    "delegate": {
        "id": 3651,
        "url": "http://patchwork.ozlabs.org/api/users/3651/?format=api",
        "username": "trini",
        "first_name": "Tom",
        "last_name": "Rini",
        "email": "trini@ti.com"
    },
    "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/1505318412-27121-4-git-send-email-patrice.chotard@st.com/mbox/",
    "series": [
        {
            "id": 2943,
            "url": "http://patchwork.ozlabs.org/api/series/2943/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=2943",
            "date": "2017-09-13T16:00:03",
            "name": "Add STM32H7 SoC, Discovery and Evaluation board support",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/2943/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/813497/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/813497/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<u-boot-bounces@lists.denx.de>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org",
        "Authentication-Results": "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=lists.denx.de\n\t(client-ip=81.169.180.215; helo=lists.denx.de;\n\tenvelope-from=u-boot-bounces@lists.denx.de;\n\treceiver=<UNKNOWN>)",
        "Received": [
            "from lists.denx.de (dione.denx.de [81.169.180.215])\n\tby ozlabs.org (Postfix) with ESMTP id 3xsmdR4GQcz9sPk\n\tfor <incoming@patchwork.ozlabs.org>;\n\tThu, 14 Sep 2017 02:02:19 +1000 (AEST)",
            "by lists.denx.de (Postfix, from userid 105)\n\tid 5B872C224CE; Wed, 13 Sep 2017 16:01:27 +0000 (UTC)",
            "from lists.denx.de (localhost [IPv6:::1])\n\tby lists.denx.de (Postfix) with ESMTP id 372C8C21F0C;\n\tWed, 13 Sep 2017 16:00:27 +0000 (UTC)",
            "by lists.denx.de (Postfix, from userid 105)\n\tid 971B0C22044; Wed, 13 Sep 2017 16:00:21 +0000 (UTC)",
            "from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com\n\t[62.209.51.94]) by lists.denx.de (Postfix) with ESMTPS id 037A5C21F0C\n\tfor <u-boot@lists.denx.de>; Wed, 13 Sep 2017 16:00:20 +0000 (UTC)",
            "from pps.filterd (m0046037.ppops.net [127.0.0.1])\n\tby mx07-.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id\n\tv8DFwrcN006747; Wed, 13 Sep 2017 18:00:19 +0200",
            "from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35])\n\tby mx07-00178001.pphosted.com with ESMTP id 2cy3kr1eg4-1\n\t(version=TLSv1 cipher=ECDHE-RSA-AES256-SHA bits=256 verify=NOT);\n\tWed, 13 Sep 2017 18:00:19 +0200",
            "from zeta.dmz-eu.st.com (zeta.dmz-eu.st.com [164.129.230.9])\n\tby beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 41AA031;\n\tWed, 13 Sep 2017 16:00:19 +0000 (GMT)",
            "from Webmail-eu.st.com (sfhdag6node3.st.com [10.75.127.18])\n\tby zeta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 0DE7C2B31;\n\tWed, 13 Sep 2017 16:00:19 +0000 (GMT)",
            "from localhost (10.75.127.44) by SFHDAG6NODE3.st.com (10.75.127.18)\n\twith Microsoft SMTP Server (TLS) id 15.0.1178.4;\n\tWed, 13 Sep 2017 18:00:18 +0200"
        ],
        "X-Spam-Checker-Version": "SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de",
        "X-Spam-Level": "",
        "X-Spam-Status": "No, score=-0.7 required=5.0 tests=RCVD_IN_DNSWL_LOW\n\tautolearn=unavailable autolearn_force=no version=3.4.0",
        "From": "<patrice.chotard@st.com>",
        "To": "<u-boot@lists.denx.de>, <albert.u.boot@aribaud.net>, <sjg@chromium.org>, \n\t<vikas.manocha@st.com>",
        "Date": "Wed, 13 Sep 2017 18:00:06 +0200",
        "Message-ID": "<1505318412-27121-4-git-send-email-patrice.chotard@st.com>",
        "X-Mailer": "git-send-email 1.9.1",
        "In-Reply-To": "<1505318412-27121-1-git-send-email-patrice.chotard@st.com>",
        "References": "<1505318412-27121-1-git-send-email-patrice.chotard@st.com>",
        "MIME-Version": "1.0",
        "X-Originating-IP": "[10.75.127.44]",
        "X-ClientProxiedBy": "SFHDAG6NODE2.st.com (10.75.127.17) To SFHDAG6NODE3.st.com\n\t(10.75.127.18)",
        "X-Proofpoint-Virus-Version": "vendor=fsecure engine=2.50.10432:, ,\n\tdefinitions=2017-09-13_04:, , signatures=0",
        "Subject": "[U-Boot] [PATCH v2 3/9] dm: clk: add clk driver support for stm32h7\n\tSoCs",
        "X-BeenThere": "u-boot@lists.denx.de",
        "X-Mailman-Version": "2.1.18",
        "Precedence": "list",
        "List-Id": "U-Boot discussion <u-boot.lists.denx.de>",
        "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n\t<mailto:u-boot-request@lists.denx.de?subject=unsubscribe>",
        "List-Archive": "<http://lists.denx.de/pipermail/u-boot/>",
        "List-Post": "<mailto:u-boot@lists.denx.de>",
        "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>",
        "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n\t<mailto:u-boot-request@lists.denx.de?subject=subscribe>",
        "Content-Type": "text/plain; charset=\"utf-8\"",
        "Content-Transfer-Encoding": "base64",
        "Errors-To": "u-boot-bounces@lists.denx.de",
        "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>"
    },
    "content": "From: Patrice Chotard <patrice.chotard@st.com>\n\nThis driver implements basic clock setup, only clock gating\nis implemented.\n\nThis driver doesn't implement .of_match as it's binded\nby MFD RCC driver.\n\nFiles include/dt-bindings/clock/stm32h7-clks.h and\ndoc/device-tree-bindings/clock/st,stm32h7-rcc.txt\nwill be available soon in a kernel tag, as all the\nbindings have been acked by Rob Herring [1].\n\n[1] http://lkml.iu.edu/hypermail/linux/kernel/1704.0/00935.html\n\nSigned-off-by: Patrice Chotard <patrice.chotard@st.com>\n---\n doc/device-tree-bindings/clock/st,stm32h7-rcc.txt | 152 ++++\n drivers/clk/Makefile                              |   1 +\n drivers/clk/clk_stm32h7.c                         | 802 ++++++++++++++++++++++\n include/dt-bindings/clock/stm32h7-clks.h          | 167 +++++\n 4 files changed, 1122 insertions(+)\n create mode 100644 doc/device-tree-bindings/clock/st,stm32h7-rcc.txt\n create mode 100644 drivers/clk/clk_stm32h7.c\n create mode 100644 include/dt-bindings/clock/stm32h7-clks.h",
    "diff": "diff --git a/doc/device-tree-bindings/clock/st,stm32h7-rcc.txt b/doc/device-tree-bindings/clock/st,stm32h7-rcc.txt\nnew file mode 100644\nindex 0000000..9d4b587\n--- /dev/null\n+++ b/doc/device-tree-bindings/clock/st,stm32h7-rcc.txt\n@@ -0,0 +1,152 @@\n+STMicroelectronics STM32H7 Reset and Clock Controller\n+=====================================================\n+\n+The RCC IP is both a reset and a clock controller.\n+\n+Please refer to clock-bindings.txt for common clock controller binding usage.\n+Please also refer to reset.txt for common reset controller binding usage.\n+\n+Required properties:\n+- compatible: Should be:\n+  \"st,stm32h743-rcc\"\n+\n+- reg: should be register base and length as documented in the\n+  datasheet\n+\n+- #reset-cells: 1, see below\n+\n+- #clock-cells : from common clock binding; shall be set to 1\n+\n+- clocks: External oscillator clock phandle\n+  - high speed external clock signal (HSE)\n+  - low speed external clock signal (LSE)\n+  - external I2S clock (I2S_CKIN)\n+\n+- st,syscfg: phandle for pwrcfg, mandatory to disable/enable backup domain\n+  write protection (RTC clock).\n+\n+- pll x node: Allow to register a pll with specific parameters.\n+  Please see PLL section below.\n+\n+Example:\n+\n+\trcc: rcc@58024400 {\n+\t\t#reset-cells = <1>;\n+\t\t#clock-cells = <2>\n+\t\tcompatible = \"st,stm32h743-rcc\", \"st,stm32-rcc\";\n+\t\treg = <0x58024400 0x400>;\n+\t\tclocks = <&clk_hse>, <&clk_lse>, <&clk_i2s_ckin>;\n+\n+\t\tst,syscfg = <&pwrcfg>;\n+\n+\t\t#address-cells = <1>;\n+\t\t#size-cells = <0>;\n+\n+\t\tvco1@58024430 {\n+\t\t\t#clock-cells = <0>;\n+\t\t\tcompatible = \"stm32,pll\";\n+\t\t\treg = <0>;\n+\t\t};\n+\n+\t\tvco2@58024438 {\n+\t\t\t#clock-cells = <0>;\n+\t\t\tcompatible = \"stm32,pll\";\n+\t\t\treg = <1>;\n+\t\t\tst,clock-div = <2>;\n+\t\t\tst,clock-mult = <40>;\n+\t\t\tst,frac-status = <0>;\n+\t\t\tst,frac = <0>;\n+\t\t\tst,vcosel = <1>;\n+\t\t\tst,pllrge = <2>;\n+\t\t};\n+\t};\n+\n+\n+STM32H7 PLL\n+-----------\n+\n+The VCO of STM32 PLL could be reprensented like this:\n+\n+  Vref    ---------       --------\n+    ---->| / DIVM  |---->| x DIVN | ------> VCO\n+          ---------       --------\n+\t\t             ^\n+\t\t\t     |\n+\t                  -------\n+\t\t         | FRACN |\n+\t\t          -------\n+\n+When the PLL is configured in integer mode:\n+- VCO = ( Vref / DIVM ) * DIVN\n+\n+When the PLL is configured in fractional mode:\n+- VCO = ( Vref / DIVM ) * ( DIVN + FRACN / 2^13)\n+\n+\n+Required properties for pll node:\n+- compatible: Should be:\n+  \"stm32,pll\"\n+\n+- #clock-cells: from common clock binding; shall be set to 0\n+- reg: Should be the pll number.\n+\n+Optional properties:\n+- st,clock-div:  DIVM division factor       : <1..63>\n+- st,clock-mult: DIVN multiplication factor : <4..512>\n+\n+- st,frac-status:\n+   - 0 Pll is configured in integer mode\n+   - 1 Pll is configure in fractional mode\n+\n+- st,frac: Fractional part of the multiplication factor : <0..8191>\n+\n+- st,vcosel: VCO selection\n+  - 0: Wide VCO range:192 to 836 MHz\n+  - 1: Medium VCO range:150 to 420 MHz\n+\n+- st,pllrge: PLL input frequency range\n+  - 0: The PLL input (Vref / DIVM) clock range frequency is between 1 and 2 MHz\n+  - 1: The PLL input (Vref / DIVM) clock range frequency is between 2 and 4 MHz\n+  - 2: The PLL input (Vref / DIVM) clock range frequency is between 4 and 8 MHz\n+  - 3: The PLL input (Vref / DIVM) clock range frequency is between 8 and 16 MHz\n+\n+\n+The peripheral clock consumer should specify the desired clock by\n+having the clock ID in its \"clocks\" phandle cell.\n+\n+All available clocks are defined as preprocessor macros in\n+dt-bindings/clock/stm32h7-clks.h header and can be used in device\n+tree sources.\n+\n+Example:\n+\n+\t\ttimer5: timer@40000c00 {\n+\t\t\tcompatible = \"st,stm32-timer\";\n+\t\t\treg = <0x40000c00 0x400>;\n+\t\t\tinterrupts = <50>;\n+\t\t\tclocks = <&rcc TIM5_CK>;\n+\n+\t\t};\n+\n+Specifying softreset control of devices\n+=======================================\n+\n+Device nodes should specify the reset channel required in their \"resets\"\n+property, containing a phandle to the reset device node and an index specifying\n+which channel to use.\n+The index is the bit number within the RCC registers bank, starting from RCC\n+base address.\n+It is calculated as: index = register_offset / 4 * 32 + bit_offset.\n+Where bit_offset is the bit offset within the register.\n+\n+For example, for CRC reset:\n+  crc = AHB4RSTR_offset / 4 * 32 + CRCRST_bit_offset = 0x88 / 4 * 32 + 19 = 1107\n+\n+All available preprocessor macros for reset are defined dt-bindings//mfd/stm32h7-rcc.h\n+header and can be used in device tree sources.\n+\n+example:\n+\n+\ttimer2 {\n+\t\tresets\t= <&rcc STM32H7_APB1L_RESET(TIM2)>;\n+\t};\ndiff --git a/drivers/clk/Makefile b/drivers/clk/Makefile\nindex b773593..83fe88c 100644\n--- a/drivers/clk/Makefile\n+++ b/drivers/clk/Makefile\n@@ -22,3 +22,4 @@ obj-$(CONFIG_CLK_BCM6345) += clk_bcm6345.o\n obj-$(CONFIG_CLK_BOSTON) += clk_boston.o\n obj-$(CONFIG_ARCH_ASPEED) += aspeed/\n obj-$(CONFIG_STM32F7) += clk_stm32f7.o\n+obj-$(CONFIG_STM32H7) += clk_stm32h7.o\ndiff --git a/drivers/clk/clk_stm32h7.c b/drivers/clk/clk_stm32h7.c\nnew file mode 100644\nindex 0000000..fd0e3ab\n--- /dev/null\n+++ b/drivers/clk/clk_stm32h7.c\n@@ -0,0 +1,802 @@\n+/*\n+ * Copyright (C) STMicroelectronics SA 2017\n+ * Author(s): Patrice CHOTARD, <patrice.chotard@st.com> for STMicroelectronics.\n+ *\n+ * SPDX-License-Identifier:\tGPL-2.0+\n+ */\n+\n+#include <common.h>\n+#include <clk-uclass.h>\n+#include <dm.h>\n+#include <regmap.h>\n+#include <syscon.h>\n+#include <asm/io.h>\n+#include <dm/root.h>\n+\n+#include <dt-bindings/clock/stm32h7-clks.h>\n+\n+DECLARE_GLOBAL_DATA_PTR;\n+\n+/* RCC CR specific definitions */\n+#define RCC_CR_HSION\t\t\tBIT(0)\n+#define RCC_CR_HSIRDY\t\t\tBIT(2)\n+\n+#define RCC_CR_HSEON\t\t\tBIT(16)\n+#define RCC_CR_HSERDY\t\t\tBIT(17)\n+#define RCC_CR_HSEBYP\t\t\tBIT(18)\n+#define RCC_CR_PLL1ON\t\t\tBIT(24)\n+#define RCC_CR_PLL1RDY\t\t\tBIT(25)\n+\n+#define RCC_CR_HSIDIV_MASK\t\tGENMASK(4, 3)\n+#define RCC_CR_HSIDIV_SHIFT\t\t3\n+\n+#define RCC_CFGR_SW_MASK\t\tGENMASK(2, 0)\n+#define RCC_CFGR_SW_HSI\t\t\t0\n+#define RCC_CFGR_SW_CSI\t\t\t1\n+#define RCC_CFGR_SW_HSE\t\t\t2\n+#define RCC_CFGR_SW_PLL1\t\t3\n+\n+#define RCC_PLLCKSELR_PLLSRC_HSI\t0\n+#define RCC_PLLCKSELR_PLLSRC_CSI\t1\n+#define RCC_PLLCKSELR_PLLSRC_HSE\t2\n+#define RCC_PLLCKSELR_PLLSRC_NO_CLK\t3\n+\n+#define RCC_PLLCKSELR_PLLSRC_MASK\tGENMASK(1, 0)\n+\n+#define RCC_PLLCKSELR_DIVM1_SHIFT\t4\n+#define RCC_PLLCKSELR_DIVM1_MASK\tGENMASK(9, 4)\n+\n+#define RCC_PLL1DIVR_DIVN1_MASK\t\tGENMASK(8, 0)\n+\n+#define RCC_PLL1DIVR_DIVP1_SHIFT\t9\n+#define RCC_PLL1DIVR_DIVP1_MASK\t\tGENMASK(15, 9)\n+\n+#define RCC_PLL1DIVR_DIVQ1_SHIFT\t16\n+#define RCC_PLL1DIVR_DIVQ1_MASK\t\tGENMASK(22, 16)\n+\n+#define RCC_PLL1DIVR_DIVR1_SHIFT\t24\n+#define RCC_PLL1DIVR_DIVR1_MASK\t\tGENMASK(30, 24)\n+\n+#define RCC_PLL1FRACR_FRACN1_SHIFT\t3\n+#define RCC_PLL1FRACR_FRACN1_MASK\tGENMASK(15, 3)\n+\n+#define RCC_PLLCFGR_PLL1RGE_SHIFT\t2\n+#define\t\tPLL1RGE_1_2_MHZ\t\t0\n+#define\t\tPLL1RGE_2_4_MHZ\t\t1\n+#define\t\tPLL1RGE_4_8_MHZ\t\t2\n+#define\t\tPLL1RGE_8_16_MHZ\t3\n+#define RCC_PLLCFGR_DIVP1EN\t\tBIT(16)\n+#define RCC_PLLCFGR_DIVQ1EN\t\tBIT(17)\n+#define RCC_PLLCFGR_DIVR1EN\t\tBIT(18)\n+\n+#define RCC_D1CFGR_HPRE_MASK\t\tGENMASK(3, 0)\n+#define RCC_D1CFGR_HPRE_DIVIDED\t\tBIT(3)\n+#define RCC_D1CFGR_HPRE_DIVIDER\t\tGENMASK(2, 0)\n+\n+#define RCC_D1CFGR_HPRE_DIV2\t\t8\n+\n+#define RCC_D1CFGR_D1PPRE_SHIFT\t\t4\n+#define RCC_D1CFGR_D1PPRE_DIVIDED\tBIT(6)\n+#define RCC_D1CFGR_D1PPRE_DIVIDER\tGENMASK(5, 4)\n+\n+#define RCC_D1CFGR_D1CPRE_SHIFT\t\t8\n+#define RCC_D1CFGR_D1CPRE_DIVIDER\tGENMASK(10, 8)\n+#define RCC_D1CFGR_D1CPRE_DIVIDED\tBIT(11)\n+\n+#define RCC_D2CFGR_D2PPRE1_SHIFT\t4\n+#define RCC_D2CFGR_D2PPRE1_DIVIDED\tBIT(6)\n+#define RCC_D2CFGR_D2PPRE1_DIVIDER\tGENMASK(5, 4)\n+\n+#define RCC_D2CFGR_D2PPRE2_SHIFT\t8\n+#define RCC_D2CFGR_D2PPRE2_DIVIDED\tBIT(10)\n+#define RCC_D2CFGR_D2PPRE2_DIVIDER\tGENMASK(9, 8)\n+\n+#define RCC_D3CFGR_D3PPRE_SHIFT\t\t4\n+#define RCC_D3CFGR_D3PPRE_DIVIDED\tBIT(6)\n+#define RCC_D3CFGR_D3PPRE_DIVIDER\tGENMASK(5, 4)\n+\n+#define RCC_D1CCIPR_FMCSRC_MASK\t\tGENMASK(1, 0)\n+#define\t\tFMCSRC_HCLKD1\t\t0\n+#define\t\tFMCSRC_PLL1_Q_CK\t1\n+#define\t\tFMCSRC_PLL2_R_CK\t2\n+#define\t\tFMCSRC_PER_CK\t\t3\n+\n+#define RCC_D1CCIPR_QSPISRC_MASK\tGENMASK(5, 4)\n+#define RCC_D1CCIPR_QSPISRC_SHIFT\t4\n+#define\t\tQSPISRC_HCLKD1\t\t0\n+#define\t\tQSPISRC_PLL1_Q_CK\t1\n+#define\t\tQSPISRC_PLL2_R_CK\t2\n+#define\t\tQSPISRC_PER_CK\t\t3\n+\n+#define PWR_CR3\t\t\t\t0x0c\n+#define PWR_CR3_SDEN\t\t\tBIT(2)\n+#define PWR_D3CR\t\t\t0x18\n+#define PWR_D3CR_VOS_MASK\t\tGENMASK(15, 14)\n+#define PWR_D3CR_VOS_SHIFT\t\t14\n+#define\t\tVOS_SCALE_3\t\t1\n+#define\t\tVOS_SCALE_2\t\t2\n+#define\t\tVOS_SCALE_1\t\t3\n+#define PWR_D3CR_VOSREADY\t\tBIT(13)\n+\n+struct stm32_rcc_regs {\n+\tu32 cr;\t\t/* 0x00 Source Control Register */\n+\tu32 icscr;\t/* 0x04 Internal Clock Source Calibration Register */\n+\tu32 crrcr;\t/* 0x08 Clock Recovery RC Register */\n+\tu32 reserved1;\t/* 0x0c reserved */\n+\tu32 cfgr;\t/* 0x10 Clock Configuration Register */\n+\tu32 reserved2;\t/* 0x14 reserved */\n+\tu32 d1cfgr;\t/* 0x18 Domain 1 Clock Configuration Register */\n+\tu32 d2cfgr;\t/* 0x1c Domain 2 Clock Configuration Register */\n+\tu32 d3cfgr;\t/* 0x20 Domain 3 Clock Configuration Register */\n+\tu32 reserved3;\t/* 0x24 reserved */\n+\tu32 pllckselr;\t/* 0x28 PLLs Clock Source Selection Register */\n+\tu32 pllcfgr;\t/* 0x2c PLLs Configuration Register */\n+\tu32 pll1divr;\t/* 0x30 PLL1 Dividers Configuration Register */\n+\tu32 pll1fracr;\t/* 0x34 PLL1 Fractional Divider Register */\n+\tu32 pll2divr;\t/* 0x38 PLL2 Dividers Configuration Register */\n+\tu32 pll2fracr;\t/* 0x3c PLL2 Fractional Divider Register */\n+\tu32 pll3divr;\t/* 0x40 PLL3 Dividers Configuration Register */\n+\tu32 pll3fracr;\t/* 0x44 PLL3 Fractional Divider Register */\n+\tu32 reserved4;\t/* 0x48 reserved */\n+\tu32 d1ccipr;\t/* 0x4c Domain 1 Kernel Clock Configuration Register */\n+\tu32 d2ccip1r;\t/* 0x50 Domain 2 Kernel Clock Configuration Register */\n+\tu32 d2ccip2r;\t/* 0x54 Domain 2 Kernel Clock Configuration Register */\n+\tu32 d3ccipr;\t/* 0x58 Domain 3 Kernel Clock Configuration Register */\n+\tu32 reserved5;\t/* 0x5c reserved */\n+\tu32 cier;\t/* 0x60 Clock Source Interrupt Enable Register */\n+\tu32 cifr;\t/* 0x64 Clock Source Interrupt Flag Register */\n+\tu32 cicr;\t/* 0x68 Clock Source Interrupt Clear Register */\n+\tu32 reserved6;\t/* 0x6c reserved */\n+\tu32 bdcr;\t/* 0x70 Backup Domain Control Register */\n+\tu32 csr;\t/* 0x74 Clock Control and Status Register */\n+\tu32 reserved7;\t/* 0x78 reserved */\n+\n+\tu32 ahb3rstr;\t/* 0x7c AHB3 Peripheral Reset Register */\n+\tu32 ahb1rstr;\t/* 0x80 AHB1 Peripheral Reset Register */\n+\tu32 ahb2rstr;\t/* 0x84 AHB2 Peripheral Reset Register */\n+\tu32 ahb4rstr;\t/* 0x88 AHB4 Peripheral Reset Register */\n+\n+\tu32 apb3rstr;\t/* 0x8c APB3 Peripheral Reset Register */\n+\tu32 apb1lrstr;\t/* 0x90 APB1 low Peripheral Reset Register */\n+\tu32 apb1hrstr;\t/* 0x94 APB1 high Peripheral Reset Register */\n+\tu32 apb2rstr;\t/* 0x98 APB2 Clock Register */\n+\tu32 apb4rstr;\t/* 0x9c APB4 Clock Register */\n+\n+\tu32 gcr;\t/* 0xa0 Global Control Register */\n+\tu32 reserved8;\t/* 0xa4 reserved */\n+\tu32 d3amr;\t/* 0xa8 D3 Autonomous mode Register */\n+\tu32 reserved9[9];/* 0xac to 0xcc reserved */\n+\tu32 rsr;\t/* 0xd0 Reset Status Register */\n+\tu32 ahb3enr;\t/* 0xd4 AHB3 Clock Register */\n+\tu32 ahb1enr;\t/* 0xd8 AHB1 Clock Register */\n+\tu32 ahb2enr;\t/* 0xdc AHB2 Clock Register */\n+\tu32 ahb4enr;\t/* 0xe0 AHB4 Clock Register */\n+\n+\tu32 apb3enr;\t/* 0xe4 APB3 Clock Register */\n+\tu32 apb1lenr;\t/* 0xe8 APB1 low Clock Register */\n+\tu32 apb1henr;\t/* 0xec APB1 high Clock Register */\n+\tu32 apb2enr;\t/* 0xf0 APB2 Clock Register */\n+\tu32 apb4enr;\t/* 0xf4 APB4 Clock Register */\n+};\n+\n+#define RCC_AHB3ENR\toffsetof(struct stm32_rcc_regs, ahb3enr)\n+#define RCC_AHB1ENR\toffsetof(struct stm32_rcc_regs, ahb1enr)\n+#define RCC_AHB2ENR\toffsetof(struct stm32_rcc_regs, ahb2enr)\n+#define RCC_AHB4ENR\toffsetof(struct stm32_rcc_regs, ahb4enr)\n+#define RCC_APB3ENR\toffsetof(struct stm32_rcc_regs, apb3enr)\n+#define RCC_APB1LENR\toffsetof(struct stm32_rcc_regs, apb1lenr)\n+#define RCC_APB1HENR\toffsetof(struct stm32_rcc_regs, apb1henr)\n+#define RCC_APB2ENR\toffsetof(struct stm32_rcc_regs, apb2enr)\n+#define RCC_APB4ENR\toffsetof(struct stm32_rcc_regs, apb4enr)\n+\n+struct clk_cfg {\n+\tu32 gate_offset;\n+\tu8  gate_bit_idx;\n+\tconst char *name;\n+};\n+\n+#define CLK(_gate_offset, _bit_idx, _name) \\\n+{ \\\n+\t.gate_offset = _gate_offset,\\\n+\t.gate_bit_idx = _bit_idx,\\\n+\t.name = _name,\\\n+}\n+\n+/*\n+ * the way all these entries are sorted in this array could seem\n+ * unlogical, but we are dependant of kernel DT_bindings,\n+ * where clocks are separate in 2 banks, peripheral clocks and\n+ * kernel clocks.\n+ */\n+\n+static const struct clk_cfg clk_map[] = {\n+\tCLK(RCC_AHB3ENR,  31, \"d1sram1\"),\t/* peripheral clocks */\n+\tCLK(RCC_AHB3ENR,  30, \"itcm\"),\n+\tCLK(RCC_AHB3ENR,  29, \"dtcm2\"),\n+\tCLK(RCC_AHB3ENR,  28, \"dtcm1\"),\n+\tCLK(RCC_AHB3ENR,   8, \"flitf\"),\n+\tCLK(RCC_AHB3ENR,   5, \"jpgdec\"),\n+\tCLK(RCC_AHB3ENR,   4, \"dma2d\"),\n+\tCLK(RCC_AHB3ENR,   0, \"mdma\"),\n+\tCLK(RCC_AHB1ENR,  28, \"usb2ulpi\"),\n+\tCLK(RCC_AHB1ENR,  17, \"eth1rx\"),\n+\tCLK(RCC_AHB1ENR,  16, \"eth1tx\"),\n+\tCLK(RCC_AHB1ENR,  15, \"eth1mac\"),\n+\tCLK(RCC_AHB1ENR,  14, \"art\"),\n+\tCLK(RCC_AHB1ENR,  26, \"usb1ulpi\"),\n+\tCLK(RCC_AHB1ENR,   1, \"dma2\"),\n+\tCLK(RCC_AHB1ENR,   0, \"dma1\"),\n+\tCLK(RCC_AHB2ENR,  31, \"d2sram3\"),\n+\tCLK(RCC_AHB2ENR,  30, \"d2sram2\"),\n+\tCLK(RCC_AHB2ENR,  29, \"d2sram1\"),\n+\tCLK(RCC_AHB2ENR,   5, \"hash\"),\n+\tCLK(RCC_AHB2ENR,   4, \"crypt\"),\n+\tCLK(RCC_AHB2ENR,   0, \"camitf\"),\n+\tCLK(RCC_AHB4ENR,  28, \"bkpram\"),\n+\tCLK(RCC_AHB4ENR,  25, \"hsem\"),\n+\tCLK(RCC_AHB4ENR,  21, \"bdma\"),\n+\tCLK(RCC_AHB4ENR,  19, \"crc\"),\n+\tCLK(RCC_AHB4ENR,  10, \"gpiok\"),\n+\tCLK(RCC_AHB4ENR,   9, \"gpioj\"),\n+\tCLK(RCC_AHB4ENR,   8, \"gpioi\"),\n+\tCLK(RCC_AHB4ENR,   7, \"gpioh\"),\n+\tCLK(RCC_AHB4ENR,   6, \"gpiog\"),\n+\tCLK(RCC_AHB4ENR,   5, \"gpiof\"),\n+\tCLK(RCC_AHB4ENR,   4, \"gpioe\"),\n+\tCLK(RCC_AHB4ENR,   3, \"gpiod\"),\n+\tCLK(RCC_AHB4ENR,   2, \"gpioc\"),\n+\tCLK(RCC_AHB4ENR,   1, \"gpiob\"),\n+\tCLK(RCC_AHB4ENR,   0, \"gpioa\"),\n+\tCLK(RCC_APB3ENR,   6, \"wwdg1\"),\n+\tCLK(RCC_APB1LENR, 29, \"dac12\"),\n+\tCLK(RCC_APB1LENR, 11, \"wwdg2\"),\n+\tCLK(RCC_APB1LENR,  8, \"tim14\"),\n+\tCLK(RCC_APB1LENR,  7, \"tim13\"),\n+\tCLK(RCC_APB1LENR,  6, \"tim12\"),\n+\tCLK(RCC_APB1LENR,  5, \"tim7\"),\n+\tCLK(RCC_APB1LENR,  4, \"tim6\"),\n+\tCLK(RCC_APB1LENR,  3, \"tim5\"),\n+\tCLK(RCC_APB1LENR,  2, \"tim4\"),\n+\tCLK(RCC_APB1LENR,  1, \"tim3\"),\n+\tCLK(RCC_APB1LENR,  0, \"tim2\"),\n+\tCLK(RCC_APB1HENR,  5, \"mdios\"),\n+\tCLK(RCC_APB1HENR,  4, \"opamp\"),\n+\tCLK(RCC_APB1HENR,  1, \"crs\"),\n+\tCLK(RCC_APB2ENR,  18, \"tim17\"),\n+\tCLK(RCC_APB2ENR,  17, \"tim16\"),\n+\tCLK(RCC_APB2ENR,  16, \"tim15\"),\n+\tCLK(RCC_APB2ENR,   1, \"tim8\"),\n+\tCLK(RCC_APB2ENR,   0, \"tim1\"),\n+\tCLK(RCC_APB4ENR,  26, \"tmpsens\"),\n+\tCLK(RCC_APB4ENR,  16, \"rtcapb\"),\n+\tCLK(RCC_APB4ENR,  15, \"vref\"),\n+\tCLK(RCC_APB4ENR,  14, \"comp12\"),\n+\tCLK(RCC_APB4ENR,   1, \"syscfg\"),\n+\tCLK(RCC_AHB3ENR,  16, \"sdmmc1\"),\t/* kernel clocks */\n+\tCLK(RCC_AHB3ENR,  14, \"quadspi\"),\n+\tCLK(RCC_AHB3ENR,  12, \"fmc\"),\n+\tCLK(RCC_AHB1ENR,  27, \"usb2otg\"),\n+\tCLK(RCC_AHB1ENR,  25, \"usb1otg\"),\n+\tCLK(RCC_AHB1ENR,   5, \"adc12\"),\n+\tCLK(RCC_AHB2ENR,   9, \"sdmmc2\"),\n+\tCLK(RCC_AHB2ENR,   6, \"rng\"),\n+\tCLK(RCC_AHB4ENR,  24, \"adc3\"),\n+\tCLK(RCC_APB3ENR,   4, \"dsi\"),\n+\tCLK(RCC_APB3ENR,   3, \"ltdc\"),\n+\tCLK(RCC_APB1LENR, 31, \"usart8\"),\n+\tCLK(RCC_APB1LENR, 30, \"usart7\"),\n+\tCLK(RCC_APB1LENR, 27, \"hdmicec\"),\n+\tCLK(RCC_APB1LENR, 23, \"i2c3\"),\n+\tCLK(RCC_APB1LENR, 22, \"i2c2\"),\n+\tCLK(RCC_APB1LENR, 21, \"i2c1\"),\n+\tCLK(RCC_APB1LENR, 20, \"uart5\"),\n+\tCLK(RCC_APB1LENR, 19, \"uart4\"),\n+\tCLK(RCC_APB1LENR, 18, \"usart3\"),\n+\tCLK(RCC_APB1LENR, 17, \"usart2\"),\n+\tCLK(RCC_APB1LENR, 16, \"spdifrx\"),\n+\tCLK(RCC_APB1LENR, 15, \"spi3\"),\n+\tCLK(RCC_APB1LENR, 14, \"spi2\"),\n+\tCLK(RCC_APB1LENR,  9, \"lptim1\"),\n+\tCLK(RCC_APB1HENR,  8, \"fdcan\"),\n+\tCLK(RCC_APB1HENR,  2, \"swp\"),\n+\tCLK(RCC_APB2ENR,  29, \"hrtim\"),\n+\tCLK(RCC_APB2ENR,  28, \"dfsdm1\"),\n+\tCLK(RCC_APB2ENR,  24, \"sai3\"),\n+\tCLK(RCC_APB2ENR,  23, \"sai2\"),\n+\tCLK(RCC_APB2ENR,  22, \"sai1\"),\n+\tCLK(RCC_APB2ENR,  20, \"spi5\"),\n+\tCLK(RCC_APB2ENR,  13, \"spi4\"),\n+\tCLK(RCC_APB2ENR,  12, \"spi1\"),\n+\tCLK(RCC_APB2ENR,   5, \"usart6\"),\n+\tCLK(RCC_APB2ENR,   4, \"usart1\"),\n+\tCLK(RCC_APB4ENR,  21, \"sai4a\"),\n+\tCLK(RCC_APB4ENR,  21, \"sai4b\"),\n+\tCLK(RCC_APB4ENR,  12, \"lptim5\"),\n+\tCLK(RCC_APB4ENR,  11, \"lptim4\"),\n+\tCLK(RCC_APB4ENR,  10, \"lptim3\"),\n+\tCLK(RCC_APB4ENR,   9, \"lptim2\"),\n+\tCLK(RCC_APB4ENR,   7, \"i2c4\"),\n+\tCLK(RCC_APB4ENR,   5,  \"spi6\"),\n+\tCLK(RCC_APB4ENR,   3, \"lpuart1\"),\n+};\n+\n+struct stm32_clk {\n+\tstruct stm32_rcc_regs *rcc_base;\n+\tstruct regmap *pwr_regmap;\n+};\n+\n+struct pll_psc {\n+\tu8\tdivm;\n+\tu16\tdivn;\n+\tu8\tdivp;\n+\tu8\tdivq;\n+\tu8\tdivr;\n+};\n+\n+/*\n+ * OSC_HSE = 25 MHz\n+ * VCO = 500MHz\n+ * pll1_p = 250MHz / pll1_q = 250MHz pll1_r = 250Mhz\n+ */\n+struct pll_psc sys_pll_psc = {\n+\t.divm = 4,\n+\t.divn = 80,\n+\t.divp = 2,\n+\t.divq = 2,\n+\t.divr = 2,\n+};\n+\n+int configure_clocks(struct udevice *dev)\n+{\n+\tstruct stm32_clk *priv = dev_get_priv(dev);\n+\tstruct stm32_rcc_regs *regs = priv->rcc_base;\n+\tuint8_t *pwr_base = (uint8_t *)regmap_get_range(priv->pwr_regmap, 0);\n+\tuint32_t pllckselr = 0;\n+\tuint32_t pll1divr = 0;\n+\tuint32_t pllcfgr = 0;\n+\n+\t/* Switch on HSI */\n+\tsetbits_le32(&regs->cr, RCC_CR_HSION);\n+\twhile (!(readl(&regs->cr) & RCC_CR_HSIRDY))\n+\t\t;\n+\n+\t/* Reset CFGR, now HSI is the default system clock */\n+\twritel(0, &regs->cfgr);\n+\n+\t/* Set all kernel domain clock registers to reset value*/\n+\twritel(0x0, &regs->d1ccipr);\n+\twritel(0x0, &regs->d2ccip1r);\n+\twritel(0x0, &regs->d2ccip2r);\n+\n+\t/* Set voltage scaling at scale 1 */\n+\tclrsetbits_le32(pwr_base + PWR_D3CR, PWR_D3CR_VOS_MASK,\n+\t\t\tVOS_SCALE_1 << PWR_D3CR_VOS_SHIFT);\n+\t/* disable step down converter */\n+\tclrbits_le32(pwr_base + PWR_CR3, PWR_CR3_SDEN);\n+\twhile (!(readl(pwr_base + PWR_D3CR) & PWR_D3CR_VOSREADY))\n+\t\t;\n+\n+\t/* disable HSE to configure it  */\n+\tclrbits_le32(&regs->cr, RCC_CR_HSEON);\n+\twhile ((readl(&regs->cr) & RCC_CR_HSERDY))\n+\t\t;\n+\n+\t/* clear HSE bypass and set it ON */\n+\tclrbits_le32(&regs->cr, RCC_CR_HSEBYP);\n+\t/* Switch on HSE */\n+\tsetbits_le32(&regs->cr, RCC_CR_HSEON);\n+\twhile (!(readl(&regs->cr) & RCC_CR_HSERDY))\n+\t\t;\n+\n+\t/* pll setup, disable it */\n+\tclrbits_le32(&regs->cr, RCC_CR_PLL1ON);\n+\twhile ((readl(&regs->cr) & RCC_CR_PLL1RDY))\n+\t\t;\n+\n+\t/* Select HSE as PLL clock source */\n+\tpllckselr |= RCC_PLLCKSELR_PLLSRC_HSE;\n+\tpllckselr |= sys_pll_psc.divm << RCC_PLLCKSELR_DIVM1_SHIFT;\n+\twritel(pllckselr, &regs->pllckselr);\n+\n+\tpll1divr |= (sys_pll_psc.divr - 1) << RCC_PLL1DIVR_DIVR1_SHIFT;\n+\tpll1divr |= (sys_pll_psc.divq - 1) << RCC_PLL1DIVR_DIVQ1_SHIFT;\n+\tpll1divr |= (sys_pll_psc.divp - 1) << RCC_PLL1DIVR_DIVP1_SHIFT;\n+\tpll1divr |= (sys_pll_psc.divn - 1);\n+\twritel(pll1divr, &regs->pll1divr);\n+\n+\tpllcfgr |= PLL1RGE_4_8_MHZ << RCC_PLLCFGR_PLL1RGE_SHIFT;\n+\tpllcfgr |= RCC_PLLCFGR_DIVP1EN;\n+\tpllcfgr |= RCC_PLLCFGR_DIVQ1EN;\n+\tpllcfgr |= RCC_PLLCFGR_DIVR1EN;\n+\twritel(pllcfgr, &regs->pllcfgr);\n+\n+\t/* pll setup, enable it */\n+\tsetbits_le32(&regs->cr, RCC_CR_PLL1ON);\n+\n+\t/* set HPRE (/2) DI clk --> 125MHz */\n+\tclrsetbits_le32(&regs->d1cfgr, RCC_D1CFGR_HPRE_MASK,\n+\t\t\tRCC_D1CFGR_HPRE_DIV2);\n+\n+\t/*  select PLL1 as system clock source (sys_ck)*/\n+\tclrsetbits_le32(&regs->cfgr, RCC_CFGR_SW_MASK, RCC_CFGR_SW_PLL1);\n+\twhile ((readl(&regs->cfgr) & RCC_CFGR_SW_MASK) != RCC_CFGR_SW_PLL1)\n+\t\t;\n+\n+\t/* sdram: use pll1_q as fmc_k clk */\n+\tclrsetbits_le32(&regs->d1ccipr, RCC_D1CCIPR_FMCSRC_MASK,\n+\t\t\tFMCSRC_PLL1_Q_CK);\n+\n+\treturn 0;\n+}\n+\n+static u32 stm32_get_HSI_divider(struct stm32_rcc_regs *regs)\n+{\n+\tu32 divider;\n+\n+\t/* get HSI divider value */\n+\tdivider = readl(&regs->cr) & RCC_CR_HSIDIV_MASK;\n+\tdivider = divider >> RCC_CR_HSIDIV_SHIFT;\n+\n+\treturn divider;\n+};\n+\n+enum pllsrc {\n+\tHSE,\n+\tLSE,\n+\tHSI,\n+\tCSI,\n+\tI2S,\n+\tTIMER,\n+\tPLLSRC_NB,\n+};\n+\n+static const char * const pllsrc_name[PLLSRC_NB] = {\n+\t[HSE] = \"clk-hse\",\n+\t[LSE] = \"clk-lse\",\n+\t[HSI] = \"clk-hsi\",\n+\t[CSI] = \"clk-csi\",\n+\t[I2S] = \"clk-i2s\",\n+\t[TIMER] = \"timer-clk\"\n+};\n+\n+static ulong stm32_get_rate(struct stm32_rcc_regs *regs, enum pllsrc pllsrc)\n+{\n+\tstruct clk clk;\n+\tstruct udevice *fixed_clock_dev = NULL;\n+\tu32 divider;\n+\tint ret;\n+\tconst char *name = pllsrc_name[pllsrc];\n+\n+\tdebug(\"%s name %s\\n\", __func__, name);\n+\n+\tclk.id = 0;\n+\tret = uclass_get_device_by_name(UCLASS_CLK, name, &fixed_clock_dev);\n+\tif (ret) {\n+\t\terror(\"Can't find clk %s (%d)\", name, ret);\n+\t\treturn 0;\n+\t}\n+\n+\tret = clk_request(fixed_clock_dev, &clk);\n+\tif (ret) {\n+\t\terror(\"Can't request %s clk (%d)\", name, ret);\n+\t\treturn 0;\n+\t}\n+\n+\tdivider = 0;\n+\tif (pllsrc == HSI)\n+\t\tdivider = stm32_get_HSI_divider(regs);\n+\n+\tdebug(\"%s divider %d rate %ld\\n\", __func__,\n+\t      divider, clk_get_rate(&clk));\n+\n+\treturn clk_get_rate(&clk) >> divider;\n+};\n+\n+enum pll1_output {\n+\tPLL1_P_CK,\n+\tPLL1_Q_CK,\n+\tPLL1_R_CK,\n+};\n+\n+static u32 stm32_get_PLL1_rate(struct stm32_rcc_regs *regs,\n+\t\t\t       enum pll1_output output)\n+{\n+\tulong pllsrc = 0;\n+\tu32 divm1, divn1, divp1, divq1, divr1, fracn1;\n+\tulong vco, rate;\n+\n+\t/* get the PLLSRC */\n+\tswitch (readl(&regs->pllckselr) & RCC_PLLCKSELR_PLLSRC_MASK) {\n+\tcase RCC_PLLCKSELR_PLLSRC_HSI:\n+\t\tpllsrc = stm32_get_rate(regs, HSI);\n+\t\tbreak;\n+\tcase RCC_PLLCKSELR_PLLSRC_CSI:\n+\t\tpllsrc = stm32_get_rate(regs, CSI);\n+\t\tbreak;\n+\tcase RCC_PLLCKSELR_PLLSRC_HSE:\n+\t\tpllsrc = stm32_get_rate(regs, HSE);\n+\t\tbreak;\n+\tcase RCC_PLLCKSELR_PLLSRC_NO_CLK:\n+\t\t/* shouldn't happen */\n+\t\terror(\"wrong value for RCC_PLLCKSELR register\\n\");\n+\t\tpllsrc = 0;\n+\t\tbreak;\n+\t}\n+\n+\t/* pllsrc = 0 ? no need to go ahead */\n+\tif (!pllsrc)\n+\t\treturn pllsrc;\n+\n+\t/* get divm1, divp1, divn1 and divr1 */\n+\tdivm1 = readl(&regs->pllckselr) & RCC_PLLCKSELR_DIVM1_MASK;\n+\tdivm1 = divm1 >> RCC_PLLCKSELR_DIVM1_SHIFT;\n+\n+\tdivn1 = (readl(&regs->pll1divr) & RCC_PLL1DIVR_DIVN1_MASK) + 1;\n+\n+\tdivp1 = readl(&regs->pll1divr) & RCC_PLL1DIVR_DIVP1_MASK;\n+\tdivp1 = (divp1 >> RCC_PLL1DIVR_DIVP1_SHIFT) + 1;\n+\n+\tdivq1 = readl(&regs->pll1divr) & RCC_PLL1DIVR_DIVQ1_MASK;\n+\tdivq1 = (divq1 >> RCC_PLL1DIVR_DIVQ1_SHIFT) + 1;\n+\n+\tdivr1 = readl(&regs->pll1divr) & RCC_PLL1DIVR_DIVR1_MASK;\n+\tdivr1 = (divr1 >> RCC_PLL1DIVR_DIVR1_SHIFT) + 1;\n+\n+\tfracn1 = readl(&regs->pll1fracr) & RCC_PLL1DIVR_DIVR1_MASK;\n+\tfracn1 = fracn1 & RCC_PLL1DIVR_DIVR1_SHIFT;\n+\n+\tvco = (pllsrc / divm1) * divn1;\n+\trate = (pllsrc * fracn1) / (divm1 * 8192);\n+\n+\tdebug(\"%s divm1 = %d divn1 = %d divp1 = %d divq1 = %d divr1 = %d\\n\",\n+\t      __func__, divm1, divn1, divp1, divq1, divr1);\n+\tdebug(\"%s fracn1 = %d vco = %ld rate = %ld\\n\",\n+\t      __func__, fracn1, vco, rate);\n+\n+\tswitch (output) {\n+\tcase PLL1_P_CK:\n+\t\treturn (vco + rate) / divp1;\n+\t\tbreak;\n+\tcase PLL1_Q_CK:\n+\t\treturn (vco + rate) / divq1;\n+\t\tbreak;\n+\n+\tcase PLL1_R_CK:\n+\t\treturn (vco + rate) / divr1;\n+\t\tbreak;\n+\t}\n+\n+\treturn -EINVAL;\n+}\n+\n+static ulong stm32_clk_get_rate(struct clk *clk)\n+{\n+\tstruct stm32_clk *priv = dev_get_priv(clk->dev);\n+\tstruct stm32_rcc_regs *regs = priv->rcc_base;\n+\tulong sysclk = 0;\n+\tu32 gate_offset;\n+\tu32 d1cfgr;\n+\t/* prescaler table lookups for clock computation */\n+\tu16 prescaler_table[8] = {2, 4, 8, 16, 64, 128, 256, 512};\n+\tu8 source, idx;\n+\n+\t/*\n+\t * get system clock (sys_ck) source\n+\t * can be HSI_CK, CSI_CK, HSE_CK or pll1_p_ck\n+\t */\n+\tsource = readl(&regs->cfgr) & RCC_CFGR_SW_MASK;\n+\tswitch (source) {\n+\tcase RCC_CFGR_SW_PLL1:\n+\t\tsysclk = stm32_get_PLL1_rate(regs, PLL1_P_CK);\n+\t\tbreak;\n+\tcase RCC_CFGR_SW_HSE:\n+\t\tsysclk = stm32_get_rate(regs, HSE);\n+\t\tbreak;\n+\n+\tcase RCC_CFGR_SW_CSI:\n+\t\tsysclk = stm32_get_rate(regs, CSI);\n+\t\tbreak;\n+\n+\tcase RCC_CFGR_SW_HSI:\n+\t\tsysclk = stm32_get_rate(regs, HSI);\n+\t\tbreak;\n+\t}\n+\n+\t/* sysclk = 0 ? no need to go ahead */\n+\tif (!sysclk)\n+\t\treturn sysclk;\n+\n+\tdebug(\"%s system clock: source = %d freq = %ld\\n\",\n+\t      __func__, source, sysclk);\n+\n+\td1cfgr = readl(&regs->d1cfgr);\n+\n+\tif (d1cfgr & RCC_D1CFGR_D1CPRE_DIVIDED) {\n+\t\t/* get D1 domain Core prescaler */\n+\t\tidx = (d1cfgr & RCC_D1CFGR_D1CPRE_DIVIDER) >>\n+\t\t      RCC_D1CFGR_D1CPRE_SHIFT;\n+\t\tsysclk = sysclk / prescaler_table[idx];\n+\t}\n+\n+\tif (d1cfgr & RCC_D1CFGR_HPRE_DIVIDED) {\n+\t\t/* get D1 domain AHB prescaler */\n+\t\tidx = d1cfgr & RCC_D1CFGR_HPRE_DIVIDER;\n+\t\tsysclk = sysclk / prescaler_table[idx];\n+\t}\n+\n+\tgate_offset = clk_map[clk->id].gate_offset;\n+\n+\tdebug(\"%s clk->id=%ld gate_offset=0x%x sysclk=%ld\\n\",\n+\t      __func__, clk->id, gate_offset, sysclk);\n+\n+\tswitch (gate_offset) {\n+\tcase RCC_AHB3ENR:\n+\tcase RCC_AHB1ENR:\n+\tcase RCC_AHB2ENR:\n+\tcase RCC_AHB4ENR:\n+\t\treturn sysclk;\n+\t\tbreak;\n+\n+\tcase RCC_APB3ENR:\n+\t\tif (d1cfgr & RCC_D1CFGR_D1PPRE_DIVIDED) {\n+\t\t\t/* get D1 domain APB3 prescaler */\n+\t\t\tidx = (d1cfgr & RCC_D1CFGR_D1PPRE_DIVIDER) >>\n+\t\t\t      RCC_D1CFGR_D1PPRE_SHIFT;\n+\t\t\tsysclk = sysclk / prescaler_table[idx];\n+\t\t}\n+\n+\t\tdebug(\"%s system clock: freq after APB3 prescaler = %ld\\n\",\n+\t\t      __func__, sysclk);\n+\n+\t\treturn sysclk;\n+\t\tbreak;\n+\n+\tcase RCC_APB4ENR:\n+\t\tif (d1cfgr & RCC_D3CFGR_D3PPRE_DIVIDED) {\n+\t\t\t/* get D3 domain APB4 prescaler */\n+\t\t\tidx = (d1cfgr & RCC_D3CFGR_D3PPRE_DIVIDER) >>\n+\t\t\t      RCC_D3CFGR_D3PPRE_SHIFT;\n+\t\t\tsysclk = sysclk / prescaler_table[idx];\n+\t\t}\n+\n+\t\tdebug(\"%s system clock: freq after APB4 prescaler = %ld\\n\",\n+\t\t      __func__, sysclk);\n+\n+\t\treturn sysclk;\n+\t\tbreak;\n+\n+\tcase RCC_APB1LENR:\n+\tcase RCC_APB1HENR:\n+\t\tif (d1cfgr & RCC_D2CFGR_D2PPRE1_DIVIDED) {\n+\t\t\t/* get D2 domain APB1 prescaler */\n+\t\t\tidx = (d1cfgr & RCC_D2CFGR_D2PPRE1_DIVIDER) >>\n+\t\t\t      RCC_D2CFGR_D2PPRE1_SHIFT;\n+\t\t\tsysclk = sysclk / prescaler_table[idx];\n+\t\t}\n+\n+\t\tdebug(\"%s system clock: freq after APB1 prescaler = %ld\\n\",\n+\t\t      __func__, sysclk);\n+\n+\t\treturn sysclk;\n+\t\tbreak;\n+\n+\tcase RCC_APB2ENR:\n+\t\tif (d1cfgr & RCC_D2CFGR_D2PPRE2_DIVIDED) {\n+\t\t\t/* get D2 domain APB1 prescaler */\n+\t\t\tidx = (d1cfgr & RCC_D2CFGR_D2PPRE2_DIVIDER) >>\n+\t\t\t      RCC_D2CFGR_D2PPRE2_SHIFT;\n+\t\t\tsysclk = sysclk / prescaler_table[idx];\n+\t\t}\n+\n+\t\tdebug(\"%s system clock: freq after APB2 prescaler = %ld\\n\",\n+\t\t      __func__, sysclk);\n+\n+\t\treturn sysclk;\n+\t\tbreak;\n+\n+\tdefault:\n+\t\terror(\"unexpected gate_offset value (0x%x)\\n\", gate_offset);\n+\t\treturn -EINVAL;\n+\t\tbreak;\n+\t}\n+}\n+\n+static int stm32_clk_enable(struct clk *clk)\n+{\n+\tstruct stm32_clk *priv = dev_get_priv(clk->dev);\n+\tstruct stm32_rcc_regs *regs = priv->rcc_base;\n+\tu32 gate_offset;\n+\tu32 gate_bit_index;\n+\tunsigned long clk_id = clk->id;\n+\n+\tgate_offset = clk_map[clk_id].gate_offset;\n+\tgate_bit_index = clk_map[clk_id].gate_bit_idx;\n+\n+\tdebug(\"%s: clkid=%ld gate offset=0x%x bit_index=%d name=%s\\n\",\n+\t      __func__, clk->id, gate_offset, gate_bit_index,\n+\t      clk_map[clk_id].name);\n+\n+\tsetbits_le32(&regs->cr + (gate_offset / 4), BIT(gate_bit_index));\n+\n+\treturn 0;\n+}\n+\n+static int stm32_clk_probe(struct udevice *dev)\n+{\n+\tstruct stm32_clk *priv = dev_get_priv(dev);\n+\tstruct udevice *syscon;\n+\tfdt_addr_t addr;\n+\tint err;\n+\n+\taddr = dev_read_addr(dev);\n+\tif (addr == FDT_ADDR_T_NONE)\n+\t\treturn -EINVAL;\n+\n+\tpriv->rcc_base = (struct stm32_rcc_regs *)addr;\n+\n+\t/* get corresponding syscon phandle */\n+\terr = uclass_get_device_by_phandle(UCLASS_SYSCON, dev,\n+\t\t\t\t\t   \"st,syscfg\", &syscon);\n+\n+\tif (err) {\n+\t\terror(\"unable to find syscon device\\n\");\n+\t\treturn err;\n+\t}\n+\n+\tpriv->pwr_regmap = syscon_get_regmap(syscon);\n+\tif (!priv->pwr_regmap) {\n+\t\terror(\"unable to find regmap\\n\");\n+\t\treturn -ENODEV;\n+\t}\n+\n+\tconfigure_clocks(dev);\n+\n+\treturn 0;\n+}\n+\n+static int stm32_clk_of_xlate(struct clk *clk,\n+\t\t\tstruct ofnode_phandle_args *args)\n+{\n+\tif (args->args_count != 1) {\n+\t\tdebug(\"Invaild args_count: %d\\n\", args->args_count);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tif (args->args_count) {\n+\t\tclk->id = args->args[0];\n+\t\t/*\n+\t\t * this computation convert DT clock index which is used to\n+\t\t * point into 2 separate clock arrays (peripheral and kernel\n+\t\t * clocks bank) (see include/dt-bindings/clock/stm32h7-clks.h)\n+\t\t * into index to point into only one array where peripheral\n+\t\t * and kernel clocks are consecutive\n+\t\t */\n+\t\tif (clk->id >= KERN_BANK) {\n+\t\t\tclk->id -= KERN_BANK;\n+\t\t\tclk->id += LAST_PERIF_BANK - PERIF_BANK + 1;\n+\t\t} else {\n+\t\t\tclk->id -= PERIF_BANK;\n+\t\t}\n+\t} else {\n+\t\tclk->id = 0;\n+\t}\n+\n+\tdebug(\"%s clk->id %ld\\n\", __func__, clk->id);\n+\n+\treturn 0;\n+}\n+\n+static struct clk_ops stm32_clk_ops = {\n+\t.of_xlate\t= stm32_clk_of_xlate,\n+\t.enable\t\t= stm32_clk_enable,\n+\t.get_rate\t= stm32_clk_get_rate,\n+};\n+\n+U_BOOT_DRIVER(stm32h7_clk) = {\n+\t.name\t\t\t= \"stm32h7_rcc_clock\",\n+\t.id\t\t\t= UCLASS_CLK,\n+\t.ops\t\t\t= &stm32_clk_ops,\n+\t.probe\t\t\t= stm32_clk_probe,\n+\t.priv_auto_alloc_size\t= sizeof(struct stm32_clk),\n+\t.flags\t\t\t= DM_FLAG_PRE_RELOC,\n+};\ndiff --git a/include/dt-bindings/clock/stm32h7-clks.h b/include/dt-bindings/clock/stm32h7-clks.h\nnew file mode 100644\nindex 0000000..4d87e7e\n--- /dev/null\n+++ b/include/dt-bindings/clock/stm32h7-clks.h\n@@ -0,0 +1,167 @@\n+/* SYS, CORE AND BUS CLOCKS */\n+#define SYS_D1CPRE 0\n+#define HCLK 1\n+#define PCLK1 2\n+#define PCLK2 3\n+#define PCLK3 4\n+#define PCLK4 5\n+#define HSI_DIV 6\n+#define HSE_1M 7\n+#define I2S_CKIN 8\n+#define CK_DSI_PHY 9\n+#define HSE_CK 10\n+#define LSE_CK 11\n+#define CSI_KER_DIV122 12\n+#define RTC_CK 13\n+#define CPU_SYSTICK 14\n+\n+/* OSCILLATOR BANK */\n+#define OSC_BANK 18\n+#define HSI_CK 18\n+#define HSI_KER_CK 19\n+#define CSI_CK 20\n+#define CSI_KER_CK 21\n+#define RC48_CK 22\n+#define LSI_CK 23\n+\n+/* MCLOCK BANK */\n+#define MCLK_BANK 28\n+#define PER_CK 28\n+#define PLLSRC 29\n+#define SYS_CK 30\n+#define TRACEIN_CK 31\n+\n+/* ODF BANK */\n+#define ODF_BANK 32\n+#define PLL1_P 32\n+#define PLL1_Q 33\n+#define PLL1_R 34\n+#define PLL2_P 35\n+#define PLL2_Q 36\n+#define PLL2_R 37\n+#define PLL3_P 38\n+#define PLL3_Q 39\n+#define PLL3_R 40\n+\n+/* MCO BANK */\n+#define MCO_BANK 41\n+#define MCO1 41\n+#define MCO2 42\n+\n+/* PERIF BANK */\n+#define PERIF_BANK 50\n+#define D1SRAM1_CK 50\n+#define ITCM_CK 51\n+#define DTCM2_CK 52\n+#define DTCM1_CK 53\n+#define FLITF_CK 54\n+#define JPGDEC_CK 55\n+#define DMA2D_CK 56\n+#define MDMA_CK 57\n+#define USB2ULPI_CK 58\n+#define USB1ULPI_CK 59\n+#define ETH1RX_CK 60\n+#define ETH1TX_CK 61\n+#define ETH1MAC_CK 62\n+#define ART_CK 63\n+#define DMA2_CK 64\n+#define DMA1_CK 65\n+#define D2SRAM3_CK 66\n+#define D2SRAM2_CK 67\n+#define D2SRAM1_CK 68\n+#define HASH_CK 69\n+#define CRYPT_CK 70\n+#define CAMITF_CK 71\n+#define BKPRAM_CK 72\n+#define HSEM_CK 73\n+#define BDMA_CK 74\n+#define CRC_CK 75\n+#define GPIOK_CK 76\n+#define GPIOJ_CK 77\n+#define GPIOI_CK 78\n+#define GPIOH_CK 79\n+#define GPIOG_CK 80\n+#define GPIOF_CK 81\n+#define GPIOE_CK 82\n+#define GPIOD_CK 83\n+#define GPIOC_CK 84\n+#define GPIOB_CK 85\n+#define GPIOA_CK 86\n+#define WWDG1_CK 87\n+#define DAC12_CK 88\n+#define WWDG2_CK 89\n+#define TIM14_CK 90\n+#define TIM13_CK 91\n+#define TIM12_CK 92\n+#define TIM7_CK 93\n+#define TIM6_CK 94\n+#define TIM5_CK 95\n+#define TIM4_CK 96\n+#define TIM3_CK 97\n+#define TIM2_CK 98\n+#define MDIOS_CK 99\n+#define OPAMP_CK 100\n+#define CRS_CK 101\n+#define TIM17_CK 102\n+#define TIM16_CK 103\n+#define TIM15_CK 104\n+#define TIM8_CK 105\n+#define TIM1_CK 106\n+#define TMPSENS_CK 107\n+#define RTCAPB_CK 108\n+#define VREF_CK 109\n+#define COMP12_CK 110\n+#define SYSCFG_CK 111\n+/* must be equal to last peripheral clock index */\n+#define LAST_PERIF_BANK SYSCFG_CK\n+\n+/* KERNEL BANK */\n+#define KERN_BANK 120\n+#define SDMMC1_CK 120\n+#define QUADSPI_CK 121\n+#define FMC_CK 122\n+#define USB2OTG_CK 123\n+#define USB1OTG_CK 124\n+#define ADC12_CK 125\n+#define SDMMC2_CK 126\n+#define RNG_CK 127\n+#define ADC3_CK 128\n+#define DSI_CK 129\n+#define LTDC_CK 130\n+#define USART8_CK 131\n+#define USART7_CK 132\n+#define HDMICEC_CK 133\n+#define I2C3_CK 134\n+#define I2C2_CK 135\n+#define I2C1_CK 136\n+#define UART5_CK 137\n+#define UART4_CK 138\n+#define USART3_CK 139\n+#define USART2_CK 140\n+#define SPDIFRX_CK 141\n+#define SPI3_CK 142\n+#define SPI2_CK 143\n+#define LPTIM1_CK 144\n+#define FDCAN_CK 145\n+#define SWP_CK 146\n+#define HRTIM_CK 147\n+#define DFSDM1_CK 148\n+#define SAI3_CK 149\n+#define SAI2_CK 150\n+#define SAI1_CK 151\n+#define SPI5_CK 152\n+#define SPI4_CK 153\n+#define SPI1_CK 154\n+#define USART6_CK 155\n+#define USART1_CK 156\n+#define SAI4B_CK 157\n+#define SAI4A_CK 158\n+#define LPTIM5_CK 159\n+#define LPTIM4_CK 160\n+#define LPTIM3_CK 161\n+#define LPTIM2_CK 162\n+#define I2C4_CK 163\n+#define SPI6_CK 164\n+#define LPUART1_CK 165\n+\n+#define STM32H7_MAX_CLKS 166\n",
    "prefixes": [
        "U-Boot",
        "v2",
        "3/9"
    ]
}