From patchwork Tue Jan 22 09:31:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacky Bai X-Patchwork-Id: 10775151 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EC85D91E for ; Tue, 22 Jan 2019 09:31:54 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D795E29E0A for ; Tue, 22 Jan 2019 09:31:54 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C992A2A27E; Tue, 22 Jan 2019 09:31:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id E0CBB29E0A for ; Tue, 22 Jan 2019 09:31:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727244AbfAVJbt (ORCPT ); Tue, 22 Jan 2019 04:31:49 -0500 Received: from mail-eopbgr140077.outbound.protection.outlook.com ([40.107.14.77]:54027 "EHLO EUR01-VE1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727165AbfAVJbt (ORCPT ); Tue, 22 Jan 2019 04:31:49 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=HBwZMiNJdsNfm1PcGjgb0ELKcb7ZoFcjt4XvmI/8DZU=; b=ZV4FxH04Y2zG/L7Pxt+8kPbUPuRi3P/8sPEOJDyvd09tpDuE+tAFwU3Ird7RcuCOIZPfNTSQcJ2FCQd7aLy0PokVeWEOnfgrrViglqMDSKQyhGOZHmOJS/zdrNMaPQfS8jFY4VIv0thr3dQR2XuVHU0CYWP15HpUDkcXlyvXgIY= Received: from VI1PR0402MB3519.eurprd04.prod.outlook.com (52.134.4.24) by VI1PR0402MB3405.eurprd04.prod.outlook.com (52.134.1.154) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1537.30; Tue, 22 Jan 2019 09:31:42 +0000 Received: from VI1PR0402MB3519.eurprd04.prod.outlook.com ([fe80::85ec:f90c:2a0c:20d3]) by VI1PR0402MB3519.eurprd04.prod.outlook.com ([fe80::85ec:f90c:2a0c:20d3%4]) with mapi id 15.20.1537.031; Tue, 22 Jan 2019 09:31:42 +0000 From: Jacky Bai To: "sboyd@kernel.org" , "mturquette@baylibre.com" , "robh+dt@kernel.org" , "shawnguo@kernel.org" CC: Fabio Estevam , Aisheng Dong , dl-linux-imx , "linux-clk@vger.kernel.org" , "devicetree@vger.kernel.org" Subject: [PATCH v2 1/3] clk: imx: Add PLLs driver for imx8mm soc Thread-Topic: [PATCH v2 1/3] clk: imx: Add PLLs driver for imx8mm soc Thread-Index: AQHUsjVIBczI4/Ci0EGW39AF7NgRxg== Date: Tue, 22 Jan 2019 09:31:41 +0000 Message-ID: <1548149769-32267-1-git-send-email-ping.bai@nxp.com> Accept-Language: zh-CN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-mailer: git-send-email 1.9.1 x-clientproxiedby: HK0P153CA0015.APCP153.PROD.OUTLOOK.COM (2603:1096:203:18::27) To VI1PR0402MB3519.eurprd04.prod.outlook.com (2603:10a6:803:8::24) authentication-results: spf=none (sender IP is ) smtp.mailfrom=ping.bai@nxp.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [119.31.174.71] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1;VI1PR0402MB3405;6:+izjEGQgwFpgeY4zb+wAAKgAg7pi5hogOtYCOcBy5pJ6IDK7Exb5128u1ptj0CUTx4Cg0rBbDvFJtffq5a8GrPggbBA7LY8XXawsM8fVZUp7yzurId5jBTxOtKj3F/Ux3eIirCJndYEzpwqPZvSOmRUI3+r3YX4Axcacn4j7L74YXsZd99xqlOcwcPveNJnF2+U8TJXcsF35VOPMwK3XgbFcyTbnnGqsjpgvVByEq8MeMf9fyIqicN/5+s3kypeLsaoUn93pFlwfe3dm21NfitwYY08LbmC6G3T3fNbuWYTR/9lXErKFDUZkqruSF522pjP3iSIh4SttLgE1WsLDIVvH3/AJPePKXkJ+lMRyLqDTv0J6/ePMgQrrZMU7kS9gppmZmZAc5MyrS+BP4FQStj/Nl/OUGfzMh6Lx+S6tDeiJq1wQH0rT9uOKPLASpg9edEuCMju6/KSSQ2QJez0ezQ==;5:oOeM0OvuKgWyngMcC2ic3oOggo7UsOFbfWD9lzs3f7e082zoqedkYicwY6LRGHvP9Af9ORsYn/+0jbRfIDK4WNJIAnZ4svub7kxkqubD7FGz94rH2l/DWLEQ6t4D3moR+yhpLzPlloe63QS0dY2mBhH9B/mvE15p/VztijJLhxX9s/K1Gn6aJWOqrjHTl/wmj1oDSht8HqXnVJ8G8VVPEQ==;7:XKjhOltHBVVHLpRdFvymXrwxb9d5cqvSjOMdHALU8Kc09Ltc1pyRQ/rSkkHNiKDQOwsqCWDYanpMSVghTYLRMYlBfkZe0gNZV8qUlrTrY1ryNXX6ui/jApE4QuwcdmfbLGCnIvVTMWMIlHhVPDFbiQ== x-ms-office365-filtering-correlation-id: dddd4a03-d3cb-4a8f-4987-08d6804c6a8c x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600109)(711020)(4618075)(2017052603328)(7153060)(7193020);SRVR:VI1PR0402MB3405; x-ms-traffictypediagnostic: VI1PR0402MB3405: x-microsoft-antispam-prvs: x-forefront-prvs: 0925081676 x-forefront-antispam-report: SFV:NSPM;SFS:(10009020)(39860400002)(136003)(376002)(396003)(346002)(366004)(199004)(189003)(102836004)(81156014)(2906002)(97736004)(81166006)(26005)(66066001)(3846002)(6116002)(71190400001)(71200400001)(186003)(7736002)(4326008)(99286004)(486006)(6436002)(305945005)(8676002)(386003)(6506007)(36756003)(476003)(2616005)(105586002)(14444005)(256004)(6486002)(2501003)(25786009)(316002)(106356001)(8936002)(54906003)(52116002)(86362001)(478600001)(110136005)(50226002)(6512007)(14454004)(30864003)(68736007)(53936002)(32563001);DIR:OUT;SFP:1101;SCL:1;SRVR:VI1PR0402MB3405;H:VI1PR0402MB3519.eurprd04.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;A:1;MX:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: SIDWmKgnjHc1OpASFyxfG+dqemUWVUk6dwYpSQQaLaQNPTQZUOq8GGPDOwLH7KkC3Jbwy3Rx/F/MLCpzOFaJIQ7BBjWbGCdHH/CBoLv3dJzV/dgKlkWZW7+ve2giSfB4F4CSKv5YmBzX6coUTZyA67HuNsX4V7fUSUSGOLSSSVvEe+PlpMcHPDdzfc6+ew38a0ss9RM5RhK3NpJ9+6ncICYcqJSPwiTHSrJOVZKBeSw+xAEbR00pSCLdlrox0niIOSzPFtJpLytfun5CZ5tFk1kZ0XB1PqulO/USjGxphYL0Q97htyH2uwRWr6LjnWV0Q0sVG1ti6aPx86HDiqKtqlPadO/f4SDHcV9agM12gY/6Jls6htwZA13iTE014cnmEPyxeUnnaOFO1hbRZ2tyXXyIWYJy3Q7tEtB/e9VoBbM= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: dddd4a03-d3cb-4a8f-4987-08d6804c6a8c X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Jan 2019 09:31:38.1900 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0402MB3405 Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Bai Ping New PLLs are introduced on i.MX8M Mini SOC. PLL1416X is Integer PLL, PLL1443X is a Frac PLL. Signed-off-by: Bai Ping --- change v1->v2 - remove the unnecessary parenthesis & brackets - use readl_poll_timeout for pll lock check --- drivers/clk/imx/Makefile | 3 +- drivers/clk/imx/clk-pll14xx.c | 392 ++++++++++++++++++++++++++++++++++++++++++ drivers/clk/imx/clk.h | 24 +++ 3 files changed, 418 insertions(+), 1 deletion(-) create mode 100644 drivers/clk/imx/clk-pll14xx.c diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index 73119fb..ff74287 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -18,7 +18,8 @@ obj-$(CONFIG_MXC_CLK) += \ clk-pllv2.o \ clk-pllv3.o \ clk-pllv4.o \ - clk-sccg-pll.o + clk-sccg-pll.o \ + clk-pll14xx.o obj-$(CONFIG_MXC_CLK_SCU) += \ clk-scu.o \ diff --git a/drivers/clk/imx/clk-pll14xx.c b/drivers/clk/imx/clk-pll14xx.c new file mode 100644 index 0000000..1acfa3e --- /dev/null +++ b/drivers/clk/imx/clk-pll14xx.c @@ -0,0 +1,392 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2017-2018 NXP. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "clk.h" + +#define GNRL_CTL 0x0 +#define DIV_CTL 0x4 +#define LOCK_STATUS BIT(31) +#define LOCK_SEL_MASK BIT(29) +#define CLKE_MASK BIT(11) +#define RST_MASK BIT(9) +#define BYPASS_MASK BIT(4) +#define MDIV_SHIFT 12 +#define MDIV_MASK GENMASK(21, 12) +#define PDIV_SHIFT 4 +#define PDIV_MASK GENMASK(9, 4) +#define SDIV_SHIFT 0 +#define SDIV_MASK GENMASK(2, 0) +#define KDIV_SHIFT 0 +#define KDIV_MASK GENMASK(15, 0) + +#define LOCK_TIMEOUT_US 10000 + +struct clk_pll14xx { + struct clk_hw hw; + void __iomem *base; + enum imx_pll14xx_type type; + const struct imx_pll14xx_rate_table *rate_table; + int rate_count; +}; + +#define to_clk_pll14xx(_hw) container_of(_hw, struct clk_pll14xx, hw) + +static const struct imx_pll14xx_rate_table *imx_get_pll_settings( + struct clk_pll14xx *pll, unsigned long rate) +{ + const struct imx_pll14xx_rate_table *rate_table = pll->rate_table; + int i; + + for (i = 0; i < pll->rate_count; i++) + if (rate == rate_table[i].rate) + return &rate_table[i]; + + return NULL; +} + +static long clk_pll14xx_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + struct clk_pll14xx *pll = to_clk_pll14xx(hw); + const struct imx_pll14xx_rate_table *rate_table = pll->rate_table; + int i; + + /* Assumming rate_table is in descending order */ + for (i = 0; i < pll->rate_count; i++) + if (rate >= rate_table[i].rate) + return rate_table[i].rate; + + /* return minimum supported value */ + return rate_table[i - 1].rate; +} + +static unsigned long clk_pll1416x_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pll14xx *pll = to_clk_pll14xx(hw); + u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div; + u64 fvco = parent_rate; + + pll_gnrl = readl_relaxed(pll->base); + pll_div = readl_relaxed(pll->base + 4); + mdiv = (pll_div & MDIV_MASK) >> MDIV_SHIFT; + pdiv = (pll_div & PDIV_MASK) >> PDIV_SHIFT; + sdiv = (pll_div & SDIV_MASK) >> SDIV_SHIFT; + + fvco *= mdiv; + do_div(fvco, pdiv << sdiv); + + return fvco; +} + +static unsigned long clk_pll1443x_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_pll14xx *pll = to_clk_pll14xx(hw); + u32 mdiv, pdiv, sdiv, pll_gnrl, pll_div_ctl0, pll_div_ctl1; + short int kdiv; + u64 fvco = parent_rate; + + pll_gnrl = readl_relaxed(pll->base); + pll_div_ctl0 = readl_relaxed(pll->base + 4); + pll_div_ctl1 = readl_relaxed(pll->base + 8); + mdiv = (pll_div_ctl0 & MDIV_MASK) >> MDIV_SHIFT; + pdiv = (pll_div_ctl0 & PDIV_MASK) >> PDIV_SHIFT; + sdiv = (pll_div_ctl0 & SDIV_MASK) >> SDIV_SHIFT; + kdiv = pll_div_ctl1 & KDIV_MASK; + + /* fvco = (m * 65536 + k) * Fin / (p * 65536) */ + fvco *= (mdiv * 65536 + kdiv); + pdiv *= 65536; + + do_div(fvco, pdiv << sdiv); + + return fvco; +} + +static inline bool clk_pll1416x_mp_change(const struct imx_pll14xx_rate_table *rate, + u32 pll_div) +{ + u32 old_mdiv, old_pdiv; + + old_mdiv = (pll_div >> MDIV_SHIFT) & MDIV_MASK; + old_pdiv = (pll_div >> PDIV_SHIFT) & PDIV_MASK; + + return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv; +} + +static inline bool clk_pll1443x_mpk_change(const struct imx_pll14xx_rate_table *rate, + u32 pll_div_ctl0, u32 pll_div_ctl1) +{ + u32 old_mdiv, old_pdiv, old_kdiv; + + old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK; + old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK; + old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK; + + return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv || + rate->kdiv != old_kdiv; +} + +static inline bool clk_pll1443x_mp_change(const struct imx_pll14xx_rate_table *rate, + u32 pll_div_ctl0, u32 pll_div_ctl1) +{ + u32 old_mdiv, old_pdiv, old_kdiv; + + old_mdiv = (pll_div_ctl0 >> MDIV_SHIFT) & MDIV_MASK; + old_pdiv = (pll_div_ctl0 >> PDIV_SHIFT) & PDIV_MASK; + old_kdiv = (pll_div_ctl1 >> KDIV_SHIFT) & KDIV_MASK; + + return rate->mdiv != old_mdiv || rate->pdiv != old_pdiv || + rate->kdiv != old_kdiv; +} + +static int clk_pll14xx_wait_lock(struct clk_pll14xx *pll) +{ + u32 val; + + return readl_poll_timeout(pll->base, val, val & LOCK_TIMEOUT_US, 0, + LOCK_TIMEOUT_US); +} + +static int clk_pll1416x_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long prate) +{ + struct clk_pll14xx *pll = to_clk_pll14xx(hw); + const struct imx_pll14xx_rate_table *rate; + u32 tmp, div_val; + int ret; + + rate = imx_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; + } + + tmp = readl_relaxed(pll->base + 4); + + if (!clk_pll1416x_mp_change(rate, tmp)) { + tmp &= ~(SDIV_MASK) << SDIV_SHIFT; + tmp |= rate->sdiv << SDIV_SHIFT; + writel_relaxed(tmp, pll->base + 4); + + return 0; + } + + /* Bypass clock and set lock to pll output lock */ + tmp = readl_relaxed(pll->base); + tmp |= LOCK_SEL_MASK; + writel_relaxed(tmp, pll->base); + + /* Enable RST */ + tmp &= ~RST_MASK; + writel_relaxed(tmp, pll->base); + + div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) | + (rate->sdiv << SDIV_SHIFT); + writel_relaxed(div_val, pll->base + 0x4); + + /* + * According to SPEC, t3 - t2 need to be greater than + * 1us and 1/FREF, respectively. + * FREF is FIN / Prediv, the prediv is [1, 63], so choose + * 3us. + */ + udelay(3); + + /* Disable RST */ + tmp |= RST_MASK; + writel_relaxed(tmp, pll->base); + + /* Wait Lock */ + ret = clk_pll14xx_wait_lock(pll); + if (ret) + return ret; + + /* Bypass */ + tmp &= ~BYPASS_MASK; + writel_relaxed(tmp, pll->base); + + return 0; +} + +static int clk_pll1443x_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long prate) +{ + struct clk_pll14xx *pll = to_clk_pll14xx(hw); + const struct imx_pll14xx_rate_table *rate; + u32 tmp, div_val; + int ret; + + rate = imx_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; + } + + tmp = readl_relaxed(pll->base + 4); + div_val = readl_relaxed(pll->base + 8); + + if (!clk_pll1443x_mpk_change(rate, tmp, div_val)) { + tmp &= ~(SDIV_MASK) << SDIV_SHIFT; + tmp |= rate->sdiv << SDIV_SHIFT; + writel_relaxed(tmp, pll->base + 4); + + return 0; + } + + /* Enable RST */ + tmp = readl_relaxed(pll->base); + tmp &= ~RST_MASK; + writel_relaxed(tmp, pll->base); + + div_val = (rate->mdiv << MDIV_SHIFT) | (rate->pdiv << PDIV_SHIFT) | + (rate->sdiv << SDIV_SHIFT); + writel_relaxed(div_val, pll->base + 0x4); + writel_relaxed(rate->kdiv << KDIV_SHIFT, pll->base + 0x8); + + /* + * According to SPEC, t3 - t2 need to be greater than + * 1us and 1/FREF, respectively. + * FREF is FIN / Prediv, the prediv is [1, 63], so choose + * 3us. + */ + udelay(3); + + /* Disable RST */ + tmp |= RST_MASK; + writel_relaxed(tmp, pll->base); + + /* Wait Lock*/ + ret = clk_pll14xx_wait_lock(pll); + if (ret) + return ret; + + /* Bypass */ + tmp &= ~BYPASS_MASK; + writel_relaxed(tmp, pll->base); + + return 0; +} + +static int clk_pll14xx_prepare(struct clk_hw *hw) +{ + struct clk_pll14xx *pll = to_clk_pll14xx(hw); + u32 val; + + /* + * RESETB = 1 from 0, PLL starts its normal + * operation after lock time + */ + val = readl_relaxed(pll->base + GNRL_CTL); + val |= RST_MASK; + writel_relaxed(val, pll->base + GNRL_CTL); + + return clk_pll14xx_wait_lock(pll); +} + +static int clk_pll14xx_is_prepared(struct clk_hw *hw) +{ + struct clk_pll14xx *pll = to_clk_pll14xx(hw); + u32 val; + + val = readl_relaxed(pll->base + GNRL_CTL); + + return (val & RST_MASK) ? 1 : 0; +} + +static void clk_pll14xx_unprepare(struct clk_hw *hw) +{ + struct clk_pll14xx *pll = to_clk_pll14xx(hw); + u32 val; + + /* + * Set RST to 0, power down mode is enabled and + * every digital block is reset + */ + val = readl_relaxed(pll->base + GNRL_CTL); + val &= ~RST_MASK; + writel_relaxed(val, pll->base + GNRL_CTL); +} + +static const struct clk_ops clk_pll1416x_ops = { + .prepare = clk_pll14xx_prepare, + .unprepare = clk_pll14xx_unprepare, + .is_prepared = clk_pll14xx_is_prepared, + .recalc_rate = clk_pll1416x_recalc_rate, + .round_rate = clk_pll14xx_round_rate, + .set_rate = clk_pll1416x_set_rate, +}; + +static const struct clk_ops clk_pll1416x_min_ops = { + .recalc_rate = clk_pll1416x_recalc_rate, +}; + +static const struct clk_ops clk_pll1443x_ops = { + .prepare = clk_pll14xx_prepare, + .unprepare = clk_pll14xx_unprepare, + .is_prepared = clk_pll14xx_is_prepared, + .recalc_rate = clk_pll1443x_recalc_rate, + .round_rate = clk_pll14xx_round_rate, + .set_rate = clk_pll1443x_set_rate, +}; + +struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, + void __iomem *base, + const struct imx_pll14xx_clk *pll_clk) +{ + struct clk_pll14xx *pll; + struct clk *clk; + struct clk_init_data init; + + pll = kzalloc(sizeof(*pll), GFP_KERNEL); + if (!pll) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.flags = pll_clk->flags; + init.parent_names = &parent_name; + init.num_parents = 1; + + switch (pll_clk->type) { + case PLL_1416X: + if (!pll->rate_table) + init.ops = &clk_pll1416x_min_ops; + else + init.ops = &clk_pll1416x_ops; + break; + case PLL_1443X: + init.ops = &clk_pll1443x_ops; + break; + default: + pr_err("%s: Unknown pll type for pll clk %s\n", + __func__, name); + }; + + pll->base = base; + pll->hw.init = &init; + pll->type = pll_clk->type; + pll->rate_table = pll_clk->rate_table; + pll->rate_count = pll_clk->rate_count; + + clk = clk_register(NULL, &pll->hw); + if (IS_ERR(clk)) { + pr_err("%s: failed to register pll %s %lu\n", + __func__, name, PTR_ERR(clk)); + kfree(pll); + } + + return clk; +} diff --git a/drivers/clk/imx/clk.h b/drivers/clk/imx/clk.h index 028312d..71929bf 100644 --- a/drivers/clk/imx/clk.h +++ b/drivers/clk/imx/clk.h @@ -27,6 +27,30 @@ enum imx_sccg_pll_type { SCCG_PLL2, }; +enum imx_pll14xx_type { + PLL_1416X, + PLL_1443X, +}; + +/* NOTE: Rate table should be kept sorted in descending order. */ +struct imx_pll14xx_rate_table { + unsigned int rate; + unsigned int pdiv; + unsigned int mdiv; + unsigned int sdiv; + unsigned int kdiv; +}; + +struct imx_pll14xx_clk { + enum imx_pll14xx_type type; + const struct imx_pll14xx_rate_table *rate_table; + int rate_count; + int flags; +}; + +struct clk *imx_clk_pll14xx(const char *name, const char *parent_name, + void __iomem *base, const struct imx_pll14xx_clk *pll_clk); + struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name, const char *parent, void __iomem *base); From patchwork Tue Jan 22 09:31:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacky Bai X-Patchwork-Id: 10775153 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1B154139A for ; Tue, 22 Jan 2019 09:32:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 088E529E0A for ; Tue, 22 Jan 2019 09:32:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E65632A294; Tue, 22 Jan 2019 09:32:00 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B9C7729E0A for ; Tue, 22 Jan 2019 09:31:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727727AbfAVJby (ORCPT ); Tue, 22 Jan 2019 04:31:54 -0500 Received: from mail-eopbgr00068.outbound.protection.outlook.com ([40.107.0.68]:50861 "EHLO EUR02-AM5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727505AbfAVJbx (ORCPT ); Tue, 22 Jan 2019 04:31:53 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=fNeNxVJ0nCHxv19W0piYK+uUVb05PN7ADIm7epFpB7g=; b=edpY+MevXy3LLmj62oXIerqAfLBtGkzGHym2YvlLOw+jGmnc9wCyqCXdxNwCwM8qMMLLksOw7Jd/yPUr4E4MkNPeTD8QhapI+u8ntBOU/nO4UR9JZxSuyMAygc7mC7UJen7TNHIvElDmyEFRK2bu8WDNsltzpnLfUeWjcsUu2zc= Received: from VI1PR0402MB3519.eurprd04.prod.outlook.com (52.134.4.24) by VI1PR0402MB3391.eurprd04.prod.outlook.com (52.134.1.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1537.30; Tue, 22 Jan 2019 09:31:47 +0000 Received: from VI1PR0402MB3519.eurprd04.prod.outlook.com ([fe80::85ec:f90c:2a0c:20d3]) by VI1PR0402MB3519.eurprd04.prod.outlook.com ([fe80::85ec:f90c:2a0c:20d3%4]) with mapi id 15.20.1537.031; Tue, 22 Jan 2019 09:31:47 +0000 From: Jacky Bai To: "sboyd@kernel.org" , "mturquette@baylibre.com" , "robh+dt@kernel.org" , "shawnguo@kernel.org" CC: Fabio Estevam , Aisheng Dong , dl-linux-imx , "linux-clk@vger.kernel.org" , "devicetree@vger.kernel.org" Subject: [PATCH v2 2/3] dt-bindings: imx: Add clock binding doc for imx8mm Thread-Topic: [PATCH v2 2/3] dt-bindings: imx: Add clock binding doc for imx8mm Thread-Index: AQHUsjVL0ajxCDKGH0y2aoN8eo2PJA== Date: Tue, 22 Jan 2019 09:31:46 +0000 Message-ID: <1548149769-32267-2-git-send-email-ping.bai@nxp.com> References: <1548149769-32267-1-git-send-email-ping.bai@nxp.com> In-Reply-To: <1548149769-32267-1-git-send-email-ping.bai@nxp.com> Accept-Language: zh-CN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-mailer: git-send-email 1.9.1 x-clientproxiedby: HK0P153CA0015.APCP153.PROD.OUTLOOK.COM (2603:1096:203:18::27) To VI1PR0402MB3519.eurprd04.prod.outlook.com (2603:10a6:803:8::24) authentication-results: spf=none (sender IP is ) smtp.mailfrom=ping.bai@nxp.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [119.31.174.71] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1;VI1PR0402MB3391;6:WOKyRheVX43dPerllT5LkUPCI4mj6WRINudJbbkviABb3cvPs9EwALBULriHJd1NJ1a0J7gnajaGpZ+amfjyMT8y+KtoFuAAD1fKzBL0QkYuzdVWXZdN1hSOImFWj8g4Arlj7/8Zh/v7pt8aSMC/+C0nM2VY20lQd2PzivRPL1QCQvjcS5hDEopZ6cYHUSzaiOoobjMisys2qPbR1Wq84d05kpLHLR5hzQ1PxfAILllxaUUyOQ6//X21FVcQSPtr7qoM1GQc/WiOV4vamQ74Tr2uGQnvQUvz4n8nbIpQPXHPQNkm80SAkiH/WezlvWSt935IoZTlY5PwrHpoG1cf2x/LqAgICWsLDQGfOvZhFrQbCXN8yvOVo5HmGUWZMCUxtE/sB/jml4H1dRPEkaVHhur4OjC+soh98ZKrnvnHbB0wG2SGsvMmOrLbxequzav519yqDSLbVFa2ytRYua8ScA==;5:wbJTroZS24tIqSrexFdEtO3nlICjOlPIEslL/9xR8nwt3XVLswW418z6nhyutbp5tIiANqf7XuHOmYDcFluqL67W94eTSKN7erXMpibURvyigpE1Jc6urin3scRJvbYaYkU+fyszx4W3NxLWWZagixasmg8OJmmhbI8vswEeTaX9uLkDUI3DhRomVQDf1nJ/m6iQkuxc6SR+B+y8oRQ2tA==;7:2A9317iBreSRT59oNEhzPx+uvhnKM8cUOpsnGr9bpxb7fviIWnfuTTJJXvhbWE3VPzTdnwVe4xnJUSSvlX6Bokv6Jz/2x1siEhvIfDOoC2gTONnqikuAcNBMnC7XAvPmVuU6rl/gOjRDH1UnnqqFzg== x-ms-office365-filtering-correlation-id: 33baf3f1-a8c0-4dc0-4887-08d6804c6daa x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600109)(711020)(4618075)(2017052603328)(7153060)(7193020);SRVR:VI1PR0402MB3391; x-ms-traffictypediagnostic: VI1PR0402MB3391: x-microsoft-antispam-prvs: x-forefront-prvs: 0925081676 x-forefront-antispam-report: SFV:NSPM;SFS:(10009020)(366004)(396003)(376002)(346002)(39860400002)(136003)(189003)(199004)(8936002)(2906002)(66066001)(81156014)(50226002)(25786009)(81166006)(97736004)(4326008)(316002)(54906003)(478600001)(14454004)(110136005)(99286004)(68736007)(76176011)(36756003)(6436002)(6486002)(8676002)(86362001)(386003)(102836004)(6506007)(186003)(7736002)(305945005)(105586002)(26005)(106356001)(486006)(6116002)(3846002)(476003)(2616005)(11346002)(256004)(53936002)(6512007)(71190400001)(71200400001)(446003)(2501003)(52116002)(32563001);DIR:OUT;SFP:1101;SCL:1;SRVR:VI1PR0402MB3391;H:VI1PR0402MB3519.eurprd04.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: 1tF1PsgvZwlccNUtWDUU5BMuUnmWY2kwG5r2DEjcXT1IG46mN9rVNr+4O+Yu+T6ElqfhWMyGrSHByaktNHX+IgT7RUzZ5kSZniYsgU0qhlPXsHNvPYqs0zU5WdhN5noDefxO2YkthSSHAQmc8pYoJIdbP+ilcFlchyUMIf3ogJsVK0yDiaK7lnwdvhOuHQ0QHg9auychTaHRA9dVH69+uasqnEpdY1q4bj0l/gPs1xOE68h0VwBe/Qpi+3dUXROo/SkP4Vfr7sFggFCFDPgUmrEaZ2aJyxX9J0jWgjcdoZxCAlegKQM282ov2/VDLEJvW3OU77BnElgkc5ATbX0GJavKiSCawMiiIrS4uuEgSUtNUadGT4aEzfmi+z4PnxZc8ZE0GHfrdJ4PxQpgcMHjGI9D00n7MltIg2wNL6SumbM= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: 33baf3f1-a8c0-4dc0-4887-08d6804c6daa X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Jan 2019 09:31:43.4057 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0402MB3391 Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Bai Ping Add the clock binding doc for i.MX8MM. Signed-off-by: Bai Ping Reviewed-by: Rob Herring --- change v1->v2 - add the provider node example; - replace table with space after define. --- .../devicetree/bindings/clock/imx8mm-clock.txt | 29 +++ include/dt-bindings/clock/imx8mm-clock.h | 244 +++++++++++++++++++++ 2 files changed, 273 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/imx8mm-clock.txt create mode 100644 include/dt-bindings/clock/imx8mm-clock.h diff --git a/Documentation/devicetree/bindings/clock/imx8mm-clock.txt b/Documentation/devicetree/bindings/clock/imx8mm-clock.txt new file mode 100644 index 0000000..8e4ab9e --- /dev/null +++ b/Documentation/devicetree/bindings/clock/imx8mm-clock.txt @@ -0,0 +1,29 @@ +* Clock bindings for NXP i.MX8M Mini + +Required properties: +- compatible: Should be "fsl,imx8mm-ccm" +- reg: Address and length of the register set +- #clock-cells: Should be <1> +- clocks: list of clock specifiers, must contain an entry for each required + entry in clock-names +- clock-names: should include the following entries: + - "osc_32k" + - "osc_24m" + - "clk_ext1" + - "clk_ext2" + - "clk_ext3" + - "clk_ext4" + +clk: clock-controller@30380000 { + compatible = "fsl,imx8mm-ccm"; + reg = <0x0 0x30380000 0x0 0x10000>; + #clock-cells = <1>; + clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>, <&clk_ext2>, + <&clk_ext3>, <&clk_ext4>; + clock-names = "osc_32k", "osc_24m", "clk_ext1", "clk_ext2", + "clk_ext3", "clk_ext4"; +}; + +The clock consumer should specify the desired clock by having the clock +ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8mm-clock.h +for the full list of i.MX8M Mini clock IDs. diff --git a/include/dt-bindings/clock/imx8mm-clock.h b/include/dt-bindings/clock/imx8mm-clock.h new file mode 100644 index 0000000..1b4353e --- /dev/null +++ b/include/dt-bindings/clock/imx8mm-clock.h @@ -0,0 +1,244 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2017-2018 NXP + */ + +#ifndef __DT_BINDINGS_CLOCK_IMX8MM_H +#define __DT_BINDINGS_CLOCK_IMX8MM_H + +#define IMX8MM_CLK_DUMMY 0 +#define IMX8MM_CLK_32K 1 +#define IMX8MM_CLK_24M 2 +#define IMX8MM_OSC_HDMI_CLK 3 +#define IMX8MM_CLK_EXT1 4 +#define IMX8MM_CLK_EXT2 5 +#define IMX8MM_CLK_EXT3 6 +#define IMX8MM_CLK_EXT4 7 +#define IMX8MM_AUDIO_PLL1_REF_SEL 8 +#define IMX8MM_AUDIO_PLL2_REF_SEL 9 +#define IMX8MM_VIDEO_PLL1_REF_SEL 10 +#define IMX8MM_DRAM_PLL_REF_SEL 11 +#define IMX8MM_GPU_PLL_REF_SEL 12 +#define IMX8MM_VPU_PLL_REF_SEL 13 +#define IMX8MM_ARM_PLL_REF_SEL 14 +#define IMX8MM_SYS_PLL1_REF_SEL 15 +#define IMX8MM_SYS_PLL2_REF_SEL 16 +#define IMX8MM_SYS_PLL3_REF_SEL 17 +#define IMX8MM_AUDIO_PLL1 18 +#define IMX8MM_AUDIO_PLL2 19 +#define IMX8MM_VIDEO_PLL1 20 +#define IMX8MM_DRAM_PLL 21 +#define IMX8MM_GPU_PLL 22 +#define IMX8MM_VPU_PLL 23 +#define IMX8MM_ARM_PLL 24 +#define IMX8MM_SYS_PLL1 25 +#define IMX8MM_SYS_PLL2 26 +#define IMX8MM_SYS_PLL3 27 +#define IMX8MM_AUDIO_PLL1_BYPASS 28 +#define IMX8MM_AUDIO_PLL2_BYPASS 29 +#define IMX8MM_VIDEO_PLL1_BYPASS 30 +#define IMX8MM_DRAM_PLL_BYPASS 31 +#define IMX8MM_GPU_PLL_BYPASS 32 +#define IMX8MM_VPU_PLL_BYPASS 33 +#define IMX8MM_ARM_PLL_BYPASS 34 +#define IMX8MM_SYS_PLL1_BYPASS 35 +#define IMX8MM_SYS_PLL2_BYPASS 36 +#define IMX8MM_SYS_PLL3_BYPASS 37 +#define IMX8MM_AUDIO_PLL1_OUT 38 +#define IMX8MM_AUDIO_PLL2_OUT 39 +#define IMX8MM_VIDEO_PLL1_OUT 40 +#define IMX8MM_DRAM_PLL_OUT 41 +#define IMX8MM_GPU_PLL_OUT 42 +#define IMX8MM_VPU_PLL_OUT 43 +#define IMX8MM_ARM_PLL_OUT 44 +#define IMX8MM_SYS_PLL1_OUT 45 +#define IMX8MM_SYS_PLL2_OUT 46 +#define IMX8MM_SYS_PLL3_OUT 47 +#define IMX8MM_SYS_PLL1_40M 48 +#define IMX8MM_SYS_PLL1_80M 49 +#define IMX8MM_SYS_PLL1_100M 50 +#define IMX8MM_SYS_PLL1_133M 51 +#define IMX8MM_SYS_PLL1_160M 52 +#define IMX8MM_SYS_PLL1_200M 53 +#define IMX8MM_SYS_PLL1_266M 54 +#define IMX8MM_SYS_PLL1_400M 55 +#define IMX8MM_SYS_PLL1_800M 56 +#define IMX8MM_SYS_PLL2_50M 57 +#define IMX8MM_SYS_PLL2_100M 58 +#define IMX8MM_SYS_PLL2_125M 59 +#define IMX8MM_SYS_PLL2_166M 60 +#define IMX8MM_SYS_PLL2_200M 61 +#define IMX8MM_SYS_PLL2_250M 62 +#define IMX8MM_SYS_PLL2_333M 63 +#define IMX8MM_SYS_PLL2_500M 64 +#define IMX8MM_SYS_PLL2_1000M 65 + +/* core */ +#define IMX8MM_CLK_A53_SRC 66 +#define IMX8MM_CLK_M4_SRC 67 +#define IMX8MM_CLK_VPU_SRC 68 +#define IMX8MM_CLK_GPU3D_SRC 69 +#define IMX8MM_CLK_GPU2D_SRC 70 +#define IMX8MM_CLK_A53_CG 71 +#define IMX8MM_CLK_M4_CG 72 +#define IMX8MM_CLK_VPU_CG 73 +#define IMX8MM_CLK_GPU3D_CG 74 +#define IMX8MM_CLK_GPU2D_CG 75 +#define IMX8MM_CLK_A53_DIV 76 +#define IMX8MM_CLK_M4_DIV 77 +#define IMX8MM_CLK_VPU_DIV 78 +#define IMX8MM_CLK_GPU3D_DIV 79 +#define IMX8MM_CLK_GPU2D_DIV 80 + +/* bus */ +#define IMX8MM_CLK_MAIN_AXI 81 +#define IMX8MM_CLK_ENET_AXI 82 +#define IMX8MM_CLK_NAND_USDHC_BUS 83 +#define IMX8MM_CLK_VPU_BUS 84 +#define IMX8MM_CLK_DISP_AXI 85 +#define IMX8MM_CLK_DISP_APB 86 +#define IMX8MM_CLK_DISP_RTRM 87 +#define IMX8MM_CLK_USB_BUS 88 +#define IMX8MM_CLK_GPU_AXI 89 +#define IMX8MM_CLK_GPU_AHB 90 +#define IMX8MM_CLK_NOC 91 +#define IMX8MM_CLK_NOC_APB 92 + +#define IMX8MM_CLK_AHB 93 +#define IMX8MM_CLK_AUDIO_AHB 94 +#define IMX8MM_CLK_IPG_ROOT 95 +#define IMX8MM_CLK_IPG_AUDIO_ROOT 96 + +#define IMX8MM_CLK_DRAM_ALT 97 +#define IMX8MM_CLK_DRAM_APB 98 +#define IMX8MM_CLK_VPU_G1 99 +#define IMX8MM_CLK_VPU_G2 100 +#define IMX8MM_CLK_DISP_DTRC 101 +#define IMX8MM_CLK_DISP_DC8000 102 +#define IMX8MM_CLK_PCIE1_CTRL 103 +#define IMX8MM_CLK_PCIE1_PHY 104 +#define IMX8MM_CLK_PCIE1_AUX 105 +#define IMX8MM_CLK_DC_PIXEL 106 +#define IMX8MM_CLK_LCDIF_PIXEL 107 +#define IMX8MM_CLK_SAI1 108 +#define IMX8MM_CLK_SAI2 109 +#define IMX8MM_CLK_SAI3 110 +#define IMX8MM_CLK_SAI4 111 +#define IMX8MM_CLK_SAI5 112 +#define IMX8MM_CLK_SAI6 113 +#define IMX8MM_CLK_SPDIF1 114 +#define IMX8MM_CLK_SPDIF2 115 +#define IMX8MM_CLK_ENET_REF 116 +#define IMX8MM_CLK_ENET_TIMER 117 +#define IMX8MM_CLK_ENET_PHY_REF 118 +#define IMX8MM_CLK_NAND 119 +#define IMX8MM_CLK_QSPI 120 +#define IMX8MM_CLK_USDHC1 121 +#define IMX8MM_CLK_USDHC2 122 +#define IMX8MM_CLK_I2C1 123 +#define IMX8MM_CLK_I2C2 124 +#define IMX8MM_CLK_I2C3 125 +#define IMX8MM_CLK_I2C4 126 +#define IMX8MM_CLK_UART1 127 +#define IMX8MM_CLK_UART2 128 +#define IMX8MM_CLK_UART3 129 +#define IMX8MM_CLK_UART4 130 +#define IMX8MM_CLK_USB_CORE_REF 131 +#define IMX8MM_CLK_USB_PHY_REF 132 +#define IMX8MM_CLK_ECSPI1 133 +#define IMX8MM_CLK_ECSPI2 134 +#define IMX8MM_CLK_PWM1 135 +#define IMX8MM_CLK_PWM2 136 +#define IMX8MM_CLK_PWM3 137 +#define IMX8MM_CLK_PWM4 138 +#define IMX8MM_CLK_GPT1 139 +#define IMX8MM_CLK_WDOG 140 +#define IMX8MM_CLK_WRCLK 141 +#define IMX8MM_CLK_DSI_CORE 142 +#define IMX8MM_CLK_DSI_PHY_REF 143 +#define IMX8MM_CLK_DSI_DBI 144 +#define IMX8MM_CLK_USDHC3 145 +#define IMX8MM_CLK_CSI1_CORE 146 +#define IMX8MM_CLK_CSI1_PHY_REF 147 +#define IMX8MM_CLK_CSI1_ESC 148 +#define IMX8MM_CLK_CSI2_CORE 149 +#define IMX8MM_CLK_CSI2_PHY_REF 150 +#define IMX8MM_CLK_CSI2_ESC 151 +#define IMX8MM_CLK_PCIE2_CTRL 152 +#define IMX8MM_CLK_PCIE2_PHY 153 +#define IMX8MM_CLK_PCIE2_AUX 154 +#define IMX8MM_CLK_ECSPI3 155 +#define IMX8MM_CLK_PDM 156 +#define IMX8MM_CLK_VPU_H1 157 +#define IMX8MM_CLK_CLKO1 158 + +#define IMX8MM_CLK_ECSPI1_ROOT 159 +#define IMX8MM_CLK_ECSPI2_ROOT 160 +#define IMX8MM_CLK_ECSPI3_ROOT 161 +#define IMX8MM_CLK_ENET1_ROOT 162 +#define IMX8MM_CLK_GPT1_ROOT 163 +#define IMX8MM_CLK_I2C1_ROOT 164 +#define IMX8MM_CLK_I2C2_ROOT 165 +#define IMX8MM_CLK_I2C3_ROOT 166 +#define IMX8MM_CLK_I2C4_ROOT 167 +#define IMX8MM_CLK_OCOTP_ROOT 168 +#define IMX8MM_CLK_PCIE1_ROOT 169 +#define IMX8MM_CLK_PWM1_ROOT 170 +#define IMX8MM_CLK_PWM2_ROOT 171 +#define IMX8MM_CLK_PWM3_ROOT 172 +#define IMX8MM_CLK_PWM4_ROOT 173 +#define IMX8MM_CLK_QSPI_ROOT 174 +#define IMX8MM_CLK_NAND_ROOT 175 +#define IMX8MM_CLK_SAI1_ROOT 176 +#define IMX8MM_CLK_SAI1_IPG 177 +#define IMX8MM_CLK_SAI2_ROOT 178 +#define IMX8MM_CLK_SAI2_IPG 179 +#define IMX8MM_CLK_SAI3_ROOT 180 +#define IMX8MM_CLK_SAI3_IPG 181 +#define IMX8MM_CLK_SAI4_ROOT 182 +#define IMX8MM_CLK_SAI4_IPG 183 +#define IMX8MM_CLK_SAI5_ROOT 184 +#define IMX8MM_CLK_SAI5_IPG 185 +#define IMX8MM_CLK_SAI6_ROOT 186 +#define IMX8MM_CLK_SAI6_IPG 187 +#define IMX8MM_CLK_UART1_ROOT 188 +#define IMX8MM_CLK_UART2_ROOT 189 +#define IMX8MM_CLK_UART3_ROOT 190 +#define IMX8MM_CLK_UART4_ROOT 191 +#define IMX8MM_CLK_USB1_CTRL_ROOT 192 +#define IMX8MM_CLK_GPU3D_ROOT 193 +#define IMX8MM_CLK_USDHC1_ROOT 194 +#define IMX8MM_CLK_USDHC2_ROOT 195 +#define IMX8MM_CLK_WDOG1_ROOT 196 +#define IMX8MM_CLK_WDOG2_ROOT 197 +#define IMX8MM_CLK_WDOG3_ROOT 198 +#define IMX8MM_CLK_VPU_G1_ROOT 199 +#define IMX8MM_CLK_GPU_BUS_ROOT 200 +#define IMX8MM_CLK_VPU_H1_ROOT 201 +#define IMX8MM_CLK_VPU_G2_ROOT 202 +#define IMX8MM_CLK_PDM_ROOT 203 +#define IMX8MM_CLK_DISP_ROOT 204 +#define IMX8MM_CLK_DISP_AXI_ROOT 205 +#define IMX8MM_CLK_DISP_APB_ROOT 206 +#define IMX8MM_CLK_DISP_RTRM_ROOT 207 +#define IMX8MM_CLK_USDHC3_ROOT 208 +#define IMX8MM_CLK_TMU_ROOT 209 +#define IMX8MM_CLK_VPU_DEC_ROOT 210 +#define IMX8MM_CLK_SDMA1_ROOT 211 +#define IMX8MM_CLK_SDMA2_ROOT 212 +#define IMX8MM_CLK_SDMA3_ROOT 213 +#define IMX8MM_CLK_GPT_3M 214 +#define IMX8MM_CLK_ARM 215 +#define IMX8MM_CLK_PDM_IPG 216 +#define IMX8MM_CLK_GPU2D_ROOT 217 +#define IMX8MM_CLK_MU_ROOT 218 +#define IMX8MM_CLK_CSI1_ROOT 219 + +#define IMX8MM_CLK_DRAM_CORE 220 +#define IMX8MM_CLK_DRAM_ALT_ROOT 221 + +#define IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK 222 + +#define IMX8MM_CLK_END 223 + +#endif From patchwork Tue Jan 22 09:31:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jacky Bai X-Patchwork-Id: 10775155 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 97380139A for ; Tue, 22 Jan 2019 09:32:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 825C929E0A for ; Tue, 22 Jan 2019 09:32:14 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 760792A27E; Tue, 22 Jan 2019 09:32:14 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2225D2A31F for ; Tue, 22 Jan 2019 09:32:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727808AbfAVJcI (ORCPT ); Tue, 22 Jan 2019 04:32:08 -0500 Received: from mail-eopbgr00050.outbound.protection.outlook.com ([40.107.0.50]:26304 "EHLO EUR02-AM5-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1727729AbfAVJcI (ORCPT ); Tue, 22 Jan 2019 04:32:08 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nxp.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=RdjzSZQ1mc8ptWWdGLY0TmOvCUAInn0WqK9Lod2qFkQ=; b=fweCNj3cxqdLJ43M06QcUwA2N+T9t78YBVG0NSWw83zxFVPs7qwLIB30DKqsNybgmVVAdHnVS80PdeLbOml+sTdR2wptaXao70rCnpclUS8Z3LAJPrHWEVUCoRcT8Fgc8FaU2JCTQPwjWDyk6uw/MgysL7SdPYeK8v3PFdcJKCw= Received: from VI1PR0402MB3519.eurprd04.prod.outlook.com (52.134.4.24) by VI1PR0402MB3391.eurprd04.prod.outlook.com (52.134.1.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1537.30; Tue, 22 Jan 2019 09:31:52 +0000 Received: from VI1PR0402MB3519.eurprd04.prod.outlook.com ([fe80::85ec:f90c:2a0c:20d3]) by VI1PR0402MB3519.eurprd04.prod.outlook.com ([fe80::85ec:f90c:2a0c:20d3%4]) with mapi id 15.20.1537.031; Tue, 22 Jan 2019 09:31:52 +0000 From: Jacky Bai To: "sboyd@kernel.org" , "mturquette@baylibre.com" , "robh+dt@kernel.org" , "shawnguo@kernel.org" CC: Fabio Estevam , Aisheng Dong , dl-linux-imx , "linux-clk@vger.kernel.org" , "devicetree@vger.kernel.org" Subject: [PATCH v2 3/3] clk: imx: Add clock driver support for imx8mm Thread-Topic: [PATCH v2 3/3] clk: imx: Add clock driver support for imx8mm Thread-Index: AQHUsjVOYBUDM/nhU0qrbtoZuP7WLA== Date: Tue, 22 Jan 2019 09:31:51 +0000 Message-ID: <1548149769-32267-3-git-send-email-ping.bai@nxp.com> References: <1548149769-32267-1-git-send-email-ping.bai@nxp.com> In-Reply-To: <1548149769-32267-1-git-send-email-ping.bai@nxp.com> Accept-Language: zh-CN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-mailer: git-send-email 1.9.1 x-clientproxiedby: HK0P153CA0015.APCP153.PROD.OUTLOOK.COM (2603:1096:203:18::27) To VI1PR0402MB3519.eurprd04.prod.outlook.com (2603:10a6:803:8::24) authentication-results: spf=none (sender IP is ) smtp.mailfrom=ping.bai@nxp.com; x-ms-exchange-messagesentrepresentingtype: 1 x-originating-ip: [119.31.174.71] x-ms-publictraffictype: Email x-microsoft-exchange-diagnostics: 1;VI1PR0402MB3391;6:fzYv8OztFLgcjaBTTv1kQkR6V8fh0KkztqgMPCMoafo1XclUmrEca0fCT1zanWUMGDjglyy407qh1gSqy2DbpylbrcZq9AdYm33h8roFyiu22cMYR+CvopLQfn3Fzwe3FoJwgMiLHD3L84CJYCX6677VBs4iHME5M8BC7kN1a+GBkP5cfxuLEa+zIDX53BkTNc1GX3dnk6zVBNal4pMNpgmZEqf2v12cUHSGr/olzaQWGyWVzX1Col/tHMDdXhFmrIrfW4NPFEIWdTH7/MvNijTjshcpgEwB8m0qQvIT7Mbj9Xf1q4qYxa1HjmbVoXfn0BMVYWb5k0Zho/feYDhqRdsdQ2MaFyTHtFpKS6ltT+oHQPBY3gXJTmbj07zr9fJLwR2j87qX+RiAuFte6HG4zgLPTXH7BOQsFO8M18dMMeezMBIsdXuUbjoY2MEhy/z3kdPEYm7PsYIh33ZPoXwQwA==;5:siVvuVcpdqycLp0zOWM4duEMHFdiR77VI9fD0VfeS6aBoc2qUZBnUduGexRDBJwKetOjxG9zKllfUKbHHhZzMp5cZlh4KaDmhUZgCCWwsHZbBSwEzWwJHQKWzxiDsMSRGlDfHXqOWK+uV/yxqcUWAv+FwrWi1pUd01Ntl7syqO9SLYf9EJVOjxP80w3og/fA1XzsEzCeIP51Hnbe6+DSAA==;7:YYJn8DUI/26YuyhPjsfBgXLo0D7UTv0hs+gJsVcVT6kjvSLrw7lnVPxvW4RiLGoKs2kkea132byBGZ+jJOBy8H4wpOz5FzDNsyafp4JmvL7FsexILNU0RaU0Zw1jo24kOgWwbXLZY4LjXOvbydIZPg== x-ms-office365-filtering-correlation-id: a05e0237-f561-4d73-9d25-08d6804c7091 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0;PCL:0;RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600109)(711020)(4618075)(2017052603328)(7153060)(7193020);SRVR:VI1PR0402MB3391; x-ms-traffictypediagnostic: VI1PR0402MB3391: x-microsoft-antispam-prvs: x-forefront-prvs: 0925081676 x-forefront-antispam-report: SFV:NSPM;SFS:(10009020)(366004)(396003)(376002)(346002)(39860400002)(136003)(189003)(199004)(8936002)(2906002)(66066001)(81156014)(50226002)(25786009)(81166006)(97736004)(4326008)(316002)(54906003)(478600001)(30864003)(14454004)(110136005)(99286004)(68736007)(76176011)(36756003)(6436002)(6486002)(8676002)(86362001)(386003)(102836004)(6506007)(186003)(7736002)(305945005)(105586002)(26005)(106356001)(486006)(6116002)(3846002)(476003)(2616005)(11346002)(256004)(53946003)(53936002)(6512007)(71190400001)(71200400001)(446003)(2501003)(52116002)(32563001)(559001)(579004)(569006);DIR:OUT;SFP:1101;SCL:1;SRVR:VI1PR0402MB3391;H:VI1PR0402MB3519.eurprd04.prod.outlook.com;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;MX:1;A:1; received-spf: None (protection.outlook.com: nxp.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: nr4t4JHfCqAV0gajFxh0QSppdJ2AZbcj9hHpMdz662RonJxg0rz/cyjTJKMNFsGej4axOToi9QtStqRfee76Na+aHmSOrvS8ykzRGmYgOuFhADA0zdr60izV8AlveWYQkiE8vU9hgNWHyFlS6+6FQMfzYxFwQmVtsILPleb/NI9IHic1geyzzifYBNtsJ9cV63xHDhTB4pTqXxvUo/ETKvofjvCYd+0CGmq7BGDOjLdBZawC7ZgYGKKSWa+RF0lT7IgcRCkrm7STVyB6LrjcyfHxBJ7WUkdAbemzEuP8nUwXO/TlhLSrE8YzCH/OxkoU6WXzZa0SOSqRKLRJ5Jw8tOlvUhxDLWE6m4x0gUR2ahDqLmG+F2uCsBffdDmpbYUvVpQYI0q8GOKI12DHSUm4/a5PihcEsI5CzdFsdmHf4DI= spamdiagnosticoutput: 1:99 spamdiagnosticmetadata: NSPM MIME-Version: 1.0 X-OriginatorOrg: nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: a05e0237-f561-4d73-9d25-08d6804c7091 X-MS-Exchange-CrossTenant-originalarrivaltime: 22 Jan 2019 09:31:48.2632 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR0402MB3391 Sender: linux-clk-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-clk@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Bai Ping Add clock driver support for i.MX8MM SOC. Signed-off-by: Bai Ping --- change v1->v2 - remove the uncessary print log - back to use CLK_OF_DECLARE_DRIVER, it is because some comsumer side - dose not carefully handle the DEFER_PROBE, so for now, we just keep - the driver registered as old i.MX6/7. --- drivers/clk/imx/Kconfig | 6 + drivers/clk/imx/Makefile | 1 + drivers/clk/imx/clk-imx8mm.c | 675 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 682 insertions(+) create mode 100644 drivers/clk/imx/clk-imx8mm.c diff --git a/drivers/clk/imx/Kconfig b/drivers/clk/imx/Kconfig index 4aae31a..0eaf418 100644 --- a/drivers/clk/imx/Kconfig +++ b/drivers/clk/imx/Kconfig @@ -8,6 +8,12 @@ config MXC_CLK_SCU bool depends on IMX_SCU +config CLK_IMX8MM + bool "IMX8MM CCM Clock Driver" + depends on ARCH_MXC && ARM64 + help + Build the driver for i.MX8MM CCM Clock Driver + config CLK_IMX8MQ bool "IMX8MQ CCM Clock Driver" depends on ARCH_MXC && ARM64 diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index ff74287..0d5180f 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_MXC_CLK_SCU) += \ clk-scu.o \ clk-lpcg-scu.o +obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o diff --git a/drivers/clk/imx/clk-imx8mm.c b/drivers/clk/imx/clk-imx8mm.c new file mode 100644 index 0000000..b7f3ac2 --- /dev/null +++ b/drivers/clk/imx/clk-imx8mm.c @@ -0,0 +1,675 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2017-2018 NXP. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk.h" + +static u32 share_count_sai1; +static u32 share_count_sai2; +static u32 share_count_sai3; +static u32 share_count_sai4; +static u32 share_count_sai5; +static u32 share_count_sai6; +static u32 share_count_dcss; +static u32 share_count_pdm; +static u32 share_count_nand; + +#define PLL_1416X_RATE(_rate, _m, _p, _s) \ + { \ + .rate = (_rate), \ + .mdiv = (_m), \ + .pdiv = (_p), \ + .sdiv = (_s), \ + } + +#define PLL_1443X_RATE(_rate, _m, _p, _s, _k) \ + { \ + .rate = (_rate), \ + .mdiv = (_m), \ + .pdiv = (_p), \ + .sdiv = (_s), \ + .kdiv = (_k), \ + } + +static const struct imx_pll14xx_rate_table imx8mm_pll1416x_tbl[] = { + PLL_1416X_RATE(1800000000U, 225, 3, 0), + PLL_1416X_RATE(1600000000U, 200, 3, 0), + PLL_1416X_RATE(1200000000U, 300, 3, 1), + PLL_1416X_RATE(1000000000U, 250, 3, 1), + PLL_1416X_RATE(800000000U, 200, 3, 1), + PLL_1416X_RATE(750000000U, 250, 2, 2), + PLL_1416X_RATE(700000000U, 350, 3, 2), + PLL_1416X_RATE(600000000U, 300, 3, 2), +}; + +static const struct imx_pll14xx_rate_table imx8mm_audiopll_tbl[] = { + PLL_1443X_RATE(786432000U, 655, 5, 2, 23593), + PLL_1443X_RATE(722534400U, 301, 5, 1, 3670), +}; + +static const struct imx_pll14xx_rate_table imx8mm_videopll_tbl[] = { + PLL_1443X_RATE(650000000U, 325, 3, 2, 0), + PLL_1443X_RATE(594000000U, 198, 2, 2, 0), +}; + +static const struct imx_pll14xx_rate_table imx8mm_drampll_tbl[] = { + PLL_1443X_RATE(650000000U, 325, 3, 2, 0), +}; + +static struct imx_pll14xx_clk imx8mm_audio_pll __initdata = { + .type = PLL_1443X, + .rate_table = imx8mm_audiopll_tbl, + .rate_count = ARRAY_SIZE(imx8mm_audiopll_tbl), +}; + +static struct imx_pll14xx_clk imx8mm_video_pll __initdata = { + .type = PLL_1443X, + .rate_table = imx8mm_videopll_tbl, + .rate_count = ARRAY_SIZE(imx8mm_videopll_tbl), +}; + +static struct imx_pll14xx_clk imx8mm_dram_pll __initdata = { + .type = PLL_1443X, + .rate_table = imx8mm_drampll_tbl, + .rate_count = ARRAY_SIZE(imx8mm_drampll_tbl), +}; + +static struct imx_pll14xx_clk imx8mm_arm_pll __initdata = { + .type = PLL_1416X, + .rate_table = imx8mm_pll1416x_tbl, + .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl), +}; + +static struct imx_pll14xx_clk imx8mm_gpu_pll __initdata = { + .type = PLL_1416X, + .rate_table = imx8mm_pll1416x_tbl, + .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl), +}; + +static struct imx_pll14xx_clk imx8mm_vpu_pll __initdata = { + .type = PLL_1416X, + .rate_table = imx8mm_pll1416x_tbl, + .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl), +}; + +static struct imx_pll14xx_clk imx8mm_sys_pll __initdata = { + .type = PLL_1416X, + .rate_table = imx8mm_pll1416x_tbl, + .rate_count = ARRAY_SIZE(imx8mm_pll1416x_tbl), +}; + +static const char *pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", }; +static const char *audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", }; +static const char *audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", }; +static const char *video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", }; +static const char *dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", }; +static const char *gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", }; +static const char *vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", }; +static const char *arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", }; +static const char *sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", }; +static const char *sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", }; +static const char *sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", }; + +/* CCM ROOT */ +static const char *imx8mm_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m", + "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "sys_pll3_out", }; + +static const char *imx8mm_m4_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m", "sys_pll1_266m", + "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", }; + +static const char *imx8mm_vpu_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m", "sys_pll2_1000m", + "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "vpu_pll_out", }; + +static const char *imx8mm_gpu3d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out", + "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; + +static const char *imx8mm_gpu2d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m", "sys_pll3_out", + "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; + +static const char *imx8mm_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m", "sys_pll2_250m", + "sys_pll2_1000m", "audio_pll1_out", "video_pll1_out", "sys_pll1_100m",}; + +static const char *imx8mm_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_250m", + "sys_pll2_200m", "audio_pll1_out", "video_pll1_out", "sys_pll3_out", }; + +static const char *imx8mm_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_200m", + "sys_pll1_133m", "sys_pll3_out", "sys_pll2_250m", "audio_pll1_out", }; + +static const char *imx8mm_vpu_bus_sels[] = {"osc_24m", "sys_pll1_800m", "vpu_pll_out", "audio_pll2_out", + "sys_pll3_out", "sys_pll2_1000m", "sys_pll2_200m", "sys_pll1_100m", }; + +static const char *imx8mm_disp_axi_sels[] = {"osc_24m", "sys_pll2_1000m", "sys_pll1_800m", "sys_pll3_out", + "sys_pll1_40m", "audio_pll2_out", "clk_ext1", "clk_ext4", }; + +static const char *imx8mm_disp_apb_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll1_800m", "sys_pll3_out", + "sys_pll1_40m", "audio_pll2_out", "clk_ext1", "clk_ext3", }; + +static const char *imx8mm_disp_rtrm_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll2_200m", "sys_pll2_1000m", + "audio_pll1_out", "video_pll1_out", "clk_ext2", "clk_ext3", }; + +static const char *imx8mm_usb_bus_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_100m", + "sys_pll2_200m", "clk_ext2", "clk_ext4", "audio_pll2_out", }; + +static const char *imx8mm_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m", + "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; + +static const char *imx8mm_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out", "sys_pll3_out", "sys_pll2_1000m", + "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; + +static const char *imx8mm_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out", "sys_pll2_1000m", "sys_pll2_500m", + "audio_pll1_out", "video_pll1_out", "audio_pll2_out", }; + +static const char *imx8mm_noc_apb_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll3_out", "sys_pll2_333m", "sys_pll2_200m", + "sys_pll1_800m", "audio_pll1_out", "video_pll1_out", }; + +static const char *imx8mm_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m", "sys_pll1_400m", + "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", }; + +static const char *imx8mm_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m", "sys_pll2_1000m", + "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", "video_pll1_out", }; + +static const char *imx8mm_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m", "sys_pll2_500m", + "sys_pll2_1000m", "sys_pll3_out", "audio_pll1_out", "sys_pll1_266m", }; + +static const char *imx8mm_dram_apb_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m", + "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", }; + +static const char *imx8mm_vpu_g1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m", + "sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", }; + +static const char *imx8mm_vpu_g2_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m", + "sys_pll1_100m", "sys_pll2_125m", "sys_pll3_out", "audio_pll1_out", }; + +static const char *imx8mm_disp_dtrc_sels[] = {"osc_24m", "video_pll2_out", "sys_pll1_800m", "sys_pll2_1000m", + "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", }; + +static const char *imx8mm_disp_dc8000_sels[] = {"osc_24m", "video_pll2_out", "sys_pll1_800m", "sys_pll2_1000m", + "sys_pll1_160m", "video_pll1_out", "sys_pll3_out", "audio_pll2_out", }; + +static const char *imx8mm_pcie1_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m", + "sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", }; + +static const char *imx8mm_pcie1_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m", "clk_ext1", "clk_ext2", + "clk_ext3", "clk_ext4", "sys_pll1_400m", }; + +static const char *imx8mm_pcie1_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out", + "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", }; + +static const char *imx8mm_dc_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", + "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", }; + +static const char *imx8mm_lcdif_pixel_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", "audio_pll1_out", + "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", }; + +static const char *imx8mm_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", + "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", }; + +static const char *imx8mm_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", + "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", }; + +static const char *imx8mm_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", + "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", }; + +static const char *imx8mm_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", + "sys_pll1_133m", "osc_hdmi", "clk_ext1", "clk_ext2", }; + +static const char *imx8mm_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", + "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", }; + +static const char *imx8mm_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", + "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", }; + +static const char *imx8mm_spdif1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", + "sys_pll1_133m", "osc_hdmi", "clk_ext2", "clk_ext3", }; + +static const char *imx8mm_spdif2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", "video_pll1_out", + "sys_pll1_133m", "osc_hdmi", "clk_ext3", "clk_ext4", }; + +static const char *imx8mm_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m", "sys_pll2_100m", + "sys_pll1_160m", "audio_pll1_out", "video_pll1_out", "clk_ext4", }; + +static const char *imx8mm_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "clk_ext1", "clk_ext2", + "clk_ext3", "clk_ext4", "video_pll1_out", }; + +static const char *imx8mm_enet_phy_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m", "sys_pll2_200m", + "sys_pll2_500m", "video_pll1_out", "audio_pll2_out", }; + +static const char *imx8mm_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out", "sys_pll1_400m", + "audio_pll2_out", "sys_pll3_out", "sys_pll2_250m", "video_pll1_out", }; + +static const char *imx8mm_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", + "audio_pll2_out", "sys_pll1_266m", "sys_pll3_out", "sys_pll1_100m", }; + +static const char *imx8mm_usdhc1_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", + "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", }; + +static const char *imx8mm_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", + "sys_pll3_out", "sys_pll1_266m", "audio_pll2_out", "sys_pll1_100m", }; + +static const char *imx8mm_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", }; + +static const char *imx8mm_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", }; + +static const char *imx8mm_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", }; + +static const char *imx8mm_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m", "sys_pll3_out", "audio_pll1_out", + "video_pll1_out", "audio_pll2_out", "sys_pll1_133m", }; + +static const char *imx8mm_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m", + "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", }; + +static const char *imx8mm_uart2_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m", + "sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", }; + +static const char *imx8mm_uart3_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m", + "sys_pll3_out", "clk_ext2", "clk_ext4", "audio_pll2_out", }; + +static const char *imx8mm_uart4_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m", "sys_pll2_100m", + "sys_pll3_out", "clk_ext2", "clk_ext3", "audio_pll2_out", }; + +static const char *imx8mm_usb_core_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m", + "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; + +static const char *imx8mm_usb_phy_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m", "sys_pll2_100m", + "sys_pll2_200m", "clk_ext2", "clk_ext3", "audio_pll2_out", }; + +static const char *imx8mm_ecspi1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m", + "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", }; + +static const char *imx8mm_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m", + "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", }; + +static const char *imx8mm_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m", + "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", }; + +static const char *imx8mm_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m", + "sys_pll3_out", "clk_ext1", "sys_pll1_80m", "video_pll1_out", }; + +static const char *imx8mm_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m", + "sys3_pll2_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", }; + +static const char *imx8mm_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m", "sys_pll1_40m", + "sys_pll3_out", "clk_ext2", "sys_pll1_80m", "video_pll1_out", }; + +static const char *imx8mm_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m", "sys_pll1_40m", + "video_pll1_out", "sys_pll1_800m", "audio_pll1_out", "clk_ext1" }; + +static const char *imx8mm_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m", "vpu_pll_out", + "sys_pll2_125m", "sys_pll3_out", "sys_pll1_80m", "sys_pll2_166m", }; + +static const char *imx8mm_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_out", "sys_pll3_out", "sys_pll2_200m", + "sys_pll1_266m", "sys_pll2_500m", "sys_pll1_100m", }; + +static const char *imx8mm_dsi_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m", + "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", }; + +static const char *imx8mm_dsi_phy_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_100m", "sys_pll1_800m", + "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", }; + +static const char *imx8mm_dsi_dbi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_100m", "sys_pll1_800m", + "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", }; + +static const char *imx8mm_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m", "sys_pll2_500m", + "sys_pll3_out", "sys_pll1_266m", "audio_pll2_clk", "sys_pll1_100m", }; + +static const char *imx8mm_csi1_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m", + "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", }; + +static const char *imx8mm_csi1_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m", + "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", }; + +static const char *imx8mm_csi1_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m", + "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", }; + +static const char *imx8mm_csi2_core_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m", "sys_pll1_800m", + "sys_pll2_1000m", "sys_pll3_out", "audio_pll2_out", "video_pll1_out", }; + +static const char *imx8mm_csi2_phy_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m", "sys_pll1_800m", + "sys_pll2_1000m", "clk_ext2", "audio_pll2_out", "video_pll1_out", }; + +static const char *imx8mm_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_800m", + "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", }; + +static const char *imx8mm_pcie2_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m", "sys_pll1_266m", + "sys_pll1_800m", "sys_pll2_500m", "sys_pll2_333m", "sys_pll3_out", }; + +static const char *imx8mm_pcie2_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m", "clk_ext1", + "clk_ext2", "clk_ext3", "clk_ext4", "sys_pll1_400m", }; + +static const char *imx8mm_pcie2_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m", "sys_pll3_out", + "sys_pll2_100m", "sys_pll1_80m", "sys_pll1_160m", "sys_pll1_200m", }; + +static const char *imx8mm_ecspi3_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m", "sys_pll1_160m", + "sys_pll1_800m", "sys_pll3_out", "sys_pll2_250m", "audio_pll2_out", }; + +static const char *imx8mm_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out", "sys_pll1_800m", + "sys_pll2_1000m", "sys_pll3_out", "clk_ext3", "audio_pll2_out", }; + +static const char *imx8mm_vpu_h1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m", "sys_pll2_1000m", + "audio_pll2_clk", "sys_pll2_125m", "sys_pll3_clk", "audio_pll1_out", }; + +static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; + +static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m", "sys_pll1_200m", "audio_pll2_clk", + "vpu_pll", "sys_pll1_80m", }; + +static struct clk *clks[IMX8MM_CLK_END]; +static struct clk_onecell_data clk_data; + +static struct clk ** const uart_clks[] __initconst = { + &clks[IMX8MM_CLK_UART1_ROOT], + &clks[IMX8MM_CLK_UART2_ROOT], + &clks[IMX8MM_CLK_UART3_ROOT], + &clks[IMX8MM_CLK_UART4_ROOT], + NULL +}; + +static int imx8mm_clocks_init(struct device_node *ccm_node) +{ + struct device_node *np; + void __iomem *base; + int ret; + + clks[IMX8MM_CLK_DUMMY] = imx_clk_fixed("dummy", 0); + clks[IMX8MM_CLK_24M] = of_clk_get_by_name(ccm_node, "osc_24m"); + clks[IMX8MM_CLK_32K] = of_clk_get_by_name(ccm_node, "osc_32k"); + clks[IMX8MM_CLK_EXT1] = of_clk_get_by_name(ccm_node, "clk_ext1"); + clks[IMX8MM_CLK_EXT2] = of_clk_get_by_name(ccm_node, "clk_ext2"); + clks[IMX8MM_CLK_EXT3] = of_clk_get_by_name(ccm_node, "clk_ext3"); + clks[IMX8MM_CLK_EXT4] = of_clk_get_by_name(ccm_node, "clk_ext4"); + + np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop"); + base = of_iomap(np, 0); + if (WARN_ON(!base)) + return -ENOMEM; + + clks[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + clks[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + clks[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + clks[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + clks[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + clks[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + clks[IMX8MM_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + clks[IMX8MM_SYS_PLL1_REF_SEL] = imx_clk_mux("sys_pll1_ref_sel", base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + clks[IMX8MM_SYS_PLL2_REF_SEL] = imx_clk_mux("sys_pll2_ref_sel", base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + clks[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + + clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx8mm_audio_pll); + clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx8mm_audio_pll); + clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx8mm_video_pll); + clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx8mm_dram_pll); + clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx8mm_gpu_pll); + clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx8mm_vpu_pll); + clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx8mm_arm_pll); + clks[IMX8MM_SYS_PLL1] = imx_clk_pll14xx("sys_pll1", "sys_pll1_ref_sel", base + 0x94, &imx8mm_sys_pll); + clks[IMX8MM_SYS_PLL2] = imx_clk_pll14xx("sys_pll2", "sys_pll2_ref_sel", base + 0x104, &imx8mm_sys_pll); + clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx8mm_sys_pll); + + /* PLL bypass out */ + clks[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 4, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 4, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 4, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 4, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX8MM_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 4, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX8MM_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 4, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX8MM_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 4, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX8MM_SYS_PLL1_BYPASS] = imx_clk_mux_flags("sys_pll1_bypass", base + 0x94, 4, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX8MM_SYS_PLL2_BYPASS] = imx_clk_mux_flags("sys_pll2_bypass", base + 0x104, 4, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT); + clks[IMX8MM_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 4, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT); + + /* unbypass all the plls */ + clk_set_parent(clks[IMX8MM_AUDIO_PLL1_BYPASS], clks[IMX8MM_AUDIO_PLL1]); + clk_set_parent(clks[IMX8MM_AUDIO_PLL2_BYPASS], clks[IMX8MM_AUDIO_PLL2]); + clk_set_parent(clks[IMX8MM_VIDEO_PLL1_BYPASS], clks[IMX8MM_VIDEO_PLL1]); + clk_set_parent(clks[IMX8MM_DRAM_PLL_BYPASS], clks[IMX8MM_DRAM_PLL]); + clk_set_parent(clks[IMX8MM_GPU_PLL_BYPASS], clks[IMX8MM_GPU_PLL]); + clk_set_parent(clks[IMX8MM_VPU_PLL_BYPASS], clks[IMX8MM_VPU_PLL]); + clk_set_parent(clks[IMX8MM_ARM_PLL_BYPASS], clks[IMX8MM_ARM_PLL]); + clk_set_parent(clks[IMX8MM_SYS_PLL1_BYPASS], clks[IMX8MM_SYS_PLL1]); + clk_set_parent(clks[IMX8MM_SYS_PLL2_BYPASS], clks[IMX8MM_SYS_PLL2]); + clk_set_parent(clks[IMX8MM_SYS_PLL3_BYPASS], clks[IMX8MM_SYS_PLL3]); + + /* PLL out gate */ + clks[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base, 13); + clks[IMX8MM_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13); + clks[IMX8MM_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13); + clks[IMX8MM_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13); + clks[IMX8MM_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 13); + clks[IMX8MM_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 13); + clks[IMX8MM_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 13); + clks[IMX8MM_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1_bypass", base + 0x94, 13); + clks[IMX8MM_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2_bypass", base + 0x104, 13); + clks[IMX8MM_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 13); + + /* SYS PLL fixed output */ + clks[IMX8MM_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20); + clks[IMX8MM_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10); + clks[IMX8MM_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8); + clks[IMX8MM_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6); + clks[IMX8MM_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5); + clks[IMX8MM_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4); + clks[IMX8MM_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3); + clks[IMX8MM_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2); + clks[IMX8MM_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1); + + clks[IMX8MM_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20); + clks[IMX8MM_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10); + clks[IMX8MM_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8); + clks[IMX8MM_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6); + clks[IMX8MM_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5); + clks[IMX8MM_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4); + clks[IMX8MM_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3); + clks[IMX8MM_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2); + clks[IMX8MM_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); + + np = ccm_node; + base = of_iomap(np, 0); + if (WARN_ON(!base)) + return -ENOMEM; + + /* Core Slice */ + clks[IMX8MM_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels)); + clks[IMX8MM_CLK_M4_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mm_m4_sels, ARRAY_SIZE(imx8mm_m4_sels)); + clks[IMX8MM_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mm_vpu_sels, ARRAY_SIZE(imx8mm_vpu_sels)); + clks[IMX8MM_CLK_GPU3D_SRC] = imx_clk_mux2("gpu3d_src", base + 0x8180, 24, 3, imx8mm_gpu3d_sels, ARRAY_SIZE(imx8mm_gpu3d_sels)); + clks[IMX8MM_CLK_GPU2D_SRC] = imx_clk_mux2("gpu2d_src", base + 0x8200, 24, 3, imx8mm_gpu2d_sels, ARRAY_SIZE(imx8mm_gpu2d_sels)); + clks[IMX8MM_CLK_A53_CG] = imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28); + clks[IMX8MM_CLK_M4_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28); + clks[IMX8MM_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28); + clks[IMX8MM_CLK_GPU3D_CG] = imx_clk_gate3("gpu3d_cg", "gpu3d_src", base + 0x8180, 28); + clks[IMX8MM_CLK_GPU2D_CG] = imx_clk_gate3("gpu2d_cg", "gpu2d_src", base + 0x8200, 28); + clks[IMX8MM_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3); + clks[IMX8MM_CLK_M4_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3); + clks[IMX8MM_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3); + clks[IMX8MM_CLK_GPU3D_DIV] = imx_clk_divider2("gpu3d_div", "gpu3d_cg", base + 0x8180, 0, 3); + clks[IMX8MM_CLK_GPU2D_DIV] = imx_clk_divider2("gpu2d_div", "gpu2d_cg", base + 0x8200, 0, 3); + + /* BUS */ + clks[IMX8MM_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mm_main_axi_sels, base + 0x8800); + clks[IMX8MM_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mm_enet_axi_sels, base + 0x8880); + clks[IMX8MM_CLK_NAND_USDHC_BUS] = imx8m_clk_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900); + clks[IMX8MM_CLK_VPU_BUS] = imx8m_clk_composite("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980); + clks[IMX8MM_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00); + clks[IMX8MM_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80); + clks[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_composite("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00); + clks[IMX8MM_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80); + clks[IMX8MM_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00); + clks[IMX8MM_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80); + clks[IMX8MM_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mm_noc_sels, base + 0x8d00); + clks[IMX8MM_CLK_NOC_APB] = imx8m_clk_composite_critical("noc_apb", imx8mm_noc_apb_sels, base + 0x8d80); + + /* AHB */ + clks[IMX8MM_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mm_ahb_sels, base + 0x9000); + clks[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100); + + /* IPG */ + clks[IMX8MM_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1); + clks[IMX8MM_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1); + + /* IP */ + clks[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000); + clks[IMX8MM_CLK_DRAM_APB] = imx8m_clk_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080); + clks[IMX8MM_CLK_VPU_G1] = imx8m_clk_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100); + clks[IMX8MM_CLK_VPU_G2] = imx8m_clk_composite("vpu_g2", imx8mm_vpu_g2_sels, base + 0xa180); + clks[IMX8MM_CLK_DISP_DTRC] = imx8m_clk_composite("disp_dtrc", imx8mm_disp_dtrc_sels, base + 0xa200); + clks[IMX8MM_CLK_DISP_DC8000] = imx8m_clk_composite("disp_dc8000", imx8mm_disp_dc8000_sels, base + 0xa280); + clks[IMX8MM_CLK_PCIE1_CTRL] = imx8m_clk_composite("pcie1_ctrl", imx8mm_pcie1_ctrl_sels, base + 0xa300); + clks[IMX8MM_CLK_PCIE1_PHY] = imx8m_clk_composite("pcie1_phy", imx8mm_pcie1_phy_sels, base + 0xa380); + clks[IMX8MM_CLK_PCIE1_AUX] = imx8m_clk_composite("pcie1_aux", imx8mm_pcie1_aux_sels, base + 0xa400); + clks[IMX8MM_CLK_DC_PIXEL] = imx8m_clk_composite("dc_pixel", imx8mm_dc_pixel_sels, base + 0xa480); + clks[IMX8MM_CLK_LCDIF_PIXEL] = imx8m_clk_composite("lcdif_pixel", imx8mm_lcdif_pixel_sels, base + 0xa500); + clks[IMX8MM_CLK_SAI1] = imx8m_clk_composite("sai1", imx8mm_sai1_sels, base + 0xa580); + clks[IMX8MM_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mm_sai2_sels, base + 0xa600); + clks[IMX8MM_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mm_sai3_sels, base + 0xa680); + clks[IMX8MM_CLK_SAI4] = imx8m_clk_composite("sai4", imx8mm_sai4_sels, base + 0xa700); + clks[IMX8MM_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mm_sai5_sels, base + 0xa780); + clks[IMX8MM_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mm_sai6_sels, base + 0xa800); + clks[IMX8MM_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mm_spdif1_sels, base + 0xa880); + clks[IMX8MM_CLK_SPDIF2] = imx8m_clk_composite("spdif2", imx8mm_spdif2_sels, base + 0xa900); + clks[IMX8MM_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mm_enet_ref_sels, base + 0xa980); + clks[IMX8MM_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mm_enet_timer_sels, base + 0xaa00); + clks[IMX8MM_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mm_enet_phy_sels, base + 0xaa80); + clks[IMX8MM_CLK_NAND] = imx8m_clk_composite("nand", imx8mm_nand_sels, base + 0xab00); + clks[IMX8MM_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mm_qspi_sels, base + 0xab80); + clks[IMX8MM_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mm_usdhc1_sels, base + 0xac00); + clks[IMX8MM_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mm_usdhc2_sels, base + 0xac80); + clks[IMX8MM_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mm_i2c1_sels, base + 0xad00); + clks[IMX8MM_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mm_i2c2_sels, base + 0xad80); + clks[IMX8MM_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mm_i2c3_sels, base + 0xae00); + clks[IMX8MM_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mm_i2c4_sels, base + 0xae80); + clks[IMX8MM_CLK_UART1] = imx8m_clk_composite("uart1", imx8mm_uart1_sels, base + 0xaf00); + clks[IMX8MM_CLK_UART2] = imx8m_clk_composite("uart2", imx8mm_uart2_sels, base + 0xaf80); + clks[IMX8MM_CLK_UART3] = imx8m_clk_composite("uart3", imx8mm_uart3_sels, base + 0xb000); + clks[IMX8MM_CLK_UART4] = imx8m_clk_composite("uart4", imx8mm_uart4_sels, base + 0xb080); + clks[IMX8MM_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100); + clks[IMX8MM_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180); + clks[IMX8MM_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280); + clks[IMX8MM_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300); + clks[IMX8MM_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380); + clks[IMX8MM_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mm_pwm2_sels, base + 0xb400); + clks[IMX8MM_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mm_pwm3_sels, base + 0xb480); + clks[IMX8MM_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mm_pwm4_sels, base + 0xb500); + clks[IMX8MM_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mm_gpt1_sels, base + 0xb580); + clks[IMX8MM_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mm_wdog_sels, base + 0xb900); + clks[IMX8MM_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mm_wrclk_sels, base + 0xb980); + clks[IMX8MM_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mm_clko1_sels, base + 0xba00); + clks[IMX8MM_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mm_dsi_core_sels, base + 0xbb00); + clks[IMX8MM_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mm_dsi_phy_sels, base + 0xbb80); + clks[IMX8MM_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mm_dsi_dbi_sels, base + 0xbc00); + clks[IMX8MM_CLK_USDHC3] = imx8m_clk_composite("usdhc3", imx8mm_usdhc3_sels, base + 0xbc80); + clks[IMX8MM_CLK_CSI1_CORE] = imx8m_clk_composite("csi1_core", imx8mm_csi1_core_sels, base + 0xbd00); + clks[IMX8MM_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mm_csi1_phy_sels, base + 0xbd80); + clks[IMX8MM_CLK_CSI1_ESC] = imx8m_clk_composite("csi1_esc", imx8mm_csi1_esc_sels, base + 0xbe00); + clks[IMX8MM_CLK_CSI2_CORE] = imx8m_clk_composite("csi2_core", imx8mm_csi2_core_sels, base + 0xbe80); + clks[IMX8MM_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mm_csi2_phy_sels, base + 0xbf00); + clks[IMX8MM_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mm_csi2_esc_sels, base + 0xbf80); + clks[IMX8MM_CLK_PCIE2_CTRL] = imx8m_clk_composite("pcie2_ctrl", imx8mm_pcie2_ctrl_sels, base + 0xc000); + clks[IMX8MM_CLK_PCIE2_PHY] = imx8m_clk_composite("pcie2_phy", imx8mm_pcie2_phy_sels, base + 0xc080); + clks[IMX8MM_CLK_PCIE2_AUX] = imx8m_clk_composite("pcie2_aux", imx8mm_pcie2_aux_sels, base + 0xc100); + clks[IMX8MM_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mm_ecspi3_sels, base + 0xc180); + clks[IMX8MM_CLK_PDM] = imx8m_clk_composite("pdm", imx8mm_pdm_sels, base + 0xc200); + clks[IMX8MM_CLK_VPU_H1] = imx8m_clk_composite("vpu_h1", imx8mm_vpu_h1_sels, base + 0xc280); + + /* CCGR */ + clks[IMX8MM_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0); + clks[IMX8MM_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0); + clks[IMX8MM_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0); + clks[IMX8MM_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0); + clks[IMX8MM_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0); + clks[IMX8MM_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0); + clks[IMX8MM_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0); + clks[IMX8MM_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0); + clks[IMX8MM_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0); + clks[IMX8MM_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0); + clks[IMX8MM_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0); + clks[IMX8MM_CLK_PCIE1_ROOT] = imx_clk_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0); + clks[IMX8MM_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0); + clks[IMX8MM_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0); + clks[IMX8MM_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0); + clks[IMX8MM_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0); + clks[IMX8MM_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0); + clks[IMX8MM_CLK_NAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand); + clks[IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand); + clks[IMX8MM_CLK_SAI1_ROOT] = imx_clk_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1); + clks[IMX8MM_CLK_SAI1_IPG] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1); + clks[IMX8MM_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2); + clks[IMX8MM_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2); + clks[IMX8MM_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3); + clks[IMX8MM_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3); + clks[IMX8MM_CLK_SAI4_ROOT] = imx_clk_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4); + clks[IMX8MM_CLK_SAI4_IPG] = imx_clk_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4); + clks[IMX8MM_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5); + clks[IMX8MM_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5); + clks[IMX8MM_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6); + clks[IMX8MM_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6); + clks[IMX8MM_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0); + clks[IMX8MM_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0); + clks[IMX8MM_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0); + clks[IMX8MM_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0); + clks[IMX8MM_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref", base + 0x44d0, 0); + clks[IMX8MM_CLK_GPU3D_ROOT] = imx_clk_gate4("gpu3d_root_clk", "gpu3d_div", base + 0x44f0, 0); + clks[IMX8MM_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0); + clks[IMX8MM_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0); + clks[IMX8MM_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0); + clks[IMX8MM_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0); + clks[IMX8MM_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0); + clks[IMX8MM_CLK_VPU_G1_ROOT] = imx_clk_gate4("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0); + clks[IMX8MM_CLK_GPU_BUS_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0); + clks[IMX8MM_CLK_VPU_H1_ROOT] = imx_clk_gate4("vpu_h1_root_clk", "vpu_h1", base + 0x4590, 0); + clks[IMX8MM_CLK_VPU_G2_ROOT] = imx_clk_gate4("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0); + clks[IMX8MM_CLK_PDM_ROOT] = imx_clk_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm); + clks[IMX8MM_CLK_PDM_IPG] = imx_clk_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm); + clks[IMX8MM_CLK_DISP_ROOT] = imx_clk_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_dcss); + clks[IMX8MM_CLK_DISP_AXI_ROOT] = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss); + clks[IMX8MM_CLK_DISP_APB_ROOT] = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss); + clks[IMX8MM_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss); + clks[IMX8MM_CLK_USDHC3_ROOT] = imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0); + clks[IMX8MM_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0); + clks[IMX8MM_CLK_VPU_DEC_ROOT] = imx_clk_gate4("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0); + clks[IMX8MM_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0); + clks[IMX8MM_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0); + clks[IMX8MM_CLK_SDMA3_ROOT] = imx_clk_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0); + clks[IMX8MM_CLK_GPU2D_ROOT] = imx_clk_gate4("gpu2d_root_clk", "gpu2d_div", base + 0x4660, 0); + clks[IMX8MM_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0); + + clks[IMX8MM_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc_24m", 1, 8); + + clks[IMX8MM_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4); + clks[IMX8MM_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mm_dram_core_sels, ARRAY_SIZE(imx8mm_dram_core_sels), CLK_IS_CRITICAL); + + clks[IMX8MM_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div", + clks[IMX8MM_CLK_A53_DIV], + clks[IMX8MM_CLK_A53_SRC], + clks[IMX8MM_ARM_PLL_OUT], + clks[IMX8MM_CLK_24M]); + + imx_check_clocks(clks, ARRAY_SIZE(clks)); + + clk_data.clks = clks; + clk_data.clk_num = ARRAY_SIZE(clks); + ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); + if (ret < 0) { + pr_err("failed to register clks for i.MX8MM\n"); + return -EINVAL; + } + + imx_register_uart_clocks(uart_clks); + + return 0; +} +CLK_OF_DECLARE_DRIVER(imx8mm, "fsl,imx8mm-ccm", imx8mm_clocks_init);