Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/819129/?format=api
{ "id": 819129, "url": "http://patchwork.ozlabs.org/api/patches/819129/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/1506515969-1472-4-git-send-email-kever.yang@rock-chips.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": "<1506515969-1472-4-git-send-email-kever.yang@rock-chips.com>", "list_archive_url": null, "date": "2017-09-27T12:39:24", "name": "[U-Boot,3/8] rockchip: rk3128: add clock driver", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "6be80bc9deec3b9918462319e8fff2bc7fb17bb8", "submitter": { "id": 64532, "url": "http://patchwork.ozlabs.org/api/people/64532/?format=api", "name": "Kever Yang", "email": "kever.yang@rock-chips.com" }, "delegate": { "id": 69486, "url": "http://patchwork.ozlabs.org/api/users/69486/?format=api", "username": "ptomsich", "first_name": "Philipp", "last_name": "Tomsich", "email": "philipp.tomsich@theobroma-systems.com" }, "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/1506515969-1472-4-git-send-email-kever.yang@rock-chips.com/mbox/", "series": [ { "id": 5353, "url": "http://patchwork.ozlabs.org/api/series/5353/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=5353", "date": "2017-09-27T12:39:21", "name": "rockchip: add new SoC support for RK3128", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/5353/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/819129/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/819129/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>)", "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=gmail.com header.i=@gmail.com\n\theader.b=\"KMZgQXLE\"; dkim-atps=neutral" ], "Received": [ "from lists.denx.de (dione.denx.de [81.169.180.215])\n\tby ozlabs.org (Postfix) with ESMTP id 3y2HX00zWsz9tXf\n\tfor <incoming@patchwork.ozlabs.org>;\n\tWed, 27 Sep 2017 22:42:08 +1000 (AEST)", "by lists.denx.de (Postfix, from userid 105)\n\tid D7FBBC21DC6; Wed, 27 Sep 2017 12:41:43 +0000 (UTC)", "from lists.denx.de (localhost [IPv6:::1])\n\tby lists.denx.de (Postfix) with ESMTP id AFA68C21D92;\n\tWed, 27 Sep 2017 12:40:15 +0000 (UTC)", "by lists.denx.de (Postfix, from userid 105)\n\tid 5216EC21D8D; Wed, 27 Sep 2017 12:39:56 +0000 (UTC)", "from mail-pg0-f67.google.com (mail-pg0-f67.google.com\n\t[74.125.83.67])\n\tby lists.denx.de (Postfix) with ESMTPS id BB6B5C21D84\n\tfor <u-boot@lists.denx.de>; Wed, 27 Sep 2017 12:39:51 +0000 (UTC)", "by mail-pg0-f67.google.com with SMTP id j16so9093832pga.2\n\tfor <u-boot@lists.denx.de>; Wed, 27 Sep 2017 05:39:51 -0700 (PDT)", "from localhost.localdomain ([103.29.142.67])\n\tby smtp.gmail.com with ESMTPSA id\n\tv24sm21833899pfi.132.2017.09.27.05.39.46\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128);\n\tWed, 27 Sep 2017 05:39:49 -0700 (PDT)" ], "X-Spam-Checker-Version": "SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de", "X-Spam-Level": "", "X-Spam-Status": "No, score=-0.0 required=5.0 tests=RCVD_IN_DNSWL_NONE,\n\tRCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL,\n\tT_DKIM_INVALID autolearn=unavailable\n\tautolearn_force=no version=3.4.0", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025;\n\th=sender:from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=X7/JWFaeReDSJHyz1y07koOSIvNdt4eMwMAQg1RC3r8=;\n\tb=KMZgQXLEsNE3clAgeIoIjWdVlyn/Qm9bAaXK/jslENItALdGY8gvvBLo7PwjLDk6Rk\n\tpxNrpLEX02JZgRPZbZsMB2Xxz02y/6NpIEOhcTECia42ki5lIRvcQ2dKf/VUa+bdaSyu\n\tJZ1CP2voymP3JlJ3GCcdqSorBgZMoQJoV9oRYgZzbe0wV0n1oEyRwsgCyw1ot3qqe9GP\n\t7BZOI4ktx8NjNBboP1bgVzt5UMuQR1G7E3PnIScQhIIs4EBkNsNqKL/ZufzkuUEKdi4Z\n\trtJ+Sk/7rgmNeGLJjKQLkwnONPMlhQOvIU+FLadSwDs/Q3KN5caIOylxrxK+fm+0yRar\n\t+3Pw==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:sender:from:to:cc:subject:date:message-id\n\t:in-reply-to:references;\n\tbh=X7/JWFaeReDSJHyz1y07koOSIvNdt4eMwMAQg1RC3r8=;\n\tb=cxxsakk6KRBQT2DycR5ea9oAnBTH1wc8zzCw6gUh7hy4ypgPcqHf/tq6ApoyM4ZoXh\n\tOvQ7Ku1MNIRQaDzDpfPaGAH9U3J7eGXO8OM3hBl71SQqPcGbBQtGJxk+yvRjX6k/yUSQ\n\t7Hkt+aWoHUG6cibSE92ECVaQjGHDKNC32tX3KtkQEv4V0YDeMAOQR6PhQJorshpVMeWf\n\tsp6U4jxfkDAh8QqfX5UqeGlhhSptgHmHTgvNJCTX7RUsgKpE6V057R5eQk/ZyF1KPoKo\n\tpptMkNJGAqVDbCBq1xwFJ/ZI2jGZ/wcNyQhl5eQjYS+dpTgPURVmZQujoIs3JQ3OPM2l\n\t/IOw==", "X-Gm-Message-State": "AHPjjUicjn9/U67PUpVGBI9jexGsgjsg2z2ciFt8SZpJuPIGnZAIxS/S\n\tx7ddDfE+TCOYy9uh1xnYMTve4Q==", "X-Google-Smtp-Source": "AOwi7QDXIYTd1ZspyCstfziVdwh988AuVJdngBc52VgakE5TK3aIgV6uASEdywlLvMHr2Ro1Pd6wOQ==", "X-Received": "by 10.84.132.111 with SMTP id 102mr1151571ple.348.1506515989798; \n\tWed, 27 Sep 2017 05:39:49 -0700 (PDT)", "From": "Kever Yang <kever.yang@rock-chips.com>", "To": "u-boot@lists.denx.de", "Date": "Wed, 27 Sep 2017 20:39:24 +0800", "Message-Id": "<1506515969-1472-4-git-send-email-kever.yang@rock-chips.com>", "X-Mailer": "git-send-email 1.9.1", "In-Reply-To": "<1506515969-1472-1-git-send-email-kever.yang@rock-chips.com>", "References": "<1506515969-1472-1-git-send-email-kever.yang@rock-chips.com>", "Cc": "Andy Yan <andy.yan@rock-chips.com>,\n\tWilliam Zhang <william.zhang@rock-chips.com>", "Subject": "[U-Boot] [PATCH 3/8] rockchip: rk3128: add clock driver", "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>", "MIME-Version": "1.0", "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": "Add rk3128 clock driver and cru structure definition.\n\nSigned-off-by: Kever Yang <kever.yang@rock-chips.com>\n---\n\n arch/arm/include/asm/arch-rockchip/cru_rk3128.h | 173 ++++++++++++\n arch/arm/mach-rockchip/rk3128/Makefile | 1 +\n arch/arm/mach-rockchip/rk3128/clk_rk3128.c | 32 +++\n drivers/clk/rockchip/Makefile | 3 +-\n drivers/clk/rockchip/clk_rk3128.c | 350 ++++++++++++++++++++++++\n 5 files changed, 558 insertions(+), 1 deletion(-)\n create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3128.h\n create mode 100644 arch/arm/mach-rockchip/rk3128/clk_rk3128.c\n create mode 100644 drivers/clk/rockchip/clk_rk3128.c", "diff": "diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3128.h b/arch/arm/include/asm/arch-rockchip/cru_rk3128.h\nnew file mode 100644\nindex 0000000..f511bd0\n--- /dev/null\n+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3128.h\n@@ -0,0 +1,173 @@\n+/*\n+ * Copyright (c) 2017 Rockchip Electronics Co., Ltd\n+ *\n+ * SPDX-License-Identifier: GPL-2.0+\n+ */\n+\n+#ifndef _ASM_ARCH_CRU_RK3128_H\n+#define _ASM_ARCH_CRU_RK3128_H\n+\n+#include <common.h>\n+\n+#define MHz\t\t1000000\n+#define OSC_HZ\t\t(24 * MHz)\n+\n+#define APLL_HZ\t\t(600 * MHz)\n+#define GPLL_HZ\t\t(594 * MHz)\n+\n+#define CORE_PERI_HZ\t150000000\n+#define CORE_ACLK_HZ\t300000000\n+\n+#define BUS_ACLK_HZ\t148500000\n+#define BUS_HCLK_HZ\t148500000\n+#define BUS_PCLK_HZ\t74250000\n+\n+#define PERI_ACLK_HZ\t148500000\n+#define PERI_HCLK_HZ\t148500000\n+#define PERI_PCLK_HZ\t74250000\n+\n+/* Private data for the clock driver - used by rockchip_get_cru() */\n+struct rk3128_clk_priv {\n+\tstruct rk3128_cru *cru;\n+\tulong rate;\n+};\n+\n+struct rk3128_cru {\n+\tstruct rk3128_pll {\n+\t\tunsigned int con0;\n+\t\tunsigned int con1;\n+\t\tunsigned int con2;\n+\t\tunsigned int con3;\n+\t} pll[4];\n+\tunsigned int cru_mode_con;\n+\tunsigned int cru_clksel_con[35];\n+\tunsigned int cru_clkgate_con[11];\n+\tunsigned int reserved;\n+\tunsigned int cru_glb_srst_fst_value;\n+\tunsigned int cru_glb_srst_snd_value;\n+\tunsigned int reserved1[2];\n+\tunsigned int cru_softrst_con[9];\n+\tunsigned int cru_misc_con;\n+\tunsigned int reserved2[2];\n+\tunsigned int cru_glb_cnt_th;\n+\tunsigned int reserved3[3];\n+\tunsigned int cru_glb_rst_st;\n+\tunsigned int reserved4[(0x1c0 - 0x150) / 4 - 1];\n+\tunsigned int cru_sdmmc_con[2];\n+\tunsigned int cru_sdio_con[2];\n+\tunsigned int reserved5[2];\n+\tunsigned int cru_emmc_con[2];\n+\tunsigned int reserved6[4];\n+\tunsigned int cru_pll_prg_en;\n+};\n+check_member(rk3128_cru, cru_pll_prg_en, 0x01f0);\n+\n+struct pll_div {\n+\tu32 refdiv;\n+\tu32 fbdiv;\n+\tu32 postdiv1;\n+\tu32 postdiv2;\n+\tu32 frac;\n+};\n+\n+enum {\n+\t/* PLLCON0*/\n+\tPLL_POSTDIV1_SHIFT\t= 12,\n+\tPLL_POSTDIV1_MASK\t= 7 << PLL_POSTDIV1_SHIFT,\n+\tPLL_FBDIV_SHIFT\t\t= 0,\n+\tPLL_FBDIV_MASK\t\t= 0xfff,\n+\n+\t/* PLLCON1 */\n+\tPLL_RST_SHIFT\t\t= 14,\n+\tPLL_PD_SHIFT\t\t= 13,\n+\tPLL_PD_MASK\t\t= 1 << PLL_PD_SHIFT,\n+\tPLL_DSMPD_SHIFT\t\t= 12,\n+\tPLL_DSMPD_MASK\t\t= 1 << PLL_DSMPD_SHIFT,\n+\tPLL_LOCK_STATUS_SHIFT\t= 10,\n+\tPLL_LOCK_STATUS_MASK\t= 1 << PLL_LOCK_STATUS_SHIFT,\n+\tPLL_POSTDIV2_SHIFT\t= 6,\n+\tPLL_POSTDIV2_MASK\t= 7 << PLL_POSTDIV2_SHIFT,\n+\tPLL_REFDIV_SHIFT\t= 0,\n+\tPLL_REFDIV_MASK\t\t= 0x3f,\n+\n+\t/* CRU_MODE */\n+\tGPLL_MODE_SHIFT\t\t= 12,\n+\tGPLL_MODE_MASK\t\t= 3 << GPLL_MODE_SHIFT,\n+\tGPLL_MODE_SLOW\t\t= 0,\n+\tGPLL_MODE_NORM,\n+\tGPLL_MODE_DEEP,\n+\tDPLL_MODE_SHIFT\t\t= 4,\n+\tDPLL_MODE_MASK\t\t= 1 << DPLL_MODE_SHIFT,\n+\tDPLL_MODE_SLOW\t\t= 0,\n+\tDPLL_MODE_NORM,\n+\tAPLL_MODE_SHIFT\t\t= 0,\n+\tAPLL_MODE_MASK\t\t= 1 << APLL_MODE_SHIFT,\n+\tAPLL_MODE_SLOW\t\t= 0,\n+\tAPLL_MODE_NORM,\n+\n+\t/* CRU_CLK_SEL0_CON */\n+\tBUS_ACLK_PLL_SEL_SHIFT\t= 14,\n+\tBUS_ACLK_PLL_SEL_MASK\t= 3 << BUS_ACLK_PLL_SEL_SHIFT,\n+\tBUS_ACLK_PLL_SEL_CPLL\t= 0,\n+\tBUS_ACLK_PLL_SEL_GPLL,\n+\tBUS_ACLK_PLL_SEL_GPLL_DIV2,\n+\tBUS_ACLK_PLL_SEL_GPLL_DIV3,\n+\tBUS_ACLK_DIV_SHIFT\t= 8,\n+\tBUS_ACLK_DIV_MASK\t= 0x1f << BUS_ACLK_DIV_SHIFT,\n+\tCORE_CLK_PLL_SEL_SHIFT\t= 7,\n+\tCORE_CLK_PLL_SEL_MASK\t= 1 << CORE_CLK_PLL_SEL_SHIFT,\n+\tCORE_CLK_PLL_SEL_APLL\t= 0,\n+\tCORE_CLK_PLL_SEL_GPLL_DIV2,\n+\tCORE_DIV_CON_SHIFT\t= 0,\n+\tCORE_DIV_CON_MASK\t= 0x1f << CORE_DIV_CON_SHIFT,\n+\n+\t/* CRU_CLK_SEL1_CON */\n+\tBUS_PCLK_DIV_SHIFT\t= 12,\n+\tBUS_PCLK_DIV_MASK\t= 7 << BUS_PCLK_DIV_SHIFT,\n+\tBUS_HCLK_DIV_SHIFT\t= 8,\n+\tBUS_HCLK_DIV_MASK\t= 3 << BUS_HCLK_DIV_SHIFT,\n+\tCORE_ACLK_DIV_SHIFT\t= 4,\n+\tCORE_ACLK_DIV_MASK\t= 7 << CORE_ACLK_DIV_SHIFT,\n+\tCORE_PERI_DIV_SHIFT\t= 0,\n+\tCORE_PERI_DIV_MASK\t= 0xf << CORE_PERI_DIV_SHIFT,\n+\n+\t/* CRU_CLKSEL10_CON */\n+\tPERI_PLL_SEL_SHIFT\t= 14,\n+\tPERI_PLL_SEL_MASK\t= 3 << PERI_PLL_SEL_SHIFT,\n+\tPERI_PLL_APLL\t\t= 0,\n+\tPERI_PLL_DPLL,\n+\tPERI_PLL_GPLL,\n+\tPERI_PCLK_DIV_SHIFT\t= 12,\n+\tPERI_PCLK_DIV_MASK\t= 3 << PERI_PCLK_DIV_SHIFT,\n+\tPERI_HCLK_DIV_SHIFT\t= 8,\n+\tPERI_HCLK_DIV_MASK\t= 3 << PERI_HCLK_DIV_SHIFT,\n+\tPERI_ACLK_DIV_SHIFT\t= 0,\n+\tPERI_ACLK_DIV_MASK\t= 0x1f << PERI_ACLK_DIV_SHIFT,\n+\n+\t/* CRU_CLKSEL11_CON */\n+\tMMC0_PLL_SHIFT\t\t= 6,\n+\tMMC0_PLL_MASK\t\t= 3 << MMC0_PLL_SHIFT,\n+\tMMC0_SEL_APLL\t\t= 0,\n+\tMMC0_SEL_GPLL,\n+\tMMC0_SEL_GPLL_DIV2,\n+\tMMC0_SEL_24M,\n+\tMMC0_DIV_SHIFT\t\t= 0,\n+\tMMC0_DIV_MASK\t\t= 0x3f << MMC0_DIV_SHIFT,\n+\n+\t/* CRU_CLKSEL12_CON */\n+\tEMMC_PLL_SHIFT\t\t= 14,\n+\tEMMC_PLL_MASK\t\t= 3 << EMMC_PLL_SHIFT,\n+\tEMMC_SEL_APLL\t\t= 0,\n+\tEMMC_SEL_GPLL,\n+\tEMMC_SEL_GPLL_DIV2,\n+\tEMMC_SEL_24M,\n+\tEMMC_DIV_SHIFT\t\t= 8,\n+\tEMMC_DIV_MASK\t\t= 0x3f << EMMC_DIV_SHIFT,\n+\n+\t/* CRU_SOFTRST5_CON */\n+\tDDRCTRL_PSRST_SHIFT\t= 11,\n+\tDDRCTRL_SRST_SHIFT\t= 10,\n+\tDDRPHY_PSRST_SHIFT\t= 9,\n+\tDDRPHY_SRST_SHIFT\t= 8,\n+};\n+#endif\ndiff --git a/arch/arm/mach-rockchip/rk3128/Makefile b/arch/arm/mach-rockchip/rk3128/Makefile\nindex 0f63d92..50e1117 100644\n--- a/arch/arm/mach-rockchip/rk3128/Makefile\n+++ b/arch/arm/mach-rockchip/rk3128/Makefile\n@@ -6,3 +6,4 @@\n \n obj-y += rk3128.o\n obj-y += syscon_rk3128.o\n+obj-y += clk_rk3128.o\ndiff --git a/arch/arm/mach-rockchip/rk3128/clk_rk3128.c b/arch/arm/mach-rockchip/rk3128/clk_rk3128.c\nnew file mode 100644\nindex 0000000..7ca5fd3\n--- /dev/null\n+++ b/arch/arm/mach-rockchip/rk3128/clk_rk3128.c\n@@ -0,0 +1,32 @@\n+/*\n+ * Copyright (c) 2017 Rockchip Electronics Co., Ltd\n+ *\n+ * SPDX-License-Identifier: GPL-2.0+\n+ */\n+\n+#include <common.h>\n+#include <dm.h>\n+#include <syscon.h>\n+#include <asm/arch/clock.h>\n+#include <asm/arch/cru_rk3128.h>\n+\n+int rockchip_get_clk(struct udevice **devp)\n+{\n+\treturn uclass_get_device_by_driver(UCLASS_CLK,\n+\t\t\tDM_GET_DRIVER(rockchip_rk3128_cru), devp);\n+}\n+\n+void *rockchip_get_cru(void)\n+{\n+\tstruct rk3128_clk_priv *priv;\n+\tstruct udevice *dev;\n+\tint ret;\n+\n+\tret = rockchip_get_clk(&dev);\n+\tif (ret)\n+\t\treturn ERR_PTR(ret);\n+\n+\tpriv = dev_get_priv(dev);\n+\n+\treturn priv->cru;\n+}\ndiff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile\nindex c50aff2..eae0ef6 100644\n--- a/drivers/clk/rockchip/Makefile\n+++ b/drivers/clk/rockchip/Makefile\n@@ -1,10 +1,11 @@\n #\n-# Copyright (c) 2016 Google, Inc\n+# Copyright (c) 2017 Rockchip Electronics Co., Ltd\n #\n # SPDX-License-Identifier: GPL-2.0+\n #\n \n obj-$(CONFIG_ROCKCHIP_RK3036) += clk_rk3036.o\n+obj-$(CONFIG_ROCKCHIP_RK3128) += clk_rk3128.o\n obj-$(CONFIG_ROCKCHIP_RK3188) += clk_rk3188.o\n obj-$(CONFIG_ROCKCHIP_RK322X) += clk_rk322x.o\n obj-$(CONFIG_ROCKCHIP_RK3288) += clk_rk3288.o\ndiff --git a/drivers/clk/rockchip/clk_rk3128.c b/drivers/clk/rockchip/clk_rk3128.c\nnew file mode 100644\nindex 0000000..ace154f\n--- /dev/null\n+++ b/drivers/clk/rockchip/clk_rk3128.c\n@@ -0,0 +1,350 @@\n+/*\n+ * (C) Copyright 2017 Rockchip Electronics Co., Ltd\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 <errno.h>\n+#include <syscon.h>\n+#include <asm/io.h>\n+#include <asm/arch/clock.h>\n+#include <asm/arch/cru_rk3128.h>\n+#include <asm/arch/hardware.h>\n+#include <dm/lists.h>\n+#include <dt-bindings/clock/rk3128-cru.h>\n+#include <linux/log2.h>\n+\n+DECLARE_GLOBAL_DATA_PTR;\n+\n+enum {\n+\tVCO_MAX_HZ\t= 2400U * 1000000,\n+\tVCO_MIN_HZ\t= 600 * 1000000,\n+\tOUTPUT_MAX_HZ\t= 2400U * 1000000,\n+\tOUTPUT_MIN_HZ\t= 24 * 1000000,\n+};\n+\n+#define DIV_TO_RATE(input_rate, div)\t((input_rate) / ((div) + 1))\n+\n+#define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\\\n+\t.refdiv = _refdiv,\\\n+\t.fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\\\n+\t.postdiv1 = _postdiv1, .postdiv2 = _postdiv2};\n+\n+/* use integer mode*/\n+static const struct pll_div apll_init_cfg = PLL_DIVISORS(APLL_HZ, 1, 3, 1);\n+static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 2, 2, 1);\n+\n+static int rkclk_set_pll(struct rk3128_cru *cru, enum rk_clk_id clk_id,\n+\t\t\t const struct pll_div *div)\n+{\n+\tint pll_id = rk_pll_id(clk_id);\n+\tstruct rk3128_pll *pll = &cru->pll[pll_id];\n+\n+\t/* All PLLs have same VCO and output frequency range restrictions. */\n+\tuint vco_hz = OSC_HZ / 1000 * div->fbdiv / div->refdiv * 1000;\n+\tuint output_hz = vco_hz / div->postdiv1 / div->postdiv2;\n+\n+\tdebug(\"PLL at %p:fd=%d,rd=%d,pd1=%d,pd2=%d,vco=%uHz,output=%uHz\\n\",\n+\t pll, div->fbdiv, div->refdiv, div->postdiv1,\n+\t div->postdiv2, vco_hz, output_hz);\n+\tassert(vco_hz >= VCO_MIN_HZ && vco_hz <= VCO_MAX_HZ &&\n+\t output_hz >= OUTPUT_MIN_HZ && output_hz <= OUTPUT_MAX_HZ);\n+\n+\t/* use integer mode */\n+\trk_setreg(&pll->con1, 1 << PLL_DSMPD_SHIFT);\n+\t/* Power down */\n+\trk_setreg(&pll->con1, 1 << PLL_PD_SHIFT);\n+\n+\trk_clrsetreg(&pll->con0,\n+\t\t PLL_POSTDIV1_MASK | PLL_FBDIV_MASK,\n+\t\t (div->postdiv1 << PLL_POSTDIV1_SHIFT) | div->fbdiv);\n+\trk_clrsetreg(&pll->con1, PLL_POSTDIV2_MASK | PLL_REFDIV_MASK,\n+\t\t (div->postdiv2 << PLL_POSTDIV2_SHIFT |\n+\t\t div->refdiv << PLL_REFDIV_SHIFT));\n+\n+\t/* Power Up */\n+\trk_clrreg(&pll->con1, 1 << PLL_PD_SHIFT);\n+\n+\t/* waiting for pll lock */\n+\twhile (readl(&pll->con1) & (1 << PLL_LOCK_STATUS_SHIFT))\n+\t\tudelay(1);\n+\n+\treturn 0;\n+}\n+\n+static void rkclk_init(struct rk3128_cru *cru)\n+{\n+\tu32 aclk_div;\n+\tu32 hclk_div;\n+\tu32 pclk_div;\n+\n+\t/* pll enter slow-mode */\n+\trk_clrsetreg(&cru->cru_mode_con,\n+\t\t GPLL_MODE_MASK | APLL_MODE_MASK,\n+\t\t GPLL_MODE_SLOW << GPLL_MODE_SHIFT |\n+\t\t APLL_MODE_SLOW << APLL_MODE_SHIFT);\n+\n+\t/* init pll */\n+\trkclk_set_pll(cru, CLK_ARM, &apll_init_cfg);\n+\trkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg);\n+\n+\t/*\n+\t * select apll as cpu/core clock pll source and\n+\t * set up dependent divisors for PERI and ACLK clocks.\n+\t * core hz : apll = 1:1\n+\t */\n+\taclk_div = APLL_HZ / CORE_ACLK_HZ - 1;\n+\tassert((aclk_div + 1) * CORE_ACLK_HZ == APLL_HZ && aclk_div < 0x7);\n+\n+\tpclk_div = APLL_HZ / CORE_PERI_HZ - 1;\n+\tassert((pclk_div + 1) * CORE_PERI_HZ == APLL_HZ && pclk_div < 0xf);\n+\n+\trk_clrsetreg(&cru->cru_clksel_con[0],\n+\t\t CORE_CLK_PLL_SEL_MASK | CORE_DIV_CON_MASK,\n+\t\t CORE_CLK_PLL_SEL_APLL << CORE_CLK_PLL_SEL_SHIFT |\n+\t\t 0 << CORE_DIV_CON_SHIFT);\n+\n+\trk_clrsetreg(&cru->cru_clksel_con[1],\n+\t\t CORE_ACLK_DIV_MASK | CORE_PERI_DIV_MASK,\n+\t\t aclk_div << CORE_ACLK_DIV_SHIFT |\n+\t\t pclk_div << CORE_PERI_DIV_SHIFT);\n+\n+\t/*\n+\t * select gpll as pd_bus bus clock source and\n+\t * set up dependent divisors for PCLK/HCLK and ACLK clocks.\n+\t */\n+\taclk_div = GPLL_HZ / BUS_ACLK_HZ - 1;\n+\tassert((aclk_div + 1) * BUS_ACLK_HZ == GPLL_HZ && aclk_div <= 0x1f);\n+\n+\tpclk_div = GPLL_HZ / BUS_PCLK_HZ - 1;\n+\tassert((pclk_div + 1) * BUS_PCLK_HZ == GPLL_HZ && pclk_div <= 0x7);\n+\n+\thclk_div = GPLL_HZ / BUS_HCLK_HZ - 1;\n+\tassert((hclk_div + 1) * BUS_HCLK_HZ == GPLL_HZ && hclk_div <= 0x3);\n+\n+\trk_clrsetreg(&cru->cru_clksel_con[0],\n+\t\t BUS_ACLK_PLL_SEL_MASK | BUS_ACLK_DIV_MASK,\n+\t\t BUS_ACLK_PLL_SEL_GPLL << BUS_ACLK_PLL_SEL_SHIFT |\n+\t\t aclk_div << BUS_ACLK_DIV_SHIFT);\n+\n+\trk_clrsetreg(&cru->cru_clksel_con[1],\n+\t\t BUS_PCLK_DIV_MASK | BUS_HCLK_DIV_MASK,\n+\t\t pclk_div << BUS_PCLK_DIV_SHIFT |\n+\t\t hclk_div << BUS_HCLK_DIV_SHIFT);\n+\n+\t/*\n+\t * select gpll as pd_peri bus clock source and\n+\t * set up dependent divisors for PCLK/HCLK and ACLK clocks.\n+\t */\n+\taclk_div = GPLL_HZ / PERI_ACLK_HZ - 1;\n+\tassert((aclk_div + 1) * PERI_ACLK_HZ == GPLL_HZ && aclk_div < 0x1f);\n+\n+\thclk_div = ilog2(PERI_ACLK_HZ / PERI_HCLK_HZ);\n+\tassert((1 << hclk_div) * PERI_HCLK_HZ ==\n+\t\tPERI_ACLK_HZ && (hclk_div < 0x4));\n+\n+\tpclk_div = ilog2(PERI_ACLK_HZ / PERI_PCLK_HZ);\n+\tassert((1 << pclk_div) * PERI_PCLK_HZ ==\n+\t\tPERI_ACLK_HZ && pclk_div < 0x8);\n+\n+\trk_clrsetreg(&cru->cru_clksel_con[10],\n+\t\t PERI_PLL_SEL_MASK | PERI_PCLK_DIV_MASK |\n+\t\t PERI_HCLK_DIV_MASK | PERI_ACLK_DIV_MASK,\n+\t\t PERI_PLL_GPLL << PERI_PLL_SEL_SHIFT |\n+\t\t pclk_div << PERI_PCLK_DIV_SHIFT |\n+\t\t hclk_div << PERI_HCLK_DIV_SHIFT |\n+\t\t aclk_div << PERI_ACLK_DIV_SHIFT);\n+\n+\t/* PLL enter normal-mode */\n+\trk_clrsetreg(&cru->cru_mode_con,\n+\t\t GPLL_MODE_MASK | APLL_MODE_MASK,\n+\t\t GPLL_MODE_NORM << GPLL_MODE_SHIFT |\n+\t\t APLL_MODE_NORM << APLL_MODE_SHIFT);\n+}\n+\n+/* Get pll rate by id */\n+static uint32_t rkclk_pll_get_rate(struct rk3128_cru *cru,\n+\t\t\t\t enum rk_clk_id clk_id)\n+{\n+\tuint32_t refdiv, fbdiv, postdiv1, postdiv2;\n+\tuint32_t con;\n+\tint pll_id = rk_pll_id(clk_id);\n+\tstruct rk3128_pll *pll = &cru->pll[pll_id];\n+\tstatic u8 clk_shift[CLK_COUNT] = {\n+\t\t0xff, APLL_MODE_SHIFT, DPLL_MODE_SHIFT, 0xff,\n+\t\tGPLL_MODE_SHIFT, 0xff\n+\t};\n+\tstatic u32 clk_mask[CLK_COUNT] = {\n+\t\t0xff, APLL_MODE_MASK, DPLL_MODE_MASK, 0xff,\n+\t\tGPLL_MODE_MASK, 0xff\n+\t};\n+\tuint shift;\n+\tuint mask;\n+\n+\tcon = readl(&cru->cru_mode_con);\n+\tshift = clk_shift[clk_id];\n+\tmask = clk_mask[clk_id];\n+\n+\tswitch ((con & mask) >> shift) {\n+\tcase GPLL_MODE_SLOW:\n+\t\treturn OSC_HZ;\n+\tcase GPLL_MODE_NORM:\n+\n+\t\t/* normal mode */\n+\t\tcon = readl(&pll->con0);\n+\t\tpostdiv1 = (con & PLL_POSTDIV1_MASK) >> PLL_POSTDIV1_SHIFT;\n+\t\tfbdiv = (con & PLL_FBDIV_MASK) >> PLL_FBDIV_SHIFT;\n+\t\tcon = readl(&pll->con1);\n+\t\tpostdiv2 = (con & PLL_POSTDIV2_MASK) >> PLL_POSTDIV2_SHIFT;\n+\t\trefdiv = (con & PLL_REFDIV_MASK) >> PLL_REFDIV_SHIFT;\n+\t\treturn (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;\n+\tcase GPLL_MODE_DEEP:\n+\tdefault:\n+\t\treturn 32768;\n+\t}\n+}\n+\n+static ulong rockchip_mmc_get_clk(struct rk3128_cru *cru, uint clk_general_rate,\n+\t\t\t\t int periph)\n+{\n+\tuint src_rate;\n+\tuint div, mux;\n+\tu32 con;\n+\n+\tswitch (periph) {\n+\tcase HCLK_EMMC:\n+\tcase SCLK_EMMC:\n+\tcase SCLK_EMMC_SAMPLE:\n+\t\tcon = readl(&cru->cru_clksel_con[12]);\n+\t\tmux = (con & EMMC_PLL_MASK) >> EMMC_PLL_SHIFT;\n+\t\tdiv = (con & EMMC_DIV_MASK) >> EMMC_DIV_SHIFT;\n+\t\tbreak;\n+\tcase HCLK_SDMMC:\n+\tcase SCLK_SDMMC:\n+\t\tcon = readl(&cru->cru_clksel_con[12]);\n+\t\tmux = (con & MMC0_PLL_MASK) >> MMC0_PLL_SHIFT;\n+\t\tdiv = (con & MMC0_DIV_MASK) >> MMC0_DIV_SHIFT;\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\n+\tsrc_rate = mux == EMMC_SEL_24M ? OSC_HZ : clk_general_rate;\n+\treturn DIV_TO_RATE(src_rate, div);\n+}\n+\n+static ulong rockchip_mmc_set_clk(struct rk3128_cru *cru, uint clk_general_rate,\n+\t\t\t\t int periph, uint freq)\n+{\n+\tint src_clk_div;\n+\tint mux;\n+\n+\tdebug(\"%s: clk_general_rate=%u\\n\", __func__, clk_general_rate);\n+\n+\t/* mmc clock defaulg div 2 internal, need provide double in cru */\n+\tsrc_clk_div = DIV_ROUND_UP(clk_general_rate / 2, freq);\n+\n+\tif (src_clk_div > 128) {\n+\t\tsrc_clk_div = DIV_ROUND_UP(OSC_HZ / 2, freq);\n+\t\tmux = EMMC_SEL_24M;\n+\t} else {\n+\t\tmux = EMMC_SEL_GPLL;\n+\t}\n+\n+\tswitch (periph) {\n+\tcase HCLK_EMMC:\n+\t\trk_clrsetreg(&cru->cru_clksel_con[12],\n+\t\t\t EMMC_PLL_MASK | EMMC_DIV_MASK,\n+\t\t\t mux << EMMC_PLL_SHIFT |\n+\t\t\t (src_clk_div - 1) << EMMC_DIV_SHIFT);\n+\t\tbreak;\n+\tcase HCLK_SDMMC:\n+\tcase SCLK_SDMMC:\n+\t\trk_clrsetreg(&cru->cru_clksel_con[11],\n+\t\t\t MMC0_PLL_MASK | MMC0_DIV_MASK,\n+\t\t\t mux << MMC0_PLL_SHIFT |\n+\t\t\t (src_clk_div - 1) << MMC0_DIV_SHIFT);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -EINVAL;\n+\t}\n+\n+\treturn rockchip_mmc_get_clk(cru, clk_general_rate, periph);\n+}\n+\n+static ulong rk3128_clk_get_rate(struct clk *clk)\n+{\n+\tstruct rk3128_clk_priv *priv = dev_get_priv(clk->dev);\n+\n+\tswitch (clk->id) {\n+\tcase 0 ... 63:\n+\t\treturn rkclk_pll_get_rate(priv->cru, clk->id);\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+}\n+\n+static ulong rk3128_clk_set_rate(struct clk *clk, ulong rate)\n+{\n+\tstruct rk3128_clk_priv *priv = dev_get_priv(clk->dev);\n+\tulong new_rate, gclk_rate;\n+\n+\tgclk_rate = rkclk_pll_get_rate(priv->cru, CLK_GENERAL);\n+\tswitch (clk->id) {\n+\tcase 0 ... 63:\n+\t\treturn 0;\n+\tcase HCLK_EMMC:\n+\t\tnew_rate = rockchip_mmc_set_clk(priv->cru, gclk_rate,\n+\t\t\t\t\t\tclk->id, rate);\n+\t\tbreak;\n+\tdefault:\n+\t\treturn -ENOENT;\n+\t}\n+\n+\treturn new_rate;\n+}\n+\n+static struct clk_ops rk3128_clk_ops = {\n+\t.get_rate\t= rk3128_clk_get_rate,\n+\t.set_rate\t= rk3128_clk_set_rate,\n+};\n+\n+static int rk3128_clk_probe(struct udevice *dev)\n+{\n+\tstruct rk3128_clk_priv *priv = dev_get_priv(dev);\n+\n+\tpriv->cru = (struct rk3128_cru *)devfdt_get_addr(dev);\n+\trkclk_init(priv->cru);\n+\n+\treturn 0;\n+}\n+\n+static int rk3128_clk_bind(struct udevice *dev)\n+{\n+\tint ret;\n+\n+\t/* The reset driver does not have a device node, so bind it here */\n+\tret = device_bind_driver(gd->dm_root, \"rk3128_sysreset\", \"reset\", &dev);\n+\tif (ret)\n+\t\tdebug(\"Warning: No RK3128 reset driver: ret=%d\\n\", ret);\n+\n+\treturn 0;\n+}\n+\n+static const struct udevice_id rk3128_clk_ids[] = {\n+\t{ .compatible = \"rockchip,rk3128-cru\" },\n+\t{ }\n+};\n+\n+U_BOOT_DRIVER(rockchip_rk3128_cru) = {\n+\t.name\t\t= \"clk_rk3128\",\n+\t.id\t\t= UCLASS_CLK,\n+\t.of_match\t= rk3128_clk_ids,\n+\t.priv_auto_alloc_size = sizeof(struct rk3128_clk_priv),\n+\t.ops\t\t= &rk3128_clk_ops,\n+\t.bind\t\t= rk3128_clk_bind,\n+\t.probe\t\t= rk3128_clk_probe,\n+};\n", "prefixes": [ "U-Boot", "3/8" ] }