From patchwork Thu Oct 7 19:41:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Protsenko X-Patchwork-Id: 12542819 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 15255C43219 for ; Thu, 7 Oct 2021 19:41:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DA05B610C8 for ; Thu, 7 Oct 2021 19:41:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233354AbhJGTnU (ORCPT ); Thu, 7 Oct 2021 15:43:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45796 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232940AbhJGTnM (ORCPT ); Thu, 7 Oct 2021 15:43:12 -0400 Received: from mail-lf1-x132.google.com (mail-lf1-x132.google.com [IPv6:2a00:1450:4864:20::132]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 908EEC061570 for ; Thu, 7 Oct 2021 12:41:18 -0700 (PDT) Received: by mail-lf1-x132.google.com with SMTP id y15so29488345lfk.7 for ; Thu, 07 Oct 2021 12:41:18 -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=Ix/+t+gee+jLY4mEvvcEKIS0I2uhnEhpLTqn69/kXXo=; b=yerk9gii9Yt/opJeS2cABRXKJXB6Kag06gzjeaxccuQdAA55Irt28TtHpN5h4ANCXg n1e+sosf07UhGWUtrxjduGfP+9jQmTSO91sFLSKFQromE8ri/k+NDUYacu7KbfvXDDtp f4E2b4XlSiAyqZlCzoslUh5xWfnWzXlpCR/UfUnccro4Cmw0EEpe8zMPb+bOaviEK80X 2rXh3NPj9mORk/i1bfpbdZndm7yekxk1pNZTFRiIpwFmWbrKBhD1Tq6SAjDFysQaYwPa zeHGqjFJUHYhY0cP0aDrwHhT652XU3iAozdnXjeJiEK3HZ5SQaiYA8nvayKxzRMG/B1e wJ9Q== 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=Ix/+t+gee+jLY4mEvvcEKIS0I2uhnEhpLTqn69/kXXo=; b=ieV6pOUOOTeIAaC1DkA1BQ9fKDeDBqDECZRnvJWat+v5wmRN5LYl6D5BCQIai2HWW+ cjA0V6HZVtXD2sEjzmDcT057Slt/nuapaMz/tCXwneF7Nk73poBRF6YJJteLCM/bV7Nw LyRzKxH02SdqbUDtotHcW+bk8PRcKnGRArBSYfplMwVPRDfYLYfxR2tTxCcbZvNjn0pv jy5saKQ8ZZWUN871gtMAsypvhcknNBa1mzK/GFFuRb5b9B4mN0/3S6zWKgz6qR8H+zQz tSRcE+MxYXX0w+yAsTbJviKUlQKHGaF2eM0euhH4uSkmBcXeXN9z855s90zGs1MCnk8/ 8gog== X-Gm-Message-State: AOAM532fiADLb3wrbcnvRpZEAn4A9Ke3y0J2y/SCO40vEi/5lAz9rZzV opA6dmHvTOE1dm3pAJFa/DiwJw== X-Google-Smtp-Source: ABdhPJxfFSzWGdVUFUmYc/jUPxKS9emI/NKlsUKy1TK3lHZEwVNvn+P89DNgBkpLLJZtLUJ6U+C4xg== X-Received: by 2002:a05:6512:3409:: with SMTP id i9mr5887576lfr.165.1633635676933; Thu, 07 Oct 2021 12:41:16 -0700 (PDT) Received: from localhost ([31.134.121.151]) by smtp.gmail.com with ESMTPSA id m25sm25631lji.52.2021.10.07.12.41.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Oct 2021 12:41:16 -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 v2 1/5] clk: samsung: clk-pll: Implement pll0822x PLL type Date: Thu, 7 Oct 2021 22:41:09 +0300 Message-Id: <20211007194113.10507-2-semen.protsenko@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211007194113.10507-1-semen.protsenko@linaro.org> References: <20211007194113.10507-1-semen.protsenko@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@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 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(+) 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 Thu Oct 7 19:41:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Protsenko X-Patchwork-Id: 12542821 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 29E7DC433FE for ; Thu, 7 Oct 2021 19:41:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 182856128C for ; Thu, 7 Oct 2021 19:41:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233546AbhJGTnV (ORCPT ); Thu, 7 Oct 2021 15:43:21 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45818 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240659AbhJGTnP (ORCPT ); Thu, 7 Oct 2021 15:43:15 -0400 Received: from mail-lf1-x12f.google.com (mail-lf1-x12f.google.com [IPv6:2a00:1450:4864:20::12f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ECA3FC061762 for ; Thu, 7 Oct 2021 12:41:20 -0700 (PDT) Received: by mail-lf1-x12f.google.com with SMTP id i24so27974915lfj.13 for ; Thu, 07 Oct 2021 12:41:20 -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=szxH1FnfcHfKXdtE0K3unySFXk1kX+p4ZYvH7RQ+sno=; b=pmapE8BcM9IcbxXcabEA81HjyNhL1LeYKC+1wU4C9hFMclfBhgQyXFuDFBY1aso3eW Q/aocdYRTmP+SUMcJDJEtI4LhFQF98hQ+JNm/ExImAg6sXu4oCXPBO0NidkBbfy/uh41 J271ecpLK8FKPQEIVKcCzxbNzNdeGeP6+qBaIpx9Bv2UxnDw7beBVQScrEBQlJtNMZT2 IUyLa9fDq9rW3XFdU1Eboob0KQ0D3vt2A8q4ulxKvTZea6p5P/MfXcH//HmD/8on4UQl B5LekOB5WLMn6IgF7BDYQKfyUJK4IHFqnQJVo/cs/27OKnQrkcKzBjdByGh5xvwMpLRv zdTw== 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=szxH1FnfcHfKXdtE0K3unySFXk1kX+p4ZYvH7RQ+sno=; b=4jRUPxjpwWN8rXvjEYyeXvMBiJP93Y7XJ5RdyEW9C9zAmQ9bBB/0zkChfvydotdXHN Nd1TjVzznegpw+9mJbexqahZYhgHpM23PlJ8iRw6/8CFILIsqRZB5kYDuQGEvAYMfs7t C1u2uexS5WqP0LHMM/IjXMqw0hFjtqjm+qKlrb4TWsFtSpN+hk3wGw7N64fYvvLFzuRt L3DrfE8fbPvxm01EQEXQ1qYRKD27vdgIb/OpT0cAbFni1C2Uo+dBRuP4mOrtctxgy+PZ BsChQxD/5DQVE5EqBXAbhYSyb2eT3+nPbeIt+P+WT89pkAvAHNh9/zntnoO/baxo3+Pj wO6A== X-Gm-Message-State: AOAM531ExrXo1WRQdKok3gxcr5NI+2qmyvXFyIngfM3CoDqjXDiu9srK DgFRteg6hqhUIl6GxP4a1XYT7w== X-Google-Smtp-Source: ABdhPJy+idmh6ArX2mvYOeEExL9vWJRmnj/dvH7Px73ZSky/FieDaKme08oFQKLjinkGKmo5AmXE6w== X-Received: by 2002:ac2:54a6:: with SMTP id w6mr5984234lfk.510.1633635678541; Thu, 07 Oct 2021 12:41:18 -0700 (PDT) Received: from localhost ([31.134.121.151]) by smtp.gmail.com with ESMTPSA id t17sm21503lft.296.2021.10.07.12.41.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Oct 2021 12:41:18 -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 v2 2/5] clk: samsung: clk-pll: Implement pll0831x PLL type Date: Thu, 7 Oct 2021 22:41:10 +0300 Message-Id: <20211007194113.10507-3-semen.protsenko@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211007194113.10507-1-semen.protsenko@linaro.org> References: <20211007194113.10507-1-semen.protsenko@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org pll0831x PLL is used in Exynos850 SoC for top-level fractional PLLs. The code was derived from very similar pll36xx type, with next differences: 1. Lock time for pll0831x is 500*P_DIV, when for pll36xx it's 3000*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 pll36xx implementation) 3. The offset from PMS-values register to K-value register is 0x8 for pll0831x, when for pll36xx it's 0x4 When defining pll0831x type, CON3 register offset should be provided as a "con" parameter of PLL() macro, like this: PLL(pll_0831x, 0, "fout_mmc_pll", "oscclk", PLL_LOCKTIME_PLL_MMC, PLL_CON3_PLL_MMC, pll0831x_26mhz_tbl), To define PLL rates table, one can use PLL_36XX_RATE() macro, e.g.: PLL_36XX_RATE(26 * MHZ, 799999877, 31, 1, 0, -15124) as it's completely appropriate for pl0831x 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_mmc_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 v2: - Added R-b tag by Krzysztof Kozlowski - Added Ack tag by Chanwoo Choi drivers/clk/samsung/clk-pll.c | 105 ++++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk-pll.h | 1 + 2 files changed, 106 insertions(+) diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 03131b149c0b..83d1b03647db 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -498,6 +498,103 @@ static const struct clk_ops samsung_pll0822x_clk_min_ops = { .recalc_rate = samsung_pll0822x_recalc_rate, }; +/* + * PLL0831x Clock Type + */ +/* Maximum lock time can be 500 * PDIV cycles */ +#define PLL0831X_LOCK_FACTOR (500) + +#define PLL0831X_KDIV_MASK (0xFFFF) +#define PLL0831X_MDIV_MASK (0x1FF) +#define PLL0831X_PDIV_MASK (0x3F) +#define PLL0831X_SDIV_MASK (0x7) +#define PLL0831X_MDIV_SHIFT (16) +#define PLL0831X_PDIV_SHIFT (8) +#define PLL0831X_SDIV_SHIFT (0) +#define PLL0831X_KDIV_SHIFT (0) +#define PLL0831X_LOCK_STAT_SHIFT (29) +#define PLL0831X_ENABLE_SHIFT (31) + +static unsigned long samsung_pll0831x_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, pll_con5; + s16 kdiv; + u64 fvco = parent_rate; + + pll_con3 = readl_relaxed(pll->con_reg); + pll_con5 = readl_relaxed(pll->con_reg + 8); + mdiv = (pll_con3 >> PLL0831X_MDIV_SHIFT) & PLL0831X_MDIV_MASK; + pdiv = (pll_con3 >> PLL0831X_PDIV_SHIFT) & PLL0831X_PDIV_MASK; + sdiv = (pll_con3 >> PLL0831X_SDIV_SHIFT) & PLL0831X_SDIV_MASK; + kdiv = (s16)((pll_con5 >> PLL0831X_KDIV_SHIFT) & PLL0831X_KDIV_MASK); + + fvco *= (mdiv << 16) + kdiv; + do_div(fvco, (pdiv << sdiv)); + fvco >>= 16; + + return (unsigned long)fvco; +} + +static int samsung_pll0831x_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long parent_rate) +{ + const struct samsung_pll_rate_table *rate; + struct samsung_clk_pll *pll = to_clk_pll(hw); + u32 pll_con3, pll_con5; + + /* 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; + } + + pll_con3 = readl_relaxed(pll->con_reg); + pll_con5 = readl_relaxed(pll->con_reg + 8); + + /* Change PLL PMSK values */ + pll_con3 &= ~((PLL0831X_MDIV_MASK << PLL0831X_MDIV_SHIFT) | + (PLL0831X_PDIV_MASK << PLL0831X_PDIV_SHIFT) | + (PLL0831X_SDIV_MASK << PLL0831X_SDIV_SHIFT)); + pll_con3 |= (rate->mdiv << PLL0831X_MDIV_SHIFT) | + (rate->pdiv << PLL0831X_PDIV_SHIFT) | + (rate->sdiv << PLL0831X_SDIV_SHIFT); + pll_con5 &= ~(PLL0831X_KDIV_MASK << PLL0831X_KDIV_SHIFT); + /* + * kdiv is 16-bit 2's complement (s16), but stored as unsigned int. + * Cast it to u16 to avoid leading 0xffff's in case of negative value. + */ + pll_con5 |= ((u16)rate->kdiv << PLL0831X_KDIV_SHIFT); + + /* Set PLL lock time */ + writel_relaxed(rate->pdiv * PLL0831X_LOCK_FACTOR, pll->lock_reg); + + /* Write PMSK values */ + writel_relaxed(pll_con3, pll->con_reg); + writel_relaxed(pll_con5, pll->con_reg + 8); + + /* 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_pll0831x_clk_ops = { + .recalc_rate = samsung_pll0831x_recalc_rate, + .set_rate = samsung_pll0831x_set_rate, + .round_rate = samsung_pll_round_rate, + .enable = samsung_pll3xxx_enable, + .disable = samsung_pll3xxx_disable, +}; + +static const struct clk_ops samsung_pll0831x_clk_min_ops = { + .recalc_rate = samsung_pll0831x_recalc_rate, +}; + /* * PLL45xx Clock Type */ @@ -1407,6 +1504,14 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, else init.ops = &samsung_pll36xx_clk_ops; break; + case pll_0831x: + pll->enable_offs = PLL0831X_ENABLE_SHIFT; + pll->lock_offs = PLL0831X_LOCK_STAT_SHIFT; + if (!pll->rate_table) + init.ops = &samsung_pll0831x_clk_min_ops; + else + init.ops = &samsung_pll0831x_clk_ops; + break; case pll_6552: case pll_6552_s3c2416: init.ops = &samsung_pll6552_clk_ops; diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h index 213e94a97f23..a739f2b7ae80 100644 --- a/drivers/clk/samsung/clk-pll.h +++ b/drivers/clk/samsung/clk-pll.h @@ -37,6 +37,7 @@ enum samsung_pll_type { pll_1452x, pll_1460x, pll_0822x, + pll_0831x, }; #define PLL_RATE(_fin, _m, _p, _s, _k, _ks) \ From patchwork Thu Oct 7 19:41:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Protsenko X-Patchwork-Id: 12542823 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03375C4167B for ; Thu, 7 Oct 2021 19:41:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E3EA760FC4 for ; Thu, 7 Oct 2021 19:41:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240913AbhJGTnX (ORCPT ); Thu, 7 Oct 2021 15:43:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45828 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240916AbhJGTnQ (ORCPT ); Thu, 7 Oct 2021 15:43:16 -0400 Received: from mail-lf1-x134.google.com (mail-lf1-x134.google.com [IPv6:2a00:1450:4864:20::134]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AC85BC061760 for ; Thu, 7 Oct 2021 12:41:21 -0700 (PDT) Received: by mail-lf1-x134.google.com with SMTP id n8so27620735lfk.6 for ; Thu, 07 Oct 2021 12:41:21 -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=46iuhOb9uD5HMcYrx3e2dCS6IBSe8aDIKLjR7qB7Wnw=; b=WTFx9T9C0qLb2ShAwHl4LdZ7kljyeIuarX39bl2xJ7vuEaerr9/CQiIKQ/S093wMmh tMGnaeJd0uK/Jt81rt2S/mIyji6wlbGc41uFBGZVMskxD/WgYd2gWB7YqwsOuq3uSqJX pB8jfxhU1mL7C3lw0sa/r6IJzv8dWIf/bxjKPv4gr6pfYOaOegpVSnyzqYiIPQmlJSaZ h9kNstHPAacH9OkL5VX+f6G23ZuhfgTLFgUk6to6U+48KiVz6Djcsi4396LkvVvybA2r PJimHajunXYEW7MKaEObuL96Msa66t1wnuRdGsv3WId0NJcMgGtHId6LcaE4FDCKlkgf RJnw== 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=46iuhOb9uD5HMcYrx3e2dCS6IBSe8aDIKLjR7qB7Wnw=; b=I51pBR3fB6Ddi5lV7as+1KgISEjhAsdVkC6C91GWc3ejRanB+lz8fOS+RDwyqnJybQ gMK1Ab7ztFgH31LLT31T1720gw+8CLtnuAnW7m+Ktq6llv94PdYFlzSGABUfKVGdJD0u bKMHmV0Vz7yNhxKJeHen/qgrs5kO/UXTUXQZEmXhx/DRpoZDK0rz8tTv0YeYhGwAIotE jsXx4cHNoS687tos6NcujlCKa87U+m/y4hKr+JUHsJSdO0wAGmVuEjekozTUAl+oEJGq lDYSmha1LCtNc0XmdV+5MhddkTavZEmy6BgDGxjxYztdb4LliT/0XI9gYL8flaOfagST HyoA== X-Gm-Message-State: AOAM532rGn4EVWjMVkUcrZ/i3dm9ePyzmBGJpEckJv8Ai2xoledCVTMv igxF2DOXiSMCOTGwHMwoVKc8Dg== X-Google-Smtp-Source: ABdhPJywEe3ssZX1R30cigIvdDneToqP9gIQk/6ExXsJJIqw5FZGY0VntlfY4kPbpDHG9Ucw/svIow== X-Received: by 2002:a05:6512:10cf:: with SMTP id k15mr5888412lfg.617.1633635680035; Thu, 07 Oct 2021 12:41:20 -0700 (PDT) Received: from localhost ([31.134.121.151]) by smtp.gmail.com with ESMTPSA id n7sm21269lft.309.2021.10.07.12.41.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Oct 2021 12:41:19 -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 v2 3/5] dt-bindings: clock: Add bindings definitions for Exynos850 CMU Date: Thu, 7 Oct 2021 22:41:11 +0300 Message-Id: <20211007194113.10507-4-semen.protsenko@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211007194113.10507-1-semen.protsenko@linaro.org> References: <20211007194113.10507-1-semen.protsenko@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@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 Acked-by: Chanwoo Choi --- 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 diff --git a/include/dt-bindings/clock/exynos850.h b/include/dt-bindings/clock/exynos850.h new file mode 100644 index 000000000000..a44c5f91d3c7 --- /dev/null +++ b/include/dt-bindings/clock/exynos850.h @@ -0,0 +1,141 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * 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 Thu Oct 7 19:41:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Protsenko X-Patchwork-Id: 12542825 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D7EAC4167E for ; Thu, 7 Oct 2021 19:41:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3496260FC2 for ; Thu, 7 Oct 2021 19:41:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233532AbhJGTnY (ORCPT ); Thu, 7 Oct 2021 15:43:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45836 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241309AbhJGTnR (ORCPT ); Thu, 7 Oct 2021 15:43:17 -0400 Received: from mail-lf1-x12c.google.com (mail-lf1-x12c.google.com [IPv6:2a00:1450:4864:20::12c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 37B14C061755 for ; Thu, 7 Oct 2021 12:41:23 -0700 (PDT) Received: by mail-lf1-x12c.google.com with SMTP id j21so11494930lfe.0 for ; Thu, 07 Oct 2021 12:41:23 -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=6qypjTcxQ7XQKBuiOwqn5g+UY0WDWTYynbpPAmde6MA=; b=Byf34ukrpWPrWz8IZz8w9qcSwzWA8mrQitD8/gm5xPSQ7A4U73QOfddicwA8aQ/PZq VE//d6HefRiFkfqe2GBFGKAkOFdSHgusQ7f+sTS5XBaef4a64B4E/XwwJoqaXLuUn8aV D3aDiCpaXxCokr4X1iW5AnUdcqlylPxOPCv8joD7BWcBBhmNo6pj97F+8g2QI6aEpmLM QMAdhm0Vw3cq/fBfgJqQL/lvQLKoRgHfyu/nIOYyiOGHnhqKC3LjUKdLwXKZdPFIB42X Cd04GRckN28UJM7C2wXsW86nT1mGeY7mIATawdeZT+5lZ0L+ke89XCq3bfwFBI4ayzHA PCDQ== 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=6qypjTcxQ7XQKBuiOwqn5g+UY0WDWTYynbpPAmde6MA=; b=GLcfxfOlYVqzQsu26+Vz1UCSW68gSqbV93y7Y5f+/2Oy8r+cMOtBH2W6UkgZ0CO4f1 v/apq3eMILxcKuDEsO8I3I3IQR9S6OIwYbVCaCGiMzLJNtksySl+y9ck1IFrQP7v+8ro mEBjT819FJNdCLF7F90oUgttQjsxFtEMBKvajs7654qOk9rHRjEssrB7XJIBEUkoiAui /Wm1FP1HndU2AXg3C/5HtMynXZlOGunsHpTSo+m0UUYcMOKJljRFbeTvUtNSwJyI3biT ECjsMq5Ar4GUMUmqj94Zdw3gOkBsUb/Hp9vmM/ELItME63IC0AkhVPvPoK052PaMU4wq pdXA== X-Gm-Message-State: AOAM533pd8+2/Av2S1v773XWXNtknjKsOsfecs8r+u2ZQKzst7KbH3NX bd5KpG6YYEFvhMqvV5xpyVH+mQ== X-Google-Smtp-Source: ABdhPJw1QADHTDExJHD/8BVAYf2IKTwIG+OK6TZHVQtQj1M1kyPY0A+Xpq0zE3Hc6qlvMAIy+T80TA== X-Received: by 2002:a05:6512:692:: with SMTP id t18mr5618211lfe.572.1633635681608; Thu, 07 Oct 2021 12:41:21 -0700 (PDT) Received: from localhost ([31.134.121.151]) by smtp.gmail.com with ESMTPSA id r11sm22598lfn.224.2021.10.07.12.41.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Oct 2021 12:41:21 -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 v2 4/5] dt-bindings: clock: Document Exynos850 CMU bindings Date: Thu, 7 Oct 2021 22:41:12 +0300 Message-Id: <20211007194113.10507-5-semen.protsenko@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211007194113.10507-1-semen.protsenko@linaro.org> References: <20211007194113.10507-1-semen.protsenko@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org Provide dt-schema documentation for Exynos850 SoC clock controller. Signed-off-by: Sam Protsenko Acked-by: Chanwoo Choi Reviewed-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 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 Thu Oct 7 19:41:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Protsenko X-Patchwork-Id: 12542827 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 28AE2C4332F for ; Thu, 7 Oct 2021 19:41:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0BFDE60FC2 for ; Thu, 7 Oct 2021 19:41:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232813AbhJGTnZ (ORCPT ); Thu, 7 Oct 2021 15:43:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45858 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232993AbhJGTnU (ORCPT ); Thu, 7 Oct 2021 15:43:20 -0400 Received: from mail-lf1-x12e.google.com (mail-lf1-x12e.google.com [IPv6:2a00:1450:4864:20::12e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6EBA4C061760 for ; Thu, 7 Oct 2021 12:41:25 -0700 (PDT) Received: by mail-lf1-x12e.google.com with SMTP id z11so21044969lfj.4 for ; Thu, 07 Oct 2021 12:41:25 -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=N7HkEWmvmDT1s/g4DOYlTdSS9GJxB9tTAocI5c6A++s=; b=YZc80jwlF3VWTPTT6RRxhA6hgeFu5O5qMhu6l/YGQZyWWZYtk+FUakS5JDhYQlUvMM AENVx4sht/lEkGRDMaLLOzSBLv76Mu0MrkNdSIey2GWeyUe8NXEz5jJbVjbCM+wfcFxO Y8pj2dGKTAOzZrYQFBk07NJdWo8bq5uPG2wg4cFPJSNCC2WFaS6YvBwaAHFNtFCa6V/W xzQh3rY/TeNp8eaD/H7JMukOsulyRSRu+DHf72fuz08gJTwxA8wDh2ENCt8hRYs3UPsn 7qkNOGyRoLcnq2mFFPYg/BkM1cyRsmQKSA0yvegyZjOS1wH9gU6wZQ9F8HYXqHfH8rq2 siUA== 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=N7HkEWmvmDT1s/g4DOYlTdSS9GJxB9tTAocI5c6A++s=; b=MxeQLM/ceXXARBbzipHN7fvRVIFosAT2uFHWB/+97GMlHJlxlHHZmctcalqItQpWNx bbplzojUdzT2x8XY6WfP5WuIcCZUx6YlOkXDUOTtryk6hJiP7tO97QBV5teegyB0XlL2 Nw09rNVU76pdI/nRjIn7xaXA5tISieN9igX+Nh3cfp9a1Czlny8aP37ZtIL0iAu+idRH xAPTjixQPdnckjwiANhepiIG3RBaxM6ZmhxdHCCgUhqx+HJW05VhlXwUY6vKav6pzxL8 RvGnYvEbbJ1IwzLsyxVakJBbtGkyEZEVwQkxV/e4o4VN64dxmPv0ept1u9kdnuVJCDUM dezQ== X-Gm-Message-State: AOAM532kpkuEdVOC3iw3/JTw1lBOPJgsWA4otUGF8GBwkAAodcV8xY3r RQ6Nf+g9K1rW66XxEUGii3NKpw== X-Google-Smtp-Source: ABdhPJx85S1JRPWgKtFePBc2wEOu7yY0+JnyXplwS9tfdBiPA2rvbMGQii3UiBkJtMlOJm1DA5YLDw== X-Received: by 2002:a2e:9f10:: with SMTP id u16mr6347336ljk.143.1633635683429; Thu, 07 Oct 2021 12:41:23 -0700 (PDT) Received: from localhost ([31.134.121.151]) by smtp.gmail.com with ESMTPSA id j20sm24619lfb.85.2021.10.07.12.41.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 07 Oct 2021 12:41:22 -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 v2 5/5] clk: samsung: Introduce Exynos850 clock driver Date: Thu, 7 Oct 2021 22:41:13 +0300 Message-Id: <20211007194113.10507-6-semen.protsenko@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211007194113.10507-1-semen.protsenko@linaro.org> References: <20211007194113.10507-1-semen.protsenko@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@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 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 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);