All of lore.kernel.org
 help / color / mirror / Atom feed
From: Siew Chin Lim <elly.siew.chin.lim@intel.com>
To: u-boot@lists.denx.de
Cc: Marek Vasut <marex@denx.de>, Ley Foon Tan <lftan.linux@gmail.com>,
	Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>,
	Tien Fong Chee <tien.fong.chee@intel.com>,
	Dalon Westergreen <dalon.westergreen@intel.com>,
	Simon Glass <sjg@chromium.org>,
	Yau Wai Gan <yau.wai.gan@intel.com>,
	Siew Chin Lim <elly.siew.chin.lim@intel.com>
Subject: [v3 07/17] drivers: clk: Add memory clock driver for Intel N5X device
Date: Sun, 13 Jun 2021 16:48:42 +0800	[thread overview]
Message-ID: <20210613084852.30868-8-elly.siew.chin.lim@intel.com> (raw)
In-Reply-To: <20210613084852.30868-1-elly.siew.chin.lim@intel.com>

Add memory clock manager driver for N5X. Provides memory clock
initialization and enable functions.

Signed-off-by: Siew Chin Lim <elly.siew.chin.lim@intel.com>

---
v3:
- Use BIT() and GENMASK() macro for all *MASK macro

v2:
- common.h need to be included before clock_manager.h
- For consistency, use small letter fo 0x0c and 0x1c in macros
---
 drivers/clk/altera/Makefile      |   1 +
 drivers/clk/altera/clk-mem-n5x.c | 136 +++++++++++++++++++++++++++++++
 drivers/clk/altera/clk-mem-n5x.h |  84 +++++++++++++++++++
 3 files changed, 221 insertions(+)
 create mode 100644 drivers/clk/altera/clk-mem-n5x.c
 create mode 100644 drivers/clk/altera/clk-mem-n5x.h

diff --git a/drivers/clk/altera/Makefile b/drivers/clk/altera/Makefile
index 38cd730685..33db092918 100644
--- a/drivers/clk/altera/Makefile
+++ b/drivers/clk/altera/Makefile
@@ -6,3 +6,4 @@
 obj-$(CONFIG_TARGET_SOCFPGA_AGILEX) += clk-agilex.o
 obj-$(CONFIG_TARGET_SOCFPGA_ARRIA10) += clk-arria10.o
 obj-$(CONFIG_TARGET_SOCFPGA_N5X) += clk-n5x.o
