devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ivan Vecera <ivecera@redhat.com>
To: netdev@vger.kernel.org
Cc: Michal Schmidt <mschmidt@redhat.com>,
	Vadim Fedorenko <vadim.fedorenko@linux.dev>,
	Arkadiusz Kubalewski <arkadiusz.kubalewski@intel.com>,
	Jiri Pirko <jiri@resnulli.us>, Rob Herring <robh@kernel.org>,
	Krzysztof Kozlowski <krzk+dt@kernel.org>,
	Conor Dooley <conor+dt@kernel.org>,
	Prathosh Satish <Prathosh.Satish@microchip.com>,
	Lee Jones <lee@kernel.org>, Kees Cook <kees@kernel.org>,
	Andy Shevchenko <andy@kernel.org>,
	Andrew Morton <akpm@linux-foundation.org>,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-hardening@vger.kernel.org
Subject: [PATCH 08/28] mfd: zl3073x: Add functions to work with register mailboxes
Date: Mon,  7 Apr 2025 19:28:35 +0200	[thread overview]
Message-ID: <20250407172836.1009461-9-ivecera@redhat.com> (raw)
In-Reply-To: <20250407172836.1009461-1-ivecera@redhat.com>

Registers present in page 10 and higher are organized in so-called
register mailboxes. These mailboxes are used to read and write
configuration of particular object (dpll, output, reference & synth).

Each of these register pages contains mask register that is used by
the driver to indicate an index of requested object to work with and
also semaphore register to indicate what operation is requested.
The rest of registers in the particular register page are latch
registers that are filled by the firmware during read operation or by
the driver prior write operation.

For read operation the driver...
1) ... updates the mailbox mask register with index of particular object
2) ... sets the mailbox semaphore register read bit
3) ... waits for the semaphore register read bit to be cleared by FW
4) ... reads the configuration from latch registers

For write operation the driver...
1) ... writes the requested configuration to latch registers
2) ... sets the mailbox mask register for the DPLL to be updated
3) ... sets the mailbox semaphore register bit for the write operation
4) ... waits for the semaphore register bit to be cleared by FW

Add functions to read and write mailboxes for all supported object types.

Reviewed-by: Michal Schmidt <mschmidt@redhat.com>
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
---
 drivers/mfd/zl3073x-core.c  | 185 ++++++++++++++++++++++++++++++++++++
 include/linux/mfd/zl3073x.h |  12 +++
 2 files changed, 197 insertions(+)

diff --git a/drivers/mfd/zl3073x-core.c b/drivers/mfd/zl3073x-core.c
index 33e76666e5694..feb139b550571 100644
--- a/drivers/mfd/zl3073x-core.c
+++ b/drivers/mfd/zl3073x-core.c
@@ -14,6 +14,47 @@ ZL3073X_REG16_DEF(revision,		0x0003);
 ZL3073X_REG16_DEF(fw_ver,		0x0005);
 ZL3073X_REG32_DEF(custom_config_ver,	0x0007);
 
+/*
+ * Register Map Page 10, Ref Mailbox
+ */
+ZL3073X_REG16_DEF(ref_mb_mask,			0x502);
+#define REF_MB_MASK				GENMASK(9, 0)
+
+ZL3073X_REG8_DEF(ref_mb_sem,			0x504);
+#define REF_MB_SEM_WR				BIT(0)
+#define REF_MB_SEM_RD				BIT(1)
+
+/*
+ * Register Map Page 12, DPLL Mailbox
+ */
+ZL3073X_REG16_DEF(dpll_mb_mask,			0x602);
+
+ZL3073X_REG8_DEF(dpll_mb_sem,			0x604);
+#define DPLL_MB_SEM_WR				BIT(0)
+#define DPLL_MB_SEM_RD				BIT(1)
+
+/*
+ * Register Map Page 13, Synth Mailbox
+ */
+ZL3073X_REG16_DEF(synth_mb_mask,		0x682);
+
+ZL3073X_REG8_DEF(synth_mb_sem,			0x684);
+#define SYNTH_MB_SEM_WR				BIT(0)
+#define SYNTH_MB_SEM_RD				BIT(1)
+
+ZL3073X_REG16_DEF(synth_freq_base,		0x686);
+ZL3073X_REG32_DEF(synth_freq_mult,		0x688);
+ZL3073X_REG16_DEF(synth_freq_m,			0x68c);
+ZL3073X_REG16_DEF(synth_freq_n,			0x68e);
+
+/*
+ * Register Map Page 14, Output Mailbox
+ */
+ZL3073X_REG16_DEF(output_mb_mask,		0x702);
+ZL3073X_REG8_DEF(output_mb_sem,			0x704);
+#define OUTPUT_MB_SEM_WR			BIT(0)
+#define OUTPUT_MB_SEM_RD			BIT(1)
+
 /*
  * Regmap ranges
  */
