get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 2194413,
    "url": "http://patchwork.ozlabs.org/api/patches/2194413/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/20260208212624.3413494-4-festevam@gmail.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": "<20260208212624.3413494-4-festevam@gmail.com>",
    "list_archive_url": null,
    "date": "2026-02-08T21:26:20",
    "name": "[v2,3/7] clk: rockchip: Add RV1103B clock driver",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": false,
    "hash": "3a7d62c43488aae5841e6d61dda3f0f8f366c31f",
    "submitter": {
        "id": 6978,
        "url": "http://patchwork.ozlabs.org/api/people/6978/?format=api",
        "name": "Fabio Estevam",
        "email": "festevam@gmail.com"
    },
    "delegate": {
        "id": 93623,
        "url": "http://patchwork.ozlabs.org/api/users/93623/?format=api",
        "username": "kevery",
        "first_name": "Kever",
        "last_name": "Yang",
        "email": "ykai007@gmail.com"
    },
    "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/20260208212624.3413494-4-festevam@gmail.com/mbox/",
    "series": [
        {
            "id": 491441,
            "url": "http://patchwork.ozlabs.org/api/series/491441/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=491441",
            "date": "2026-02-08T21:26:17",
            "name": "ARM: Add RV1103B Omega4 board support",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/491441/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/2194413/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/2194413/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<u-boot-bounces@lists.denx.de>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@legolas.ozlabs.org",
        "Authentication-Results": [
            "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20230601 header.b=Na1iy1ep;\n\tdkim-atps=neutral",
            "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)",
            "phobos.denx.de;\n dmarc=pass (p=none dis=none) header.from=gmail.com",
            "phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de",
            "phobos.denx.de;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.b=\"Na1iy1ep\";\n\tdkim-atps=neutral",
            "phobos.denx.de;\n dmarc=pass (p=none dis=none) header.from=gmail.com",
            "phobos.denx.de;\n spf=pass smtp.mailfrom=festevam@gmail.com"
        ],
        "Received": [
            "from phobos.denx.de (phobos.denx.de\n [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4f8LWH66jtz1xvc\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 09 Feb 2026 08:27:07 +1100 (AEDT)",
            "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id 3C8F983C5E;\n\tSun,  8 Feb 2026 22:26:47 +0100 (CET)",
            "by phobos.denx.de (Postfix, from userid 109)\n id 1C95A83C39; Sun,  8 Feb 2026 22:26:46 +0100 (CET)",
            "from mail-yw1-x1133.google.com (mail-yw1-x1133.google.com\n [IPv6:2607:f8b0:4864:20::1133])\n (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id C16D483BC9\n for <u-boot@lists.denx.de>; Sun,  8 Feb 2026 22:26:42 +0100 (CET)",
            "by mail-yw1-x1133.google.com with SMTP id\n 00721157ae682-790b7b3e594so40679007b3.3\n for <u-boot@lists.denx.de>; Sun, 08 Feb 2026 13:26:42 -0800 (PST)",
            "from fabio-Precision-3551..\n ([2804:14c:485:4b61:5d9f:efd7:6c6a:abf8])\n by smtp.gmail.com with ESMTPSA id\n 00721157ae682-7952a085999sm75229377b3.25.2026.02.08.13.26.38\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Sun, 08 Feb 2026 13:26:40 -0800 (PST)"
        ],
        "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de",
        "X-Spam-Level": "",
        "X-Spam-Status": "No, score=-1.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FORGED_GMAIL_RCVD,FREEMAIL_FROM,\n RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=no\n autolearn_force=no version=3.4.2",
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=gmail.com; s=20230601; t=1770586001; x=1771190801; darn=lists.denx.de;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=snk8PXhoU3DP+Qd4CRxxGtOd67Sf99XZgzYmPGVDsK8=;\n b=Na1iy1eplJ0RohYGnIGpZD8Qtmi5sLU8gitnu51dPqneyhyAMc/XAs2mpszDZ3t/Mh\n RTiEX+D49HgJ/hMGK1px17+/te2+UrROiME4NOcP1ds9yFljmmuYRg3a/qyaAIfld2Zj\n qnTBrFUE7BAkYcZjelWvzP97WmK9xHeWvgiEbVbdUjV2XQtEyU8iv2djtAG+wFvRPGIC\n EEHa+joixJgTpNfPdPY1EipsVUn5uZI7PgoyD8kMBtGV6aMA2mahKBtmSZvaPpR2tjXb\n 8P0ABkoDDnPrXzKLIy9dUM7b0pcQKbmCA64M0UWTcyV9VbU5c9tkpNmXoodEoQYdJuH2\n lTGA==",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20230601; t=1770586001; x=1771190801;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=snk8PXhoU3DP+Qd4CRxxGtOd67Sf99XZgzYmPGVDsK8=;\n b=uic1IAm6m54v7H9qdmCbmTx2ViddE17bgQngXd1LOE3vobn6/GAjGDUGgyyGtkifeJ\n UUoacrmqW/TnpXWiy4QDBEJW1Uqpl8utVI1796LDpdqgJbtJqU06OL3WR2JEel/PSPRx\n cq3z5ikJ/QJfweN/tbjJ2a6ngIfKrHvmZ8UlEk6KlVm+mhNNYTmz2Ua0+xZH7RTw5tsJ\n qZNQuQA11j0lNU9PDuM1J4v2vACHeD+UKOJ05JLqm4H5L9kh7Q8PfNujWI4P8VivJ2f5\n sr0INlTEdF5x27p0xeYLhErGzEJvjjjCptjCuUdVAjk0PHiZ0CHxLChuwHBCntBQ/BqD\n uR3g==",
        "X-Forwarded-Encrypted": "i=1;\n AJvYcCUQR8Cff6ecOb0oMzBGefsECNOId0rdA18DC4NficZjncF+XK5nIbZPkhN8LRJ0OoUL6fI4lxY=@lists.denx.de",
        "X-Gm-Message-State": "AOJu0Yx5ym/eexOHnmlwjrS1dLbXA40YDUmz2NjQyh3WUf+EgQCP/PuH\n RsKclCg8jpHk0C3KWlqcqaUNK2wwq07be2sNmORut9wQ5rgSj7agGeMm",
        "X-Gm-Gg": "AZuq6aIw1BYb1K6M7934cjGiyy5IzqL6P2jQrUEemKX9obj6ghz94tST8feoknGLIH6\n X2JKd/6CqLCAYqExao5h244RJEdwifyJUQBfTAGHbk8ygGKCgRqhs2gCVH8LheqC1MKdBDnAiyw\n Sd6rAOdziorzQkeuBYO5APNSes+FPYRrAngEEmi3ZAPArv+b6T3T/nrxfxljr8EqOc2NcYlXei8\n ywaxgU3tsROyj6MZBY5lpiL/eiguF6GT5qtTIovwwoztyqFLGInvX/xoNRfBmBPjSwOBKlokHML\n vn1cDIC4vNvM1LJsE5U+lt8zCa5Q1xA0egNhOKcZFKLEI5SbbkmkHnUqgZ8dMKL4KwMlpgQMHDK\n JqV22qyGlbSz08nzGfJ4CaokUn+68FLOiRLTbDrNJq5ey0H10ddDIYBgiaGfwZ/PtAtiFhbxG5i\n T8Nr9xbjAPA9Gra0WYAgoa/OwO",
        "X-Received": "by 2002:a05:690c:6610:b0:796:3124:653e with SMTP id\n 00721157ae682-79631246950mr46016447b3.4.1770586001299;\n Sun, 08 Feb 2026 13:26:41 -0800 (PST)",
        "From": "Fabio Estevam <festevam@gmail.com>",
        "To": "kever.yang@rock-chips.com",
        "Cc": "trini@konsulko.com, jonas@kwiboo.se, u-boot@lists.denx.de,\n Elaine Zhang <zhangqing@rock-chips.com>,\n Fabio Estevam <festevam@nabladev.com>",
        "Subject": "[PATCH v2 3/7] clk: rockchip: Add RV1103B clock driver",
        "Date": "Sun,  8 Feb 2026 18:26:20 -0300",
        "Message-Id": "<20260208212624.3413494-4-festevam@gmail.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20260208212624.3413494-1-festevam@gmail.com>",
        "References": "<20260208212624.3413494-1-festevam@gmail.com>",
        "MIME-Version": "1.0",
        "Content-Transfer-Encoding": "8bit",
        "X-BeenThere": "u-boot@lists.denx.de",
        "X-Mailman-Version": "2.1.39",
        "Precedence": "list",
        "List-Id": "U-Boot discussion <u-boot.lists.denx.de>",
        "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>",
        "List-Archive": "<https://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 <mailto:u-boot-request@lists.denx.de?subject=subscribe>",
        "Errors-To": "u-boot-bounces@lists.denx.de",
        "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>",
        "X-Virus-Scanned": "clamav-milter 0.103.8 at phobos.denx.de",
        "X-Virus-Status": "Clean"
    },
    "content": "From: Elaine Zhang <zhangqing@rock-chips.com>\n\nAdd basic clock for the RV1103B clock driver.\n\nSigned-off-by: Elaine Zhang <zhangqing@rock-chips.com>\nSigned-off-by: Fabio Estevam <festevam@nabladev.com>\n---\nChanges since v1:\n- Use the original author from Rockchip's vendor U-Boot tree.\n\n .../include/asm/arch-rockchip/cru_rv1103b.h   |  266 ++++\n .../include/asm/arch-rockchip/grf_rv1103b.h   |   31 +\n drivers/clk/rockchip/Makefile                 |    1 +\n drivers/clk/rockchip/clk_rv1103b.c            | 1068 +++++++++++++++++\n 4 files changed, 1366 insertions(+)\n create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rv1103b.h\n create mode 100644 arch/arm/include/asm/arch-rockchip/grf_rv1103b.h\n create mode 100644 drivers/clk/rockchip/clk_rv1103b.c",
    "diff": "diff --git a/arch/arm/include/asm/arch-rockchip/cru_rv1103b.h b/arch/arm/include/asm/arch-rockchip/cru_rv1103b.h\nnew file mode 100644\nindex 000000000000..fc7aa4dfc0db\n--- /dev/null\n+++ b/arch/arm/include/asm/arch-rockchip/cru_rv1103b.h\n@@ -0,0 +1,266 @@\n+/* SPDX-License-Identifier: GPL-2.0 */\n+/*\n+ * Copyright (c) 2024 Rockchip Electronics Co. Ltd.\n+ * Author: Elaine Zhang <zhangqing@rock-chips.com>\n+ */\n+\n+#ifndef _ASM_ARCH_CRU_RV1103B_H\n+#define _ASM_ARCH_CRU_RV1103B_H\n+\n+#define MHz\t\t1000000\n+#define KHz\t\t1000\n+#define OSC_HZ\t\t(24 * MHz)\n+#define RC_OSC_HZ\t(125 * MHz)\n+\n+#define GPLL_HZ\t\t(1188 * MHz)\n+\n+/* RV1103B pll id */\n+enum rv1103b_pll_id {\n+\tGPLL,\n+\tPLL_COUNT,\n+};\n+\n+struct rv1103b_clk_info {\n+\tunsigned long id;\n+\tchar *name;\n+\tbool is_cru;\n+};\n+\n+struct rv1103b_clk_priv {\n+\tstruct rv1103b_cru *cru;\n+\tstruct rv1103b_grf *grf;\n+\tulong gpll_hz;\n+\tulong armclk_hz;\n+\tulong armclk_enter_hz;\n+\tulong armclk_init_hz;\n+\tbool sync_kernel;\n+\tbool set_armclk_rate;\n+};\n+\n+struct rv1103b_grf_clk_priv {\n+\tstruct rv1103b_grf *grf;\n+};\n+\n+struct rv1103b_pll {\n+\tunsigned int con0;\n+\tunsigned int con1;\n+\tunsigned int con2;\n+\tunsigned int con3;\n+\tunsigned int con4;\n+\tunsigned int reserved0[3];\n+};\n+\n+struct rv1103b_cru {\n+\tunsigned int reserved0[192];\n+\tunsigned int peri_clksel_con[4];\n+\tunsigned int reserved1[316];\n+\tunsigned int peri_clkgate_con[12];\n+\tunsigned int reserved2[116];\n+\tunsigned int peri_softrst_con[12];\n+\tunsigned int reserved3[15924];\n+\tunsigned int vepu_clksel_con[3];\n+\tunsigned int reserved4[317];\n+\tunsigned int vepu_clkgate_con[1];\n+\tunsigned int reserved5[127];\n+\tunsigned int vepu_softrst_con[1];\n+\tunsigned int reserved6[15935];\n+\tunsigned int npu_clksel_con[3];\n+\tunsigned int reserved7[317];\n+\tunsigned int npu_clkgate_con[1];\n+\tunsigned int reserved8[127];\n+\tunsigned int npu_softrst_con[1];\n+\tunsigned int reserved9[15935];\n+\tunsigned int vi_clksel_con[1];\n+\tunsigned int reserved10[319];\n+\tunsigned int vi_clkgate_con[3];\n+\tunsigned int reserved11[125];\n+\tunsigned int vi_softrst_con[3];\n+\tunsigned int reserved12[15933];\n+\tunsigned int core_clksel_con[3];\n+\tunsigned int reserved13[16381];\n+\tunsigned int ddr_clksel_con[1];\n+\tunsigned int reserved14[16207];\n+\tstruct rv1103b_pll pll[2];\n+\tunsigned int reserved15[128];\n+\tunsigned int mode;\n+\tunsigned int reserved16[31];\n+\tunsigned int clksel_con[42];\n+\tunsigned int reserved17[278];\n+\tunsigned int clkgate_con[7];\n+\tunsigned int reserved18[121];\n+\tunsigned int softrst_con[1];\n+\tunsigned int reserved19[127];\n+\tunsigned int glb_cnt_th;\n+\tunsigned int glb_rst_st;\n+\tunsigned int glb_srst_fst;\n+\tunsigned int glb_srst_snd;\n+\tunsigned int glb_rst_con;\n+\tunsigned int reserved20[15803];\n+\tunsigned int pmu_clksel_con[3];\n+\tunsigned int reserved21[317];\n+\tunsigned int pmu_clkgate_con[3];\n+\tunsigned int reserved22[125];\n+\tunsigned int pmu_softrst_con[3];\n+\tunsigned int reserved23[15933];\n+\tunsigned int pmu1_clksel_con[1];\n+\tunsigned int reserved24[319];\n+\tunsigned int pmu1_clkgate_con[2];\n+\tunsigned int reserved25[126];\n+\tunsigned int pmu1_softrst_con[2];\n+};\n+\n+check_member(rv1103b_cru, pmu1_softrst_con[1], 0x80a04);\n+\n+struct pll_rate_table {\n+\tunsigned long rate;\n+\tunsigned int fbdiv;\n+\tunsigned int postdiv1;\n+\tunsigned int refdiv;\n+\tunsigned int postdiv2;\n+\tunsigned int dsmpd;\n+\tunsigned int frac;\n+};\n+\n+#define RV1103B_TOPCRU_BASE\t\t0x60000\n+#define RV1103B_PERICRU_BASE\t\t0x0\n+#define RV1103B_VICRU_BASE\t\t0x30000\n+#define RV1103B_NPUCRU_BASE\t\t0x20000\n+#define RV1103B_CORECRU_BASE\t\t0x40000\n+#define RV1103B_VEPUCRU_BASE\t\t0x10000\n+#define RV1103B_DDRCRU_BASE\t\t0x50000\n+#define RV1103B_SUBDDRCRU_BASE\t\t0x58000\n+#define RV1103B_PMUCRU_BASE\t\t0x70000\n+#define RV1103B_PMU1CRU_BASE\t\t0x80000\n+\n+#define RV1103B_CRU_BASE\t\t0x20000000\n+\n+#define RV1103B_PLL_CON(x)\t\t((x) * 0x4 + RV1103B_TOPCRU_BASE)\n+#define RV1103B_MODE_CON\t\t(0x280 + RV1103B_TOPCRU_BASE)\n+#define RV1103B_CLKSEL_CON(x)\t\t((x) * 0x4 + 0x300 + RV1103B_TOPCRU_BASE)\n+#define RV1103B_SUBDDRMODE_CON\t\t(0x280 + RV1103B_SUBDDRCRU_BASE)\n+\n+enum {\n+\t/* CORECRU_CLK_SEL0_CON */\n+\tCLK_CORE_SRC_SEL_SHIFT\t\t= 1,\n+\tCLK_CORE_SRC_SEL_MASK\t\t= 0x1 << CLK_CORE_SRC_SEL_SHIFT,\n+\tCLK_CORE_SRC_SEL_GPLL\t\t= 0,\n+\tCLK_CORE_SRC_SEL_PVTPLL,\n+\n+\t/* CRU_PERI_CLK_SEL0_CON */\n+\tCLK_TSADC_TSEN_DIV_SHIFT\t= 10,\n+\tCLK_TSADC_TSEN_DIV_MASK\t\t= 0x1f << CLK_TSADC_TSEN_DIV_SHIFT,\n+\tCLK_TSADC_DIV_SHIFT\t\t= 4,\n+\tCLK_TSADC_DIV_MASK\t\t= 0x1f << CLK_TSADC_DIV_SHIFT,\n+\tPCLK_PERI_DIV_SHIFT\t\t= 0,\n+\tPCLK_PERI_DIV_MASK\t\t= 0x3 << PCLK_PERI_DIV_SHIFT,\n+\n+\t/* CRU_PERI_CLK_SEL1_CON */\n+\tCLK_SARADC_DIV_SHIFT\t\t= 0,\n+\tCLK_SARADC_DIV_MASK\t\t= 0x7 << CLK_SARADC_DIV_SHIFT,\n+\n+\t/* CRU_CLK_SEL5_CON */\n+\tCLK_UART2_SRC_DIV_SHIFT\t\t= 10,\n+\tCLK_UART2_SRC_DIV_MASK\t\t= 0x1f << CLK_UART2_SRC_DIV_SHIFT,\n+\tCLK_UART1_SRC_DIV_SHIFT\t\t= 5,\n+\tCLK_UART1_SRC_DIV_MASK\t\t= 0x1f << CLK_UART1_SRC_DIV_SHIFT,\n+\tCLK_UART0_SRC_DIV_SHIFT\t\t= 0,\n+\tCLK_UART0_SRC_DIV_MASK\t\t= 0x1f << CLK_UART0_SRC_DIV_SHIFT,\n+\n+\t/* CRU_CLK_SEL10_CON */\n+\tCLK_UART_FRAC_NUMERATOR_SHIFT\t= 16,\n+\tCLK_UART_FRAC_NUMERATOR_MASK\t= 0xffff << 16,\n+\tCLK_UART_FRAC_DENOMINATOR_SHIFT\t= 0,\n+\tCLK_UART_FRAC_DENOMINATOR_MASK\t= 0xffff,\n+\n+\t/* CRU_CLK_SEL31_CON */\n+\tCLK_EMMC_SEL_SHIFT\t\t= 15,\n+\tCLK_EMMC_SEL_MASK\t\t= 0x1 << CLK_EMMC_SEL_SHIFT,\n+\tACLK_PERI_SEL_SHIFT\t\t= 10,\n+\tACLK_PERI_SEL_MASK\t\t= 0x3 << ACLK_PERI_SEL_SHIFT,\n+\tACLK_PERI_SEL_600M\t\t= 0,\n+\tACLK_PERI_SEL_480M,\n+\tACLK_PERI_SEL_400M,\n+\tLSCLK_PERI_SEL_SHIFT\t\t= 9,\n+\tLSCLK_PERI_SEL_MASK\t\t= 0x1 << LSCLK_PERI_SEL_SHIFT,\n+\tLSCLK_PERI_SEL_300M\t\t= 0,\n+\tLSCLK_PERI_SEL_200M,\n+\tCLK_EMMC_DIV_SHIFT\t\t= 0,\n+\tCLK_EMMC_DIV_MASK\t\t= 0xff << CLK_EMMC_DIV_SHIFT,\n+\n+\t/* CRU_CLK_SEL32_CON */\n+\tCLK_SDMMC_SEL_SHIFT\t\t= 15,\n+\tCLK_SDMMC_SEL_MASK\t\t= 0x1 << CLK_SDMMC_SEL_SHIFT,\n+\tCLK_MMC_SEL_GPLL\t\t= 0,\n+\tCLK_MMC_SEL_OSC,\n+\tCLK_UART2_SEL_SHIFT\t\t= 12,\n+\tCLK_UART2_SEL_MASK\t\t= 3 << CLK_UART2_SEL_SHIFT,\n+\tCLK_UART1_SEL_SHIFT\t\t= 10,\n+\tCLK_UART1_SEL_MASK\t\t= 3 << CLK_UART1_SEL_SHIFT,\n+\tCLK_UART0_SEL_SHIFT\t\t= 8,\n+\tCLK_UART0_SEL_MASK\t\t= 3 << CLK_UART0_SEL_SHIFT,\n+\tCLK_UART_SEL_SRC\t\t= 0,\n+\tCLK_UART_SEL_FRAC,\n+\tCLK_UART_SEL_OSC,\n+\tCLK_SDMMC_DIV_SHIFT\t\t= 0,\n+\tCLK_SDMMC_DIV_MASK\t\t= 0xff << CLK_SDMMC_DIV_SHIFT,\n+\n+\t/* CRU_CLK_SEL33_CON */\n+\tCLK_SFC_SEL_SHIFT\t\t= 15,\n+\tCLK_SFC_SEL_MASK\t\t= 0x1 << CLK_SFC_SEL_SHIFT,\n+\tCLK_SFC_DIV_SHIFT\t\t= 0,\n+\tCLK_SFC_DIV_MASK\t\t= 0xff << CLK_SFC_DIV_SHIFT,\n+\n+\t/* CRU_CLK_SEL34_CON */\n+\tCLK_PWM2_SEL_SHIFT\t\t= 14,\n+\tCLK_PWM2_SEL_MASK\t\t= 1 << CLK_PWM2_SEL_SHIFT,\n+\tCLK_PWM1_SEL_SHIFT\t\t= 13,\n+\tCLK_PWM1_SEL_MASK\t\t= 1 << CLK_PWM1_SEL_SHIFT,\n+\tCLK_PWM0_SEL_SHIFT\t\t= 12,\n+\tCLK_PWM0_SEL_MASK\t\t= 1 << CLK_PWM0_SEL_SHIFT,\n+\tCLK_PWM_SEL_100M\t\t= 0,\n+\tCLK_PWM_SEL_24M,\n+\tCLK_SPI0_SEL_SHIFT\t\t= 2,\n+\tCLK_SPI0_SEL_MASK\t\t= 3 << CLK_SPI0_SEL_SHIFT,\n+\tCLK_SPI0_SEL_200M\t\t= 0,\n+\tCLK_SPI0_SEL_100M,\n+\tCLK_SPI0_SEL_50M,\n+\tCLK_SPI0_SEL_24M,\n+\tCLK_I2C1_SEL_SHIFT\t\t= 1,\n+\tCLK_I2C1_SEL_MASK\t\t= 0x1 << CLK_I2C1_SEL_SHIFT,\n+\tCLK_I2C0_SEL_SHIFT\t\t= 0,\n+\tCLK_I2C0_SEL_MASK\t\t= 0x1 << CLK_I2C0_SEL_SHIFT,\n+\tCLK_I2C_SEL_100M\t\t= 0,\n+\tCLK_I2C_SEL_24M,\n+\n+\t/* CRU_CLK_SEL35_CON */\n+\tCLK_PKA_CRYPTO_SEL_SHIFT\t= 4,\n+\tCLK_PKA_CRYPTO_SEL_MASK\t\t= 0x3 << CLK_PKA_CRYPTO_SEL_SHIFT,\n+\tCLK_CORE_CRYPTO_SEL_SHIFT\t= 2,\n+\tCLK_CORE_CRYPTO_SEL_MASK\t= 0x3 << CLK_CORE_CRYPTO_SEL_SHIFT,\n+\tCLK_CORE_CRYPTO_SEL_300M\t= 0,\n+\tCLK_CORE_CRYPTO_SEL_200M,\n+\tCLK_CORE_CRYPTO_SEL_100M,\n+\tDCLK_DECOM_SEL_SHIFT\t\t= 0,\n+\tDCLK_DECOM_SEL_MASK\t\t= 0x3 << DCLK_DECOM_SEL_SHIFT,\n+\tDCLK_DECOM_SEL_480M\t\t= 0,\n+\tDCLK_DECOM_SEL_400M,\n+\tDCLK_DECOM_SEL_300M,\n+\n+\t/* CRU_CLK_SEL37_CON */\n+\tCLK_CORE_GPLL_DIV_SHIFT\t\t= 13,\n+\tCLK_CORE_GPLL_DIV_MASK\t\t= 0x7 << CLK_CORE_GPLL_DIV_SHIFT,\n+\tCLK_CORE_GPLL_SEL_SHIFT\t\t= 12,\n+\tCLK_CORE_GPLL_SEL_MASK\t\t= 0x1 << CLK_CORE_GPLL_SEL_SHIFT,\n+\tCLK_CORE_GPLL_SEL_GPLL\t\t= 0,\n+\tCLK_CORE_GPLL_SEL_OSC,\n+\n+\t/* CRU_PMU_CLK_SEL2_CON */\n+\tLSCLK_PMU_SEL_SHIFT\t\t= 4,\n+\tLSCLK_PMU_SEL_MASK\t\t= 0x1 << LSCLK_PMU_SEL_SHIFT,\n+\tLSCLK_PMU_SEL_24M\t\t= 0,\n+\tLSCLK_PMU_SEL_RC_OSC,\n+\tLSCLK_PMU_DIV_SHIFT\t\t= 0,\n+\tLSCLK_PMU_DIV_MASK\t\t= 0x3 << LSCLK_PMU_DIV_SHIFT,\n+\n+};\n+#endif\ndiff --git a/arch/arm/include/asm/arch-rockchip/grf_rv1103b.h b/arch/arm/include/asm/arch-rockchip/grf_rv1103b.h\nnew file mode 100644\nindex 000000000000..6bb382a8e079\n--- /dev/null\n+++ b/arch/arm/include/asm/arch-rockchip/grf_rv1103b.h\n@@ -0,0 +1,31 @@\n+/* SPDX-License-Identifier:     GPL-2.0+ */\n+\n+/*\n+ * (C) Copyright 2024 Rockchip Electronics Co., Ltd.\n+ */\n+\n+#ifndef _ASM_ARCH_GRF_RV1103B_H\n+#define _ASM_ARCH_GRF_RV1103B_H\n+\n+#define VEPU_GRF\t0x20100000\n+#define NPU_GRF\t\t0x20110000\n+#define VI_GRF\t\t0x20120000\n+#define CPU_GRF\t\t0x20130000\n+#define DDR_GRF\t\t0x20140000\n+#define SYS_GRF\t\t0x20150000\n+#define PMU_GRF\t\t0x20160000\n+\n+struct rv1103b_grf {\n+\tu32 reserved0[(SYS_GRF + 0xA0 - VEPU_GRF) / 4];\n+\tu32 gmac_con0;\t\t\t\t/* address offset: 0x00a0 */\n+\tu32 gmac_clk_con;\t\t\t/* address offset: 0x00a4 */\n+\tu32 gmac_st;\t\t\t\t/* address offset: 0x00a8 */\n+\tu32 reserved00ac;\t\t\t/* address offset: 0x00ac */\n+\tu32 macphy_con0;\t\t\t/* address offset: 0x00b0 */\n+\tu32 macphy_con1;\t\t\t/* address offset: 0x00b4 */\n+\tu32 reserved1[(PMU_GRF + 0x10000 - (SYS_GRF + 0xB4)) / 4];\n+};\n+\n+check_member(rv1103b_grf, macphy_con1, SYS_GRF + 0xB4 - VEPU_GRF);\n+\n+#endif /*  _ASM_ARCH_GRF_RV1103B_H  */\ndiff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile\nindex 34b63d4df34a..7bb0df6748cc 100644\n--- a/drivers/clk/rockchip/Makefile\n+++ b/drivers/clk/rockchip/Makefile\n@@ -19,5 +19,6 @@ obj-$(CONFIG_ROCKCHIP_RK3528) += clk_rk3528.o\n obj-$(CONFIG_ROCKCHIP_RK3568) += clk_rk3568.o\n obj-$(CONFIG_ROCKCHIP_RK3576) += clk_rk3576.o\n obj-$(CONFIG_ROCKCHIP_RK3588) += clk_rk3588.o\n+obj-$(CONFIG_ROCKCHIP_RV1103B) += clk_rv1103b.o\n obj-$(CONFIG_ROCKCHIP_RV1108) += clk_rv1108.o\n obj-$(CONFIG_ROCKCHIP_RV1126) += clk_rv1126.o\ndiff --git a/drivers/clk/rockchip/clk_rv1103b.c b/drivers/clk/rockchip/clk_rv1103b.c\nnew file mode 100644\nindex 000000000000..81d892bf43c6\n--- /dev/null\n+++ b/drivers/clk/rockchip/clk_rv1103b.c\n@@ -0,0 +1,1068 @@\n+// SPDX-License-Identifier: GPL-2.0\n+/*\n+ * Copyright (c) 2024 Rockchip Electronics Co., Ltd\n+ * Author: Elaine Zhang <zhangqing@rock-chips.com>\n+ */\n+\n+#include <bitfield.h>\n+#include <clk-uclass.h>\n+#include <dm.h>\n+#include <asm/arch-rockchip/hardware.h>\n+#include <asm/io.h>\n+#include <dm/lists.h>\n+#include <dt-bindings/clock/rockchip,rv1103b-cru.h>\n+\n+#include <clk.h>\n+#include <log.h>\n+#include <malloc.h>\n+#include <asm/global_data.h>\n+#include <asm/arch-rockchip/clock.h>\n+#include <asm/arch-rockchip/cru_rv1103b.h>\n+#include <asm/arch-rockchip/hardware.h>\n+#include <dm/device-internal.h>\n+#include <dm/lists.h>\n+#include <linux/delay.h>\n+#include <linux/stringify.h>\n+\n+DECLARE_GLOBAL_DATA_PTR;\n+\n+#define DIV_TO_RATE(input_rate, div)\t((input_rate) / ((div) + 1))\n+\n+#ifndef BITS_WITH_WMASK\n+#define BITS_WITH_WMASK(bits, msk, shift) \\\n+\t((bits) << (shift)) | ((msk) << ((shift) + 16))\n+#endif\n+\n+static struct rockchip_pll_rate_table rv1103b_pll_rates[] = {\n+\t/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */\n+\tRK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),\n+\tRK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),\n+\t{ /* sentinel */ },\n+};\n+\n+static struct rockchip_pll_clock rv1103b_pll_clks[] = {\n+\t[GPLL] = PLL(pll_rk3328, PLL_GPLL, RV1103B_PLL_CON(24),\n+\t\t     RV1103B_MODE_CON, 0, 10, 0, rv1103b_pll_rates),\n+};\n+\n+static ulong rv1103b_peri_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tu32 con, sel, div, rate, prate;\n+\n+\tswitch (clk_id) {\n+\tcase ACLK_PERI_SRC:\n+\t\tcon = readl(&cru->clksel_con[31]);\n+\t\tsel = (con & ACLK_PERI_SEL_MASK) >> ACLK_PERI_SEL_SHIFT;\n+\t\tif (sel == ACLK_PERI_SEL_600M)\n+\t\t\trate = 600 * MHz;\n+\t\telse if (sel == ACLK_PERI_SEL_480M)\n+\t\t\trate = 480 * MHz;\n+\t\telse\n+\t\t\trate = 400 * MHz;\n+\t\tbreak;\n+\tcase LSCLK_PERI_SRC:\n+\t\tcon = readl(&cru->clksel_con[31]);\n+\t\tsel = (con & LSCLK_PERI_SEL_MASK) >> LSCLK_PERI_SEL_SHIFT;\n+\t\tif (sel == LSCLK_PERI_SEL_300M)\n+\t\t\trate = 300 * MHz;\n+\t\telse\n+\t\t\trate = 200 * MHz;\n+\t\tbreak;\n+\tcase PCLK_PERI_ROOT:\n+\t\tcon = readl(&cru->peri_clksel_con[0]);\n+\t\tdiv = (con & PCLK_PERI_DIV_MASK) >> PCLK_PERI_DIV_SHIFT;\n+\t\trate = DIV_TO_RATE(rv1103b_peri_get_clk(priv, LSCLK_PERI_SRC),\n+\t\t\t\t   div);\n+\t\tbreak;\n+\tcase PCLK_TOP_ROOT:\n+\t\trate = DIV_TO_RATE(priv->gpll_hz, 11);\n+\t\tbreak;\n+\tcase LSCLK_PMU_ROOT:\n+\tcase PCLK_PMU:\n+\t\tcon = readl(&cru->pmu_clksel_con[2]);\n+\t\tsel = (con & LSCLK_PMU_SEL_MASK) >> LSCLK_PMU_SEL_SHIFT;\n+\t\tdiv = (con & LSCLK_PMU_DIV_MASK) >> LSCLK_PMU_DIV_SHIFT;\n+\t\tif (sel == LSCLK_PMU_SEL_24M)\n+\t\t\tprate = OSC_HZ;\n+\t\telse\n+\t\t\tprate = RC_OSC_HZ;\n+\t\trate = DIV_TO_RATE(prate, div);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\n+\treturn rate;\n+}\n+\n+static ulong rv1103b_peri_set_clk(struct rv1103b_clk_priv *priv,\n+\t\t\t\t  ulong clk_id, ulong rate)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tint src_clk, div;\n+\n+\tswitch (clk_id) {\n+\tcase ACLK_PERI_SRC:\n+\t\tif (rate >= 594 * MHz)\n+\t\t\tsrc_clk = ACLK_PERI_SEL_600M;\n+\t\telse if (rate >= 480 * MHz)\n+\t\t\tsrc_clk = ACLK_PERI_SEL_480M;\n+\t\telse\n+\t\t\tsrc_clk = ACLK_PERI_SEL_400M;\n+\t\trk_clrsetreg(&cru->clksel_con[31],\n+\t\t\t     ACLK_PERI_SEL_MASK,\n+\t\t\t     src_clk << ACLK_PERI_SEL_SHIFT);\n+\t\tbreak;\n+\tcase LSCLK_PERI_SRC:\n+\t\tif (rate >= 297 * MHz)\n+\t\t\tsrc_clk = LSCLK_PERI_SEL_300M;\n+\t\telse\n+\t\t\tsrc_clk = LSCLK_PERI_SEL_200M;\n+\t\trk_clrsetreg(&cru->clksel_con[31],\n+\t\t\t     LSCLK_PERI_SEL_MASK,\n+\t\t\t     src_clk << LSCLK_PERI_SEL_SHIFT);\n+\t\tbreak;\n+\tcase PCLK_PERI_ROOT:\n+\t\tdiv = DIV_ROUND_UP(rv1103b_peri_get_clk(priv, LSCLK_PERI_SRC),\n+\t\t\t\t   rate);\n+\t\trk_clrsetreg(&cru->peri_clksel_con[0],\n+\t\t\t     PCLK_PERI_DIV_MASK,\n+\t\t\t     (div - 1) << PCLK_PERI_DIV_SHIFT);\n+\t\tbreak;\n+\tcase PCLK_TOP_ROOT:\n+\t\tbreak;\n+\tcase LSCLK_PMU_ROOT:\n+\tcase PCLK_PMU:\n+\t\tif (!(OSC_HZ % rate)) {\n+\t\t\tsrc_clk = LSCLK_PMU_SEL_24M;\n+\t\t\tdiv = DIV_ROUND_UP(OSC_HZ, rate);\n+\t\t} else {\n+\t\t\tsrc_clk = LSCLK_PMU_SEL_RC_OSC;\n+\t\t\tdiv = DIV_ROUND_UP(RC_OSC_HZ, rate);\n+\t\t}\n+\t\trk_clrsetreg(&cru->pmu_clksel_con[2],\n+\t\t\t     LSCLK_PMU_SEL_MASK | LSCLK_PMU_DIV_MASK,\n+\t\t\t     (src_clk << LSCLK_PMU_SEL_SHIFT) |\n+\t\t\t     ((div - 1) << LSCLK_PMU_DIV_SHIFT));\n+\t\tbreak;\n+\tdefault:\n+\t\tprintf(\"do not support this permid freq\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn rv1103b_peri_get_clk(priv, clk_id);\n+}\n+\n+static ulong rv1103b_i2c_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tu32 sel, con;\n+\tulong rate;\n+\n+\tswitch (clk_id) {\n+\tcase CLK_I2C1:\n+\tcase CLK_I2C2:\n+\tcase CLK_I2C3:\n+\tcase CLK_I2C4:\n+\tcase CLK_I2C_PERI:\n+\t\tcon = readl(&cru->clksel_con[34]);\n+\t\tsel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT;\n+\t\tbreak;\n+\tcase CLK_I2C0:\n+\tcase CLK_I2C_PMU:\n+\t\tcon = readl(&cru->clksel_con[34]);\n+\t\tsel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\n+\tif (sel == CLK_I2C_SEL_100M)\n+\t\trate = 100 * MHz;\n+\telse\n+\t\trate = OSC_HZ;\n+\n+\treturn rate;\n+}\n+\n+static ulong rv1103b_crypto_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tu32 sel, con, rate;\n+\n+\tswitch (clk_id) {\n+\tcase ACLK_CRYPTO:\n+\tcase HCLK_CRYPTO:\n+\tcase HCLK_RK_RNG_NS:\n+\tcase HCLK_RK_RNG_S:\n+\t\treturn rv1103b_peri_get_clk(priv, LSCLK_PERI_SRC);\n+\tcase CLK_CORE_CRYPTO:\n+\t\tcon = readl(&cru->clksel_con[35]);\n+\t\tsel = (con & CLK_CORE_CRYPTO_SEL_MASK) >>\n+\t\t      CLK_CORE_CRYPTO_SEL_SHIFT;\n+\t\tbreak;\n+\tcase CLK_PKA_CRYPTO:\n+\t\tcon = readl(&cru->clksel_con[35]);\n+\t\tsel = (con & CLK_PKA_CRYPTO_SEL_MASK) >>\n+\t\t      CLK_PKA_CRYPTO_SEL_SHIFT;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\tif (sel == CLK_CORE_CRYPTO_SEL_300M)\n+\t\trate = 300 * MHz;\n+\telse if (sel == CLK_CORE_CRYPTO_SEL_200M)\n+\t\trate = 200 * MHz;\n+\telse\n+\t\trate = 100 * MHz;\n+\n+\treturn rate;\n+}\n+\n+static ulong rv1103b_crypto_set_clk(struct rv1103b_clk_priv *priv,\n+\t\t\t\t    ulong clk_id, ulong rate)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tu32 sel;\n+\n+\tif (rate >= 297 * MHz)\n+\t\tsel = CLK_CORE_CRYPTO_SEL_300M;\n+\telse if (rate >= 198 * MHz)\n+\t\tsel = CLK_CORE_CRYPTO_SEL_200M;\n+\telse\n+\t\tsel = CLK_CORE_CRYPTO_SEL_100M;\n+\n+\tswitch (clk_id) {\n+\tcase ACLK_CRYPTO:\n+\tcase HCLK_CRYPTO:\n+\tcase HCLK_RK_RNG_NS:\n+\tcase HCLK_RK_RNG_S:\n+\t\trv1103b_peri_set_clk(priv, LSCLK_PERI_SRC, rate);\n+\tcase CLK_CORE_CRYPTO:\n+\t\trk_clrsetreg(&cru->clksel_con[35],\n+\t\t\t     CLK_CORE_CRYPTO_SEL_MASK,\n+\t\t\t     (sel << CLK_CORE_CRYPTO_SEL_SHIFT));\n+\t\tbreak;\n+\tcase CLK_PKA_CRYPTO:\n+\t\trk_clrsetreg(&cru->clksel_con[35],\n+\t\t\t     CLK_PKA_CRYPTO_SEL_MASK,\n+\t\t\t     (sel << CLK_PKA_CRYPTO_SEL_SHIFT));\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\treturn rv1103b_crypto_get_clk(priv, clk_id);\n+}\n+\n+static ulong rv1103b_mmc_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tu32 div, sel, con, prate;\n+\n+\tswitch (clk_id) {\n+\tcase CCLK_SDMMC1:\n+\tcase HCLK_SDMMC1:\n+\t\tcon = readl(&cru->clksel_con[36]);\n+\t\tsel = (con & CLK_SDMMC_SEL_MASK) >>\n+\t\t      CLK_SDMMC_SEL_SHIFT;\n+\t\tdiv = (con & CLK_SDMMC_DIV_MASK) >>\n+\t\t      CLK_SDMMC_DIV_SHIFT;\n+\t\tif (sel == CLK_MMC_SEL_GPLL)\n+\t\t\tprate = priv->gpll_hz;\n+\t\telse\n+\t\t\tprate = OSC_HZ;\n+\t\treturn DIV_TO_RATE(prate, div);\n+\tcase CCLK_SDMMC0:\n+\tcase HCLK_SDMMC0:\n+\t\tcon = readl(&cru->clksel_con[32]);\n+\t\tsel = (con & CLK_SDMMC_SEL_MASK) >>\n+\t\t      CLK_SDMMC_SEL_SHIFT;\n+\t\tdiv = (con & CLK_SDMMC_DIV_MASK) >>\n+\t\t      CLK_SDMMC_DIV_SHIFT;\n+\t\tif (sel == CLK_MMC_SEL_GPLL)\n+\t\t\tprate = priv->gpll_hz;\n+\t\telse\n+\t\t\tprate = OSC_HZ;\n+\t\treturn DIV_TO_RATE(prate, div);\n+\tcase CCLK_EMMC:\n+\tcase HCLK_EMMC:\n+\t\tcon = readl(&cru->clksel_con[31]);\n+\t\tsel = (con & CLK_EMMC_SEL_MASK) >>\n+\t\t      CLK_EMMC_SEL_SHIFT;\n+\t\tdiv = (con & CLK_EMMC_DIV_MASK) >>\n+\t\t      CLK_EMMC_DIV_SHIFT;\n+\t\tif (sel == CLK_MMC_SEL_GPLL)\n+\t\t\tprate = priv->gpll_hz;\n+\t\telse\n+\t\t\tprate = OSC_HZ;\n+\t\treturn DIV_TO_RATE(prate, div);\n+\tcase SCLK_SFC_2X:\n+\tcase HCLK_SFC:\n+\t\tcon = readl(&cru->clksel_con[33]);\n+\t\tsel = (con & CLK_SFC_SEL_MASK) >>\n+\t\t      CLK_SFC_SEL_SHIFT;\n+\t\tdiv = (con & CLK_SFC_DIV_MASK) >>\n+\t\t      CLK_SFC_DIV_SHIFT;\n+\t\tif (sel == CLK_MMC_SEL_GPLL)\n+\t\t\tprate = priv->gpll_hz;\n+\t\telse\n+\t\t\tprate = OSC_HZ;\n+\t\treturn DIV_TO_RATE(prate, div);\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+}\n+\n+static ulong rv1103b_mmc_set_clk(struct rv1103b_clk_priv *priv,\n+\t\t\t\t ulong clk_id, ulong rate)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tu32 sel, src_clk_div;\n+\tulong prate = 0;\n+\n+\tif ((OSC_HZ % rate) == 0) {\n+\t\tsel = CLK_MMC_SEL_OSC;\n+\t\tprate = OSC_HZ;\n+\t} else {\n+\t\tsel = CLK_MMC_SEL_GPLL;\n+\t\tprate = priv->gpll_hz;\n+\t}\n+\tsrc_clk_div = DIV_ROUND_UP(prate, rate);\n+\n+\tswitch (clk_id) {\n+\tcase CCLK_SDMMC1:\n+\tcase HCLK_SDMMC1:\n+\t\tsrc_clk_div = DIV_ROUND_UP(prate, rate);\n+\t\trk_clrsetreg(&cru->clksel_con[36],\n+\t\t\t     CLK_SDMMC_SEL_MASK |\n+\t\t\t     CLK_SDMMC_DIV_MASK,\n+\t\t\t     (sel << CLK_SDMMC_SEL_SHIFT) |\n+\t\t\t     ((src_clk_div - 1) <<\n+\t\t\t      CLK_SDMMC_DIV_SHIFT));\n+\t\tbreak;\n+\tcase CCLK_SDMMC0:\n+\tcase HCLK_SDMMC0:\n+\t\tsrc_clk_div = DIV_ROUND_UP(prate, rate);\n+\t\trk_clrsetreg(&cru->clksel_con[32],\n+\t\t\t     CLK_SDMMC_SEL_MASK |\n+\t\t\t     CLK_SDMMC_DIV_MASK,\n+\t\t\t     (sel << CLK_SDMMC_SEL_SHIFT) |\n+\t\t\t     ((src_clk_div - 1) <<\n+\t\t\t      CLK_SDMMC_DIV_SHIFT));\n+\t\tbreak;\n+\tcase CCLK_EMMC:\n+\tcase HCLK_EMMC:\n+\t\tsrc_clk_div = DIV_ROUND_UP(prate, rate);\n+\t\trk_clrsetreg(&cru->clksel_con[31],\n+\t\t\t     CLK_EMMC_SEL_MASK |\n+\t\t\t     CLK_EMMC_DIV_MASK,\n+\t\t\t     (sel << CLK_EMMC_SEL_SHIFT) |\n+\t\t\t     ((src_clk_div - 1) <<\n+\t\t\t      CLK_EMMC_DIV_SHIFT));\n+\t\tbreak;\n+\tcase SCLK_SFC_2X:\n+\tcase HCLK_SFC:\n+\t\tsrc_clk_div = DIV_ROUND_UP(prate, rate);\n+\t\trk_clrsetreg(&cru->clksel_con[33],\n+\t\t\t     CLK_SFC_SEL_MASK |\n+\t\t\t     CLK_SFC_DIV_MASK,\n+\t\t\t     (sel << CLK_SFC_SEL_SHIFT) |\n+\t\t\t     ((src_clk_div - 1) <<\n+\t\t\t      CLK_SFC_DIV_SHIFT));\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\treturn rv1103b_mmc_get_clk(priv, clk_id);\n+}\n+\n+static ulong rv1103b_i2c_set_clk(struct rv1103b_clk_priv *priv, ulong clk_id,\n+\t\t\t\t ulong rate)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tint src_clk;\n+\n+\tif (rate == OSC_HZ)\n+\t\tsrc_clk = CLK_I2C_SEL_24M;\n+\telse\n+\t\tsrc_clk = CLK_I2C_SEL_100M;\n+\n+\tswitch (clk_id) {\n+\tcase CLK_I2C1:\n+\tcase CLK_I2C2:\n+\tcase CLK_I2C3:\n+\tcase CLK_I2C4:\n+\tcase CLK_I2C_PERI:\n+\t\trk_clrsetreg(&cru->clksel_con[34], CLK_I2C1_SEL_MASK,\n+\t\t\t     src_clk << CLK_I2C1_SEL_SHIFT);\n+\t\tbreak;\n+\tcase CLK_I2C0:\n+\tcase CLK_I2C_PMU:\n+\t\trk_clrsetreg(&cru->clksel_con[34], CLK_I2C0_SEL_MASK,\n+\t\t\t     src_clk << CLK_I2C0_SEL_SHIFT);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\treturn rv1103b_i2c_get_clk(priv, clk_id);\n+}\n+\n+static ulong rv1103b_spi_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tu32 sel, con, rate;\n+\n+\tswitch (clk_id) {\n+\tcase CLK_SPI0:\n+\t\tcon = readl(&cru->clksel_con[34]);\n+\t\tsel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\tif (sel == CLK_SPI0_SEL_200M)\n+\t\trate = 200 * MHz;\n+\telse if (sel == CLK_SPI0_SEL_100M)\n+\t\trate = 100 * MHz;\n+\telse if (sel == CLK_SPI0_SEL_50M)\n+\t\trate = 50 * MHz;\n+\telse\n+\t\trate = OSC_HZ;\n+\n+\treturn rate;\n+}\n+\n+static ulong rv1103b_spi_set_clk(struct rv1103b_clk_priv *priv,\n+\t\t\t\t ulong clk_id, ulong rate)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tint src_clk;\n+\n+\tif (rate >= 198 * MHz)\n+\t\tsrc_clk = CLK_SPI0_SEL_200M;\n+\telse if (rate >= 99 * MHz)\n+\t\tsrc_clk = CLK_SPI0_SEL_100M;\n+\telse if (rate >= 48 * MHz)\n+\t\tsrc_clk = CLK_SPI0_SEL_50M;\n+\telse\n+\t\tsrc_clk = CLK_SPI0_SEL_24M;\n+\n+\tswitch (clk_id) {\n+\tcase CLK_SPI0:\n+\t\trk_clrsetreg(&cru->clksel_con[34], CLK_SPI0_SEL_MASK,\n+\t\t\t     src_clk << CLK_SPI0_SEL_SHIFT);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\n+\treturn rv1103b_spi_get_clk(priv, clk_id);\n+}\n+\n+static ulong rv1103b_pwm_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tu32 sel, con;\n+\n+\tswitch (clk_id) {\n+\tcase CLK_PWM0:\n+\tcase CLK_PWM0_SRC:\n+\t\tcon = readl(&cru->clksel_con[34]);\n+\t\tsel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;\n+\t\tbreak;\n+\tcase CLK_PWM1:\n+\t\tcon = readl(&cru->clksel_con[34]);\n+\t\tsel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;\n+\t\tbreak;\n+\tcase CLK_PWM2:\n+\t\tcon = readl(&cru->clksel_con[34]);\n+\t\tsel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\n+\tswitch (sel) {\n+\tcase CLK_PWM_SEL_100M:\n+\t\treturn 100 * MHz;\n+\tcase CLK_PWM_SEL_24M:\n+\t\treturn OSC_HZ;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+}\n+\n+static ulong rv1103b_pwm_set_clk(struct rv1103b_clk_priv *priv,\n+\t\t\t\t ulong clk_id, ulong rate)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tint src_clk;\n+\n+\tif (rate >= 99 * MHz)\n+\t\tsrc_clk = CLK_PWM_SEL_100M;\n+\telse\n+\t\tsrc_clk = CLK_PWM_SEL_24M;\n+\n+\tswitch (clk_id) {\n+\tcase CLK_PWM0:\n+\tcase CLK_PWM0_SRC:\n+\t\trk_clrsetreg(&cru->clksel_con[34],\n+\t\t\t     CLK_PWM0_SEL_MASK,\n+\t\t\t     src_clk << CLK_PWM0_SEL_SHIFT);\n+\t\tbreak;\n+\tcase CLK_PWM1:\n+\t\trk_clrsetreg(&cru->clksel_con[34],\n+\t\t\t     CLK_PWM1_SEL_MASK,\n+\t\t\t     src_clk << CLK_PWM1_SEL_SHIFT);\n+\t\tbreak;\n+\tcase CLK_PWM2:\n+\t\trk_clrsetreg(&cru->clksel_con[34],\n+\t\t\t     CLK_PWM2_SEL_MASK,\n+\t\t\t     src_clk << CLK_PWM2_SEL_SHIFT);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\n+\treturn rv1103b_pwm_get_clk(priv, clk_id);\n+}\n+\n+static ulong rv1103b_adc_get_clk(struct rv1103b_clk_priv *priv, ulong clk_id)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tu32 div, con;\n+\n+\tswitch (clk_id) {\n+\tcase CLK_SARADC:\n+\t\tcon = readl(&cru->peri_clksel_con[1]);\n+\t\tdiv = (con & CLK_SARADC_DIV_MASK) >>\n+\t\t      CLK_SARADC_DIV_SHIFT;\n+\t\treturn DIV_TO_RATE(OSC_HZ, div);\n+\tcase CLK_TSADC_TSEN:\n+\t\tcon = readl(&cru->peri_clksel_con[0]);\n+\t\tdiv = (con & CLK_TSADC_TSEN_DIV_MASK) >>\n+\t\t      CLK_TSADC_TSEN_DIV_SHIFT;\n+\t\treturn DIV_TO_RATE(OSC_HZ, div);\n+\tcase CLK_TSADC:\n+\t\tcon = readl(&cru->peri_clksel_con[0]);\n+\t\tdiv = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT;\n+\t\treturn DIV_TO_RATE(OSC_HZ, div);\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+}\n+\n+static ulong rv1103b_adc_set_clk(struct rv1103b_clk_priv *priv,\n+\t\t\t\t ulong clk_id, ulong rate)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tint src_clk_div;\n+\n+\tsrc_clk_div = DIV_ROUND_UP(OSC_HZ, rate);\n+\n+\tswitch (clk_id) {\n+\tcase CLK_SARADC:\n+\t\tassert(src_clk_div - 1 <= 7);\n+\t\trk_clrsetreg(&cru->peri_clksel_con[1],\n+\t\t\t     CLK_SARADC_DIV_MASK,\n+\t\t\t     (src_clk_div - 1) <<\n+\t\t\t     CLK_SARADC_DIV_SHIFT);\n+\t\tbreak;\n+\tcase CLK_TSADC_TSEN:\n+\t\tassert(src_clk_div - 1 <= 32);\n+\t\trk_clrsetreg(&cru->peri_clksel_con[0],\n+\t\t\t     CLK_TSADC_TSEN_DIV_MASK,\n+\t\t\t     (src_clk_div - 1) <<\n+\t\t\t     CLK_TSADC_TSEN_DIV_SHIFT);\n+\t\tbreak;\n+\tcase CLK_TSADC:\n+\t\tassert(src_clk_div - 1 <= 32);\n+\t\trk_clrsetreg(&cru->peri_clksel_con[0],\n+\t\t\t     CLK_TSADC_DIV_MASK,\n+\t\t\t     (src_clk_div - 1) <<\n+\t\t\t     CLK_TSADC_DIV_SHIFT);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\treturn rv1103b_adc_get_clk(priv, clk_id);\n+}\n+\n+/*\n+ *\n+ * rational_best_approximation(31415, 10000,\n+ *\t\t(1 << 8) - 1, (1 << 5) - 1, &n, &d);\n+ *\n+ * you may look at given_numerator as a fixed point number,\n+ * with the fractional part size described in given_denominator.\n+ *\n+ * for theoretical background, see:\n+ * http://en.wikipedia.org/wiki/Continued_fraction\n+ */\n+static void rational_best_approximation(unsigned long given_numerator,\n+\t\t\t\t\tunsigned long given_denominator,\n+\t\t\t\t\tunsigned long max_numerator,\n+\t\t\t\t\tunsigned long max_denominator,\n+\t\t\t\t\tunsigned long *best_numerator,\n+\t\t\t\t\tunsigned long *best_denominator)\n+{\n+\tunsigned long n, d, n0, d0, n1, d1;\n+\n+\tn = given_numerator;\n+\td = given_denominator;\n+\tn0 = 0;\n+\td1 = 0;\n+\tn1 = 1;\n+\td0 = 1;\n+\tfor (;;) {\n+\t\tunsigned long t, a;\n+\n+\t\tif (n1 > max_numerator || d1 > max_denominator) {\n+\t\t\tn1 = n0;\n+\t\t\td1 = d0;\n+\t\t\tbreak;\n+\t\t}\n+\t\tif (d == 0)\n+\t\t\tbreak;\n+\t\tt = d;\n+\t\ta = n / d;\n+\t\td = n % d;\n+\t\tn = t;\n+\t\tt = n0 + a * n1;\n+\t\tn0 = n1;\n+\t\tn1 = t;\n+\t\tt = d0 + a * d1;\n+\t\td0 = d1;\n+\t\td1 = t;\n+\t}\n+\t*best_numerator = n1;\n+\t*best_denominator = d1;\n+}\n+\n+static ulong rv1103b_uart_get_rate(struct rv1103b_clk_priv *priv, ulong clk_id)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tu32 reg, con, fracdiv, div, src, p_rate;\n+\tunsigned long m, n;\n+\n+\tswitch (clk_id) {\n+\tcase SCLK_UART0:\n+\t\treg = 10;\n+\t\tcon = readl(&cru->clksel_con[32]);\n+\t\tsrc = (con & CLK_UART0_SEL_MASK) >> CLK_UART0_SEL_SHIFT;\n+\t\tcon = readl(&cru->clksel_con[5]);\n+\t\tdiv = (con & CLK_UART0_SRC_DIV_MASK) >> CLK_UART0_SRC_DIV_SHIFT;\n+\t\tbreak;\n+\tcase SCLK_UART1:\n+\t\treg = 11;\n+\t\tcon = readl(&cru->clksel_con[32]);\n+\t\tsrc = (con & CLK_UART1_SEL_MASK) >> CLK_UART1_SEL_SHIFT;\n+\t\tcon = readl(&cru->clksel_con[5]);\n+\t\tdiv = (con & CLK_UART1_SRC_DIV_MASK) >> CLK_UART1_SRC_DIV_SHIFT;\n+\t\tbreak;\n+\tcase SCLK_UART2:\n+\t\treg = 12;\n+\t\tcon = readl(&cru->clksel_con[32]);\n+\t\tsrc = (con & CLK_UART2_SEL_MASK) >> CLK_UART2_SEL_SHIFT;\n+\t\tcon = readl(&cru->clksel_con[5]);\n+\t\tdiv = (con & CLK_UART2_SRC_DIV_MASK) >> CLK_UART2_SRC_DIV_SHIFT;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\n+\tp_rate = priv->gpll_hz;\n+\tif (src == CLK_UART_SEL_SRC) {\n+\t\treturn DIV_TO_RATE(p_rate, div);\n+\t} else if (src == CLK_UART_SEL_FRAC) {\n+\t\tfracdiv = readl(&cru->clksel_con[reg]);\n+\t\tn = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;\n+\t\tn >>= CLK_UART_FRAC_NUMERATOR_SHIFT;\n+\t\tm = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;\n+\t\tm >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;\n+\t\treturn DIV_TO_RATE(p_rate, div) * n / m;\n+\t} else {\n+\t\treturn OSC_HZ;\n+\t}\n+}\n+\n+static ulong rv1103b_uart_set_rate(struct rv1103b_clk_priv *priv,\n+\t\t\t\t   ulong clk_id, ulong rate)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tu32 reg, uart_src, div;\n+\tunsigned long m = 0, n = 0, val;\n+\n+\tif (priv->gpll_hz % rate == 0) {\n+\t\tuart_src = CLK_UART_SEL_SRC;\n+\t\tdiv = DIV_ROUND_UP(priv->gpll_hz, rate);\n+\t} else if (rate == OSC_HZ) {\n+\t\tuart_src = CLK_UART_SEL_OSC;\n+\t\tdiv = 2;\n+\t} else {\n+\t\tuart_src = CLK_UART_SEL_FRAC;\n+\t\tdiv = 2;\n+\t\trational_best_approximation(rate, priv->gpll_hz / div,\n+\t\t\t\t\t    GENMASK(16 - 1, 0),\n+\t\t\t\t\t    GENMASK(16 - 1, 0),\n+\t\t\t\t\t    &m, &n);\n+\t}\n+\n+\tswitch (clk_id) {\n+\tcase SCLK_UART0:\n+\t\treg = 10;\n+\t\trk_clrsetreg(&cru->clksel_con[5],\n+\t\t\t     CLK_UART0_SRC_DIV_MASK,\n+\t\t\t     div << CLK_UART0_SRC_DIV_SHIFT);\n+\t\trk_clrsetreg(&cru->clksel_con[32],\n+\t\t\t     CLK_UART0_SEL_MASK,\n+\t\t\t     uart_src << CLK_UART0_SEL_SHIFT);\n+\t\tbreak;\n+\tcase SCLK_UART1:\n+\t\treg = 11;\n+\t\trk_clrsetreg(&cru->clksel_con[5],\n+\t\t\t     CLK_UART1_SRC_DIV_MASK,\n+\t\t\t     div << CLK_UART1_SRC_DIV_SHIFT);\n+\t\trk_clrsetreg(&cru->clksel_con[32],\n+\t\t\t     CLK_UART1_SEL_MASK,\n+\t\t\t     uart_src << CLK_UART1_SEL_SHIFT);\n+\t\tbreak;\n+\tcase SCLK_UART2:\n+\t\treg = 12;\n+\t\trk_clrsetreg(&cru->clksel_con[5],\n+\t\t\t     CLK_UART2_SRC_DIV_MASK,\n+\t\t\t     div << CLK_UART2_SRC_DIV_SHIFT);\n+\t\trk_clrsetreg(&cru->clksel_con[32],\n+\t\t\t     CLK_UART2_SEL_MASK,\n+\t\t\t     uart_src << CLK_UART2_SEL_SHIFT);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\tif (m && n) {\n+\t\tval = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;\n+\t\twritel(val, &cru->clksel_con[reg]);\n+\t}\n+\n+\treturn rv1103b_uart_get_rate(priv, clk_id);\n+}\n+\n+static ulong rv1103b_decom_get_clk(struct rv1103b_clk_priv *priv)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tu32 sel, con, prate;\n+\n+\tcon = readl(&cru->clksel_con[35]);\n+\tsel = (con & DCLK_DECOM_SEL_MASK) >>\n+\t      DCLK_DECOM_SEL_SHIFT;\n+\tif (sel == DCLK_DECOM_SEL_480M)\n+\t\tprate = 480 * MHz;\n+\telse if (sel == DCLK_DECOM_SEL_400M)\n+\t\tprate = 400 * MHz;\n+\telse\n+\t\tprate = 300 * MHz;\n+\treturn prate;\n+}\n+\n+static ulong rv1103b_decom_set_clk(struct rv1103b_clk_priv *priv, ulong rate)\n+{\n+\tstruct rv1103b_cru *cru = priv->cru;\n+\tu32 sel;\n+\n+\tif (rate >= 480 * MHz)\n+\t\tsel = DCLK_DECOM_SEL_480M;\n+\telse if (rate >= 396 * MHz)\n+\t\tsel = DCLK_DECOM_SEL_400M;\n+\telse\n+\t\tsel = DCLK_DECOM_SEL_300M;\n+\trk_clrsetreg(&cru->clksel_con[35], DCLK_DECOM_SEL_MASK,\n+\t\t     (sel << DCLK_DECOM_SEL_SHIFT));\n+\n+\treturn rv1103b_decom_get_clk(priv);\n+}\n+\n+static ulong rv1103b_clk_get_rate(struct clk *clk)\n+{\n+\tstruct rv1103b_clk_priv *priv = dev_get_priv(clk->dev);\n+\tulong rate = 0;\n+\n+\tif (!priv->gpll_hz) {\n+\t\tprintf(\"%s gpll=%lu\\n\", __func__, priv->gpll_hz);\n+\t\treturn -ENOENT;\n+\t}\n+\n+\tswitch (clk->id) {\n+\tcase PLL_GPLL:\n+\t\trate = rockchip_pll_get_rate(&rv1103b_pll_clks[GPLL], priv->cru,\n+\t\t\t\t\t     GPLL);\n+\t\tbreak;\n+\tcase ACLK_PERI_SRC:\n+\tcase LSCLK_PERI_SRC:\n+\tcase PCLK_PERI_ROOT:\n+\tcase PCLK_TOP_ROOT:\n+\tcase LSCLK_PMU_ROOT:\n+\tcase PCLK_PMU:\n+\t\trate = rv1103b_peri_get_clk(priv, clk->id);\n+\t\tbreak;\n+\tcase ACLK_CRYPTO:\n+\tcase HCLK_CRYPTO:\n+\tcase HCLK_RK_RNG_NS:\n+\tcase HCLK_RK_RNG_S:\n+\tcase CLK_CORE_CRYPTO:\n+\tcase CLK_PKA_CRYPTO:\n+\t\trate = rv1103b_crypto_get_clk(priv, clk->id);\n+\t\tbreak;\n+\tcase CCLK_SDMMC1:\n+\tcase HCLK_SDMMC1:\n+\tcase CCLK_SDMMC0:\n+\tcase HCLK_SDMMC0:\n+\tcase CCLK_EMMC:\n+\tcase HCLK_EMMC:\n+\tcase SCLK_SFC_2X:\n+\tcase HCLK_SFC:\n+\t\trate = rv1103b_mmc_get_clk(priv, clk->id);\n+\t\tbreak;\n+\tcase CLK_I2C1:\n+\tcase CLK_I2C2:\n+\tcase CLK_I2C3:\n+\tcase CLK_I2C4:\n+\tcase CLK_I2C_PERI:\n+\tcase CLK_I2C0:\n+\tcase CLK_I2C_PMU:\n+\t\trate = rv1103b_i2c_get_clk(priv, clk->id);\n+\t\tbreak;\n+\tcase CLK_SPI0:\n+\t\trate = rv1103b_spi_get_clk(priv, clk->id);\n+\t\tbreak;\n+\tcase CLK_PWM0:\n+\tcase CLK_PWM0_SRC:\n+\tcase CLK_PWM1:\n+\tcase CLK_PWM2:\n+\t\trate = rv1103b_pwm_get_clk(priv, clk->id);\n+\t\tbreak;\n+\tcase CLK_SARADC:\n+\tcase CLK_TSADC_TSEN:\n+\tcase CLK_TSADC:\n+\t\trate = rv1103b_adc_get_clk(priv, clk->id);\n+\t\tbreak;\n+\tcase SCLK_UART0:\n+\tcase SCLK_UART1:\n+\tcase SCLK_UART2:\n+\t\trate = rv1103b_uart_get_rate(priv, clk->id);\n+\t\tbreak;\n+\tcase DCLK_DECOM_SRC:\n+\tcase DCLK_DECOM:\n+\t\trate = rv1103b_decom_get_clk(priv);\n+\t\tbreak;\n+\tcase TCLK_WDT_LPMCU:\n+\tcase TCLK_WDT_HPMCU:\n+\tcase TCLK_WDT_NS:\n+\tcase TCLK_WDT_S:\n+\t\trate = OSC_HZ;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\n+\treturn rate;\n+};\n+\n+static ulong rv1103b_clk_set_rate(struct clk *clk, ulong rate)\n+{\n+\tstruct rv1103b_clk_priv *priv = dev_get_priv(clk->dev);\n+\tulong ret = 0;\n+\n+\tif (!priv->gpll_hz) {\n+\t\tprintf(\"%s gpll=%lu\\n\", __func__, priv->gpll_hz);\n+\t\treturn -ENOENT;\n+\t}\n+\n+\tswitch (clk->id) {\n+\tcase PLL_GPLL:\n+\t\tret = rockchip_pll_set_rate(&rv1103b_pll_clks[GPLL], priv->cru,\n+\t\t\t\t\t    GPLL, rate);\n+\t\tbreak;\n+\tcase ACLK_PERI_SRC:\n+\tcase LSCLK_PERI_SRC:\n+\tcase PCLK_PERI_ROOT:\n+\tcase PCLK_TOP_ROOT:\n+\tcase LSCLK_PMU_ROOT:\n+\tcase PCLK_PMU:\n+\t\tret = rv1103b_peri_set_clk(priv, clk->id, rate);\n+\t\tbreak;\n+\tcase ACLK_CRYPTO:\n+\tcase HCLK_CRYPTO:\n+\tcase HCLK_RK_RNG_NS:\n+\tcase HCLK_RK_RNG_S:\n+\tcase CLK_CORE_CRYPTO:\n+\tcase CLK_PKA_CRYPTO:\n+\t\tret = rv1103b_crypto_set_clk(priv, clk->id, rate);\n+\t\tbreak;\n+\tcase CCLK_SDMMC1:\n+\tcase HCLK_SDMMC1:\n+\tcase CCLK_SDMMC0:\n+\tcase HCLK_SDMMC0:\n+\tcase CCLK_EMMC:\n+\tcase HCLK_EMMC:\n+\tcase SCLK_SFC_2X:\n+\tcase HCLK_SFC:\n+\t\tret = rv1103b_mmc_set_clk(priv, clk->id, rate);\n+\t\tbreak;\n+\tcase CLK_I2C1:\n+\tcase CLK_I2C2:\n+\tcase CLK_I2C3:\n+\tcase CLK_I2C4:\n+\tcase CLK_I2C_PERI:\n+\tcase CLK_I2C0:\n+\tcase CLK_I2C_PMU:\n+\t\tret = rv1103b_i2c_set_clk(priv, clk->id, rate);\n+\t\tbreak;\n+\tcase CLK_SPI0:\n+\t\tret = rv1103b_spi_set_clk(priv, clk->id, rate);\n+\t\tbreak;\n+\tcase CLK_PWM0:\n+\tcase CLK_PWM0_SRC:\n+\tcase CLK_PWM1:\n+\tcase CLK_PWM2:\n+\t\tret = rv1103b_pwm_set_clk(priv, clk->id, rate);\n+\t\tbreak;\n+\tcase CLK_SARADC:\n+\tcase CLK_TSADC_TSEN:\n+\tcase CLK_TSADC:\n+\t\tret = rv1103b_adc_set_clk(priv, clk->id, rate);\n+\t\tbreak;\n+\tcase SCLK_UART0:\n+\tcase SCLK_UART1:\n+\tcase SCLK_UART2:\n+\t\tret = rv1103b_uart_set_rate(priv, clk->id, rate);\n+\t\tbreak;\n+\tcase DCLK_DECOM_SRC:\n+\tcase DCLK_DECOM:\n+\t\trate = rv1103b_decom_set_clk(priv, rate);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\n+\treturn ret;\n+};\n+\n+static int rv1103b_clk_set_parent(struct clk *clk, struct clk *parent)\n+{\n+\tswitch (clk->id) {\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static struct clk_ops rv1103b_clk_ops = {\n+\t.get_rate = rv1103b_clk_get_rate,\n+\t.set_rate = rv1103b_clk_set_rate,\n+#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA))\n+\t.set_parent = rv1103b_clk_set_parent,\n+#endif\n+};\n+\n+static void rv1103b_clk_init(struct rv1103b_clk_priv *priv)\n+{\n+\tint ret;\n+\tu32 div;\n+\n+\tpriv->sync_kernel = false;\n+\tpriv->gpll_hz = rockchip_pll_get_rate(&rv1103b_pll_clks[GPLL],\n+\t\t\t\t\t      priv->cru, GPLL);\n+\tif (priv->gpll_hz != GPLL_HZ) {\n+\t\tret = rockchip_pll_set_rate(&rv1103b_pll_clks[GPLL], priv->cru,\n+\t\t\t\t\t    GPLL, GPLL_HZ);\n+\t\tif (!ret)\n+\t\t\tpriv->gpll_hz = GPLL_HZ;\n+\t}\n+\n+\tif (!priv->armclk_enter_hz) {\n+\t\tdiv = (readl(&priv->cru->clksel_con[37]) &\n+\t\t       CLK_CORE_GPLL_DIV_MASK) >>\n+\t\t      CLK_CORE_GPLL_DIV_SHIFT;\n+\t\tpriv->armclk_enter_hz = DIV_TO_RATE(priv->gpll_hz, div);\n+\t\tpriv->armclk_init_hz = priv->armclk_enter_hz;\n+\t}\n+}\n+\n+static int rv1103b_clk_probe(struct udevice *dev)\n+{\n+\tstruct rv1103b_clk_priv *priv = dev_get_priv(dev);\n+\tint ret;\n+\n+#ifdef CONFIG_SPL_BUILD\n+\t/* fix lsclk_prei div */\n+\twritel(BITS_WITH_WMASK(1, 0x1U, 9), RV1103B_CRU_BASE + RV1103B_CLKSEL_CON(31));\n+\t/* fix cpu div */\n+\twritel(BITS_WITH_WMASK(1, 0x7U, 13), RV1103B_CRU_BASE + RV1103B_CLKSEL_CON(37));\n+\t/* fix gpll postdiv1 */\n+\twritel(BITS_WITH_WMASK(1, 0x7U, 12), RV1103B_CRU_BASE + RV1103B_PLL_CON(24));\n+#endif\n+\n+\trv1103b_clk_init(priv);\n+\n+\t/* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */\n+\tret = clk_set_defaults(dev, 1);\n+\tif (ret)\n+\t\tdebug(\"%s clk_set_defaults failed %d\\n\", __func__, ret);\n+\telse\n+\t\tpriv->sync_kernel = true;\n+\treturn 0;\n+}\n+\n+static int rv1103b_clk_of_to_plat(struct udevice *dev)\n+{\n+\tstruct rv1103b_clk_priv *priv = dev_get_priv(dev);\n+\n+\tpriv->cru = dev_read_addr_ptr(dev);\n+\n+\treturn 0;\n+}\n+\n+static int rv1103b_clk_bind(struct udevice *dev)\n+{\n+\tstruct udevice *sys_child;\n+\tstruct sysreset_reg *priv;\n+\tint ret;\n+\n+\t/* The sysreset driver does not have a device node, so bind it here */\n+\tret = device_bind_driver(dev, \"rockchip_sysreset\", \"sysreset\", &sys_child);\n+\tif (ret) {\n+\t\tdebug(\"Warning: No sysreset driver: ret=%d\\n\", ret);\n+\t} else {\n+\t\tpriv = malloc(sizeof(struct sysreset_reg));\n+\t\tpriv->glb_srst_fst_value = offsetof(struct rv1103b_cru, glb_srst_fst);\n+\t\tpriv->glb_srst_snd_value = offsetof(struct rv1103b_cru, glb_srst_snd);\n+\t\tdev_set_priv(sys_child, priv);\n+\t}\n+\n+#if CONFIG_IS_ENABLED(RESET_ROCKCHIP)\n+\tret = offsetof(struct rv1103b_cru, peri_softrst_con[0]);\n+\tret = rockchip_reset_bind(dev, ret, 12); /* number of reset registers */\n+\tif (ret)\n+\t\tdebug(\"Warning: software reset driver bind failed\\n\");\n+#endif\n+\n+\treturn 0;\n+}\n+\n+static const struct udevice_id rv1103b_clk_ids[] = {\n+\t{ .compatible = \"rockchip,rv1103b-cru\" },\n+\t{ }\n+};\n+\n+U_BOOT_DRIVER(clk_rv1103b) = {\n+\t.name\t\t= \"clk_rv1103b\",\n+\t.id\t\t= UCLASS_CLK,\n+\t.of_match\t= rv1103b_clk_ids,\n+\t.priv_auto\t= sizeof(struct rv1103b_clk_priv),\n+\t.of_to_plat\t= rv1103b_clk_of_to_plat,\n+\t.ops\t\t= &rv1103b_clk_ops,\n+\t.bind\t\t= rv1103b_clk_bind,\n+\t.probe\t\t= rv1103b_clk_probe,\n+};\n",
    "prefixes": [
        "v2",
        "3/7"
    ]
}