+obj-$(CONFIG_TARGET_SOCFPGA_N5X) += clk-mem-n5x.o
diff --git a/drivers/clk/altera/clk-mem-n5x.c b/drivers/clk/altera/clk-mem-n5x.c
new file mode 100644
index 0000000000..ca44998641
--- /dev/null
+++ b/drivers/clk/altera/clk-mem-n5x.c
@@ -0,0 +1,136 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020-2021 Intel Corporation <www.intel.com>
+ */
+
+#include <common.h>
+#include <asm/arch/clock_manager.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include "clk-mem-n5x.h"
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <dm/util.h>
+#include <dt-bindings/clock/n5x-clock.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct socfpga_mem_clk_plat {
+	void __iomem *regs;
+};
+
+void clk_mem_wait_for_lock(struct socfpga_mem_clk_plat *plat, u32 mask)
+{
+	u32 inter_val;
+	u32 retry = 0;
+
+	do {
+		inter_val = CM_REG_READL(plat, MEMCLKMGR_STAT) & mask;
+
+		/* Wait for stable lock */
+		if (inter_val == mask)
+			retry++;
+		else
+			retry = 0;
+
+		if (retry >= 10)
+			return;
+	} while (1);
+}
+
+/*
+ * function to write the bypass register which requires a poll of the
+ * busy bit
+ */
+void clk_mem_write_bypass_mempll(struct socfpga_mem_clk_plat *plat, u32 val)
+{
+	CM_REG_WRITEL(plat, val, MEMCLKMGR_MEMPLL_BYPASS);
+}
+
+/*
+ * Setup clocks while making no assumptions about previous state of the clocks.
+ */
+static void clk_mem_basic_init(struct udevice *dev,
+			       const struct cm_config * const cfg)
+{
+	struct socfpga_mem_clk_plat *plat = dev_get_plat(dev);
+
+	if (!cfg)
+		return;
+
+	/* Put PLLs in bypass */
+	clk_mem_write_bypass_mempll(plat, MEMCLKMGR_BYPASS_MEMPLL_ALL);
+
+	/* Put PLLs in Reset */
+	CM_REG_SETBITS(plat, MEMCLKMGR_MEMPLL_PLLCTRL,
+		       MEMCLKMGR_PLLCTRL_BYPASS_MASK);
+
+	/* setup mem PLL */
+	CM_REG_WRITEL(plat, cfg->mem_memdiv, MEMCLKMGR_MEMPLL_MEMDIV);
+	CM_REG_WRITEL(plat, cfg->mem_pllglob, MEMCLKMGR_MEMPLL_PLLGLOB);
+	CM_REG_WRITEL(plat, cfg->mem_plldiv, MEMCLKMGR_MEMPLL_PLLDIV);
+	CM_REG_WRITEL(plat, cfg->mem_plloutdiv, MEMCLKMGR_MEMPLL_PLLOUTDIV);
+
+	/* Take PLL out of reset and power up */
+	CM_REG_CLRBITS(plat, MEMCLKMGR_MEMPLL_PLLCTRL,
+		       MEMCLKMGR_PLLCTRL_BYPASS_MASK);
+}
+
+static int socfpga_mem_clk_enable(struct clk *clk)
+{
+	const struct cm_config *cm_default_cfg = cm_get_default_config();
+	struct socfpga_mem_clk_plat *plat = dev_get_plat(clk->dev);
+
+	clk_mem_basic_init(clk->dev, cm_default_cfg);
+
+	clk_mem_wait_for_lock(plat, MEMCLKMGR_STAT_ALLPLL_LOCKED_MASK);
+
+	CM_REG_WRITEL(plat, CM_REG_READL(plat, MEMCLKMGR_MEMPLL_PLLGLOB) |
+		      MEMCLKMGR_PLLGLOB_CLR_LOSTLOCK_BYPASS_MASK,
+		      MEMCLKMGR_MEMPLL_PLLGLOB);
+
+	/* Take all PLLs out of bypass */
+	clk_mem_write_bypass_mempll(plat, 0);
+
+	/* Clear the loss of lock bits (write 1 to clear) */
+	CM_REG_CLRBITS(plat, MEMCLKMGR_INTRCLR,
+		       MEMCLKMGR_INTER_MEMPLLLOST_MASK);
+
+	/* Take all ping pong counters out of reset */
+	CM_REG_CLRBITS(plat, MEMCLKMGR_MEMPLL_EXTCNTRST,
+		       MEMCLKMGR_EXTCNTRST_ALLCNTRST);
+
+	return 0;
+}
+
+static int socfpga_mem_clk_of_to_plat(struct udevice *dev)
+{
+	struct socfpga_mem_clk_plat *plat = dev_get_plat(dev);
+	fdt_addr_t addr;
+
+	addr = devfdt_get_addr(dev);
+	if (addr == FDT_ADDR_T_NONE)
+		return -EINVAL;
+	plat->regs = (void __iomem *)addr;
+
+	return 0;
+}
+
+static struct clk_ops socfpga_mem_clk_ops = {
+	.enable		= socfpga_mem_clk_enable
+};
+
+static const struct udevice_id socfpga_mem_clk_match[] = {
+	{ .compatible = "intel,n5x-mem-clkmgr" },
+	{}
+};
+
+U_BOOT_DRIVER(socfpga_n5x_mem_clk) = {
+	.name		= "mem-clk-n5x",
+	.id		= UCLASS_CLK,
+	.of_match	= socfpga_mem_clk_match,
+	.ops		= &socfpga_mem_clk_ops,
+	.of_to_plat     = socfpga_mem_clk_of_to_plat,
+	.plat_auto	= sizeof(struct socfpga_mem_clk_plat),
+};
diff --git a/drivers/clk/altera/clk-mem-n5x.h b/drivers/clk/altera/clk-mem-n5x.h
new file mode 100644
index 0000000000..d000ae260c
--- /dev/null
+++ b/drivers/clk/altera/clk-mem-n5x.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020-2021 Intel Corporation <www.intel.com>
+ */
+
+#ifndef	_CLK_MEM_N5X_
+#define	_CLK_MEM_N5X_
+
+#ifndef __ASSEMBLY__
+#include <linux/bitops.h>
+#endif
+
+/* Clock Manager registers */
+#define MEMCLKMGR_STAT					4
+#define MEMCLKMGR_INTRGEN				8
+#define MEMCLKMGR_INTRMSK				0x0c
+#define MEMCLKMGR_INTRCLR				0x10
+#define MEMCLKMGR_INTRSTS				0x14
+#define MEMCLKMGR_INTRSTK				0x18
+#define MEMCLKMGR_INTRRAW				0x1c
+
+/* Memory Clock Manager PPL group registers */
+#define MEMCLKMGR_MEMPLL_EN				0x20
+#define MEMCLKMGR_MEMPLL_ENS				0x24
+#define MEMCLKMGR_MEMPLL_ENR				0x28
+#define MEMCLKMGR_MEMPLL_BYPASS				0x2c
+#define MEMCLKMGR_MEMPLL_BYPASSS			0x30
+#define MEMCLKMGR_MEMPLL_BYPASSR			0x34
+#define MEMCLKMGR_MEMPLL_MEMDIV				0x38
+#define MEMCLKMGR_MEMPLL_PLLGLOB			0x3c
+#define MEMCLKMGR_MEMPLL_PLLCTRL			0x40
+#define MEMCLKMGR_MEMPLL_PLLDIV				0x44
+#define MEMCLKMGR_MEMPLL_PLLOUTDIV			0x48
+#define MEMCLKMGR_MEMPLL_EXTCNTRST			0x4c
+
+#define MEMCLKMGR_CTRL_BOOTMODE				BIT(0)
+
+#define MEMCLKMGR_STAT_MEMPLL_LOCKED			BIT(8)
+
+#define MEMCLKMGR_STAT_ALLPLL_LOCKED_MASK		\
+	(MEMCLKMGR_STAT_MEMPLL_LOCKED)
+
+#define MEMCLKMGR_INTER_MEMPLLLOCKED_MASK		BIT(0)
+#define MEMCLKMGR_INTER_MEMPLLLOST_MASK			BIT(2)
+
+#define MEMCLKMGR_BYPASS_MEMPLL_ALL			0x1
+
+#define MEMCLKMGR_MEMDIV_MPFEDIV_OFFSET			0
+#define MEMCLKMGR_MEMDIV_APBDIV_OFFSET			4
+#define MEMCLKMGR_MEMDIV_DFICTRLDIV_OFFSET		8
+#define MEMCLKMGR_MEMDIV_DFIDIV_OFFSET			12
+#define MEMCLKMGR_MEMDIV_DFICTRLDIV_MASK		BIT(0)
+#define MEMCLKMGR_MEMDIV_DIVIDER_MASK			GENMASK(1, 0)
+
+#define MEMCLKMGR_PLLGLOB_PSRC_MASK			GENMASK(17, 16)
+#define MEMCLKMGR_PLLGLOB_PSRC_OFFSET			16
+#define MEMCLKMGR_PLLGLOB_LOSTLOCK_BYPASS_EN_MASK	BIT(28)
+#define MEMCLKMGR_PLLGLOB_CLR_LOSTLOCK_BYPASS_MASK	BIT(29)
+
+#define MEMCLKMGR_PSRC_EOSC1				0
+#define MEMCLKMGR_PSRC_INTOSC				1
+#define MEMCLKMGR_PSRC_F2S				2
+
+#define MEMCLKMGR_PLLCTRL_BYPASS_MASK			BIT(0)
+#define MEMCLKMGR_PLLCTRL_RST_N_MASK			BIT(1)
+
+#define MEMCLKMGR_PLLDIV_DIVR_MASK			GENMASK(5, 0)
+#define MEMCLKMGR_PLLDIV_DIVF_MASK			GENMASK(16, 8)
+#define MEMCLKMGR_PLLDIV_DIVQ_MASK			GENMASK(26, 24)
+#define MEMCLKMGR_PLLDIV_RANGE_MASK			GENMASK(30, 28)
+
+#define MEMCLKMGR_PLLDIV_DIVR_OFFSET			0
+#define MEMCLKMGR_PLLDIV_DIVF_OFFSET			8
+#define MEMCLKMGR_PLLDIV_DIVQ_QDIV_OFFSET		24
+#define MEMCLKMGR_PLLDIV_RANGE_OFFSET			28
+
+#define MEMCLKMGR_PLLOUTDIV_C0CNT_MASK			GENMASK(4, 0)
+#define MEMCLKMGR_PLLOUTDIV_C0CNT_OFFSET		0
+
+#define MEMCLKMGR_EXTCNTRST_C0CNTRST			BIT(7)
+#define MEMCLKMGR_EXTCNTRST_ALLCNTRST			\
+	(MEMCLKMGR_EXTCNTRST_C0CNTRST)
+
+#endif /* _CLK_MEM_N5X_ */
-- 
2.19.0


  parent reply	other threads:[~2021-06-13  8:51 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-13  8:48 [v3 00/17] Add Intel N5X SoC support Siew Chin Lim
2021-06-13  8:48 ` [v3 01/17] arm: socfpga: Move linux_qspi_enable from bootcommand to board_prep_linux function Siew Chin Lim
2021-06-13  8:48 ` [v3 02/17] arm: socfpga: Changed base_addr_s10.h to base_addr_soc64.h Siew Chin Lim
2021-06-13  8:48 ` [v3 03/17] arm: socfpga: Add base address for Intel N5X device Siew Chin Lim
2021-06-13  8:48 ` [v3 04/17] arm: socfpga: Add handoff data support " Siew Chin Lim
2021-07-08 16:15   ` Ley Foon Tan
2021-06-13  8:48 ` [v3 05/17] drivers: clk: Add clock driver " Siew Chin Lim
2021-07-08 16:17   ` Ley Foon Tan
2021-06-13  8:48 ` [v3 06/17] arm: socfpga: Get clock manager base address " Siew Chin Lim
2021-06-13  8:48 ` Siew Chin Lim [this message]
2021-07-08 16:19   ` [v3 07/17] drivers: clk: Add memory clock driver " Ley Foon Tan
2021-06-13  8:48 ` [v3 08/17] arm: socfpga: Move cm_get_mpu_clk_hz function declaration to clock_manager.h Siew Chin Lim
2021-06-13  8:48 ` [v3 09/17] arm: socfpga: Add clock manager for Intel N5X device Siew Chin Lim
2021-06-13  8:48 ` [v3 10/17] arm: socfpga: Changed misc_s10.c to misc_soc64.c Siew Chin Lim
2021-06-13  8:48 ` [v3 11/17] ddr: socfpga: Enable memory test on memory size less than 1GB Siew Chin Lim
2021-06-13  8:48 ` [v3 12/17] ddr: altera: Add SDRAM driver for Intel N5X device Siew Chin Lim
2021-07-08 17:06   ` Ley Foon Tan
2021-06-13  8:48 ` [v3 13/17] arm: socfpga: Add SPL " Siew Chin Lim
2021-06-13  8:48 ` [v3 14/17] board: intel: Add socdk board support " Siew Chin Lim
2021-06-13  8:48 ` [v3 15/17] arm: dts: Add base dtsi and devkit dts " Siew Chin Lim
2021-07-08 16:32   ` Ley Foon Tan
2021-07-09  1:10     ` Lim, Elly Siew Chin
2021-06-13  8:48 ` [v3 16/17] include: configs: Add Intel N5X device CONFIGs Siew Chin Lim
2021-06-13  8:48 ` [v3 17/17] arm: socfpga: Enable Intel N5X device build Siew Chin Lim

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210613084852.30868-8-elly.siew.chin.lim@intel.com \
    --to=elly.siew.chin.lim@intel.com \
    --cc=dalon.westergreen@intel.com \
    --cc=lftan.linux@gmail.com \
    --cc=marex@denx.de \
    --cc=simon.k.r.goldschmidt@gmail.com \
    --cc=sjg@chromium.org \
    --cc=tien.fong.chee@intel.com \
    --cc=u-boot@lists.denx.de \
    --cc=yau.wai.gan@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.