@@ -142,6 +183,150 @@ int zl3073x_write_reg(struct zl3073x_dev *zldev, unsigned int reg,
 }
 EXPORT_SYMBOL_GPL(zl3073x_write_reg);
 
+/**
+ * ZL3073X_MB_OP - perform an operation on mailbox of certain type
+ * @_zldev: pointer to device structure
+ * @_type: type of mailbox (dpll, ref or output)
+ * @_index: object index of given type
+ * @_op: operation to perform
+ *
+ * Performs the requested operation on mailbox of certain type and
+ * returns 0 in case of success or negative value otherwise.
+ */
+#define ZL3073X_MB_OP(_zldev, _type, _index, _op)			\
+({									\
+	struct zl3073x_dev *__zldev = (_zldev);				\
+	u16 __mask = BIT(_index);					\
+	u8 __op = (_op);						\
+	int __rc;							\
+	do {								\
+		/* Select requested index in mask register */		\
+		__rc = zl3073x_write_##_type##_mb_mask(__zldev, __mask);\
+		if (__rc)						\
+			break;						\
+		/* Select requested command */				\
+		__rc = zl3073x_write_##_type##_mb_sem(__zldev, __op);	\
+		if (__rc)						\
+			break;						\
+		/* Wait for the command to actually finish */		\
+		__rc = zl3073x_wait_clear_bits(__zldev, _type##_mb_sem,	\
+					       __op);			\
+	} while (0);							\
+	__rc;								\
+})
+
+/**
+ * zl3073x_mb_dpll_read - read given DPLL configuration to mailbox
+ * @zldev: pointer to device structure
+ * @index: DPLL index
+ *
+ * Reads configuration of given DPLL into DPLL mailbox and returns 0
+ * in case of success or negative value otherwise.
+ */
+int zl3073x_mb_dpll_read(struct zl3073x_dev *zldev, u8 index)
+{
+	return ZL3073X_MB_OP(zldev, dpll, index, DPLL_MB_SEM_RD);
+}
+EXPORT_SYMBOL_GPL(zl3073x_mb_dpll_read);
+
+/**
+ * zl3073x_mb_dpll_write - write given DPLL configuration from mailbox
+ * @zldev: pointer to device structure
+ * @index: DPLL index
+ *
+ * Writes (commits) configuration of given DPLL from DPLL mailbox and
+ * returns 0 in case of success or negative value otherwise.
+ */
+int zl3073x_mb_dpll_write(struct zl3073x_dev *zldev, u8 index)
+{
+	return ZL3073X_MB_OP(zldev, dpll, index, DPLL_MB_SEM_WR);
+}
+EXPORT_SYMBOL_GPL(zl3073x_mb_dpll_write);
+
+/**
+ * zl3073x_mb_output_read - read given output configuration to mailbox
+ * @zldev: pointer to device structure
+ * @index: output index
+ *
+ * Reads configuration of given output into output mailbox and returns 0
+ * in case of success or negative value otherwise.
+ */
+int zl3073x_mb_output_read(struct zl3073x_dev *zldev, u8 index)
+{
+	return ZL3073X_MB_OP(zldev, output, index, OUTPUT_MB_SEM_RD);
+}
+EXPORT_SYMBOL_GPL(zl3073x_mb_output_read);
+
+/**
+ * zl3073x_mb_output_write - write given output configuration from mailbox
+ * @zldev: pointer to device structure
+ * @index: DPLL index
+ *
+ * Writes (commits) configuration of given output from output mailbox and
+ * returns 0 in case of success or negative value otherwise.
+ */
+int zl3073x_mb_output_write(struct zl3073x_dev *zldev, u8 index)
+{
+	return ZL3073X_MB_OP(zldev, output, index, OUTPUT_MB_SEM_WR);
+}
+EXPORT_SYMBOL_GPL(zl3073x_mb_output_write);
+
+/**
+ * zl3073x_mb_ref_read - read given reference configuration to mailbox
+ * @zldev: pointer to device structure
+ * @index: reference index
+ *
+ * Reads configuration of given reference into reference mailbox and
+ * returns 0 in case of success or negative value otherwise.
+ */
+int zl3073x_mb_ref_read(struct zl3073x_dev *zldev, u8 index)
+{
+	return ZL3073X_MB_OP(zldev, ref, index, REF_MB_SEM_RD);
+}
+EXPORT_SYMBOL_GPL(zl3073x_mb_ref_read);
+
+/**
+ * zl3073x_mb_ref_write - write given reference configuration from mailbox
+ * @zldev: pointer to device structure
+ * @index: reference index
+ *
+ * Writes (commits) configuration of given reference from reference mailbox
+ * and returns 0 in case of success or negative value otherwise.
+ */
+int zl3073x_mb_ref_write(struct zl3073x_dev *zldev, u8 index)
+{
+	return ZL3073X_MB_OP(zldev, ref, index, REF_MB_SEM_WR);
+}
+EXPORT_SYMBOL_GPL(zl3073x_mb_ref_write);
+
+/**
+ * zl3073x_mb_synth_read - read given synth configuration to mailbox
+ * @zldev: pointer to device structure
+ * @index: synth index
+ *
+ * Reads configuration of given synth into synth mailbox and returns 0
+ * in case of success or negative value otherwise.
+ */
+int zl3073x_mb_synth_read(struct zl3073x_dev *zldev, u8 index)
+{
+	return ZL3073X_MB_OP(zldev, synth, index, SYNTH_MB_SEM_RD);
+}
+EXPORT_SYMBOL_GPL(zl3073x_mb_synth_read);
+
+/**
+ * zl3073x_mb_synth_write - write given synth configuration from mailbox
+ * @zldev: pointer to device structure
+ * @index: synth index
+ *
+ * Writes (commits) configuration of given synth from reference mailbox
+ * and returns 0 in case of success or negative value otherwise.
+ */
+int zl3073x_mb_synth_write(struct zl3073x_dev *zldev, u8 index)
+{
+	return ZL3073X_MB_OP(zldev, synth, index, SYNTH_MB_SEM_WR);
+}
+EXPORT_SYMBOL_GPL(zl3073x_mb_synth_write);
+
 /**
  * zl3073x_devlink_info_get - Devlink device info callback
  * @devlink: devlink structure pointer
diff --git a/include/linux/mfd/zl3073x.h b/include/linux/mfd/zl3073x.h
index 15dfb0d8bf3cb..436f79f2fda63 100644
--- a/include/linux/mfd/zl3073x.h
+++ b/include/linux/mfd/zl3073x.h
@@ -172,4 +172,16 @@ int zl3073x_write_##_name(struct zl3073x_dev *zldev, unsigned int idx,	\
 	__rc;								\
 })
 
+/*
+ * Mailbox operations
+ */
+int zl3073x_mb_dpll_read(struct zl3073x_dev *zldev, u8 index);
+int zl3073x_mb_dpll_write(struct zl3073x_dev *zldev, u8 index);
+int zl3073x_mb_output_read(struct zl3073x_dev *zldev, u8 index);
+int zl3073x_mb_output_write(struct zl3073x_dev *zldev, u8 index);
+int zl3073x_mb_ref_read(struct zl3073x_dev *zldev, u8 index);
+int zl3073x_mb_ref_write(struct zl3073x_dev *zldev, u8 index);
+int zl3073x_mb_synth_read(struct zl3073x_dev *zldev, u8 index);
+int zl3073x_mb_synth_write(struct zl3073x_dev *zldev, u8 index);
+
 #endif /* __LINUX_MFD_ZL3073X_H */
