From nobody Thu Dec 18 09:49:02 2025 Received: from mail-ed1-f45.google.com (mail-ed1-f45.google.com [209.85.208.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3E4DC19D06E for ; Sun, 29 Dec 2024 14:50:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735483855; cv=none; b=IkcN+pTGpcp/Xz7KCuulRs71qcP44ZusnldJbBqriQmRl8KA0o7GGHvGThoTPUdmcMRmjia2qBl2oX9s0h5urOayZojVJTZhhBXY9wRDVOzk3oWHFwn3a+dn1vXx/21kTpHR0Q9OFzoEfA35DwHqaWCo75ogjC+WDo74/ax2bvU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1735483855; c=relaxed/simple; bh=bWRmFvxqhZ+28yf5JFXHx8pdct+bHGksNb6SFLtN498=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=OHeojJwACrXY+obh+IZJ6OCSRrZrgibGJqQvPI0yXaY3VUVo1DClSJKb24iyRN7Ro9neozwgxomqP/mrppB+LpzcPyhzISoUuFJDPGUXWbtT1UkOoHx1VvSh1ipNoA/PEif9evo3tVK/n9g8oO888zthZkmF3nby/1rKuOpruUU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=amarulasolutions.com; spf=pass smtp.mailfrom=amarulasolutions.com; dkim=pass (1024-bit key) header.d=amarulasolutions.com header.i=@amarulasolutions.com header.b=QgZ5N9pN; arc=none smtp.client-ip=209.85.208.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=amarulasolutions.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=amarulasolutions.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=amarulasolutions.com header.i=@amarulasolutions.com header.b="QgZ5N9pN" Received: by mail-ed1-f45.google.com with SMTP id 4fb4d7f45d1cf-5d3e9f60bf4so14479170a12.3 for ; Sun, 29 Dec 2024 06:50:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; t=1735483850; x=1736088650; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=R3M2Twd4RPp+D4raQf7zz0xs4A+eb54+adCLPeXEQO4=; b=QgZ5N9pNVvZsM1+HC6ykgPfh24hbTc942+ikdgZYB1DrJchbUzn2OHQt+HNKK4varO kiQ7/b2bTb67eZzivkCZtlUZ9bbx0KErhsdiXklNrILGwDyKxH2VfT4FHHCvS7UXoSpS 9Iep8iF5fdDbTpm7yjt+cVR4qHmrymWEYINm8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1735483850; x=1736088650; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=R3M2Twd4RPp+D4raQf7zz0xs4A+eb54+adCLPeXEQO4=; b=wsnesQa4Y3S2V7GJ2q46pmVKSnpEwj7fISLUbirONoMiiv1qhfofgJaR2x3xuvvqXh j1r+1SHg44MoYAeAOh7hujGGgUCUJrFTX1VgnIcLP0xkUq0NSVchrtFMORX3JXcwp9fp 3M3I82e7PS04YwvTMDFo8lI7H9sSQbYbAQp8TECciEFyOfz6k2ZiSUtlF72ht2N8yEsp FX4J7iG9o+i6h79hK5ETsrEMbtZvYbl/T5mhch2/q2XGVxGK3tOUtFYmcg/zKPv6TmTW Te9eUNHW3Fangc508AGYb3ylcb9TdWrYXPbQxlCZmy2Bd6HALtwcJhzbXI/9V3K+fFZ0 sbcQ== X-Gm-Message-State: AOJu0YyW0z12eGfTT2J8tnjcq/b1tbLN/YD4vcOW0UuqQYDiRWCmwW+3 ozDCap77epq3OZZFSNkz52HRj29K8T7JGHzSCOgcBTD/RENexfcqo0yS6KLodXGrhHnVPzaYNEC 0 X-Gm-Gg: ASbGnct3oLKj8QOFNGZfRqnJl/d9zwcBdRD3/sgNXtDErfdQ9hcFb5v2Dam8lgNxjFD TwqHRlVbbIg1DRQODcfgByPHjmPCZruG27nDyOf0hGsjG6Q/uh99RQMyXZ2x5GQQj9uEgEz94R4 s9bzBgOlb8EC6sppRKwxoo+ffS//k6xjEbULvl1EtykMxPJ3xDR/K1a+M37Os2LNe+VCG7CK83g 63mprc8AUuOBzeSBvPyRldw4Ng5HPKJZLaULR7v7/AASWOOCiuf7wPh4QG+37v4ZIykfPDrr4eF l92dvH+kdcxRS7YXz4R0aw== X-Google-Smtp-Source: AGHT+IHImVLFZCAV8H6RyLgRl3bcygH3qBj3OU6J7FaswfRb+4E/3AfXdWPdVndilDa7Go3oc6Yykg== X-Received: by 2002:a17:906:d54f:b0:aac:622:8f6 with SMTP id a640c23a62f3a-aac3342d0c5mr2662720066b.17.1735483849746; Sun, 29 Dec 2024 06:50:49 -0800 (PST) Received: from dario-ThinkPad-T14s-Gen-2i.. ([2.196.43.175]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-aac0e895080sm1362084466b.47.2024.12.29.06.50.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 29 Dec 2024 06:50:49 -0800 (PST) From: Dario Binacchi To: linux-kernel@vger.kernel.org Cc: linux-amarula@amarulasolutions.com, Dario Binacchi , Abel Vesa , Fabio Estevam , Michael Turquette , Peng Fan , Pengutronix Kernel Team , Sascha Hauer , Shawn Guo , Stephen Boyd , imx@lists.linux.dev, linux-arm-kernel@lists.infradead.org, linux-clk@vger.kernel.org Subject: [PATCH v8 11/18] clk: imx: add support for i.MX8MN anatop clock driver Date: Sun, 29 Dec 2024 15:49:35 +0100 Message-ID: <20241229145027.3984542-12-dario.binacchi@amarulasolutions.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20241229145027.3984542-1-dario.binacchi@amarulasolutions.com> References: <20241229145027.3984542-1-dario.binacchi@amarulasolutions.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Support NXP i.MX8M anatop PLL module which generates PLLs to CCM root. By doing so, we also simplify the CCM driver code. The changes are backward compatible. Signed-off-by: Dario Binacchi Reviewed-by: Peng Fan --- Changes in v8: - Drop call of of_parse_phandle() to get the anatop's device node. Changes in v7: - Update the code based on the changes made to the imx8m_anatop_get_clk_hw(): - Rename imx8m_anatop_get_clk_hw to imx_anatop_get_clk_hw - Add device_node type parameter - Call of_parse_phandle() to get the anatop's device node. Changes in v6: - Define IMX8MN_ANATOP_CLK_END inside the driver after it has ben removed from include/dt-bindings/clock/imx8mn-clock.h. Changes in v4: - New drivers/clk/imx/Makefile | 2 +- drivers/clk/imx/clk-imx8mn-anatop.c | 283 ++++++++++++++++++++++++++++ drivers/clk/imx/clk-imx8mn.c | 183 ++++++++---------- 3 files changed, 364 insertions(+), 104 deletions(-) create mode 100644 drivers/clk/imx/clk-imx8mn-anatop.c diff --git a/drivers/clk/imx/Makefile b/drivers/clk/imx/Makefile index 03f2b2a1ab63..f0f1d01c68f8 100644 --- a/drivers/clk/imx/Makefile +++ b/drivers/clk/imx/Makefile @@ -26,7 +26,7 @@ mxc-clk-objs +=3D clk-gpr-mux.o obj-$(CONFIG_MXC_CLK) +=3D mxc-clk.o =20 obj-$(CONFIG_CLK_IMX8MM) +=3D clk-imx8mm.o -obj-$(CONFIG_CLK_IMX8MN) +=3D clk-imx8mn.o +obj-$(CONFIG_CLK_IMX8MN) +=3D clk-imx8mn-anatop.o clk-imx8mn.o obj-$(CONFIG_CLK_IMX8MP) +=3D clk-imx8mp.o clk-imx8mp-audiomix.o obj-$(CONFIG_CLK_IMX8MQ) +=3D clk-imx8mq.o =20 diff --git a/drivers/clk/imx/clk-imx8mn-anatop.c b/drivers/clk/imx/clk-imx8= mn-anatop.c new file mode 100644 index 000000000000..895569d886f4 --- /dev/null +++ b/drivers/clk/imx/clk-imx8mn-anatop.c @@ -0,0 +1,283 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * clk-imx8mn-anatop.c - NXP i.MX8MN anatop clock driver + * + * Copyright (c) 2024 Dario Binacchi + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "clk.h" + +#define IMX8MN_ANATOP_CLK_END IMX8MN_ANATOP_CLK_CLKOUT2 + +static const char * const pll_ref_sels[] =3D { "osc_24m", "dummy", "dummy"= , "dummy", }; +static const char * const audio_pll1_bypass_sels[] =3D {"audio_pll1", "aud= io_pll1_ref_sel", }; +static const char * const audio_pll2_bypass_sels[] =3D {"audio_pll2", "aud= io_pll2_ref_sel", }; +static const char * const video_pll_bypass_sels[] =3D {"video_pll", "video= _pll_ref_sel", }; +static const char * const dram_pll_bypass_sels[] =3D {"dram_pll", "dram_pl= l_ref_sel", }; +static const char * const gpu_pll_bypass_sels[] =3D {"gpu_pll", "gpu_pll_r= ef_sel", }; +static const char * const m7_alt_pll_bypass_sels[] =3D {"m7_alt_pll", "m7_= alt_pll_ref_sel", }; +static const char * const arm_pll_bypass_sels[] =3D {"arm_pll", "arm_pll_r= ef_sel", }; +static const char * const sys_pll3_bypass_sels[] =3D {"sys_pll3", "sys_pll= 3_ref_sel", }; +static const char * const clkout_sels[] =3D {"audio_pll1_out", "audio_pll2= _out", "video_pll_out", + "dummy", "dummy", "gpu_pll_out", "dummy", + "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3", + "dummy", "dummy", "osc_24m", "dummy", "osc_32k"}; + +static struct clk_hw_onecell_data *clk_hw_data; +static struct clk_hw **hws; + +static int imx8mn_anatop_clocks_probe(struct platform_device *pdev) +{ + struct device *dev =3D &pdev->dev; + struct device_node *np =3D dev->of_node; + void __iomem *base; + int ret; + + base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) { + dev_err(dev, "failed to get base address\n"); + return PTR_ERR(base); + } + + clk_hw_data =3D devm_kzalloc(dev, struct_size(clk_hw_data, hws, + IMX8MN_ANATOP_CLK_END), + GFP_KERNEL); + if (WARN_ON(!clk_hw_data)) + return -ENOMEM; + + clk_hw_data->num =3D IMX8MN_ANATOP_CLK_END; + hws =3D clk_hw_data->hws; + + hws[IMX8MN_ANATOP_CLK_DUMMY] =3D imx_clk_hw_fixed("dummy", 0); + hws[IMX8MN_ANATOP_CLK_32K] =3D imx_get_clk_hw_by_name(np, "osc_32k"); + hws[IMX8MN_ANATOP_CLK_24M] =3D imx_get_clk_hw_by_name(np, "osc_24m"); + + hws[IMX8MN_ANATOP_AUDIO_PLL1_REF_SEL] =3D + imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, + pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_ANATOP_AUDIO_PLL2_REF_SEL] =3D + imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, + pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_ANATOP_VIDEO_PLL_REF_SEL] =3D + imx_clk_hw_mux("video_pll_ref_sel", base + 0x28, 0, 2, + pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_ANATOP_DRAM_PLL_REF_SEL] =3D + imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, + pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_ANATOP_GPU_PLL_REF_SEL] =3D + imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, + pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_ANATOP_M7_ALT_PLL_REF_SEL] =3D + imx_clk_hw_mux("m7_alt_pll_ref_sel", base + 0x74, 0, 2, + pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_ANATOP_ARM_PLL_REF_SEL] =3D + imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2, + pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + hws[IMX8MN_ANATOP_SYS_PLL3_REF_SEL] =3D + imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, + pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); + + hws[IMX8MN_ANATOP_AUDIO_PLL1] =3D + imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", + base, &imx_1443x_pll); + hws[IMX8MN_ANATOP_AUDIO_PLL2] =3D + imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", + base + 0x14, &imx_1443x_pll); + hws[IMX8MN_ANATOP_VIDEO_PLL] =3D + imx_clk_hw_pll14xx("video_pll", "video_pll_ref_sel", + base + 0x28, &imx_1443x_pll); + hws[IMX8MN_ANATOP_DRAM_PLL] =3D + imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, + &imx_1443x_dram_pll); + hws[IMX8MN_ANATOP_GPU_PLL] =3D + imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, + &imx_1416x_pll); + hws[IMX8MN_ANATOP_M7_ALT_PLL] =3D + imx_clk_hw_pll14xx("m7_alt_pll", "m7_alt_pll_ref_sel", + base + 0x74, &imx_1416x_pll); + hws[IMX8MN_ANATOP_ARM_PLL] =3D + imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, + &imx_1416x_pll); + hws[IMX8MN_ANATOP_SYS_PLL1] =3D imx_clk_hw_fixed("sys_pll1", 800000000); + hws[IMX8MN_ANATOP_SYS_PLL2] =3D imx_clk_hw_fixed("sys_pll2", 1000000000); + hws[IMX8MN_ANATOP_SYS_PLL3] =3D + imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, + &imx_1416x_pll); + + /* PLL bypass out */ + hws[IMX8MN_ANATOP_AUDIO_PLL1_BYPASS] =3D + imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, + audio_pll1_bypass_sels, + ARRAY_SIZE(audio_pll1_bypass_sels), + CLK_SET_RATE_PARENT); + hws[IMX8MN_ANATOP_AUDIO_PLL2_BYPASS] =3D + imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, + audio_pll2_bypass_sels, + ARRAY_SIZE(audio_pll2_bypass_sels), + CLK_SET_RATE_PARENT); + hws[IMX8MN_ANATOP_VIDEO_PLL_BYPASS] =3D + imx_clk_hw_mux_flags("video_pll_bypass", base + 0x28, 16, 1, + video_pll_bypass_sels, + ARRAY_SIZE(video_pll_bypass_sels), + CLK_SET_RATE_PARENT); + hws[IMX8MN_ANATOP_DRAM_PLL_BYPASS] =3D + imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, + dram_pll_bypass_sels, + ARRAY_SIZE(dram_pll_bypass_sels), + CLK_SET_RATE_PARENT); + hws[IMX8MN_ANATOP_GPU_PLL_BYPASS] =3D + imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, + gpu_pll_bypass_sels, + ARRAY_SIZE(gpu_pll_bypass_sels), + CLK_SET_RATE_PARENT); + hws[IMX8MN_ANATOP_M7_ALT_PLL_BYPASS] =3D + imx_clk_hw_mux_flags("m7_alt_pll_bypass", base + 0x74, 28, 1, + m7_alt_pll_bypass_sels, + ARRAY_SIZE(m7_alt_pll_bypass_sels), + CLK_SET_RATE_PARENT); + hws[IMX8MN_ANATOP_ARM_PLL_BYPASS] =3D + imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, + arm_pll_bypass_sels, + ARRAY_SIZE(arm_pll_bypass_sels), + CLK_SET_RATE_PARENT); + hws[IMX8MN_ANATOP_SYS_PLL3_BYPASS] =3D + imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, + sys_pll3_bypass_sels, + ARRAY_SIZE(sys_pll3_bypass_sels), + CLK_SET_RATE_PARENT); + + /* PLL out gate */ + hws[IMX8MN_ANATOP_AUDIO_PLL1_OUT] =3D + imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", + base, 13); + hws[IMX8MN_ANATOP_AUDIO_PLL2_OUT] =3D + imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", + base + 0x14, 13); + hws[IMX8MN_ANATOP_VIDEO_PLL_OUT] =3D + imx_clk_hw_gate("video_pll_out", "video_pll_bypass", + base + 0x28, 13); + hws[IMX8MN_ANATOP_DRAM_PLL_OUT] =3D + imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", + base + 0x50, 13); + hws[IMX8MN_ANATOP_GPU_PLL_OUT] =3D + imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", + base + 0x64, 11); + hws[IMX8MN_ANATOP_M7_ALT_PLL_OUT] =3D + imx_clk_hw_gate("m7_alt_pll_out", "m7_alt_pll_bypass", + base + 0x74, 11); + hws[IMX8MN_ANATOP_ARM_PLL_OUT] =3D + imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", + base + 0x84, 11); + hws[IMX8MN_ANATOP_SYS_PLL3_OUT] =3D + imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", + base + 0x114, 11); + + /* SYS PLL1 fixed output */ + hws[IMX8MN_ANATOP_SYS_PLL1_OUT] =3D + imx_clk_hw_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11); + hws[IMX8MN_ANATOP_SYS_PLL1_40M] =3D + imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20); + hws[IMX8MN_ANATOP_SYS_PLL1_80M] =3D + imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10); + hws[IMX8MN_ANATOP_SYS_PLL1_100M] =3D + imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8); + hws[IMX8MN_ANATOP_SYS_PLL1_133M] =3D + imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6); + hws[IMX8MN_ANATOP_SYS_PLL1_160M] =3D + imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5); + hws[IMX8MN_ANATOP_SYS_PLL1_200M] =3D + imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4); + hws[IMX8MN_ANATOP_SYS_PLL1_266M] =3D + imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3); + hws[IMX8MN_ANATOP_SYS_PLL1_400M] =3D + imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2); + hws[IMX8MN_ANATOP_SYS_PLL1_800M] =3D + imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1); + + /* SYS PLL2 fixed output */ + hws[IMX8MN_ANATOP_SYS_PLL2_OUT] =3D + imx_clk_hw_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11); + hws[IMX8MN_ANATOP_SYS_PLL2_50M] =3D + imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20); + hws[IMX8MN_ANATOP_SYS_PLL2_100M] =3D + imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10); + hws[IMX8MN_ANATOP_SYS_PLL2_125M] =3D + imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8); + hws[IMX8MN_ANATOP_SYS_PLL2_166M] =3D + imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6); + hws[IMX8MN_ANATOP_SYS_PLL2_200M] =3D + imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5); + hws[IMX8MN_ANATOP_SYS_PLL2_250M] =3D + imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4); + hws[IMX8MN_ANATOP_SYS_PLL2_333M] =3D + imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3); + hws[IMX8MN_ANATOP_SYS_PLL2_500M] =3D + imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2); + hws[IMX8MN_ANATOP_SYS_PLL2_1000M] =3D + imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); + + hws[IMX8MN_ANATOP_CLK_CLKOUT1_SEL] =3D + imx_clk_hw_mux2("clkout1_sel", base + 0x128, 4, 4, + clkout_sels, ARRAY_SIZE(clkout_sels)); + hws[IMX8MN_ANATOP_CLK_CLKOUT1_DIV] =3D + imx_clk_hw_divider("clkout1_div", "clkout1_sel", base + 0x128, + 0, 4); + hws[IMX8MN_ANATOP_CLK_CLKOUT1] =3D + imx_clk_hw_gate("clkout1", "clkout1_div", base + 0x128, 8); + hws[IMX8MN_ANATOP_CLK_CLKOUT2_SEL] =3D + imx_clk_hw_mux2("clkout2_sel", base + 0x128, 20, 4, + clkout_sels, ARRAY_SIZE(clkout_sels)); + hws[IMX8MN_ANATOP_CLK_CLKOUT2_DIV] =3D + imx_clk_hw_divider("clkout2_div", "clkout2_sel", base + 0x128, + 16, 4); + hws[IMX8MN_ANATOP_CLK_CLKOUT2] =3D + imx_clk_hw_gate("clkout2", "clkout2_div", base + 0x128, 24); + + imx_check_clk_hws(hws, IMX8MN_ANATOP_CLK_END); + + ret =3D of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); + if (ret < 0) { + imx_unregister_hw_clocks(hws, IMX8MN_ANATOP_CLK_END); + return dev_err_probe(dev, ret, + "failed to register anatop clock provider\n"); + } + + dev_info(dev, "NXP i.MX8MN anatop clock driver probed\n"); + return 0; +} + +static const struct of_device_id imx8mn_anatop_clk_of_match[] =3D { + { .compatible =3D "fsl,imx8mn-anatop" }, + { /* Sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, imx8mn_anatop_clk_of_match); + +static struct platform_driver imx8mn_anatop_clk_driver =3D { + .probe =3D imx8mn_anatop_clocks_probe, + .driver =3D { + .name =3D "imx8mn-anatop", + /* + * Disable bind attributes: clocks are not removed and + * reloading the driver will crash or break devices. + */ + .suppress_bind_attrs =3D true, + .of_match_table =3D imx8mn_anatop_clk_of_match, + }, +}; + +module_platform_driver(imx8mn_anatop_clk_driver); + +MODULE_AUTHOR("Dario Binacchi "); +MODULE_DESCRIPTION("NXP i.MX8MN anatop clock driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c index ab77e148e70c..c3a3d063d58e 100644 --- a/drivers/clk/imx/clk-imx8mn.c +++ b/drivers/clk/imx/clk-imx8mn.c @@ -24,16 +24,6 @@ static u32 share_count_disp; static u32 share_count_pdm; static u32 share_count_nand; =20 -static const char * const pll_ref_sels[] =3D { "osc_24m", "dummy", "dummy"= , "dummy", }; -static const char * const audio_pll1_bypass_sels[] =3D {"audio_pll1", "aud= io_pll1_ref_sel", }; -static const char * const audio_pll2_bypass_sels[] =3D {"audio_pll2", "aud= io_pll2_ref_sel", }; -static const char * const video_pll_bypass_sels[] =3D {"video_pll", "video= _pll_ref_sel", }; -static const char * const dram_pll_bypass_sels[] =3D {"dram_pll", "dram_pl= l_ref_sel", }; -static const char * const gpu_pll_bypass_sels[] =3D {"gpu_pll", "gpu_pll_r= ef_sel", }; -static const char * const m7_alt_pll_bypass_sels[] =3D {"m7_alt_pll", "m7_= alt_pll_ref_sel", }; -static const char * const arm_pll_bypass_sels[] =3D {"arm_pll", "arm_pll_r= ef_sel", }; -static const char * const sys_pll3_bypass_sels[] =3D {"sys_pll3", "sys_pll= 3_ref_sel", }; - static const char * const imx8mn_a53_sels[] =3D {"osc_24m", "arm_pll_out",= "sys_pll2_500m", "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m", "audio_pll1_out", "sys_pll3_out", }; @@ -308,21 +298,20 @@ static const char * const imx8mn_clko2_sels[] =3D {"o= sc_24m", "sys_pll2_200m", "sy "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", "video_pll_out", "osc_32k", }; =20 -static const char * const clkout_sels[] =3D {"audio_pll1_out", "audio_pll2= _out", "video_pll_out", - "dummy", "dummy", "gpu_pll_out", "dummy", - "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3", - "dummy", "dummy", "osc_24m", "dummy", "osc_32k"}; - static struct clk_hw_onecell_data *clk_hw_data; static struct clk_hw **hws; =20 static int imx8mn_clocks_probe(struct platform_device *pdev) { struct device *dev =3D &pdev->dev; - struct device_node *np =3D dev->of_node; + struct device_node *np =3D dev->of_node, *anp; void __iomem *base; int ret; =20 + base =3D devm_platform_ioremap_resource(pdev, 0); + if (WARN_ON(IS_ERR(base))) + return PTR_ERR(base); + clk_hw_data =3D devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MN_CLK_END), GFP_KERNEL); if (WARN_ON(!clk_hw_data)) @@ -331,99 +320,90 @@ static int imx8mn_clocks_probe(struct platform_device= *pdev) clk_hw_data->num =3D IMX8MN_CLK_END; hws =3D clk_hw_data->hws; =20 - hws[IMX8MN_CLK_DUMMY] =3D imx_clk_hw_fixed("dummy", 0); - hws[IMX8MN_CLK_24M] =3D imx_get_clk_hw_by_name(np, "osc_24m"); - hws[IMX8MN_CLK_32K] =3D imx_get_clk_hw_by_name(np, "osc_32k"); + anp =3D of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop"); + if (!anp) + return dev_err_probe(dev, -ENODEV, "missing anatop\n"); + + of_node_put(anp); + + hws[IMX8MN_CLK_DUMMY] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_CLK_DU= MMY); + hws[IMX8MN_CLK_24M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_CLK_24M); + hws[IMX8MN_CLK_32K] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_CLK_32K); hws[IMX8MN_CLK_EXT1] =3D imx_get_clk_hw_by_name(np, "clk_ext1"); hws[IMX8MN_CLK_EXT2] =3D imx_get_clk_hw_by_name(np, "clk_ext2"); hws[IMX8MN_CLK_EXT3] =3D imx_get_clk_hw_by_name(np, "clk_ext3"); hws[IMX8MN_CLK_EXT4] =3D imx_get_clk_hw_by_name(np, "clk_ext4"); =20 - np =3D of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop"); - base =3D devm_of_iomap(dev, np, 0, NULL); - of_node_put(np); - if (WARN_ON(IS_ERR(base))) { - ret =3D PTR_ERR(base); - goto unregister_hws; - } - - hws[IMX8MN_AUDIO_PLL1_REF_SEL] =3D imx_clk_hw_mux("audio_pll1_ref_sel", b= ase + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - hws[IMX8MN_AUDIO_PLL2_REF_SEL] =3D imx_clk_hw_mux("audio_pll2_ref_sel", b= ase + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - hws[IMX8MN_VIDEO_PLL_REF_SEL] =3D imx_clk_hw_mux("video_pll_ref_sel", bas= e + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - hws[IMX8MN_DRAM_PLL_REF_SEL] =3D imx_clk_hw_mux("dram_pll_ref_sel", base = + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - hws[IMX8MN_GPU_PLL_REF_SEL] =3D imx_clk_hw_mux("gpu_pll_ref_sel", base + = 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - hws[IMX8MN_M7_ALT_PLL_REF_SEL] =3D imx_clk_hw_mux("m7_alt_pll_ref_sel", b= ase + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - hws[IMX8MN_ARM_PLL_REF_SEL] =3D imx_clk_hw_mux("arm_pll_ref_sel", base + = 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - hws[IMX8MN_SYS_PLL3_REF_SEL] =3D imx_clk_hw_mux("sys_pll3_ref_sel", base = + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels)); - - hws[IMX8MN_AUDIO_PLL1] =3D imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_r= ef_sel", base, &imx_1443x_pll); - hws[IMX8MN_AUDIO_PLL2] =3D imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_r= ef_sel", base + 0x14, &imx_1443x_pll); - hws[IMX8MN_VIDEO_PLL] =3D imx_clk_hw_pll14xx("video_pll", "video_pll_ref_= sel", base + 0x28, &imx_1443x_pll); - hws[IMX8MN_DRAM_PLL] =3D imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel= ", base + 0x50, &imx_1443x_dram_pll); - hws[IMX8MN_GPU_PLL] =3D imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", = base + 0x64, &imx_1416x_pll); - hws[IMX8MN_M7_ALT_PLL] =3D imx_clk_hw_pll14xx("m7_alt_pll", "m7_alt_pll_r= ef_sel", base + 0x74, &imx_1416x_pll); - hws[IMX8MN_ARM_PLL] =3D imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", = base + 0x84, &imx_1416x_pll); - hws[IMX8MN_SYS_PLL1] =3D imx_clk_hw_fixed("sys_pll1", 800000000); - hws[IMX8MN_SYS_PLL2] =3D imx_clk_hw_fixed("sys_pll2", 1000000000); - hws[IMX8MN_SYS_PLL3] =3D imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel= ", base + 0x114, &imx_1416x_pll); + hws[IMX8MN_AUDIO_PLL1_REF_SEL] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANAT= OP_AUDIO_PLL1_REF_SEL); + hws[IMX8MN_AUDIO_PLL2_REF_SEL] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANAT= OP_AUDIO_PLL2_REF_SEL); + hws[IMX8MN_VIDEO_PLL_REF_SEL] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATO= P_VIDEO_PLL_REF_SEL); + hws[IMX8MN_DRAM_PLL_REF_SEL] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP= _DRAM_PLL_REF_SEL); + hws[IMX8MN_GPU_PLL_REF_SEL] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_= GPU_PLL_REF_SEL); + hws[IMX8MN_M7_ALT_PLL_REF_SEL] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANAT= OP_M7_ALT_PLL_REF_SEL); + hws[IMX8MN_ARM_PLL_REF_SEL] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_= ARM_PLL_REF_SEL); + hws[IMX8MN_SYS_PLL3_REF_SEL] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP= _SYS_PLL3_REF_SEL); + + hws[IMX8MN_AUDIO_PLL1] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_AUDIO= _PLL1); + hws[IMX8MN_AUDIO_PLL2] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_AUDIO= _PLL2); + hws[IMX8MN_VIDEO_PLL] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_VIDEO_= PLL); + hws[IMX8MN_DRAM_PLL] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_DRAM_PL= L); + hws[IMX8MN_GPU_PLL] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_GPU_PLL); + hws[IMX8MN_M7_ALT_PLL] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_M7_AL= T_PLL); + hws[IMX8MN_ARM_PLL] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_ARM_PLL); + hws[IMX8MN_SYS_PLL1] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SYS_PLL= 1); + hws[IMX8MN_SYS_PLL2] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SYS_PLL= 2); + hws[IMX8MN_SYS_PLL3] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SYS_PLL= 3); =20 /* PLL bypass out */ - hws[IMX8MN_AUDIO_PLL1_BYPASS] =3D imx_clk_hw_mux_flags("audio_pll1_bypass= ", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels),= CLK_SET_RATE_PARENT); - hws[IMX8MN_AUDIO_PLL2_BYPASS] =3D imx_clk_hw_mux_flags("audio_pll2_bypass= ", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass= _sels), CLK_SET_RATE_PARENT); - hws[IMX8MN_VIDEO_PLL_BYPASS] =3D imx_clk_hw_mux_flags("video_pll_bypass",= base + 0x28, 16, 1, video_pll_bypass_sels, ARRAY_SIZE(video_pll_bypass_sel= s), CLK_SET_RATE_PARENT); - hws[IMX8MN_DRAM_PLL_BYPASS] =3D imx_clk_hw_mux_flags("dram_pll_bypass", b= ase + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), = CLK_SET_RATE_PARENT); - hws[IMX8MN_GPU_PLL_BYPASS] =3D imx_clk_hw_mux_flags("gpu_pll_bypass", bas= e + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_= SET_RATE_PARENT); - hws[IMX8MN_M7_ALT_PLL_BYPASS] =3D imx_clk_hw_mux_flags("m7_alt_pll_bypass= ", base + 0x74, 28, 1, m7_alt_pll_bypass_sels, ARRAY_SIZE(m7_alt_pll_bypass= _sels), CLK_SET_RATE_PARENT); - hws[IMX8MN_ARM_PLL_BYPASS] =3D imx_clk_hw_mux_flags("arm_pll_bypass", bas= e + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_= SET_RATE_PARENT); - hws[IMX8MN_SYS_PLL3_BYPASS] =3D imx_clk_hw_mux_flags("sys_pll3_bypass", b= ase + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels),= CLK_SET_RATE_PARENT); + hws[IMX8MN_AUDIO_PLL1_BYPASS] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATO= P_AUDIO_PLL1_BYPASS); + hws[IMX8MN_AUDIO_PLL2_BYPASS] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATO= P_AUDIO_PLL2_BYPASS); + hws[IMX8MN_VIDEO_PLL_BYPASS] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP= _VIDEO_PLL_BYPASS); + hws[IMX8MN_DRAM_PLL_BYPASS] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_= DRAM_PLL_BYPASS); + hws[IMX8MN_GPU_PLL_BYPASS] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_G= PU_PLL_BYPASS); + hws[IMX8MN_M7_ALT_PLL_BYPASS] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATO= P_M7_ALT_PLL_BYPASS); + hws[IMX8MN_ARM_PLL_BYPASS] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_A= RM_PLL_BYPASS); + hws[IMX8MN_SYS_PLL3_BYPASS] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_= SYS_PLL3_BYPASS); =20 /* PLL out gate */ - hws[IMX8MN_AUDIO_PLL1_OUT] =3D imx_clk_hw_gate("audio_pll1_out", "audio_p= ll1_bypass", base, 13); - hws[IMX8MN_AUDIO_PLL2_OUT] =3D imx_clk_hw_gate("audio_pll2_out", "audio_p= ll2_bypass", base + 0x14, 13); - hws[IMX8MN_VIDEO_PLL_OUT] =3D imx_clk_hw_gate("video_pll_out", "video_pll= _bypass", base + 0x28, 13); - hws[IMX8MN_DRAM_PLL_OUT] =3D imx_clk_hw_gate("dram_pll_out", "dram_pll_by= pass", base + 0x50, 13); - hws[IMX8MN_GPU_PLL_OUT] =3D imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypas= s", base + 0x64, 11); - hws[IMX8MN_M7_ALT_PLL_OUT] =3D imx_clk_hw_gate("m7_alt_pll_out", "m7_alt_= pll_bypass", base + 0x74, 11); - hws[IMX8MN_ARM_PLL_OUT] =3D imx_clk_hw_gate("arm_pll_out", "arm_pll_bypas= s", base + 0x84, 11); - hws[IMX8MN_SYS_PLL3_OUT] =3D imx_clk_hw_gate("sys_pll3_out", "sys_pll3_by= pass", base + 0x114, 11); + hws[IMX8MN_AUDIO_PLL1_OUT] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_A= UDIO_PLL1_OUT); + hws[IMX8MN_AUDIO_PLL2_OUT] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_A= UDIO_PLL2_OUT); + hws[IMX8MN_VIDEO_PLL_OUT] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_VI= DEO_PLL_OUT); + hws[IMX8MN_DRAM_PLL_OUT] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_DRA= M_PLL_OUT); + hws[IMX8MN_GPU_PLL_OUT] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_GPU_= PLL_OUT); + hws[IMX8MN_M7_ALT_PLL_OUT] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_M= 7_ALT_PLL_OUT); + hws[IMX8MN_ARM_PLL_OUT] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_ARM_= PLL_OUT); + hws[IMX8MN_SYS_PLL3_OUT] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SYS= _PLL3_OUT); =20 /* SYS PLL1 fixed output */ - hws[IMX8MN_SYS_PLL1_OUT] =3D imx_clk_hw_gate("sys_pll1_out", "sys_pll1", = base + 0x94, 11); - hws[IMX8MN_SYS_PLL1_40M] =3D imx_clk_hw_fixed_factor("sys_pll1_40m", "sys= _pll1_out", 1, 20); - hws[IMX8MN_SYS_PLL1_80M] =3D imx_clk_hw_fixed_factor("sys_pll1_80m", "sys= _pll1_out", 1, 10); - hws[IMX8MN_SYS_PLL1_100M] =3D imx_clk_hw_fixed_factor("sys_pll1_100m", "s= ys_pll1_out", 1, 8); - hws[IMX8MN_SYS_PLL1_133M] =3D imx_clk_hw_fixed_factor("sys_pll1_133m", "s= ys_pll1_out", 1, 6); - hws[IMX8MN_SYS_PLL1_160M] =3D imx_clk_hw_fixed_factor("sys_pll1_160m", "s= ys_pll1_out", 1, 5); - hws[IMX8MN_SYS_PLL1_200M] =3D imx_clk_hw_fixed_factor("sys_pll1_200m", "s= ys_pll1_out", 1, 4); - hws[IMX8MN_SYS_PLL1_266M] =3D imx_clk_hw_fixed_factor("sys_pll1_266m", "s= ys_pll1_out", 1, 3); - hws[IMX8MN_SYS_PLL1_400M] =3D imx_clk_hw_fixed_factor("sys_pll1_400m", "s= ys_pll1_out", 1, 2); - hws[IMX8MN_SYS_PLL1_800M] =3D imx_clk_hw_fixed_factor("sys_pll1_800m", "s= ys_pll1_out", 1, 1); + hws[IMX8MN_SYS_PLL1_OUT] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SYS= _PLL1_OUT); + hws[IMX8MN_SYS_PLL1_40M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SYS= _PLL1_40M); + hws[IMX8MN_SYS_PLL1_80M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SYS= _PLL1_80M); + hws[IMX8MN_SYS_PLL1_100M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SY= S_PLL1_100M); + hws[IMX8MN_SYS_PLL1_133M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SY= S_PLL1_133M); + hws[IMX8MN_SYS_PLL1_160M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SY= S_PLL1_160M); + hws[IMX8MN_SYS_PLL1_200M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SY= S_PLL1_200M); + hws[IMX8MN_SYS_PLL1_266M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SY= S_PLL1_266M); + hws[IMX8MN_SYS_PLL1_400M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SY= S_PLL1_400M); + hws[IMX8MN_SYS_PLL1_800M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SY= S_PLL1_800M); =20 /* SYS PLL2 fixed output */ - hws[IMX8MN_SYS_PLL2_OUT] =3D imx_clk_hw_gate("sys_pll2_out", "sys_pll2", = base + 0x104, 11); - hws[IMX8MN_SYS_PLL2_50M] =3D imx_clk_hw_fixed_factor("sys_pll2_50m", "sys= _pll2_out", 1, 20); - hws[IMX8MN_SYS_PLL2_100M] =3D imx_clk_hw_fixed_factor("sys_pll2_100m", "s= ys_pll2_out", 1, 10); - hws[IMX8MN_SYS_PLL2_125M] =3D imx_clk_hw_fixed_factor("sys_pll2_125m", "s= ys_pll2_out", 1, 8); - hws[IMX8MN_SYS_PLL2_166M] =3D imx_clk_hw_fixed_factor("sys_pll2_166m", "s= ys_pll2_out", 1, 6); - hws[IMX8MN_SYS_PLL2_200M] =3D imx_clk_hw_fixed_factor("sys_pll2_200m", "s= ys_pll2_out", 1, 5); - hws[IMX8MN_SYS_PLL2_250M] =3D imx_clk_hw_fixed_factor("sys_pll2_250m", "s= ys_pll2_out", 1, 4); - hws[IMX8MN_SYS_PLL2_333M] =3D imx_clk_hw_fixed_factor("sys_pll2_333m", "s= ys_pll2_out", 1, 3); - hws[IMX8MN_SYS_PLL2_500M] =3D imx_clk_hw_fixed_factor("sys_pll2_500m", "s= ys_pll2_out", 1, 2); - hws[IMX8MN_SYS_PLL2_1000M] =3D imx_clk_hw_fixed_factor("sys_pll2_1000m", = "sys_pll2_out", 1, 1); - - hws[IMX8MN_CLK_CLKOUT1_SEL] =3D imx_clk_hw_mux2("clkout1_sel", base + 0x1= 28, 4, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); - hws[IMX8MN_CLK_CLKOUT1_DIV] =3D imx_clk_hw_divider("clkout1_div", "clkout= 1_sel", base + 0x128, 0, 4); - hws[IMX8MN_CLK_CLKOUT1] =3D imx_clk_hw_gate("clkout1", "clkout1_div", bas= e + 0x128, 8); - hws[IMX8MN_CLK_CLKOUT2_SEL] =3D imx_clk_hw_mux2("clkout2_sel", base + 0x1= 28, 20, 4, clkout_sels, ARRAY_SIZE(clkout_sels)); - hws[IMX8MN_CLK_CLKOUT2_DIV] =3D imx_clk_hw_divider("clkout2_div", "clkout= 2_sel", base + 0x128, 16, 4); - hws[IMX8MN_CLK_CLKOUT2] =3D imx_clk_hw_gate("clkout2", "clkout2_div", bas= e + 0x128, 24); - - np =3D dev->of_node; - base =3D devm_platform_ioremap_resource(pdev, 0); - if (WARN_ON(IS_ERR(base))) { - ret =3D PTR_ERR(base); - goto unregister_hws; - } + hws[IMX8MN_SYS_PLL2_OUT] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SYS= _PLL2_OUT); + hws[IMX8MN_SYS_PLL2_50M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SYS= _PLL2_50M); + hws[IMX8MN_SYS_PLL2_100M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SY= S_PLL2_100M); + hws[IMX8MN_SYS_PLL2_125M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SY= S_PLL2_125M); + hws[IMX8MN_SYS_PLL2_166M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SY= S_PLL2_166M); + hws[IMX8MN_SYS_PLL2_200M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SY= S_PLL2_200M); + hws[IMX8MN_SYS_PLL2_250M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SY= S_PLL2_250M); + hws[IMX8MN_SYS_PLL2_333M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SY= S_PLL2_333M); + hws[IMX8MN_SYS_PLL2_500M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_SY= S_PLL2_500M); + hws[IMX8MN_SYS_PLL2_1000M] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_S= YS_PLL2_1000M); + + hws[IMX8MN_CLK_CLKOUT1_SEL] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_= CLK_CLKOUT1_SEL); + hws[IMX8MN_CLK_CLKOUT1_DIV] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_= CLK_CLKOUT1_DIV); + hws[IMX8MN_CLK_CLKOUT1] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_CLK_= CLKOUT1); + hws[IMX8MN_CLK_CLKOUT2_SEL] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_= CLK_CLKOUT2_SEL); + hws[IMX8MN_CLK_CLKOUT2_DIV] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_= CLK_CLKOUT2_DIV); + hws[IMX8MN_CLK_CLKOUT2] =3D imx_anatop_get_clk_hw(anp, IMX8MN_ANATOP_CLK_= CLKOUT2); =20 /* CORE */ hws[IMX8MN_CLK_A53_DIV] =3D imx8m_clk_hw_composite_core("arm_a53_div", im= x8mn_a53_sels, base + 0x8000); @@ -599,18 +579,15 @@ static int imx8mn_clocks_probe(struct platform_device= *pdev) =20 ret =3D of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); if (ret < 0) { - dev_err(dev, "failed to register hws for i.MX8MN\n"); - goto unregister_hws; + imx_unregister_hw_clocks(hws, IMX8MN_CLK_END); + return dev_err_probe(dev, ret, + "failed to register hws for i.MX8MN\n"); } =20 imx_register_uart_clocks(); =20 + dev_info(dev, "NXP i.MX8MN ccm clock driver probed\n"); return 0; - -unregister_hws: - imx_unregister_hw_clocks(hws, IMX8MN_CLK_END); - - return ret; } =20 static const struct of_device_id imx8mn_clk_of_match[] =3D { --=20 2.43.0