lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250110-ub9xx-improvements-v1-16-e0b9a1f644da@ideasonboard.com>
Date: Fri, 10 Jan 2025 11:14:16 +0200
From: Tomi Valkeinen <tomi.valkeinen@...asonboard.com>
To: Mauro Carvalho Chehab <mchehab@...nel.org>
Cc: linux-media@...r.kernel.org, linux-kernel@...r.kernel.org, 
 Devarsh Thakkar <devarsht@...com>, Jai Luthra <jai.luthra@...asonboard.com>, 
 Sakari Ailus <sakari.ailus@...ux.intel.com>, 
 Tomi Valkeinen <tomi.valkeinen@...asonboard.com>
Subject: [PATCH 16/19] media: i2c: ds90ub960: Enable SSCG for UB9702

From: Jai Luthra <jai.luthra@...asonboard.com>

UB9702 supports spread-spectrum clock generation for the back-channel
clock, which is futher used by serializers in synchronous mode to
generate the forward-channel clock, which can help reduce peak EMI
energy. The SSCG is common to all RX ports, so it can only be used if
all the ports are in the same mode.

Add basic support for SSCG by adding a module parameter to enable the
SSCG. The SSCG uses hardcoded configurationg, with 0.5% center-spread at
33kHz modulation rate. See datasheet if different configuration is
required.

Signed-off-by: Jai Luthra <jai.luthra@...asonboard.com>
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@...asonboard.com>
---
 drivers/media/i2c/ds90ub960.c | 102 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)

diff --git a/drivers/media/i2c/ds90ub960.c b/drivers/media/i2c/ds90ub960.c
index f6d6c2fe12cd..a534d077f045 100644
--- a/drivers/media/i2c/ds90ub960.c
+++ b/drivers/media/i2c/ds90ub960.c
@@ -52,6 +52,10 @@
 #include <media/v4l2-fwnode.h>
 #include <media/v4l2-subdev.h>
 
+static bool ub960_enable_sscg;
+module_param_named(enable_sscg, ub960_enable_sscg, bool, 0644);
+MODULE_PARM_DESC(enable_sscg, "Enable SSCG (if available)");
+
 #define MHZ(v) ((u32)((v) * HZ_PER_MHZ))
 
 /*
@@ -359,6 +363,7 @@
 /* Indirect register blocks */
 #define UB960_IND_TARGET_PAT_GEN		0x00
 #define UB960_IND_TARGET_RX_ANA(n)		(0x01 + (n))
+#define UB960_IND_TARGET_PLL_CTRL		0x05
 #define UB960_IND_TARGET_CSI_ANA		0x07
 
 /* UB960_IR_PGEN_*: Indirect Registers for Test Pattern Generator */
@@ -382,6 +387,22 @@
 #define UB960_IR_PGEN_VFP			0x0f
 #define UB960_IR_PGEN_COLOR(n)			(0x10 + (n)) /* n < 15 */
 
+#define UB960_IR_PLL_DEN_MASH2			0x80
+#define UB960_IR_PLL_DEN_MASH1			0x81
+#define UB960_IR_PLL_DEN_MASH0			0x82
+#define UB960_IR_PLL_NUM_MASH2			0x83
+#define UB960_IR_PLL_NUM_MASH1			0x84
+#define UB960_IR_PLL_NUM_MASH0			0x85
+#define UB960_IR_PLL_NCOUNT1			0x86
+#define UB960_IR_PLL_NCOUNT0			0x87
+#define UB960_IR_PLL_SSCG_CTRL1			0x88
+#define UB960_IR_PLL_MASH_ORDER			0x8a
+#define UB960_IR_PLL_SSCG_CTRL2			0x8b
+#define UB960_IR_PLL_SSCG_CTRL3			0x8c
+#define UB960_IR_PLL_SSCG_CTRL4			0x8d
+#define UB960_IR_PLL_SSCG_CTRL5			0x8e
+#define UB960_IR_PLL_SSCG_MASH_CTRL		0x8f
+
 #define UB960_IR_RX_ANA_STROBE_SET_CLK		0x08
 #define UB960_IR_RX_ANA_STROBE_SET_CLK_NO_EXTRA_DELAY	BIT(3)
 #define UB960_IR_RX_ANA_STROBE_SET_CLK_DELAY_MASK	GENMASK(2, 0)