-- 
2.48.1


  parent reply	other threads:[~2025-04-07 17:29 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-04-07 17:28 [PATCH 00/28] Add Microchip ZL3073x support Ivan Vecera
2025-04-07 17:28 ` [PATCH 01/28] mfd: " Ivan Vecera
2025-04-07 17:53   ` Krzysztof Kozlowski
2025-04-09  6:31     ` Ivan Vecera
2025-04-07 18:05   ` Andy Shevchenko
2025-04-09  6:40     ` Ivan Vecera
2025-04-14  6:36       ` Andy Shevchenko
2025-04-14 11:39         ` Ivan Vecera
2025-04-14 11:52           ` Ivan Vecera
2025-04-14 13:55             ` Andy Shevchenko
2025-04-14 14:08               ` Ivan Vecera
2025-04-14 14:07             ` Ivan Vecera
2025-04-14 14:10               ` Andy Shevchenko
2025-04-14 14:13                 ` Andy Shevchenko
2025-04-14 14:16                   ` Andy Shevchenko
2025-04-14 14:53                     ` Ivan Vecera
2025-04-14 17:09                       ` Andy Shevchenko
2025-04-14 17:42                         ` Ivan Vecera
2025-04-14 13:58           ` Andy Shevchenko
2025-04-07 17:28 ` [PATCH 02/28] mfd: zl3073x: Register itself as devlink device Ivan Vecera
2025-04-07 20:57   ` Andrew Lunn
2025-04-09  6:41     ` Ivan Vecera
2025-04-07 17:28 ` [PATCH 03/28] mfd: zl3073x: Add register access helpers Ivan Vecera
2025-04-07 21:03   ` Andrew Lunn
2025-04-09  6:42     ` Ivan Vecera
2025-04-07 17:28 ` [PATCH 04/28] mfd: zl3073x: Add macros for device registers access Ivan Vecera
2025-04-07 17:28 ` [PATCH 05/28] mfd: zl3073x: Add components versions register defs Ivan Vecera
2025-04-07 21:09   ` Andrew Lunn
2025-04-09  6:44     ` Ivan Vecera
2025-04-10  7:11       ` Krzysztof Kozlowski
2025-04-10 10:23         ` Ivan Vecera
2025-04-10 10:42           ` Krzysztof Kozlowski
2025-04-10 12:01             ` Ivan Vecera
2025-04-07 17:28 ` [PATCH 06/28] mfd: zl3073x: Implement devlink device info Ivan Vecera
2025-04-07 17:28 ` [PATCH 07/28] mfd: zl3073x: Add macro to wait for register value bits to be cleared Ivan Vecera
2025-04-07 17:28 ` Ivan Vecera [this message]
2025-04-07 17:28 ` [PATCH 09/28] mfd: zl3073x: Add clock_id field Ivan Vecera
2025-04-07 17:31 ` [PATCH 10/28] lib: Allow modules to use strnchrnul Ivan Vecera
2025-04-07 17:50   ` Kees Cook
2025-04-07 17:31 ` [PATCH 11/28] mfd: zl3073x: Load mfg file into HW if it is present Ivan Vecera
2025-04-07 17:31 ` [PATCH 12/28] mfd: zl3073x: Fetch invariants during probe Ivan Vecera
2025-04-07 17:31 ` [PATCH 13/28] dpll: Add Microchip ZL3073x DPLL driver Ivan Vecera
2025-04-07 17:31 ` [PATCH 14/28] mfd: zl3073x: Register DPLL sub-device during init Ivan Vecera
2025-04-07 17:31 ` [PATCH 15/28] dt-bindings: dpll: Add device tree bindings for DPLL device and pin Ivan Vecera
2025-04-07 18:01   ` Krzysztof Kozlowski
2025-04-07 18:10     ` Krzysztof Kozlowski
2025-04-08  5:19     ` Michal Schmidt
2025-04-09  7:09     ` Ivan Vecera
2025-04-07 17:31 ` [PATCH 16/28] dt-bindings: dpll: Add support for Microchip Azurite chip family Ivan Vecera
2025-04-07 18:04   ` Krzysztof Kozlowski
2025-04-09  7:19     ` Ivan Vecera
2025-04-10  7:01       ` Krzysztof Kozlowski
2025-04-10 10:28         ` Ivan Vecera
2025-04-10 12:19           ` Krzysztof Kozlowski
2025-04-10 12:38             ` Ivan Vecera
2025-04-07 17:31 ` [PATCH 17/28] dpll: zl3073x: Read DPLL types from firmware Ivan Vecera
2025-04-07 17:31 ` [PATCH 18/28] dpll: zl3073x: Read optional pin properties " Ivan Vecera
2025-04-07 18:06   ` Krzysztof Kozlowski
2025-04-09  7:22     ` Ivan Vecera
2025-04-07 17:31 ` [PATCH 19/28] dpll: zl3073x: Implement input pin selection in manual mode Ivan Vecera
2025-04-07 17:32 ` [PATCH 20/28] dpll: zl3073x: Add support to get/set priority on input pins Ivan Vecera
2025-04-07 17:32 ` [PATCH 21/28] dpll: zl3073x: Implement input pin state setting in automatic mode Ivan Vecera
2025-04-07 17:32 ` [PATCH 22/28] dpll: zl3073x: Add support to get/set frequency on input pins Ivan Vecera
2025-04-07 17:32 ` [PATCH 23/28] dpll: zl3073x: Add support to get/set frequency on output pins Ivan Vecera
2025-04-07 17:32 ` [PATCH 24/28] dpll: zl3073x: Read pin supported frequencies from firmware Ivan Vecera
2025-04-07 17:32 ` [PATCH 25/28] dpll: zl3073x: Add support to get phase offset on input pins Ivan Vecera
2025-04-07 17:32 ` [PATCH 26/28] dpll: zl3073x: Add support to get/set phase adjust on pins Ivan Vecera
2025-04-07 17:33 ` [PATCH 27/28] dpll: zl3073x: Add support to get/set esync " Ivan Vecera
2025-04-07 17:33 ` [PATCH 28/28] dpll: zl3073x: Add support to get fractional frequency offset on input pins Ivan Vecera
2025-04-07 18:06 ` [PATCH 00/28] Add Microchip ZL3073x support Andy Shevchenko

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=20250407172836.1009461-9-ivecera@redhat.com \
    --to=ivecera@redhat.com \
    --cc=Prathosh.Satish@microchip.com \
    --cc=akpm@linux-foundation.org \
    --cc=andy@kernel.org \
    --cc=arkadiusz.kubalewski@intel.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=jiri@resnulli.us \
    --cc=kees@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=lee@kernel.org \
    --cc=linux-hardening@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mschmidt@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=vadim.fedorenko@linux.dev \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).