From patchwork Fri Oct 8 15:43:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Protsenko X-Patchwork-Id: 515576 Delivered-To: patch@linaro.org Received: by 2002:adf:fbc8:0:0:0:0:0 with SMTP id d8csp3044679wrs; Fri, 8 Oct 2021 08:44:06 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzNwE+pwkZYCasMG8aSnOVzWX2uR45bTxIQlfgoGstVZ8MjlwzLqLnTSpbXC/4I6QfsMYil X-Received: by 2002:a17:903:124f:b0:13e:25e6:f733 with SMTP id u15-20020a170903124f00b0013e25e6f733mr9952751plh.42.1633707846499; Fri, 08 Oct 2021 08:44:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1633707846; cv=none; d=google.com; s=arc-20160816; b=dvXJFJQKLR3sg94tEZjnZpTJL+uHkedikz8qDiqm0uFYfR3Y3GlZ/KwjNVT0kzY4/I Skn9jPvRG0a2tpMG1hv8A3gpIZP0syO+hP8Jjt8arASaXH0Jg/cQaTIBt5oCOTsHTWC0 s8x7VePpAck8UBckp+hFubetx+Sl/NGicTx/4fENlik50CyEXYj16nVV3guVaKAXNGrT i2PN3jwla/Lewtynu4QDjoOnCxCEpIg6AHeD2Fabizt/0d/sPkIVwoIj/WxABGCI7qnQ Ixan7mRfI0WcU1/g5fP2JjE9vXkBwNylYcLtdgjwxaUpfBxPcVWqOreIIaKhsPWiFKzb d2FQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=VxxLufFz8LSGyDkzHDaRKQ8X1sXY/c0Ny6fFIjRH6DM=; b=DRbeEWJi/WG1zPl1hpASFQo2abn/Ff6fuGaBs4MMtadA7T9ZPkAU9hFlzcawu4MVsa IgrrWdO01LdDvRPdOpHfUY2yQ/iOiQgApAcL3H2kKR7QE/p+xOdQO4dO1MIifLy5+fPS S1rk/7u4Jv/ub2F++K2qvppRBmvrc29FUFipqlFOe58FB11En+E3gRrFwW/+J2egp5cu LyWabVBPZoysO1qunnHyTiBNXv9k7Zc0OQzj4bWh2vCTsuSdXRjpVX1IFMP+yyLr9yiK +KxqbwrbcZAzITtNiBtr/BS3OUYgkpK9kYNBe5hrWB9jw4TXgZvaYsQRsGkCNR6j3GB9 Yj4A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ZpGolWIT; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id mw9si3741521pjb.55.2021.10.08.08.44.06; Fri, 08 Oct 2021 08:44:06 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=ZpGolWIT; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243213AbhJHPp6 (ORCPT + 7 others); Fri, 8 Oct 2021 11:45:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36054 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243148AbhJHPpx (ORCPT ); Fri, 8 Oct 2021 11:45:53 -0400 Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EBD8CC061765 for ; Fri, 8 Oct 2021 08:43:57 -0700 (PDT) Received: by mail-ed1-x534.google.com with SMTP id v18so38435484edc.11 for ; Fri, 08 Oct 2021 08:43:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=VxxLufFz8LSGyDkzHDaRKQ8X1sXY/c0Ny6fFIjRH6DM=; b=ZpGolWITvvQjVxyHaYF0SpF/qbZLAaMeX5IPa2qgMm8xWINpdCjFe3JrbixLU9nNCe KGMIuZuCsaMoO9OYIfJXyQr4AmXaDixScrRn7KYTD4halgNgEhapFnFkUIWFq0P/2KoJ EC4DulvwZxX+1FCYfy9/7Cu3kmaDyNzClrtjA6THPXo0Z8EMyMnIfsu1nJj9Rex5lHzK y5yo0b2rcfKB5YekYssIQFerD5YyeciDhOcdSNe/ob0ZcKlMG6AA55nN0aYocDYErjSz UFPyARt21IqNPv65PQPe6vK+matic6WgkkBPaFPnvfmq2gVo6FJ7PIDHp1VXSlUyINbP 1rzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=VxxLufFz8LSGyDkzHDaRKQ8X1sXY/c0Ny6fFIjRH6DM=; b=voTB2Knc+3QS8E0Vz/SDJXvue5tSka/x2ZH8ocaamp7lq1el15W5XcH5idNdlyGONa kqbzX+Mwb/07O4ImwcvmKXMvnzRExq8B1PY3k46Qxnlny9PO0Z7m1s9grUhWVUHPcwGz VzwUgNkjyhTExxtg0X6599lJiWYBLWBvLcsxtTNgClLfMmmDvSt9kQzk+VffCduOjyKR krB2t3TcVhEYTZPde2+omo9xSOSRUyZZ6gcI+GHfZHDSAn32DFckKQlD4Ppo/UMO3P0y iDW7hTK+ZX4kdqIbYcJOvM0BvfGCjsNFcwt5WHbFf0XhSs43hEMHEGn/mjOJYwPWHkGp LcRQ== X-Gm-Message-State: AOAM531izFti8Y7RBc6UGaB8J1d1bexBdUcjdvlsUedl6Fl0bCL0jPDv oL/cEpQyuxZm97Q1/fQbif9Dah/wo42hsVcz X-Received: by 2002:a05:6402:1d55:: with SMTP id dz21mr3727528edb.164.1633707836543; Fri, 08 Oct 2021 08:43:56 -0700 (PDT) Received: from localhost ([31.134.121.151]) by smtp.gmail.com with ESMTPSA id fx4sm1066209ejb.113.2021.10.08.08.43.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 08 Oct 2021 08:43:55 -0700 (PDT) From: Sam Protsenko To: Krzysztof Kozlowski , Sylwester Nawrocki , =?utf-8?q?Pawe=C5=82_Chmiel?= , Chanwoo Choi , Tomasz Figa , Rob Herring , Stephen Boyd , Michael Turquette Cc: Ryu Euiyoul , Tom Gall , Sumit Semwal , John Stultz , Amit Pundir , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, linux-samsung-soc@vger.kernel.org Subject: [PATCH v3 1/5] clk: samsung: clk-pll: Implement pll0822x PLL type Date: Fri, 8 Oct 2021 18:43:48 +0300 Message-Id: <20211008154352.19519-2-semen.protsenko@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211008154352.19519-1-semen.protsenko@linaro.org> References: <20211008154352.19519-1-semen.protsenko@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org pll0822x PLL is used in Exynos850 SoC for top-level integer PLLs. The code was derived from very similar pll35xx type, with next differences: 1. Lock time for pll0822x is 150*P_DIV, when for pll35xx it's 270*P_DIV 2. It's not suggested in Exynos850 TRM that S_DIV change doesn't require performing PLL lock procedure (which is done in pll35xx implementation) When defining pll0822x type, CON3 register offset should be provided as a "con" parameter of PLL() macro, like this: PLL(pll_0822x, 0, "fout_shared0_pll", "oscclk", PLL_LOCKTIME_PLL_SHARED0, PLL_CON3_PLL_SHARED0, exynos850_shared0_pll_rates), To define PLL rates table, one can use PLL_35XX_RATE() macro, e.g.: PLL_35XX_RATE(26 * MHZ, 1600 * MHZ, 800, 13, 0) as it's completely appropriate for pl0822x type and there is no sense in duplicating that. If bit #1 (MANUAL_PLL_CTRL) is not set in CON1 register, it won't be possible to set new rate, with next error showing in kernel log: Could not lock PLL fout_shared1_pll That can happen for example if bootloader clears that bit beforehand. PLL driver doesn't account for that, so if MANUAL_PLL_CTRL bit was cleared, it's assumed it was done for a reason and it shouldn't be possible to change that PLL's rate at all. Signed-off-by: Sam Protsenko Reviewed-by: Krzysztof Kozlowski Acked-by: Chanwoo Choi --- Changes in v3: - (none) Changes in v2: - Added R-b tag by Krzysztof Kozlowski - Added Ack tag by Chanwoo Choi drivers/clk/samsung/clk-pll.c | 91 +++++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk-pll.h | 1 + 2 files changed, 92 insertions(+) -- 2.30.2 diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 5873a9354b50..03131b149c0b 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -415,6 +415,89 @@ static const struct clk_ops samsung_pll36xx_clk_min_ops = { .recalc_rate = samsung_pll36xx_recalc_rate, }; +/* + * PLL0822x Clock Type + */ +/* Maximum lock time can be 150 * PDIV cycles */ +#define PLL0822X_LOCK_FACTOR (150) + +#define PLL0822X_MDIV_MASK (0x3FF) +#define PLL0822X_PDIV_MASK (0x3F) +#define PLL0822X_SDIV_MASK (0x7) +#define PLL0822X_MDIV_SHIFT (16) +#define PLL0822X_PDIV_SHIFT (8) +#define PLL0822X_SDIV_SHIFT (0) +#define PLL0822X_LOCK_STAT_SHIFT (29) +#define PLL0822X_ENABLE_SHIFT (31) + +static unsigned long samsung_pll0822x_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct samsung_clk_pll *pll = to_clk_pll(hw); + u32 mdiv, pdiv, sdiv, pll_con3; + u64 fvco = parent_rate; + + pll_con3 = readl_relaxed(pll->con_reg); + mdiv = (pll_con3 >> PLL0822X_MDIV_SHIFT) & PLL0822X_MDIV_MASK; + pdiv = (pll_con3 >> PLL0822X_PDIV_SHIFT) & PLL0822X_PDIV_MASK; + sdiv = (pll_con3 >> PLL0822X_SDIV_SHIFT) & PLL0822X_SDIV_MASK; + + fvco *= mdiv; + do_div(fvco, (pdiv << sdiv)); + + return (unsigned long)fvco; +} + +static int samsung_pll0822x_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long prate) +{ + const struct samsung_pll_rate_table *rate; + struct samsung_clk_pll *pll = to_clk_pll(hw); + u32 pll_con3; + + /* Get required rate settings from table */ + rate = samsung_get_pll_settings(pll, drate); + if (!rate) { + pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, + drate, clk_hw_get_name(hw)); + return -EINVAL; + } + + /* Change PLL PMS values */ + pll_con3 = readl_relaxed(pll->con_reg); + pll_con3 &= ~((PLL0822X_MDIV_MASK << PLL0822X_MDIV_SHIFT) | + (PLL0822X_PDIV_MASK << PLL0822X_PDIV_SHIFT) | + (PLL0822X_SDIV_MASK << PLL0822X_SDIV_SHIFT)); + pll_con3 |= (rate->mdiv << PLL0822X_MDIV_SHIFT) | + (rate->pdiv << PLL0822X_PDIV_SHIFT) | + (rate->sdiv << PLL0822X_SDIV_SHIFT); + + /* Set PLL lock time */ + writel_relaxed(rate->pdiv * PLL0822X_LOCK_FACTOR, + pll->lock_reg); + + /* Write PMS values */ + writel_relaxed(pll_con3, pll->con_reg); + + /* Wait for PLL lock if the PLL is enabled */ + if (pll_con3 & BIT(pll->enable_offs)) + return samsung_pll_lock_wait(pll, BIT(pll->lock_offs)); + + return 0; +} + +static const struct clk_ops samsung_pll0822x_clk_ops = { + .recalc_rate = samsung_pll0822x_recalc_rate, + .round_rate = samsung_pll_round_rate, + .set_rate = samsung_pll0822x_set_rate, + .enable = samsung_pll3xxx_enable, + .disable = samsung_pll3xxx_disable, +}; + +static const struct clk_ops samsung_pll0822x_clk_min_ops = { + .recalc_rate = samsung_pll0822x_recalc_rate, +}; + /* * PLL45xx Clock Type */ @@ -1296,6 +1379,14 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, else init.ops = &samsung_pll35xx_clk_ops; break; + case pll_0822x: + pll->enable_offs = PLL0822X_ENABLE_SHIFT; + pll->lock_offs = PLL0822X_LOCK_STAT_SHIFT; + if (!pll->rate_table) + init.ops = &samsung_pll0822x_clk_min_ops; + else + init.ops = &samsung_pll0822x_clk_ops; + break; case pll_4500: init.ops = &samsung_pll45xx_clk_min_ops; break; diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h index 79e41c226b90..213e94a97f23 100644 --- a/drivers/clk/samsung/clk-pll.h +++ b/drivers/clk/samsung/clk-pll.h @@ -36,6 +36,7 @@ enum samsung_pll_type { pll_1451x, pll_1452x, pll_1460x, + pll_0822x, }; #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \ From patchwork Fri Oct 8 15:43:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Protsenko X-Patchwork-Id: 515578 Delivered-To: patch@linaro.org Received: by 2002:adf:fbc8:0:0:0:0:0 with SMTP id d8csp3044748wrs; Fri, 8 Oct 2021 08:44:09 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxuTdm3OhpAcwASUMhJARdwnIYZozpJ86bIIUGBjnEFLNKKngo+LGt4nQmsJIy3DF4UNmkc X-Received: by 2002:a17:902:6f02:b0:13e:5dce:eb9e with SMTP id w2-20020a1709026f0200b0013e5dceeb9emr10337014plk.64.1633707849168; Fri, 08 Oct 2021 08:44:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1633707849; cv=none; d=google.com; s=arc-20160816; b=KD4nz05h0H/v2YL+Xyx8dFlhnlJhefeqTkCyZl9bAYojSEHVy02FPH+Q4BUg5vCea5 twwEPWCtj4LyWGqU2ceWKoy91XZi0OJe807rBjhgJbvvDa0um7yNWEaMV838XIHnB/ZI cFWjVYymLE+MLJQanZCAfbKhjd/wFCQC7LHYibILEcSm3SVUAUk6flPKedyzGVFi91ku TJqpxriIXeo4SKfeXMZ3HJ3fuWWcGwUfuZ3oM/42yoK78u5qSylBZuFIvpjX8vikLLlj PZnDHUscnl7EIynDCbw/VprL8e4PSHs4CWZ/c3KjkgvE3hT52wta6ddSlKv/F7X28czc N4Pg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=chYv1ePzDELqnhmYHQGPQeqr7+We1a2rp4WTbrbwbgM=; b=teLlYRGAuXl3+1S3IJMk1KdOK9z80rEYfedJjXUUsR83IxTrKc7+F7XQjB512QtQwa 8GZJnYJwQ9aoGBlb74q0+Y3Ue0lS6ioI2N9w5WokMnfYidod4atp75vlW7r0444DPVt/ 7Jqt1K2VXvRKKfA7JU68kFSlJWL+StsdUY5By/0f6Kz7NJTMjo0949wa2mGMGlfnnfjr 4VHSS3mkczfm6DWUGt3KlxUb2acQOB2HR4Tkvz77fFHY0i9nvHHypjIdbXqZ7y7U2+4x xyHwDrArpFAV7zMmom3/iynzbGBq0+68CHn0JDohOv0lHw4pKSaeTcEu1eJWkmoTb74F oL/w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=N7s40XLV; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id mw9si3741521pjb.55.2021.10.08.08.44.08; Fri, 08 Oct 2021 08:44:09 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=N7s40XLV; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243092AbhJHPqB (ORCPT + 7 others); Fri, 8 Oct 2021 11:46:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36086 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243078AbhJHPp5 (ORCPT ); Fri, 8 Oct 2021 11:45:57 -0400 Received: from mail-ed1-x52b.google.com (mail-ed1-x52b.google.com [IPv6:2a00:1450:4864:20::52b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B9006C061755 for ; Fri, 8 Oct 2021 08:44:01 -0700 (PDT) Received: by mail-ed1-x52b.google.com with SMTP id i20so21741796edj.10 for ; Fri, 08 Oct 2021 08:44:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=chYv1ePzDELqnhmYHQGPQeqr7+We1a2rp4WTbrbwbgM=; b=N7s40XLVAmQqccqKzun56sKA+k+715zFx8pZHxZykM4NvO5GgM84W94pFj2LHBKylt rGg9ZvzXWk4GPNMokPni6rQ5tI3N06kIwNC+/U8W9ZjpsYqfTBE+7mzr0jOaPhHe50cV uVhtuBj4Y7Rcu3qOLtfseI5bf0Cd+1nXhRtzZ/ktiB/OVbxM7bbaBnfPfDAHBnD0OfIk EPW84tRZtRFh+DwdfaxAwnN7OgfZ9jL4izgp506aaVBsJbzkhNrN1ipdoPaZ0x52W5LC UTHYyWHZmlsU4Wjkl3pVGA5r/tgRp3P+TpukB8LdzVCAuiln7PxMVLRQwiDvkAXgnjpX x1Zw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=chYv1ePzDELqnhmYHQGPQeqr7+We1a2rp4WTbrbwbgM=; b=P8DczsZ/ZnNuIbDTe+xW5i4pAVPUDJfclK5AsUwqzB1Wc2IdmPRm1DYfuVKyt+jawD srDYpD6dBGBL4uyJXvr6ColDhpPRyVOKL0HaHKEnjRZtHlrziYOET63tis/yom0lAzzW Iiao7kGdjyHyJ+WLcg7DaOP4XVuPE9ziGf6PGAQ85+msbPX0DAdW8Keo5mJ4NIefje90 1he3ChNSbW67CJd7ojtYjfHdWp6mLwfaKkshsBIMRehD6Z5jngZx8mLKkNXRgLsF/3Sh MgSHZgJUdBZQqVzAb9dg7Wp4KX+/3DMqJ+ssKe5QJLJZoyPkFCG1HrKBa0GmNizsi7pa 8m/Q== X-Gm-Message-State: AOAM530HFxob43c6qPx/rzMRmPH7IkCT5tIGNY1/BT7z0or0dB/cOiiO z6ylouhsM4aaiDYw2RKVhiBk4A== X-Received: by 2002:a05:6402:1d2b:: with SMTP id dh11mr15725225edb.276.1633707840177; Fri, 08 Oct 2021 08:44:00 -0700 (PDT) Received: from localhost ([31.134.121.151]) by smtp.gmail.com with ESMTPSA id e11sm1225342edl.70.2021.10.08.08.43.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 08 Oct 2021 08:43:59 -0700 (PDT) From: Sam Protsenko To: Krzysztof Kozlowski , Sylwester Nawrocki , =?utf-8?q?Pawe=C5=82_Chmiel?= , Chanwoo Choi , Tomasz Figa , Rob Herring , Stephen Boyd , Michael Turquette Cc: Ryu Euiyoul , Tom Gall , Sumit Semwal , John Stultz , Amit Pundir , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, linux-samsung-soc@vger.kernel.org Subject: [PATCH v3 3/5] dt-bindings: clock: Add bindings definitions for Exynos850 CMU Date: Fri, 8 Oct 2021 18:43:50 +0300 Message-Id: <20211008154352.19519-4-semen.protsenko@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211008154352.19519-1-semen.protsenko@linaro.org> References: <20211008154352.19519-1-semen.protsenko@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Clock controller driver is designed to have separate instances for each particular CMU. So clock IDs in this bindings header also start from 1 for each CMU. Signed-off-by: Sam Protsenko Reviewed-by: Krzysztof Kozlowski Acked-by: Rob Herring --- Changes in v3: - Changed the license to GPL-2.0-only + BSD-2-Clause Changes in v2: - Added all clock ids - Added CLK_ prefix for all clock constants - Added R-b tag by Krzysztof Kozlowski - Added Ack tag by Rob Herring include/dt-bindings/clock/exynos850.h | 141 ++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 include/dt-bindings/clock/exynos850.h -- 2.30.2 diff --git a/include/dt-bindings/clock/exynos850.h b/include/dt-bindings/clock/exynos850.h new file mode 100644 index 000000000000..8999184f94a2 --- /dev/null +++ b/include/dt-bindings/clock/exynos850.h @@ -0,0 +1,141 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2021 Linaro Ltd. + * Author: Sam Protsenko + * + * Device Tree binding constants for Exynos850 clock controller. + */ + +#ifndef _DT_BINDINGS_CLOCK_EXYNOS_850_H +#define _DT_BINDINGS_CLOCK_EXYNOS_850_H + +/* CMU_TOP */ +#define CLK_FOUT_SHARED0_PLL 1 +#define CLK_FOUT_SHARED1_PLL 2 +#define CLK_FOUT_MMC_PLL 3 +#define CLK_MOUT_SHARED0_PLL 4 +#define CLK_MOUT_SHARED1_PLL 5 +#define CLK_MOUT_MMC_PLL 6 +#define CLK_MOUT_CORE_BUS 7 +#define CLK_MOUT_CORE_CCI 8 +#define CLK_MOUT_CORE_MMC_EMBD 9 +#define CLK_MOUT_CORE_SSS 10 +#define CLK_MOUT_DPU 11 +#define CLK_MOUT_HSI_BUS 12 +#define CLK_MOUT_HSI_MMC_CARD 13 +#define CLK_MOUT_HSI_USB20DRD 14 +#define CLK_MOUT_PERI_BUS 15 +#define CLK_MOUT_PERI_UART 16 +#define CLK_MOUT_PERI_IP 17 +#define CLK_DOUT_SHARED0_DIV3 18 +#define CLK_DOUT_SHARED0_DIV2 19 +#define CLK_DOUT_SHARED1_DIV3 20 +#define CLK_DOUT_SHARED1_DIV2 21 +#define CLK_DOUT_SHARED0_DIV4 22 +#define CLK_DOUT_SHARED1_DIV4 23 +#define CLK_DOUT_CORE_BUS 24 +#define CLK_DOUT_CORE_CCI 25 +#define CLK_DOUT_CORE_MMC_EMBD 26 +#define CLK_DOUT_CORE_SSS 27 +#define CLK_DOUT_DPU 28 +#define CLK_DOUT_HSI_BUS 29 +#define CLK_DOUT_HSI_MMC_CARD 30 +#define CLK_DOUT_HSI_USB20DRD 31 +#define CLK_DOUT_PERI_BUS 32 +#define CLK_DOUT_PERI_UART 33 +#define CLK_DOUT_PERI_IP 34 +#define CLK_GOUT_CORE_BUS 35 +#define CLK_GOUT_CORE_CCI 36 +#define CLK_GOUT_CORE_MMC_EMBD 37 +#define CLK_GOUT_CORE_SSS 38 +#define CLK_GOUT_DPU 39 +#define CLK_GOUT_HSI_BUS 40 +#define CLK_GOUT_HSI_MMC_CARD 41 +#define CLK_GOUT_HSI_USB20DRD 42 +#define CLK_GOUT_PERI_BUS 43 +#define CLK_GOUT_PERI_UART 44 +#define CLK_GOUT_PERI_IP 45 +#define TOP_NR_CLK 46 + +/* CMU_HSI */ +#define CLK_MOUT_HSI_BUS_USER 1 +#define CLK_MOUT_HSI_MMC_CARD_USER 2 +#define CLK_MOUT_HSI_USB20DRD_USER 3 +#define CLK_MOUT_HSI_RTC 4 +#define CLK_GOUT_USB_RTC_CLK 5 +#define CLK_GOUT_USB_REF_CLK 6 +#define CLK_GOUT_USB_PHY_REF_CLK 7 +#define CLK_GOUT_USB_PHY_ACLK 8 +#define CLK_GOUT_USB_BUS_EARLY_CLK 9 +#define CLK_GOUT_GPIO_HSI_PCLK 10 +#define CLK_GOUT_MMC_CARD_ACLK 11 +#define CLK_GOUT_MMC_CARD_SDCLKIN 12 +#define CLK_GOUT_SYSREG_HSI_PCLK 13 +#define HSI_NR_CLK 14 + +/* CMU_PERI */ +#define CLK_MOUT_PERI_BUS_USER 1 +#define CLK_MOUT_PERI_UART_USER 2 +#define CLK_MOUT_PERI_HSI2C_USER 3 +#define CLK_MOUT_PERI_SPI_USER 4 +#define CLK_DOUT_PERI_HSI2C0 5 +#define CLK_DOUT_PERI_HSI2C1 6 +#define CLK_DOUT_PERI_HSI2C2 7 +#define CLK_DOUT_PERI_SPI0 8 +#define CLK_GOUT_PERI_HSI2C0 9 +#define CLK_GOUT_PERI_HSI2C1 10 +#define CLK_GOUT_PERI_HSI2C2 11 +#define CLK_GOUT_GPIO_PERI_PCLK 12 +#define CLK_GOUT_HSI2C0_IPCLK 13 +#define CLK_GOUT_HSI2C0_PCLK 14 +#define CLK_GOUT_HSI2C1_IPCLK 15 +#define CLK_GOUT_HSI2C1_PCLK 16 +#define CLK_GOUT_HSI2C2_IPCLK 17 +#define CLK_GOUT_HSI2C2_PCLK 18 +#define CLK_GOUT_I2C0_PCLK 19 +#define CLK_GOUT_I2C1_PCLK 20 +#define CLK_GOUT_I2C2_PCLK 21 +#define CLK_GOUT_I2C3_PCLK 22 +#define CLK_GOUT_I2C4_PCLK 23 +#define CLK_GOUT_I2C5_PCLK 24 +#define CLK_GOUT_I2C6_PCLK 25 +#define CLK_GOUT_MCT_PCLK 26 +#define CLK_GOUT_PWM_MOTOR_PCLK 27 +#define CLK_GOUT_SPI0_IPCLK 28 +#define CLK_GOUT_SPI0_PCLK 29 +#define CLK_GOUT_SYSREG_PERI_PCLK 30 +#define CLK_GOUT_UART_IPCLK 31 +#define CLK_GOUT_UART_PCLK 32 +#define CLK_GOUT_WDT0_PCLK 33 +#define CLK_GOUT_WDT1_PCLK 34 +#define PERI_NR_CLK 35 + +/* CMU_CORE */ +#define CLK_MOUT_CORE_BUS_USER 1 +#define CLK_MOUT_CORE_CCI_USER 2 +#define CLK_MOUT_CORE_MMC_EMBD_USER 3 +#define CLK_MOUT_CORE_SSS_USER 4 +#define CLK_MOUT_CORE_GIC 5 +#define CLK_DOUT_CORE_BUSP 6 +#define CLK_GOUT_CCI_ACLK 7 +#define CLK_GOUT_GIC_CLK 8 +#define CLK_GOUT_MMC_EMBD_ACLK 9 +#define CLK_GOUT_MMC_EMBD_SDCLKIN 10 +#define CLK_GOUT_SSS_ACLK 11 +#define CLK_GOUT_SSS_PCLK 12 +#define CORE_NR_CLK 13 + +/* CMU_DPU */ +#define CLK_MOUT_DPU_USER 1 +#define CLK_DOUT_DPU_BUSP 2 +#define CLK_GOUT_DPU_CMU_DPU_PCLK 3 +#define CLK_GOUT_DPU_DECON0_ACLK 4 +#define CLK_GOUT_DPU_DMA_ACLK 5 +#define CLK_GOUT_DPU_DPP_ACLK 6 +#define CLK_GOUT_DPU_PPMU_ACLK 7 +#define CLK_GOUT_DPU_PPMU_PCLK 8 +#define CLK_GOUT_DPU_SMMU_CLK 9 +#define CLK_GOUT_DPU_SYSREG_PCLK 10 +#define DPU_NR_CLK 11 + +#endif /* _DT_BINDINGS_CLOCK_EXYNOS_850_H */ From patchwork Fri Oct 8 15:43:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Protsenko X-Patchwork-Id: 515579 Delivered-To: patch@linaro.org Received: by 2002:adf:fbc8:0:0:0:0:0 with SMTP id d8csp3044767wrs; Fri, 8 Oct 2021 08:44:10 -0700 (PDT) X-Google-Smtp-Source: ABdhPJx7Tm0tnXqzDYnfNC2pLCohOK3CMJNFY+4hsIpK7P7tia3X+by4WgBLfrnfofC+N7YknQ09 X-Received: by 2002:aa7:9250:0:b0:44c:27d1:7f0f with SMTP id 16-20020aa79250000000b0044c27d17f0fmr11028121pfp.41.1633707850330; Fri, 08 Oct 2021 08:44:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1633707850; cv=none; d=google.com; s=arc-20160816; b=EMMhblh6ZPAf861kjqJeD1l8mV/WdO3IM2bSadeW+ZCr+j6IE81gONV9tovTSGzl/M i4MIB9TX1SdvisWQAF2K6ki3Oa/J9AmVRuEJ7DGouNlYx4JQwMgkYJ6vL83LN3wyO64G fp0tHd1CJ8U9naxF/+e/940Cq+sQ5i5Hh88IPjLnS/7JNWHLJ+rAWCJnDdPmrNoX51ib TqsEQ1JAQPOUkRpdn0vBb92+G3uiXGO+v8gNpIOgsHir5e9jUcEjaBG6tAQ6Szjugzc4 QJrBaInHjQJbsMHbbiqwLIxPu4kku0m4ZFF2l2lqtBBggBNHXAqLgE/54q6izp6uGR3+ xqxg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=2WVtOa8/GOzyCMHZHw3G3dz8qp2GM3aiIOxGFUb6CZI=; b=hHNqO1+o81gWVffO8FRfg8vOJFzUWD5zN2zKIB/8iG1Xy0c89KJgw+cGO1LSFRBDT5 dOSgG2b2qvhppLIFV0gB47JlTOlYrjKTjgerx2LB9L6QDaFHW9bHAbfMEFI2Xn3bO7Y4 K6ssYunISyZrHkCebtJSpoOi3FEv+Jbe2RfWeFaKsmwrkV1R1dVz8+1jYsDM6wwGUE5c 2Iwy81ZSUrxJiLTboTnB/9dyLyakyVpvHQWHeqXptSQkfk+1z44xSalvM/sLoh3EcMH9 CsycTrKx5WEdU0YBXzBpNRHaa2X7/PmiFs9BXmnNk/Z97MVw+zztSL3jxTCVH98WjsY7 tUHw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=rjiCGvNC; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id mw9si3741521pjb.55.2021.10.08.08.44.10; Fri, 08 Oct 2021 08:44:10 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=rjiCGvNC; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243300AbhJHPqC (ORCPT + 7 others); Fri, 8 Oct 2021 11:46:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36074 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243287AbhJHPp6 (ORCPT ); Fri, 8 Oct 2021 11:45:58 -0400 Received: from mail-ed1-x535.google.com (mail-ed1-x535.google.com [IPv6:2a00:1450:4864:20::535]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 317CBC061766 for ; Fri, 8 Oct 2021 08:44:03 -0700 (PDT) Received: by mail-ed1-x535.google.com with SMTP id z20so37777405edc.13 for ; Fri, 08 Oct 2021 08:44:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=2WVtOa8/GOzyCMHZHw3G3dz8qp2GM3aiIOxGFUb6CZI=; b=rjiCGvNCz1e9F2IvQ7r8R+u4jQKWW5Ldlkx2zdPR9LHBYyd1VT356cX4tK9xzACwCB TV/uOQjJjpTGwg4JDq1gnsg7EutXuw395l6t2M+MyKheQSAHmsz9uBJOT+CK++XbF3nE L3BkQ6dIBsp+O2/zxjNV+OtikPUqgd25NtWU9xDoYXE8k4Bx3zJJpFJccJeDLqq+qilE zYJP2k0FVV4pftje/Vgun55hEk8U9zAPQvX8M6ks66LuOFHNEsXbohKwtI94gf2jdw7a fgSqz5eKCUxcLEDCfU63U4XvT++j5+i5lP/kdNBEtzGc1G69zImcuWSARa5YPSsqrcLu YQvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=2WVtOa8/GOzyCMHZHw3G3dz8qp2GM3aiIOxGFUb6CZI=; b=6QgUpAV4gYPI9pTgEPbWyJE0H2GHe3XtP8iYor0fstEoqVQQuittPjr4la3yzZZKhE l+CQR9nWBg8X7EJlc0g+E+xOA4NvOfFZ7ztOzOv7XQO9CsIc+9DrXVAh29sumuyjGGAG Y9jEzovVNLV2OwLxn28R9p4RkMhagFjR7AL12n435/Hd0l+vyNQrq49PZVbuepgG0Lfk UCvSCHsrMtDnPufEGxmFTTJLbrMmucldrK0VoagTZQaDwDDDsC2l78gR3R3QfF8Yz+UU SBVKBdyU7fYvbI25VI1ttqkDhCCQgcJGIHtWN2DbNefC4OKfZhycFVhMPxlwR2Ee1A0K zg/w== X-Gm-Message-State: AOAM530kdMMKYBHT3mBtbfS4/RSLh6TlzH0SCwhrimiRn2RcjsSY77Ej y9XR0M2Y6i9sYmge/ot0c+aSjQ== X-Received: by 2002:a05:6402:5255:: with SMTP id t21mr15192241edd.103.1633707841708; Fri, 08 Oct 2021 08:44:01 -0700 (PDT) Received: from localhost ([31.134.121.151]) by smtp.gmail.com with ESMTPSA id bx11sm1086714ejb.107.2021.10.08.08.44.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 08 Oct 2021 08:44:01 -0700 (PDT) From: Sam Protsenko To: Krzysztof Kozlowski , Sylwester Nawrocki , =?utf-8?q?Pawe=C5=82_Chmiel?= , Chanwoo Choi , Tomasz Figa , Rob Herring , Stephen Boyd , Michael Turquette Cc: Ryu Euiyoul , Tom Gall , Sumit Semwal , John Stultz , Amit Pundir , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, linux-samsung-soc@vger.kernel.org Subject: [PATCH v3 4/5] dt-bindings: clock: Document Exynos850 CMU bindings Date: Fri, 8 Oct 2021 18:43:51 +0300 Message-Id: <20211008154352.19519-5-semen.protsenko@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211008154352.19519-1-semen.protsenko@linaro.org> References: <20211008154352.19519-1-semen.protsenko@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Provide dt-schema documentation for Exynos850 SoC clock controller. Signed-off-by: Sam Protsenko Reviewed-by: Krzysztof Kozlowski Acked-by: Chanwoo Choi --- Changes in v3: - Added R-b tag by Krzysztof Kozlowski Changes in v2: - Dropped OSCCLK node declaration example - Dropped UART node declaration example - Added Ack tag by Chanwoo Choi .../clock/samsung,exynos850-clock.yaml | 185 ++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml -- 2.30.2 diff --git a/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml b/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml new file mode 100644 index 000000000000..79202e6e6402 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/samsung,exynos850-clock.yaml @@ -0,0 +1,185 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/samsung,exynos850-clock.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Samsung Exynos850 SoC clock controller + +maintainers: + - Sam Protsenko + - Chanwoo Choi + - Krzysztof Kozlowski + - Sylwester Nawrocki + - Tomasz Figa + +description: | + Exynos850 clock controller is comprised of several CMU units, generating + clocks for different domains. Those CMU units are modeled as separate device + tree nodes, and might depend on each other. Root clocks in that clock tree are + two external clocks:: OSCCLK (26 MHz) and RTCCLK (32768 Hz). Those external + clocks must be defined as fixed-rate clocks in dts. + + CMU_TOP is a top-level CMU, where all base clocks are prepared using PLLs and + dividers; all other leaf clocks (other CMUs) are usually derived from CMU_TOP. + + Each clock is assigned an identifier and client nodes can use this identifier + to specify the clock which they consume. All clocks that available for usage + in clock consumer nodes are defined as preprocessor macros in + 'dt-bindings/clock/exynos850.h' header. + +properties: + compatible: + enum: + - samsung,exynos850-cmu-top + - samsung,exynos850-cmu-core + - samsung,exynos850-cmu-dpu + - samsung,exynos850-cmu-hsi + - samsung,exynos850-cmu-peri + + clocks: + minItems: 1 + maxItems: 5 + + clock-names: + minItems: 1 + maxItems: 5 + + "#clock-cells": + const: 1 + + reg: + maxItems: 1 + +allOf: + - if: + properties: + compatible: + contains: + const: samsung,exynos850-cmu-top + + then: + properties: + clocks: + items: + - description: External reference clock (26 MHz) + + clock-names: + items: + - const: oscclk + + - if: + properties: + compatible: + contains: + const: samsung,exynos850-cmu-core + + then: + properties: + clocks: + items: + - description: External reference clock (26 MHz) + - description: CMU_CORE bus clock (from CMU_TOP) + - description: CCI clock (from CMU_TOP) + - description: eMMC clock (from CMU_TOP) + - description: SSS clock (from CMU_TOP) + + clock-names: + items: + - const: oscclk + - const: dout_core_bus + - const: dout_core_cci + - const: dout_core_mmc_embd + - const: dout_core_sss + + - if: + properties: + compatible: + contains: + const: samsung,exynos850-cmu-dpu + + then: + properties: + clocks: + items: + - description: External reference clock (26 MHz) + - description: DPU clock (from CMU_TOP) + + clock-names: + items: + - const: oscclk + - const: dout_dpu + + - if: + properties: + compatible: + contains: + const: samsung,exynos850-cmu-hsi + + then: + properties: + clocks: + items: + - description: External reference clock (26 MHz) + - description: External RTC clock (32768 Hz) + - description: CMU_HSI bus clock (from CMU_TOP) + - description: SD card clock (from CMU_TOP) + - description: "USB 2.0 DRD clock (from CMU_TOP)" + + clock-names: + items: + - const: oscclk + - const: rtcclk + - const: dout_hsi_bus + - const: dout_hsi_mmc_card + - const: dout_hsi_usb20drd + + - if: + properties: + compatible: + contains: + const: samsung,exynos850-cmu-peri + + then: + properties: + clocks: + items: + - description: External reference clock (26 MHz) + - description: CMU_PERI bus clock (from CMU_TOP) + - description: UART clock (from CMU_TOP) + - description: Parent clock for HSI2C and SPI (from CMU_TOP) + + clock-names: + items: + - const: oscclk + - const: dout_peri_bus + - const: dout_peri_uart + - const: dout_peri_ip + +required: + - compatible + - "#clock-cells" + - clocks + - clock-names + - reg + +additionalProperties: false + +examples: + # Clock controller node for CMU_PERI + - | + #include + + cmu_peri: clock-controller@10030000 { + compatible = "samsung,exynos850-cmu-peri"; + reg = <0x10030000 0x8000>; + #clock-cells = <1>; + + clocks = <&oscclk>, <&cmu_top CLK_DOUT_PERI_BUS>, + <&cmu_top CLK_DOUT_PERI_UART>, + <&cmu_top CLK_DOUT_PERI_IP>; + clock-names = "oscclk", "dout_peri_bus", + "dout_peri_uart", "dout_peri_ip"; + }; + +... From patchwork Fri Oct 8 15:43:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Protsenko X-Patchwork-Id: 515580 Delivered-To: patch@linaro.org Received: by 2002:adf:fbc8:0:0:0:0:0 with SMTP id d8csp3044776wrs; Fri, 8 Oct 2021 08:44:11 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwim1vvzybXMkBIdH4CTIF4+5CSBrOcGBCfkXySt6ptmvT/SCXIXhWXORevfXHEijY+P0kD X-Received: by 2002:a63:da49:: with SMTP id l9mr5173154pgj.277.1633707850831; Fri, 08 Oct 2021 08:44:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1633707850; cv=none; d=google.com; s=arc-20160816; b=A9to6k1y0mS56ZTRdMATl+PBnZXbRXXoOgV4Y6tR3bQWpyWHrug8a27cDx+altumsN 7UIZs7OTYXFtItoKvfUIAi/Z1v0xzWc9AgoWQp/xa15UFFbvPkDDtBW20jpVvYtekUI1 6PXEb6Sgt6vVRw0HpLCFZlS6IcDu/zGCVAsH8zH10vlYuqLNUo1xvYTB/LMn1fveKq9c /9Qtk+t+jM1V1/9M95FKEsE0ewrR1uLTYslVkAMl/SrWvNFeqMG5phl0+BjPDHVwZXzh x4yfWKbUnueXXDSOetjALfy3Jeuf4bqrCV9PUCjQKiSBkm7bL7aMxydBAQubStSY7s6n TBNA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=cFmm8Fot/T0dcEAqIWez28aCA/JmwW4DqkLA3vW+88k=; b=b+tCNM+Y8MXFfCXpR6lH5vQQMktWrNpNrpmBhZV7sZhlnueseXAQN5g1iiahzpzm4z oCJKCKDT61Ngg3pNIirCGcLr7Lhy+5cVlz8VN6ZuWCXF4T+c9WgG5/oXWJCr9KLKtlOr DbaHqAOyzxHleQo5fMnYHRMYAtdaBJkz7iVqYrK9sLK3UGVbKNAErgfH5FE6xgU2JdIx qRB8TXRfZNrmc8dN3QekYdr8hpQsTE3InFV50I9efHprvbELdC/l9+AURaYgQz5pdXJ8 Wf2XywquTKsLrSCbstirDa+nT/lUI3TJ7vfExxifRa5GIUIgcOB3XGTXc+xi3kUzfv5o 2YSw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=QTF2Wikt; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id mw9si3741521pjb.55.2021.10.08.08.44.10; Fri, 08 Oct 2021 08:44:10 -0700 (PDT) Received-SPF: pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=QTF2Wikt; spf=pass (google.com: domain of devicetree-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=devicetree-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243063AbhJHPqD (ORCPT + 7 others); Fri, 8 Oct 2021 11:46:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36086 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243195AbhJHPqB (ORCPT ); Fri, 8 Oct 2021 11:46:01 -0400 Received: from mail-ed1-x533.google.com (mail-ed1-x533.google.com [IPv6:2a00:1450:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 679BDC06176A for ; Fri, 8 Oct 2021 08:44:05 -0700 (PDT) Received: by mail-ed1-x533.google.com with SMTP id d3so10533115edp.3 for ; Fri, 08 Oct 2021 08:44:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cFmm8Fot/T0dcEAqIWez28aCA/JmwW4DqkLA3vW+88k=; b=QTF2WiktHR0NMUFwLqX4fZcYvwZfz3xIGdP1767wy/Iu2TAr7X3+dBzrV4Yr/5iwhm xB667ENyIs2IbzUIFazO2EKdQqUUPuA7IAj6S07MjeCBRYs7j0FBWSDhZf26v+xzOTRn zlJVqim9S53BiAA0iXDqguhi+o21QQU5bBr6xBrW1D69C/4smldP00KO52GHhEa649WI aN/quqD3nfgI/j2KmIGz4C/LGPX1UV1y8kFfgwknZuwpoHGKIlwyeb4SyDP7wzOnE3Ug SJ9IZc8A0Y+8iYHcndQgS9/2B8Sww4biUuGimrDTO7K6KflJTS6KFiryGxQvazyuBsWr uU4w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cFmm8Fot/T0dcEAqIWez28aCA/JmwW4DqkLA3vW+88k=; b=r9IS+l/Uik6kISYiE2U8XLL2i4/gsh5D8Yw53+4Pm0+opO0LVN6xRk4kDu31Kjlqv8 rtMf3h/PPXnalUOq4cXkiQZSv/wcpmpQOUTCa/WTSIoOncillWvlIIBxKHhuUxd5gQ3i pcaLt3+OwnWvP2ZCHW+MvHxz+jcDpv7NSZzxS8Np+RIpr83v9SDkdMHn16ejj3bf/i2J rDOSVrD2w8F4ob/VFurE+oRokJ+RWagk7TuEQoukJNeypO9IFnipGSgsZz0yOSyH/7Xf uYvIa1prj0l3Gpl4ztRhK0oI60nHboVo4dZlFL5KdEDke59znHnR9Qq0ugKB14n8OmSt LQig== X-Gm-Message-State: AOAM532lmwjSpCkXdRb2yv+klRlcYe3dZghCkwG18aDH2kaMCb4WeHFI drr9Lkv23rZ78EZyMnKmBa+CJYpkRKWuMZnc X-Received: by 2002:a17:906:d182:: with SMTP id c2mr4874247ejz.47.1633707843634; Fri, 08 Oct 2021 08:44:03 -0700 (PDT) Received: from localhost ([31.134.121.151]) by smtp.gmail.com with ESMTPSA id dt4sm1081124ejb.27.2021.10.08.08.44.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 08 Oct 2021 08:44:03 -0700 (PDT) From: Sam Protsenko To: Krzysztof Kozlowski , Sylwester Nawrocki , =?utf-8?q?Pawe=C5=82_Chmiel?= , Chanwoo Choi , Tomasz Figa , Rob Herring , Stephen Boyd , Michael Turquette Cc: Ryu Euiyoul , Tom Gall , Sumit Semwal , John Stultz , Amit Pundir , devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org, linux-kernel@vger.kernel.org, linux-samsung-soc@vger.kernel.org Subject: [PATCH v3 5/5] clk: samsung: Introduce Exynos850 clock driver Date: Fri, 8 Oct 2021 18:43:52 +0300 Message-Id: <20211008154352.19519-6-semen.protsenko@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211008154352.19519-1-semen.protsenko@linaro.org> References: <20211008154352.19519-1-semen.protsenko@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This is the initial implementation adding only basic clocks like UART, MMC, I2C and corresponding parent clocks. Design is influenced by Exynos5433 clock driver. Bus clock is enabled by default (in probe function) for all CMUs except CMU_TOP, the reasoning is as follows. By default if bus clock has no users its "enable count" value is 0. It might be actually running if it's already enabled in bootloader, but then in some cases it can be disabled by mistake. For example, such case was observed when dw_mci_probe() enabled the bus clock, then failed to do something and disabled that bus clock on error path. After that, even the attempt to read the 'clk_summary' file in DebugFS freezed forever, as CMU bus clock ended up being disabled and it wasn't possible to access CMU registers anymore. To avoid such cases, CMU driver must increment the ref count for that bus clock by running clk_prepare_enable(). There is already existing '.clk_name' field in struct samsung_cmu_info, exactly for that reason. It was added in commit 523d3de41f02 ("clk: samsung: exynos5433: Add support for runtime PM"), with next mentioning in commit message: > Also for each CMU there is one special parent clock, which has to be > enabled all the time when any access to CMU registers is being done. But that clock is actually only enabled in Exynos5433 clock driver right now. So the same code is added to exynos850_cmu_probe() function, As was described above, it might be helpful not only for PM reasons, but also to prevent possible erroneous clock gating on error paths. Another way to workaround that issue would be to use CLOCK_IS_CRITICAL flag for corresponding gate clocks. But that might be not very good design decision, as we might still want to disable that bus clock, e.g. on PM suspend. Signed-off-by: Sam Protsenko Reviewed-by: Krzysztof Kozlowski --- Changes in v3: - Added R-b tag by Krzysztof Kozlowski Changes in v2: - Used of_iomap() for the whole CMU range instead of ioremap() in exynos850_init_clocks() - Used readl/writel functions in exynos850_init_clocks() for consistency with other drivers - Added all clock ids - Added CMU_DPU - Implemented platform_driver for all Power Domain capable CMUs - Moved bus clock enablement code here to probe function - Used clk_get() instead of __clk_lookup() drivers/clk/samsung/Makefile | 1 + drivers/clk/samsung/clk-exynos850.c | 835 ++++++++++++++++++++++++++++ 2 files changed, 836 insertions(+) create mode 100644 drivers/clk/samsung/clk-exynos850.c -- 2.30.2 diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index 028b2e27a37e..c46cf11e4d0b 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o obj-$(CONFIG_EXYNOS_CLKOUT) += clk-exynos-clkout.o obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos7.o +obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos850.o obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o diff --git a/drivers/clk/samsung/clk-exynos850.c b/drivers/clk/samsung/clk-exynos850.c new file mode 100644 index 000000000000..2294989e244c --- /dev/null +++ b/drivers/clk/samsung/clk-exynos850.c @@ -0,0 +1,835 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2021 Linaro Ltd. + * Author: Sam Protsenko + * + * Common Clock Framework support for Exynos850 SoC. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "clk.h" + +/* Gate register bits */ +#define GATE_MANUAL BIT(20) +#define GATE_ENABLE_HWACG BIT(28) + +/* Gate register offsets range */ +#define GATE_OFF_START 0x2000 +#define GATE_OFF_END 0x2fff + +/** + * exynos850_init_clocks - Set clocks initial configuration + * @np: CMU device tree node with "reg" property (CMU addr) + * @reg_offs: Register offsets array for clocks to init + * @reg_offs_len: Number of register offsets in reg_offs array + * + * Set manual control mode for all gate clocks. + */ +static void __init exynos850_init_clocks(struct device_node *np, + const unsigned long *reg_offs, size_t reg_offs_len) +{ + void __iomem *reg_base; + size_t i; + + reg_base = of_iomap(np, 0); + if (!reg_base) + panic("%s: failed to map registers\n", __func__); + + for (i = 0; i < reg_offs_len; ++i) { + void __iomem *reg = reg_base + reg_offs[i]; + u32 val; + + /* Modify only gate clock registers */ + if (reg_offs[i] < GATE_OFF_START || reg_offs[i] > GATE_OFF_END) + continue; + + val = readl(reg); + val |= GATE_MANUAL; + val &= ~GATE_ENABLE_HWACG; + writel(val, reg); + } + + iounmap(reg_base); +} + +/* ---- CMU_TOP ------------------------------------------------------------- */ + +/* Register Offset definitions for CMU_TOP (0x120e0000) */ +#define PLL_LOCKTIME_PLL_MMC 0x0000 +#define PLL_LOCKTIME_PLL_SHARED0 0x0004 +#define PLL_LOCKTIME_PLL_SHARED1 0x0008 +#define PLL_CON0_PLL_MMC 0x0100 +#define PLL_CON3_PLL_MMC 0x010c +#define PLL_CON0_PLL_SHARED0 0x0140 +#define PLL_CON3_PLL_SHARED0 0x014c +#define PLL_CON0_PLL_SHARED1 0x0180 +#define PLL_CON3_PLL_SHARED1 0x018c +#define CLK_CON_MUX_MUX_CLKCMU_CORE_BUS 0x1014 +#define CLK_CON_MUX_MUX_CLKCMU_CORE_CCI 0x1018 +#define CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD 0x101c +#define CLK_CON_MUX_MUX_CLKCMU_CORE_SSS 0x1020 +#define CLK_CON_MUX_MUX_CLKCMU_DPU 0x1034 +#define CLK_CON_MUX_MUX_CLKCMU_HSI_BUS 0x103c +#define CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD 0x1040 +#define CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD 0x1044 +#define CLK_CON_MUX_MUX_CLKCMU_PERI_BUS 0x1070 +#define CLK_CON_MUX_MUX_CLKCMU_PERI_IP 0x1074 +#define CLK_CON_MUX_MUX_CLKCMU_PERI_UART 0x1078 +#define CLK_CON_DIV_CLKCMU_CORE_BUS 0x1820 +#define CLK_CON_DIV_CLKCMU_CORE_CCI 0x1824 +#define CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD 0x1828 +#define CLK_CON_DIV_CLKCMU_CORE_SSS 0x182c +#define CLK_CON_DIV_CLKCMU_DPU 0x1840 +#define CLK_CON_DIV_CLKCMU_HSI_BUS 0x1848 +#define CLK_CON_DIV_CLKCMU_HSI_MMC_CARD 0x184c +#define CLK_CON_DIV_CLKCMU_HSI_USB20DRD 0x1850 +#define CLK_CON_DIV_CLKCMU_PERI_BUS 0x187c +#define CLK_CON_DIV_CLKCMU_PERI_IP 0x1880 +#define CLK_CON_DIV_CLKCMU_PERI_UART 0x1884 +#define CLK_CON_DIV_PLL_SHARED0_DIV2 0x188c +#define CLK_CON_DIV_PLL_SHARED0_DIV3 0x1890 +#define CLK_CON_DIV_PLL_SHARED0_DIV4 0x1894 +#define CLK_CON_DIV_PLL_SHARED1_DIV2 0x1898 +#define CLK_CON_DIV_PLL_SHARED1_DIV3 0x189c +#define CLK_CON_DIV_PLL_SHARED1_DIV4 0x18a0 +#define CLK_CON_GAT_GATE_CLKCMU_CORE_BUS 0x201c +#define CLK_CON_GAT_GATE_CLKCMU_CORE_CCI 0x2020 +#define CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD 0x2024 +#define CLK_CON_GAT_GATE_CLKCMU_CORE_SSS 0x2028 +#define CLK_CON_GAT_GATE_CLKCMU_DPU 0x203c +#define CLK_CON_GAT_GATE_CLKCMU_HSI_BUS 0x2044 +#define CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD 0x2048 +#define CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD 0x204c +#define CLK_CON_GAT_GATE_CLKCMU_PERI_BUS 0x2080 +#define CLK_CON_GAT_GATE_CLKCMU_PERI_IP 0x2084 +#define CLK_CON_GAT_GATE_CLKCMU_PERI_UART 0x2088 + +static const unsigned long top_clk_regs[] __initconst = { + PLL_LOCKTIME_PLL_MMC, + PLL_LOCKTIME_PLL_SHARED0, + PLL_LOCKTIME_PLL_SHARED1, + PLL_CON0_PLL_MMC, + PLL_CON3_PLL_MMC, + PLL_CON0_PLL_SHARED0, + PLL_CON3_PLL_SHARED0, + PLL_CON0_PLL_SHARED1, + PLL_CON3_PLL_SHARED1, + CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, + CLK_CON_MUX_MUX_CLKCMU_CORE_CCI, + CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD, + CLK_CON_MUX_MUX_CLKCMU_CORE_SSS, + CLK_CON_MUX_MUX_CLKCMU_DPU, + CLK_CON_MUX_MUX_CLKCMU_HSI_BUS, + CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD, + CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD, + CLK_CON_MUX_MUX_CLKCMU_PERI_BUS, + CLK_CON_MUX_MUX_CLKCMU_PERI_IP, + CLK_CON_MUX_MUX_CLKCMU_PERI_UART, + CLK_CON_DIV_CLKCMU_CORE_BUS, + CLK_CON_DIV_CLKCMU_CORE_CCI, + CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD, + CLK_CON_DIV_CLKCMU_CORE_SSS, + CLK_CON_DIV_CLKCMU_DPU, + CLK_CON_DIV_CLKCMU_HSI_BUS, + CLK_CON_DIV_CLKCMU_HSI_MMC_CARD, + CLK_CON_DIV_CLKCMU_HSI_USB20DRD, + CLK_CON_DIV_CLKCMU_PERI_BUS, + CLK_CON_DIV_CLKCMU_PERI_IP, + CLK_CON_DIV_CLKCMU_PERI_UART, + CLK_CON_DIV_PLL_SHARED0_DIV2, + CLK_CON_DIV_PLL_SHARED0_DIV3, + CLK_CON_DIV_PLL_SHARED0_DIV4, + CLK_CON_DIV_PLL_SHARED1_DIV2, + CLK_CON_DIV_PLL_SHARED1_DIV3, + CLK_CON_DIV_PLL_SHARED1_DIV4, + CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, + CLK_CON_GAT_GATE_CLKCMU_CORE_CCI, + CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD, + CLK_CON_GAT_GATE_CLKCMU_CORE_SSS, + CLK_CON_GAT_GATE_CLKCMU_DPU, + CLK_CON_GAT_GATE_CLKCMU_HSI_BUS, + CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD, + CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD, + CLK_CON_GAT_GATE_CLKCMU_PERI_BUS, + CLK_CON_GAT_GATE_CLKCMU_PERI_IP, + CLK_CON_GAT_GATE_CLKCMU_PERI_UART, +}; + +/* + * Do not provide PLL tables to core PLLs, as MANUAL_PLL_CTRL bit is not set + * for those PLLs by default, so set_rate operation would fail. + */ +static const struct samsung_pll_clock top_pll_clks[] __initconst = { + /* CMU_TOP_PURECLKCOMP */ + PLL(pll_0822x, CLK_FOUT_SHARED0_PLL, "fout_shared0_pll", "oscclk", + PLL_LOCKTIME_PLL_SHARED0, PLL_CON3_PLL_SHARED0, + NULL), + PLL(pll_0822x, CLK_FOUT_SHARED1_PLL, "fout_shared1_pll", "oscclk", + PLL_LOCKTIME_PLL_SHARED1, PLL_CON3_PLL_SHARED1, + NULL), + PLL(pll_0831x, CLK_FOUT_MMC_PLL, "fout_mmc_pll", "oscclk", + PLL_LOCKTIME_PLL_MMC, PLL_CON3_PLL_MMC, NULL), +}; + +/* List of parent clocks for Muxes in CMU_TOP */ +PNAME(mout_shared0_pll_p) = { "oscclk", "fout_shared0_pll" }; +PNAME(mout_shared1_pll_p) = { "oscclk", "fout_shared1_pll" }; +PNAME(mout_mmc_pll_p) = { "oscclk", "fout_mmc_pll" }; +/* List of parent clocks for Muxes in CMU_TOP: for CMU_CORE */ +PNAME(mout_core_bus_p) = { "dout_shared1_div2", "dout_shared0_div3", + "dout_shared1_div3", "dout_shared0_div4" }; +PNAME(mout_core_cci_p) = { "dout_shared0_div2", "dout_shared1_div2", + "dout_shared0_div3", "dout_shared1_div3" }; +PNAME(mout_core_mmc_embd_p) = { "oscclk", "dout_shared0_div2", + "dout_shared1_div2", "dout_shared0_div3", + "dout_shared1_div3", "mout_mmc_pll", + "oscclk", "oscclk" }; +PNAME(mout_core_sss_p) = { "dout_shared0_div3", "dout_shared1_div3", + "dout_shared0_div4", "dout_shared1_div4" }; +/* List of parent clocks for Muxes in CMU_TOP: for CMU_HSI */ +PNAME(mout_hsi_bus_p) = { "dout_shared0_div2", "dout_shared1_div2" }; +PNAME(mout_hsi_mmc_card_p) = { "oscclk", "dout_shared0_div2", + "dout_shared1_div2", "dout_shared0_div3", + "dout_shared1_div3", "mout_mmc_pll", + "oscclk", "oscclk" }; +PNAME(mout_hsi_usb20drd_p) = { "oscclk", "dout_shared0_div4", + "dout_shared1_div4", "oscclk" }; +/* List of parent clocks for Muxes in CMU_TOP: for CMU_PERI */ +PNAME(mout_peri_bus_p) = { "dout_shared0_div4", "dout_shared1_div4" }; +PNAME(mout_peri_uart_p) = { "oscclk", "dout_shared0_div4", + "dout_shared1_div4", "oscclk" }; +PNAME(mout_peri_ip_p) = { "oscclk", "dout_shared0_div4", + "dout_shared1_div4", "oscclk" }; + +/* List of parent clocks for Muxes in CMU_TOP: for CMU_DPU */ +PNAME(mout_dpu_p) = { "dout_shared0_div3", "dout_shared1_div3", + "dout_shared0_div4", "dout_shared1_div4" }; + +static const struct samsung_mux_clock top_mux_clks[] __initconst = { + /* CMU_TOP_PURECLKCOMP */ + MUX(CLK_MOUT_SHARED0_PLL, "mout_shared0_pll", mout_shared0_pll_p, + PLL_CON0_PLL_SHARED0, 4, 1), + MUX(CLK_MOUT_SHARED1_PLL, "mout_shared1_pll", mout_shared1_pll_p, + PLL_CON0_PLL_SHARED1, 4, 1), + MUX(CLK_MOUT_MMC_PLL, "mout_mmc_pll", mout_mmc_pll_p, + PLL_CON0_PLL_MMC, 4, 1), + + /* CORE */ + MUX(CLK_MOUT_CORE_BUS, "mout_core_bus", mout_core_bus_p, + CLK_CON_MUX_MUX_CLKCMU_CORE_BUS, 0, 2), + MUX(CLK_MOUT_CORE_CCI, "mout_core_cci", mout_core_cci_p, + CLK_CON_MUX_MUX_CLKCMU_CORE_CCI, 0, 2), + MUX(CLK_MOUT_CORE_MMC_EMBD, "mout_core_mmc_embd", mout_core_mmc_embd_p, + CLK_CON_MUX_MUX_CLKCMU_CORE_MMC_EMBD, 0, 3), + MUX(CLK_MOUT_CORE_SSS, "mout_core_sss", mout_core_sss_p, + CLK_CON_MUX_MUX_CLKCMU_CORE_SSS, 0, 2), + + /* DPU */ + MUX(CLK_MOUT_DPU, "mout_dpu", mout_dpu_p, + CLK_CON_MUX_MUX_CLKCMU_DPU, 0, 2), + + /* HSI */ + MUX(CLK_MOUT_HSI_BUS, "mout_hsi_bus", mout_hsi_bus_p, + CLK_CON_MUX_MUX_CLKCMU_HSI_BUS, 0, 1), + MUX(CLK_MOUT_HSI_MMC_CARD, "mout_hsi_mmc_card", mout_hsi_mmc_card_p, + CLK_CON_MUX_MUX_CLKCMU_HSI_MMC_CARD, 0, 3), + MUX(CLK_MOUT_HSI_USB20DRD, "mout_hsi_usb20drd", mout_hsi_usb20drd_p, + CLK_CON_MUX_MUX_CLKCMU_HSI_USB20DRD, 0, 2), + + /* PERI */ + MUX(CLK_MOUT_PERI_BUS, "mout_peri_bus", mout_peri_bus_p, + CLK_CON_MUX_MUX_CLKCMU_PERI_BUS, 0, 1), + MUX(CLK_MOUT_PERI_UART, "mout_peri_uart", mout_peri_uart_p, + CLK_CON_MUX_MUX_CLKCMU_PERI_UART, 0, 2), + MUX(CLK_MOUT_PERI_IP, "mout_peri_ip", mout_peri_ip_p, + CLK_CON_MUX_MUX_CLKCMU_PERI_IP, 0, 2), +}; + +static const struct samsung_div_clock top_div_clks[] __initconst = { + /* CMU_TOP_PURECLKCOMP */ + DIV(CLK_DOUT_SHARED0_DIV3, "dout_shared0_div3", "mout_shared0_pll", + CLK_CON_DIV_PLL_SHARED0_DIV3, 0, 2), + DIV(CLK_DOUT_SHARED0_DIV2, "dout_shared0_div2", "mout_shared0_pll", + CLK_CON_DIV_PLL_SHARED0_DIV2, 0, 1), + DIV(CLK_DOUT_SHARED1_DIV3, "dout_shared1_div3", "mout_shared1_pll", + CLK_CON_DIV_PLL_SHARED1_DIV3, 0, 2), + DIV(CLK_DOUT_SHARED1_DIV2, "dout_shared1_div2", "mout_shared1_pll", + CLK_CON_DIV_PLL_SHARED1_DIV2, 0, 1), + DIV(CLK_DOUT_SHARED0_DIV4, "dout_shared0_div4", "dout_shared0_div2", + CLK_CON_DIV_PLL_SHARED0_DIV4, 0, 1), + DIV(CLK_DOUT_SHARED1_DIV4, "dout_shared1_div4", "dout_shared1_div2", + CLK_CON_DIV_PLL_SHARED1_DIV4, 0, 1), + + /* CORE */ + DIV(CLK_DOUT_CORE_BUS, "dout_core_bus", "gout_core_bus", + CLK_CON_DIV_CLKCMU_CORE_BUS, 0, 4), + DIV(CLK_DOUT_CORE_CCI, "dout_core_cci", "gout_core_cci", + CLK_CON_DIV_CLKCMU_CORE_CCI, 0, 4), + DIV(CLK_DOUT_CORE_MMC_EMBD, "dout_core_mmc_embd", "gout_core_mmc_embd", + CLK_CON_DIV_CLKCMU_CORE_MMC_EMBD, 0, 9), + DIV(CLK_DOUT_CORE_SSS, "dout_core_sss", "gout_core_sss", + CLK_CON_DIV_CLKCMU_CORE_SSS, 0, 4), + + /* DPU */ + DIV(CLK_DOUT_DPU, "dout_dpu", "gout_dpu", + CLK_CON_DIV_CLKCMU_DPU, 0, 4), + + /* HSI */ + DIV(CLK_DOUT_HSI_BUS, "dout_hsi_bus", "gout_hsi_bus", + CLK_CON_DIV_CLKCMU_HSI_BUS, 0, 4), + DIV(CLK_DOUT_HSI_MMC_CARD, "dout_hsi_mmc_card", "gout_hsi_mmc_card", + CLK_CON_DIV_CLKCMU_HSI_MMC_CARD, 0, 9), + DIV(CLK_DOUT_HSI_USB20DRD, "dout_hsi_usb20drd", "gout_hsi_usb20drd", + CLK_CON_DIV_CLKCMU_HSI_USB20DRD, 0, 4), + + /* PERI */ + DIV(CLK_DOUT_PERI_BUS, "dout_peri_bus", "gout_peri_bus", + CLK_CON_DIV_CLKCMU_PERI_BUS, 0, 4), + DIV(CLK_DOUT_PERI_UART, "dout_peri_uart", "gout_peri_uart", + CLK_CON_DIV_CLKCMU_PERI_UART, 0, 4), + DIV(CLK_DOUT_PERI_IP, "dout_peri_ip", "gout_peri_ip", + CLK_CON_DIV_CLKCMU_PERI_IP, 0, 4), +}; + +static const struct samsung_gate_clock top_gate_clks[] __initconst = { + /* CORE */ + GATE(CLK_GOUT_CORE_BUS, "gout_core_bus", "mout_core_bus", + CLK_CON_GAT_GATE_CLKCMU_CORE_BUS, 21, 0, 0), + GATE(CLK_GOUT_CORE_CCI, "gout_core_cci", "mout_core_cci", + CLK_CON_GAT_GATE_CLKCMU_CORE_CCI, 21, 0, 0), + GATE(CLK_GOUT_CORE_MMC_EMBD, "gout_core_mmc_embd", "mout_core_mmc_embd", + CLK_CON_GAT_GATE_CLKCMU_CORE_MMC_EMBD, 21, 0, 0), + GATE(CLK_GOUT_CORE_SSS, "gout_core_sss", "mout_core_sss", + CLK_CON_GAT_GATE_CLKCMU_CORE_SSS, 21, 0, 0), + + /* DPU */ + GATE(CLK_GOUT_DPU, "gout_dpu", "mout_dpu", + CLK_CON_GAT_GATE_CLKCMU_DPU, 21, 0, 0), + + /* HSI */ + GATE(CLK_GOUT_HSI_BUS, "gout_hsi_bus", "mout_hsi_bus", + CLK_CON_GAT_GATE_CLKCMU_HSI_BUS, 21, 0, 0), + GATE(CLK_GOUT_HSI_MMC_CARD, "gout_hsi_mmc_card", "mout_hsi_mmc_card", + CLK_CON_GAT_GATE_CLKCMU_HSI_MMC_CARD, 21, 0, 0), + GATE(CLK_GOUT_HSI_USB20DRD, "gout_hsi_usb20drd", "mout_hsi_usb20drd", + CLK_CON_GAT_GATE_CLKCMU_HSI_USB20DRD, 21, 0, 0), + + /* PERI */ + GATE(CLK_GOUT_PERI_BUS, "gout_peri_bus", "mout_peri_bus", + CLK_CON_GAT_GATE_CLKCMU_PERI_BUS, 21, 0, 0), + GATE(CLK_GOUT_PERI_UART, "gout_peri_uart", "mout_peri_uart", + CLK_CON_GAT_GATE_CLKCMU_PERI_UART, 21, 0, 0), + GATE(CLK_GOUT_PERI_IP, "gout_peri_ip", "mout_peri_ip", + CLK_CON_GAT_GATE_CLKCMU_PERI_IP, 21, 0, 0), +}; + +static const struct samsung_cmu_info top_cmu_info __initconst = { + .pll_clks = top_pll_clks, + .nr_pll_clks = ARRAY_SIZE(top_pll_clks), + .mux_clks = top_mux_clks, + .nr_mux_clks = ARRAY_SIZE(top_mux_clks), + .div_clks = top_div_clks, + .nr_div_clks = ARRAY_SIZE(top_div_clks), + .gate_clks = top_gate_clks, + .nr_gate_clks = ARRAY_SIZE(top_gate_clks), + .nr_clk_ids = TOP_NR_CLK, + .clk_regs = top_clk_regs, + .nr_clk_regs = ARRAY_SIZE(top_clk_regs), +}; + +static void __init exynos850_cmu_top_init(struct device_node *np) +{ + exynos850_init_clocks(np, top_clk_regs, ARRAY_SIZE(top_clk_regs)); + samsung_cmu_register_one(np, &top_cmu_info); +} + +CLK_OF_DECLARE(exynos850_cmu_top, "samsung,exynos850-cmu-top", + exynos850_cmu_top_init); + +/* ---- CMU_HSI ------------------------------------------------------------- */ + +/* Register Offset definitions for CMU_HSI (0x13400000) */ +#define PLL_CON0_MUX_CLKCMU_HSI_BUS_USER 0x0600 +#define PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER 0x0610 +#define PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER 0x0620 +#define CLK_CON_MUX_MUX_CLK_HSI_RTC 0x1000 +#define CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV 0x2008 +#define CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50 0x200c +#define CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26 0x2010 +#define CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK 0x2018 +#define CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK 0x2024 +#define CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN 0x2028 +#define CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK 0x2038 +#define CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20 0x203c +#define CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY 0x2040 + +static const unsigned long hsi_clk_regs[] __initconst = { + PLL_CON0_MUX_CLKCMU_HSI_BUS_USER, + PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER, + PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER, + CLK_CON_MUX_MUX_CLK_HSI_RTC, + CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV, + CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50, + CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26, + CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK, + CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK, + CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN, + CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK, + CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20, + CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY, +}; + +/* List of parent clocks for Muxes in CMU_PERI */ +PNAME(mout_hsi_bus_user_p) = { "oscclk", "dout_hsi_bus" }; +PNAME(mout_hsi_mmc_card_user_p) = { "oscclk", "dout_hsi_mmc_card" }; +PNAME(mout_hsi_usb20drd_user_p) = { "oscclk", "dout_hsi_usb20drd" }; +PNAME(mout_hsi_rtc_p) = { "rtcclk", "oscclk" }; + +static const struct samsung_mux_clock hsi_mux_clks[] __initconst = { + MUX(CLK_MOUT_HSI_BUS_USER, "mout_hsi_bus_user", mout_hsi_bus_user_p, + PLL_CON0_MUX_CLKCMU_HSI_BUS_USER, 4, 1), + MUX_F(CLK_MOUT_HSI_MMC_CARD_USER, "mout_hsi_mmc_card_user", + mout_hsi_mmc_card_user_p, PLL_CON0_MUX_CLKCMU_HSI_MMC_CARD_USER, + 4, 1, CLK_SET_RATE_PARENT, 0), + MUX(CLK_MOUT_HSI_USB20DRD_USER, "mout_hsi_usb20drd_user", + mout_hsi_usb20drd_user_p, PLL_CON0_MUX_CLKCMU_HSI_USB20DRD_USER, + 4, 1), + MUX(CLK_MOUT_HSI_RTC, "mout_hsi_rtc", mout_hsi_rtc_p, + CLK_CON_MUX_MUX_CLK_HSI_RTC, 0, 1), +}; + +static const struct samsung_gate_clock hsi_gate_clks[] __initconst = { + GATE(CLK_GOUT_USB_RTC_CLK, "gout_usb_rtc", "mout_hsi_rtc", + CLK_CON_GAT_HSI_USB20DRD_TOP_I_RTC_CLK__ALV, 21, 0, 0), + GATE(CLK_GOUT_USB_REF_CLK, "gout_usb_ref", "mout_hsi_usb20drd_user", + CLK_CON_GAT_HSI_USB20DRD_TOP_I_REF_CLK_50, 21, 0, 0), + GATE(CLK_GOUT_USB_PHY_REF_CLK, "gout_usb_phy_ref", "oscclk", + CLK_CON_GAT_HSI_USB20DRD_TOP_I_PHY_REFCLK_26, 21, 0, 0), + GATE(CLK_GOUT_GPIO_HSI_PCLK, "gout_gpio_hsi_pclk", "mout_hsi_bus_user", + CLK_CON_GAT_GOUT_HSI_GPIO_HSI_PCLK, 21, 0, 0), + GATE(CLK_GOUT_MMC_CARD_ACLK, "gout_mmc_card_aclk", "mout_hsi_bus_user", + CLK_CON_GAT_GOUT_HSI_MMC_CARD_I_ACLK, 21, 0, 0), + GATE(CLK_GOUT_MMC_CARD_SDCLKIN, "gout_mmc_card_sdclkin", + "mout_hsi_mmc_card_user", + CLK_CON_GAT_GOUT_HSI_MMC_CARD_SDCLKIN, 21, CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_SYSREG_HSI_PCLK, "gout_sysreg_hsi_pclk", + "mout_hsi_bus_user", + CLK_CON_GAT_GOUT_HSI_SYSREG_HSI_PCLK, 21, 0, 0), + GATE(CLK_GOUT_USB_PHY_ACLK, "gout_usb_phy_aclk", "mout_hsi_bus_user", + CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_ACLK_PHYCTRL_20, 21, 0, 0), + GATE(CLK_GOUT_USB_BUS_EARLY_CLK, "gout_usb_bus_early", + "mout_hsi_bus_user", + CLK_CON_GAT_GOUT_HSI_USB20DRD_TOP_BUS_CLK_EARLY, 21, 0, 0), +}; + +static const struct samsung_cmu_info hsi_cmu_info __initconst = { + .mux_clks = hsi_mux_clks, + .nr_mux_clks = ARRAY_SIZE(hsi_mux_clks), + .gate_clks = hsi_gate_clks, + .nr_gate_clks = ARRAY_SIZE(hsi_gate_clks), + .nr_clk_ids = HSI_NR_CLK, + .clk_regs = hsi_clk_regs, + .nr_clk_regs = ARRAY_SIZE(hsi_clk_regs), + .clk_name = "dout_hsi_bus", +}; + +/* ---- CMU_PERI ------------------------------------------------------------ */ + +/* Register Offset definitions for CMU_PERI (0x10030000) */ +#define PLL_CON0_MUX_CLKCMU_PERI_BUS_USER 0x0600 +#define PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER 0x0610 +#define PLL_CON0_MUX_CLKCMU_PERI_SPI_USER 0x0620 +#define PLL_CON0_MUX_CLKCMU_PERI_UART_USER 0x0630 +#define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0 0x1800 +#define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1 0x1804 +#define CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2 0x1808 +#define CLK_CON_DIV_DIV_CLK_PERI_SPI_0 0x180c +#define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0 0x200c +#define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1 0x2010 +#define CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2 0x2014 +#define CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK 0x2020 +#define CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK 0x2024 +#define CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK 0x2028 +#define CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK 0x202c +#define CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK 0x2030 +#define CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK 0x2034 +#define CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK 0x2038 +#define CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK 0x203c +#define CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK 0x2040 +#define CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK 0x2044 +#define CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK 0x2048 +#define CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK 0x204c +#define CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK 0x2050 +#define CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK 0x2054 +#define CLK_CON_GAT_GOUT_PERI_MCT_PCLK 0x205c +#define CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK 0x2064 +#define CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK 0x209c +#define CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK 0x20a0 +#define CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK 0x20a4 +#define CLK_CON_GAT_GOUT_PERI_UART_IPCLK 0x20a8 +#define CLK_CON_GAT_GOUT_PERI_UART_PCLK 0x20ac +#define CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK 0x20b0 +#define CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK 0x20b4 + +static const unsigned long peri_clk_regs[] __initconst = { + PLL_CON0_MUX_CLKCMU_PERI_BUS_USER, + PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER, + PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, + PLL_CON0_MUX_CLKCMU_PERI_UART_USER, + CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0, + CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1, + CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2, + CLK_CON_DIV_DIV_CLK_PERI_SPI_0, + CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0, + CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1, + CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2, + CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK, + CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK, + CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK, + CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK, + CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK, + CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK, + CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK, + CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK, + CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK, + CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK, + CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK, + CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK, + CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK, + CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK, + CLK_CON_GAT_GOUT_PERI_MCT_PCLK, + CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK, + CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, + CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK, + CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK, + CLK_CON_GAT_GOUT_PERI_UART_IPCLK, + CLK_CON_GAT_GOUT_PERI_UART_PCLK, + CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK, + CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK, +}; + +/* List of parent clocks for Muxes in CMU_PERI */ +PNAME(mout_peri_bus_user_p) = { "oscclk", "dout_peri_bus" }; +PNAME(mout_peri_uart_user_p) = { "oscclk", "dout_peri_uart" }; +PNAME(mout_peri_hsi2c_user_p) = { "oscclk", "dout_peri_ip" }; +PNAME(mout_peri_spi_user_p) = { "oscclk", "dout_peri_ip" }; + +static const struct samsung_mux_clock peri_mux_clks[] __initconst = { + MUX(CLK_MOUT_PERI_BUS_USER, "mout_peri_bus_user", mout_peri_bus_user_p, + PLL_CON0_MUX_CLKCMU_PERI_BUS_USER, 4, 1), + MUX(CLK_MOUT_PERI_UART_USER, "mout_peri_uart_user", + mout_peri_uart_user_p, PLL_CON0_MUX_CLKCMU_PERI_UART_USER, 4, 1), + MUX(CLK_MOUT_PERI_HSI2C_USER, "mout_peri_hsi2c_user", + mout_peri_hsi2c_user_p, PLL_CON0_MUX_CLKCMU_PERI_HSI2C_USER, 4, 1), + MUX(CLK_MOUT_PERI_SPI_USER, "mout_peri_spi_user", mout_peri_spi_user_p, + PLL_CON0_MUX_CLKCMU_PERI_SPI_USER, 4, 1), +}; + +static const struct samsung_div_clock peri_div_clks[] __initconst = { + DIV(CLK_DOUT_PERI_HSI2C0, "dout_peri_hsi2c0", "gout_peri_hsi2c0", + CLK_CON_DIV_DIV_CLK_PERI_HSI2C_0, 0, 5), + DIV(CLK_DOUT_PERI_HSI2C1, "dout_peri_hsi2c1", "gout_peri_hsi2c1", + CLK_CON_DIV_DIV_CLK_PERI_HSI2C_1, 0, 5), + DIV(CLK_DOUT_PERI_HSI2C2, "dout_peri_hsi2c2", "gout_peri_hsi2c2", + CLK_CON_DIV_DIV_CLK_PERI_HSI2C_2, 0, 5), + DIV(CLK_DOUT_PERI_SPI0, "dout_peri_spi0", "mout_peri_spi_user", + CLK_CON_DIV_DIV_CLK_PERI_SPI_0, 0, 5), +}; + +static const struct samsung_gate_clock peri_gate_clks[] __initconst = { + GATE(CLK_GOUT_PERI_HSI2C0, "gout_peri_hsi2c0", "mout_peri_hsi2c_user", + CLK_CON_GAT_GATE_CLK_PERI_HSI2C_0, 21, 0, 0), + GATE(CLK_GOUT_PERI_HSI2C1, "gout_peri_hsi2c1", "mout_peri_hsi2c_user", + CLK_CON_GAT_GATE_CLK_PERI_HSI2C_1, 21, 0, 0), + GATE(CLK_GOUT_PERI_HSI2C2, "gout_peri_hsi2c2", "mout_peri_hsi2c_user", + CLK_CON_GAT_GATE_CLK_PERI_HSI2C_2, 21, 0, 0), + GATE(CLK_GOUT_HSI2C0_IPCLK, "gout_hsi2c0_ipclk", "dout_peri_hsi2c0", + CLK_CON_GAT_GOUT_PERI_HSI2C_0_IPCLK, 21, 0, 0), + GATE(CLK_GOUT_HSI2C0_PCLK, "gout_hsi2c0_pclk", "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_HSI2C_0_PCLK, 21, 0, 0), + GATE(CLK_GOUT_HSI2C1_IPCLK, "gout_hsi2c1_ipclk", "dout_peri_hsi2c1", + CLK_CON_GAT_GOUT_PERI_HSI2C_1_IPCLK, 21, 0, 0), + GATE(CLK_GOUT_HSI2C1_PCLK, "gout_hsi2c1_pclk", "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_HSI2C_1_PCLK, 21, 0, 0), + GATE(CLK_GOUT_HSI2C2_IPCLK, "gout_hsi2c2_ipclk", "dout_peri_hsi2c2", + CLK_CON_GAT_GOUT_PERI_HSI2C_2_IPCLK, 21, 0, 0), + GATE(CLK_GOUT_HSI2C2_PCLK, "gout_hsi2c2_pclk", "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_HSI2C_2_PCLK, 21, 0, 0), + GATE(CLK_GOUT_I2C0_PCLK, "gout_i2c0_pclk", "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_I2C_0_PCLK, 21, 0, 0), + GATE(CLK_GOUT_I2C1_PCLK, "gout_i2c1_pclk", "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_I2C_1_PCLK, 21, 0, 0), + GATE(CLK_GOUT_I2C2_PCLK, "gout_i2c2_pclk", "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_I2C_2_PCLK, 21, 0, 0), + GATE(CLK_GOUT_I2C3_PCLK, "gout_i2c3_pclk", "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_I2C_3_PCLK, 21, 0, 0), + GATE(CLK_GOUT_I2C4_PCLK, "gout_i2c4_pclk", "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_I2C_4_PCLK, 21, 0, 0), + GATE(CLK_GOUT_I2C5_PCLK, "gout_i2c5_pclk", "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_I2C_5_PCLK, 21, 0, 0), + GATE(CLK_GOUT_I2C6_PCLK, "gout_i2c6_pclk", "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_I2C_6_PCLK, 21, 0, 0), + GATE(CLK_GOUT_MCT_PCLK, "gout_mct_pclk", "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_MCT_PCLK, 21, 0, 0), + GATE(CLK_GOUT_PWM_MOTOR_PCLK, "gout_pwm_motor_pclk", + "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_PWM_MOTOR_PCLK, 21, 0, 0), + GATE(CLK_GOUT_SPI0_IPCLK, "gout_spi0_ipclk", "dout_peri_spi0", + CLK_CON_GAT_GOUT_PERI_SPI_0_IPCLK, 21, 0, 0), + GATE(CLK_GOUT_SPI0_PCLK, "gout_spi0_pclk", "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_SPI_0_PCLK, 21, 0, 0), + GATE(CLK_GOUT_SYSREG_PERI_PCLK, "gout_sysreg_peri_pclk", + "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_SYSREG_PERI_PCLK, 21, 0, 0), + GATE(CLK_GOUT_UART_IPCLK, "gout_uart_ipclk", "mout_peri_uart_user", + CLK_CON_GAT_GOUT_PERI_UART_IPCLK, 21, 0, 0), + GATE(CLK_GOUT_UART_PCLK, "gout_uart_pclk", "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_UART_PCLK, 21, 0, 0), + GATE(CLK_GOUT_WDT0_PCLK, "gout_wdt0_pclk", "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_WDT_0_PCLK, 21, 0, 0), + GATE(CLK_GOUT_WDT1_PCLK, "gout_wdt1_pclk", "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_WDT_1_PCLK, 21, 0, 0), + GATE(CLK_GOUT_GPIO_PERI_PCLK, "gout_gpio_peri_pclk", + "mout_peri_bus_user", + CLK_CON_GAT_GOUT_PERI_GPIO_PERI_PCLK, 21, 0, 0), +}; + +static const struct samsung_cmu_info peri_cmu_info __initconst = { + .mux_clks = peri_mux_clks, + .nr_mux_clks = ARRAY_SIZE(peri_mux_clks), + .div_clks = peri_div_clks, + .nr_div_clks = ARRAY_SIZE(peri_div_clks), + .gate_clks = peri_gate_clks, + .nr_gate_clks = ARRAY_SIZE(peri_gate_clks), + .nr_clk_ids = PERI_NR_CLK, + .clk_regs = peri_clk_regs, + .nr_clk_regs = ARRAY_SIZE(peri_clk_regs), + .clk_name = "dout_peri_bus", +}; + +/* ---- CMU_CORE ------------------------------------------------------------ */ + +/* Register Offset definitions for CMU_CORE (0x12000000) */ +#define PLL_CON0_MUX_CLKCMU_CORE_BUS_USER 0x0600 +#define PLL_CON0_MUX_CLKCMU_CORE_CCI_USER 0x0610 +#define PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER 0x0620 +#define PLL_CON0_MUX_CLKCMU_CORE_SSS_USER 0x0630 +#define CLK_CON_MUX_MUX_CLK_CORE_GIC 0x1000 +#define CLK_CON_DIV_DIV_CLK_CORE_BUSP 0x1800 +#define CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK 0x2038 +#define CLK_CON_GAT_GOUT_CORE_GIC_CLK 0x2040 +#define CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK 0x20e8 +#define CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN 0x20ec +#define CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK 0x2128 +#define CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK 0x212c + +static const unsigned long core_clk_regs[] __initconst = { + PLL_CON0_MUX_CLKCMU_CORE_BUS_USER, + PLL_CON0_MUX_CLKCMU_CORE_CCI_USER, + PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER, + PLL_CON0_MUX_CLKCMU_CORE_SSS_USER, + CLK_CON_MUX_MUX_CLK_CORE_GIC, + CLK_CON_DIV_DIV_CLK_CORE_BUSP, + CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK, + CLK_CON_GAT_GOUT_CORE_GIC_CLK, + CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK, + CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN, + CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK, + CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK, +}; + +/* List of parent clocks for Muxes in CMU_CORE */ +PNAME(mout_core_bus_user_p) = { "oscclk", "dout_core_bus" }; +PNAME(mout_core_cci_user_p) = { "oscclk", "dout_core_cci" }; +PNAME(mout_core_mmc_embd_user_p) = { "oscclk", "dout_core_mmc_embd" }; +PNAME(mout_core_sss_user_p) = { "oscclk", "dout_core_sss" }; +PNAME(mout_core_gic_p) = { "dout_core_busp", "oscclk" }; + +static const struct samsung_mux_clock core_mux_clks[] __initconst = { + MUX(CLK_MOUT_CORE_BUS_USER, "mout_core_bus_user", mout_core_bus_user_p, + PLL_CON0_MUX_CLKCMU_CORE_BUS_USER, 4, 1), + MUX(CLK_MOUT_CORE_CCI_USER, "mout_core_cci_user", mout_core_cci_user_p, + PLL_CON0_MUX_CLKCMU_CORE_CCI_USER, 4, 1), + MUX_F(CLK_MOUT_CORE_MMC_EMBD_USER, "mout_core_mmc_embd_user", + mout_core_mmc_embd_user_p, PLL_CON0_MUX_CLKCMU_CORE_MMC_EMBD_USER, + 4, 1, CLK_SET_RATE_PARENT, 0), + MUX(CLK_MOUT_CORE_SSS_USER, "mout_core_sss_user", mout_core_sss_user_p, + PLL_CON0_MUX_CLKCMU_CORE_SSS_USER, 4, 1), + MUX(CLK_MOUT_CORE_GIC, "mout_core_gic", mout_core_gic_p, + CLK_CON_MUX_MUX_CLK_CORE_GIC, 0, 1), +}; + +static const struct samsung_div_clock core_div_clks[] __initconst = { + DIV(CLK_DOUT_CORE_BUSP, "dout_core_busp", "mout_core_bus_user", + CLK_CON_DIV_DIV_CLK_CORE_BUSP, 0, 2), +}; + +static const struct samsung_gate_clock core_gate_clks[] __initconst = { + GATE(CLK_GOUT_CCI_ACLK, "gout_cci_aclk", "mout_core_cci_user", + CLK_CON_GAT_GOUT_CORE_CCI_550_ACLK, 21, 0, 0), + GATE(CLK_GOUT_GIC_CLK, "gout_gic_clk", "mout_core_gic", + CLK_CON_GAT_GOUT_CORE_GIC_CLK, 21, 0, 0), + GATE(CLK_GOUT_MMC_EMBD_ACLK, "gout_mmc_embd_aclk", "dout_core_busp", + CLK_CON_GAT_GOUT_CORE_MMC_EMBD_I_ACLK, 21, 0, 0), + GATE(CLK_GOUT_MMC_EMBD_SDCLKIN, "gout_mmc_embd_sdclkin", + "mout_core_mmc_embd_user", CLK_CON_GAT_GOUT_CORE_MMC_EMBD_SDCLKIN, + 21, CLK_SET_RATE_PARENT, 0), + GATE(CLK_GOUT_SSS_ACLK, "gout_sss_aclk", "mout_core_sss_user", + CLK_CON_GAT_GOUT_CORE_SSS_I_ACLK, 21, 0, 0), + GATE(CLK_GOUT_SSS_PCLK, "gout_sss_pclk", "dout_core_busp", + CLK_CON_GAT_GOUT_CORE_SSS_I_PCLK, 21, 0, 0), +}; + +static const struct samsung_cmu_info core_cmu_info __initconst = { + .mux_clks = core_mux_clks, + .nr_mux_clks = ARRAY_SIZE(core_mux_clks), + .div_clks = core_div_clks, + .nr_div_clks = ARRAY_SIZE(core_div_clks), + .gate_clks = core_gate_clks, + .nr_gate_clks = ARRAY_SIZE(core_gate_clks), + .nr_clk_ids = CORE_NR_CLK, + .clk_regs = core_clk_regs, + .nr_clk_regs = ARRAY_SIZE(core_clk_regs), + .clk_name = "dout_core_bus", +}; + +/* ---- CMU_DPU ------------------------------------------------------------- */ + +/* Register Offset definitions for CMU_DPU (0x13000000) */ +#define PLL_CON0_MUX_CLKCMU_DPU_USER 0x0600 +#define CLK_CON_DIV_DIV_CLK_DPU_BUSP 0x1800 +#define CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK 0x2004 +#define CLK_CON_GAT_GOUT_DPU_ACLK_DECON0 0x2010 +#define CLK_CON_GAT_GOUT_DPU_ACLK_DMA 0x2014 +#define CLK_CON_GAT_GOUT_DPU_ACLK_DPP 0x2018 +#define CLK_CON_GAT_GOUT_DPU_PPMU_ACLK 0x2028 +#define CLK_CON_GAT_GOUT_DPU_PPMU_PCLK 0x202c +#define CLK_CON_GAT_GOUT_DPU_SMMU_CLK 0x2038 +#define CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK 0x203c + +static const unsigned long dpu_clk_regs[] __initconst = { + PLL_CON0_MUX_CLKCMU_DPU_USER, + CLK_CON_DIV_DIV_CLK_DPU_BUSP, + CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK, + CLK_CON_GAT_GOUT_DPU_ACLK_DECON0, + CLK_CON_GAT_GOUT_DPU_ACLK_DMA, + CLK_CON_GAT_GOUT_DPU_ACLK_DPP, + CLK_CON_GAT_GOUT_DPU_PPMU_ACLK, + CLK_CON_GAT_GOUT_DPU_PPMU_PCLK, + CLK_CON_GAT_GOUT_DPU_SMMU_CLK, + CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK, +}; + +/* List of parent clocks for Muxes in CMU_CORE */ +PNAME(mout_dpu_user_p) = { "oscclk", "dout_dpu" }; + +static const struct samsung_mux_clock dpu_mux_clks[] __initconst = { + MUX(CLK_MOUT_DPU_USER, "mout_dpu_user", mout_dpu_user_p, + PLL_CON0_MUX_CLKCMU_DPU_USER, 4, 1), +}; + +static const struct samsung_div_clock dpu_div_clks[] __initconst = { + DIV(CLK_DOUT_DPU_BUSP, "dout_dpu_busp", "mout_dpu_user", + CLK_CON_DIV_DIV_CLK_DPU_BUSP, 0, 3), +}; + +static const struct samsung_gate_clock dpu_gate_clks[] __initconst = { + GATE(CLK_GOUT_DPU_CMU_DPU_PCLK, "gout_dpu_cmu_dpu_pclk", + "dout_dpu_busp", CLK_CON_GAT_CLK_DPU_CMU_DPU_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_DECON0_ACLK, "gout_dpu_decon0_aclk", "mout_dpu_user", + CLK_CON_GAT_GOUT_DPU_ACLK_DECON0, 21, 0, 0), + GATE(CLK_GOUT_DPU_DMA_ACLK, "gout_dpu_dma_aclk", "mout_dpu_user", + CLK_CON_GAT_GOUT_DPU_ACLK_DMA, 21, 0, 0), + GATE(CLK_GOUT_DPU_DPP_ACLK, "gout_dpu_dpp_aclk", "mout_dpu_user", + CLK_CON_GAT_GOUT_DPU_ACLK_DPP, 21, 0, 0), + GATE(CLK_GOUT_DPU_PPMU_ACLK, "gout_dpu_ppmu_aclk", "mout_dpu_user", + CLK_CON_GAT_GOUT_DPU_PPMU_ACLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_PPMU_PCLK, "gout_dpu_ppmu_pclk", "dout_dpu_busp", + CLK_CON_GAT_GOUT_DPU_PPMU_PCLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_SMMU_CLK, "gout_dpu_smmu_clk", "mout_dpu_user", + CLK_CON_GAT_GOUT_DPU_SMMU_CLK, 21, 0, 0), + GATE(CLK_GOUT_DPU_SYSREG_PCLK, "gout_dpu_sysreg_pclk", "dout_dpu_busp", + CLK_CON_GAT_GOUT_DPU_SYSREG_PCLK, 21, 0, 0), +}; + +static const struct samsung_cmu_info dpu_cmu_info __initconst = { + .mux_clks = dpu_mux_clks, + .nr_mux_clks = ARRAY_SIZE(dpu_mux_clks), + .div_clks = dpu_div_clks, + .nr_div_clks = ARRAY_SIZE(dpu_div_clks), + .gate_clks = dpu_gate_clks, + .nr_gate_clks = ARRAY_SIZE(dpu_gate_clks), + .nr_clk_ids = DPU_NR_CLK, + .clk_regs = dpu_clk_regs, + .nr_clk_regs = ARRAY_SIZE(dpu_clk_regs), + .clk_name = "dout_dpu", +}; + +/* ---- platform_driver ----------------------------------------------------- */ + +static int __init exynos850_cmu_probe(struct platform_device *pdev) +{ + const struct samsung_cmu_info *info; + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + + info = of_device_get_match_data(dev); + exynos850_init_clocks(np, info->clk_regs, info->nr_clk_regs); + samsung_cmu_register_one(np, info); + + /* Keep bus clock running, so it's possible to access CMU registers */ + if (info->clk_name) { + struct clk *bus_clk; + + bus_clk = clk_get(dev, info->clk_name); + if (IS_ERR(bus_clk)) { + pr_err("%s: could not find bus clock %s; err = %ld\n", + __func__, info->clk_name, PTR_ERR(bus_clk)); + } else { + clk_prepare_enable(bus_clk); + } + } + + return 0; +} + +/* CMUs which belong to Power Domains and need runtime PM to be implemented */ +static const struct of_device_id exynos850_cmu_of_match[] = { + { + .compatible = "samsung,exynos850-cmu-hsi", + .data = &hsi_cmu_info, + }, { + .compatible = "samsung,exynos850-cmu-peri", + .data = &peri_cmu_info, + }, { + .compatible = "samsung,exynos850-cmu-core", + .data = &core_cmu_info, + }, { + .compatible = "samsung,exynos850-cmu-dpu", + .data = &dpu_cmu_info, + }, { + }, +}; + +static struct platform_driver exynos850_cmu_driver __refdata = { + .driver = { + .name = "exynos850-cmu", + .of_match_table = exynos850_cmu_of_match, + .suppress_bind_attrs = true, + }, + .probe = exynos850_cmu_probe, +}; + +static int __init exynos850_cmu_init(void) +{ + return platform_driver_register(&exynos850_cmu_driver); +} +core_initcall(exynos850_cmu_init);