@@ -2837,6 +2858,81 @@ static int ub960_enable_dfe_lms_ub9702(struct ub960_data *priv,
 	return 0;
 }
 
+/*
+ * Configures back-channel spread-spectrum clocking with 0.5% center-spread at
+ * 33kHz modulation rate. See datasheet if different configuration is required.
+ */
+static int ub960_enable_sscg_ub9702(struct ub960_data *priv)
+{
+	struct device *dev = &priv->client->dev;
+	int ret = 0;
+
+	/*
+	 * The configuration is hard-coded with FPD4 and BC frequency
+	 * 47.1875Mbps, so make sure all RX ports are configured with
+	 * synchronous clocking mode.
+	 */
+	for_each_active_rxport(priv) {
+		if (it.rxport->cdr_mode != RXPORT_CDR_FPD4 ||
+		    it.rxport->rx_mode != RXPORT_MODE_CSI2_SYNC) {
+			dev_warn(dev,
+				 "rx%u: Not in FPD4 SYNC mode, skipping SSCG\n",
+				 it.nport);
+			return 0;
+		}
+	}
+
+	/* Disable MASH */
+	ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL,
+			UB960_IR_PLL_SSCG_MASH_CTRL, 0x40, &ret);
+
+	/* Set MASH denominator */
+	ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, UB960_IR_PLL_DEN_MASH2,
+			0x7f, &ret);
+	ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, UB960_IR_PLL_DEN_MASH1,
+			0xff, &ret);
+	ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, UB960_IR_PLL_DEN_MASH0,
+			0xf8, &ret);
+
+	/* Set MASH numerator */
+	ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, UB960_IR_PLL_NUM_MASH2,
+			0x7f, &ret);
+	ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, UB960_IR_PLL_NUM_MASH1,
+			0xff, &ret);
+	ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, UB960_IR_PLL_NUM_MASH0,
+			0xf8, &ret);
+
+	/* Set NCOUNT */
+	ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, UB960_IR_PLL_NCOUNT1,
+			0x00, &ret);
+	ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL, UB960_IR_PLL_NCOUNT0,
+			0x96, &ret);
+
+	/* Set MASH order */
+	ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL,
+			UB960_IR_PLL_MASH_ORDER, 0x20, &ret);
+
+	/* Set rampx increment and stop */
+	ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL,
+			UB960_IR_PLL_SSCG_CTRL2, 0xbd, &ret);
+	ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL,
+			UB960_IR_PLL_SSCG_CTRL4, 0x73, &ret);
+	ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL,
+			UB960_IR_PLL_SSCG_CTRL5, 0x41, &ret);
+
+	/* Enable SSCG */
+	ub960_ind_update_bits(priv, UB960_IND_TARGET_PLL_CTRL,
+			      UB960_IR_PLL_SSCG_CTRL1, BIT(7), BIT(7), &ret);
+
+	/* Enable MASH */
+	ub960_write_ind(priv, UB960_IND_TARGET_PLL_CTRL,
+			UB960_IR_PLL_SSCG_MASH_CTRL, 0x0, &ret);
+
+	dev_dbg(dev, "SSCG enabled\n");
+
+	return ret;
+}
+
 static int ub960_init_rx_ports_ub9702(struct ub960_data *priv)
 {
 	struct device *dev = &priv->client->dev;
@@ -2860,6 +2956,12 @@ static int ub960_init_rx_ports_ub9702(struct ub960_data *priv)
 	if (ret)
 		return ret;
 
+	if (ub960_enable_sscg) {
+		ret = ub960_enable_sscg_ub9702(priv);
+		if (ret)
+			return ret;
+	}
+
 	for_each_active_rxport_fpd4(priv) {
 		/* Hold state machine in reset */
 		ub960_rxport_write(priv, it.nport, UB9702_RR_RX_SM_SEL_2, 0x10,

-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