All of lore.kernel.org
 help / color / mirror / Atom feed
From: Serhii Iliushyk <sil-plv@napatech.com>
To: dev@dpdk.org
Cc: mko-plv@napatech.com, sil-plv@napatech.com, ckm@napatech.com,
	stephen@networkplumber.org
Subject: [PATCH v1 20/32] net/ntnic: add clock init
Date: Thu, 20 Feb 2025 23:03:44 +0100	[thread overview]
Message-ID: <20250220220406.3925597-21-sil-plv@napatech.com> (raw)
In-Reply-To: <20250220220406.3925597-1-sil-plv@napatech.com>

Add initialization for the clock subsystem

Signed-off-by: Serhii Iliushyk <sil-plv@napatech.com>
---
 ...00D13_U62_Si5332-GM2-RevD-1_V5-Registers.h | 425 ++++++++++++++++++
 .../net/ntnic/nthw/core/include/nthw_i2cm.h   |   1 +
 .../nthw/core/include/nthw_pcm_nt400dxx.h     |  14 +
 .../nthw/core/include/nthw_si5332_si5156.h    |  36 ++
 .../nthw/core/nt400dxx/nthw_fpga_nt400dxx.c   | 115 ++++-
 drivers/net/ntnic/nthw/core/nthw_i2cm.c       |  57 +++
 .../net/ntnic/nthw/core/nthw_si5332_si5156.c  |  93 ++++
 drivers/net/ntnic/nthw/nthw_drv.h             |   7 +-
 8 files changed, 745 insertions(+), 3 deletions(-)
 create mode 100644 drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h
 create mode 100644 drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h

diff --git a/drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h b/drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h
new file mode 100644
index 0000000000..f87828fcfe
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/include/NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h
@@ -0,0 +1,425 @@
+/*
+ * Si5332-GM2 Rev D Configuration Register Export Header File
+ *
+ * This file represents a series of Skyworks Si5332-GM2 Rev D
+ * register writes that can be performed to load a single configuration
+ * on a device. It was created by a Skyworks ClockBuilder Pro
+ * export tool.
+ *
+ * Part:		                                       Si5332-GM2 Rev D
+ * Design ID:                                          1
+ * Includes Pre/Post Download Control Register Writes: Yes
+ * Created By:                                         ClockBuilder Pro v4.5 [2022-08-23]
+ * Timestamp:                                          2022-10-11 15:44:24 GMT+02:00
+ *
+ * A complete design report corresponding to this export is included at the end
+ * of this header file.
+ *
+ */
+
+#ifndef SI5332_GM2_REVD_REG_CONFIG_HEADER
+#define SI5332_GM2_REVD_REG_CONFIG_HEADER
+
+#define SI5332_GM2_REVD_REG_CONFIG_NUM_REGS 76
+
+typedef struct {
+	unsigned int address;	/* 8-bit register address */
+	unsigned char value;	/* 8-bit register data */
+
+} si5332_gm2_revd_register_t;
+
+si5332_gm2_revd_register_t const si5332_gm2_revd_registers[SI5332_GM2_REVD_REG_CONFIG_NUM_REGS] = {
+	/* Start configuration preamble */
+	/*    Set device in Ready mode */
+	{ 0x0006, 0x01 },
+	/* End configuration preamble */
+
+	/* Start configuration registers */
+	{ 0x0017, 0x31 },
+	{ 0x0018, 0x00 },
+	{ 0x0019, 0x00 },
+	{ 0x001A, 0x00 },
+	{ 0x001B, 0x00 },
+	{ 0x001C, 0x00 },
+	{ 0x0021, 0x6A },
+	{ 0x0024, 0x01 },
+	{ 0x0025, 0x00 },
+	{ 0x0026, 0x00 },
+	{ 0x0027, 0x50 },
+	{ 0x0028, 0x50 },
+	{ 0x0029, 0x00 },
+	{ 0x002A, 0x00 },
+	{ 0x002B, 0x10 },
+	{ 0x0036, 0x07 },
+	{ 0x0037, 0x80 },
+	{ 0x0038, 0x02 },
+	{ 0x0039, 0x80 },
+	{ 0x003A, 0x05 },
+	{ 0x003B, 0x35 },
+	{ 0x003C, 0x00 },
+	{ 0x0048, 0x00 },
+	{ 0x0054, 0x00 },
+	{ 0x0060, 0x00 },
+	{ 0x0067, 0x19 },
+	{ 0x0068, 0x00 },
+	{ 0x0069, 0x00 },
+	{ 0x006A, 0x00 },
+	{ 0x006B, 0x00 },
+	{ 0x006C, 0x01 },
+	{ 0x0073, 0x00 },
+	{ 0x0074, 0x00 },
+	{ 0x0075, 0x01 },
+	{ 0x007A, 0x07 },
+	{ 0x007B, 0x01 },
+	{ 0x007C, 0x00 },
+	{ 0x007D, 0x00 },
+	{ 0x007F, 0x07 },
+	{ 0x0080, 0x01 },
+	{ 0x0081, 0x00 },
+	{ 0x0082, 0x00 },
+	{ 0x0089, 0x07 },
+	{ 0x008A, 0x01 },
+	{ 0x008B, 0x00 },
+	{ 0x008C, 0x00 },
+	{ 0x008E, 0x07 },
+	{ 0x008F, 0x01 },
+	{ 0x0090, 0x00 },
+	{ 0x0091, 0x00 },
+	{ 0x0098, 0x07 },
+	{ 0x0099, 0x01 },
+	{ 0x009A, 0x00 },
+	{ 0x009B, 0x00 },
+	{ 0x009D, 0x07 },
+	{ 0x009E, 0x01 },
+	{ 0x009F, 0x00 },
+	{ 0x00A0, 0x00 },
+	{ 0x00A7, 0x07 },
+	{ 0x00A8, 0x01 },
+	{ 0x00A9, 0x00 },
+	{ 0x00AA, 0x00 },
+	{ 0x00AC, 0x07 },
+	{ 0x00AD, 0x01 },
+	{ 0x00AE, 0x00 },
+	{ 0x00AF, 0x00 },
+	{ 0x00B6, 0xDB },
+	{ 0x00B7, 0x06 },
+	{ 0x00B9, 0x06 },
+	{ 0x00BA, 0x5E },
+	{ 0x00BB, 0x00 },
+	{ 0x00BC, 0x00 },
+	{ 0x00BD, 0x00 },
+	{ 0x00BE, 0x20 },
+	/* End configuration registers */
+
+	/* Start configuration postamble */
+	/*    Set device in Active mode */
+	{ 0x0006, 0x02 },
+	/* End configuration postamble */
+};
+
+/*
+ * Design Report
+ *
+ * Overview
+ * ========
+ * Part:               Si5332EFL Rev D
+ * Project File:       P:\Hardware\NT
+ * Adapters\NT400D13\design\Clock_syn_design\Si5332-GM2-RevD-1-Project_V5.slabtimeproj Design ID: 1
+ * Created By:         ClockBuilder Pro v4.5 [2022-08-23]
+ * Timestamp:          2022-10-11 15:44:24 GMT+02:00
+ *
+ * Design Rule Check
+ * =================
+ * Errors:
+ * - No errors
+ *
+ * Warnings:
+ * - OUT1 [156.25 MHz] and OUT2 [166.625 MHz] may have coupling [1]
+ * - OUT5 [166.625 MHz] and OUT6 [156.25 MHz] may have coupling [1]
+ *
+ * Footnotes:
+ * [1] To avoid coupling in outputs, Skyworks recommends the following:
+ *
+ * - Avoid adjacent frequency values that are close. CBPro uses an output's integration bandwidth
+ *   (IBW) to determine whether two adjacent frequencies are too close. An IBW of 20 MHz is used
+ *   for frequencies 80 MHz and larger. Lower frequencies will use IBW of OUT/4. CBPro will flag
+ *   fundamental coupling and coupling up to the fourth harmonic, where coupling
+ *   frequency = Absolute(OUTa*x - OUTb*y) for all combinations of x and y 1 through 4. If any one
+ *   of these values is less than or equal to the IBW, the output is flagged as having possible
+ *   coupling.
+ * - Adjacent frequency values that are integer multiples of one another are okay and these
+ *   outputs should be grouped accordingly.
+ * - Unused outputs can be used to separate clock outputs that might otherwise interfere
+ *   with one another.
+ *
+ * Skyworks recommends you validate your design's jitter performance using an Evaluation Board.
+ * You can request a custom phase noise report for your design from CBPro's design dashboard.
+ *
+ * Device Grade
+ * ============
+ * Maximum Output Frequency: 166.625 MHz
+ * Frequency Synthesis Mode: Fractional
+ * Frequency Plan Grade:     F
+ * Minimum Base OPN:         Si5332F*
+ *
+ * Base       Output Clock         Supported Frequency Synthesis Modes
+ * OPN Grade  Frequency Range      (Typical Jitter)
+ * ---------  ------------------  --------------------------------------------
+ * Si5332E    5 MHz to 334 MHz    Integer (~230 fs) and fractional (~500 fs)
+ * Si5332F*   5 MHz to 200 MHz    "
+ * Si5332G    5 MHz to 334 MHz    Integer only (~230 fs)
+ * Si5332H    5 MHz to 200 MHz    "
+ * Si5332L*   5 MHz to 334 MHz    Integer (~230 fs) and fractional (~500 fs)
+ *
+ * * Based on your calculated frequency plan, a Si5332F grade device is
+ * sufficient for your design. For more in-system configuration flexibility
+ * (higher frequencies and/or to enable fractional synthesis), consider
+ * selecting device grade Si5332E when specifying an ordering part number (OPN)
+ * for your application. See the datasheet Ordering Guide for more information.
+ *
+ * Design
+ * ======
+ * Base I2C Address: 0x6A
+ *
+ * Universal Hardware Input Pins:
+ *    INPUT1 (P10): None
+ *    INPUT2 (P19): None
+ *    INPUT3 (P20): None
+ *    INPUT4 (P31): None
+ *    INPUT5 (P32): None
+ *    INPUT6 (P36): None
+ *    INPUT7 (P37): None
+ *
+ * Inputs:
+ *    XAXB: 50 MHz
+ *          Crystal Mode
+ *  CLKIN2: Unused
+ *  CLKIN3: Unused
+ *
+ * Outputs:
+ *    OUT0: 156.25 MHz LVDS Fast 1.8 V, Disabled-State: Stop Low
+ *          Power-up state: Enabled
+ *    OUT1: 156.25 MHz LVDS Fast 1.8 V, Disabled-State: Stop Low
+ *          Power-up state: Enabled
+ *    OUT2: 166.625 MHz LVDS Fast 1.8 V, Disabled-State: Stop Low
+ *          Power-up state: Enabled
+ *    OUT3: 166.625 MHz LVDS Fast 1.8 V, Disabled-State: Stop Low
+ *          Power-up state: Enabled
+ *    OUT4: 166.625 MHz LVDS Fast 1.8 V, Disabled-State: Stop Low
+ *          Power-up state: Enabled
+ *    OUT5: 166.625 MHz LVDS Fast 1.8 V, Disabled-State: Stop Low
+ *          Power-up state: Enabled
+ *    OUT6: 156.25 MHz LVDS Fast 1.8 V, Disabled-State: Stop Low
+ *          Power-up state: Enabled
+ *    OUT7: 156.25 MHz LVDS Fast 1.8 V, Disabled-State: Stop Low
+ *          Power-up state: Enabled
+ *
+ * Frequency Plan
+ * ==============
+ * Fpfd = 50 MHz
+ * Fvco = 2.5 GHz
+ *
+ * P divider = 1
+ * M = 50
+ * N dividers:
+ *    N0:
+ *       Value: 15.0037509377344336... [ 15 + 5/1333 ]
+ *       OUT2: 166.625 MHz, Error: 0 ppm
+ *       OUT3: 166.625 MHz, Error: 0 ppm
+ *       OUT4: 166.625 MHz, Error: 0 ppm
+ *       OUT5: 166.625 MHz, Error: 0 ppm
+ *    N1:
+ *       Unused
+ *
+ * O dividers:
+ *    O0:
+ *       Value: 16
+ *       OUT0: 156.25 MHz, Error: 0 ppm
+ *       OUT1: 156.25 MHz, Error: 0 ppm
+ *       OUT6: 156.25 MHz, Error: 0 ppm
+ *       OUT7: 156.25 MHz, Error: 0 ppm
+ *    O1:
+ *       Unused
+ *    O2:
+ *       Unused
+ *    O3:
+ *       Unused
+ *    O4:
+ *       Unused
+ *
+ * R dividers:
+ *    R0 = 1
+ *    R1 = 1
+ *    R2 = 1
+ *    R3 = 1
+ *    R4 = 1
+ *    R5 = 1
+ *    R6 = 1
+ *    R7 = 1
+ *
+ * Estimated Power
+ * ===============
+ * Total Power: 233 mW, On Chip Power: 220 mW, Tj: 31 °C
+ *
+ *                    Frequency    Format   Voltage   Current     Power
+ *                  -----------  --------  --------  --------  --------
+ * VDD                                        1.8 V   30.7 mA     55 mW
+ * VDD Dig                                    1.8 V    7.0 mA     13 mW
+ * VDD Xtal                                   1.8 V    2.3 mA      4 mW
+ * VDDO0
+ *            OUT0   156.25 MHz  LVDSFast     1.8 V   11.1 mA     20 mW
+ * VDDO1
+ *            OUT1   156.25 MHz  LVDSFast     1.8 V   11.1 mA     20 mW
+ * VDDO2
+ *            OUT2  166.625 MHz  LVDSFast     1.8 V   11.2 mA     20 mW
+ *            OUT3  166.625 MHz  LVDSFast     1.8 V   11.2 mA     20 mW
+ * VDDO3
+ *            OUT4  166.625 MHz  LVDSFast     1.8 V   11.2 mA     20 mW
+ *            OUT5  166.625 MHz  LVDSFast     1.8 V   11.2 mA     20 mW
+ * VDDO4
+ *            OUT6   156.25 MHz  LVDSFast     1.8 V   11.1 mA     20 mW
+ * VDDO5
+ *            OUT7   156.25 MHz  LVDSFast     1.8 V   11.1 mA     20 mW
+ *                                                   --------  --------
+ *                                            Total  129.4 mA    233 mW
+ *
+ * Note:
+ *
+ * -Tj is junction temperature. Tj must be less than 125 °C (on Si5332-GM2 Revision D) for device
+ *  to comply with datasheet specifications. Tj = Ta + Theta_JA*On_Chip_Power.
+ * -Overall power includes on-chip power dissipation and adds differential load power dissipation
+ *  to estimate total power requirements.
+ * -Above are estimates only: power and temperature should be measured on your PCB.
+ *
+ * Settings
+ * ========
+ *
+ * Location    Setting Name     Decimal Value      Hex Value
+ * ----------  ---------------  -----------------  -----------------
+ * 0x17[7:0]   DESIGN_ID0       49                 0x31
+ * 0x18[7:0]   DESIGN_ID1       0                  0x00
+ * 0x19[7:0]   DESIGN_ID2       0                  0x00
+ * 0x1A[7:0]   DESIGN_ID3       0                  0x00
+ * 0x1B[7:0]   DESIGN_ID4       0                  0x00
+ * 0x1C[7:0]   DESIGN_ID5       0                  0x00
+ * 0x21[6:0]   I2C_ADDR         106                0x6A
+ * 0x24[1:0]   IMUX_SEL         1                  0x1
+ * 0x25[1:0]   OMUX0_SEL0       0                  0x0
+ * 0x25[6:4]   OMUX0_SEL1       0                  0x0
+ * 0x26[1:0]   OMUX1_SEL0       0                  0x0
+ * 0x26[6:4]   OMUX1_SEL1       0                  0x0
+ * 0x27[1:0]   OMUX2_SEL0       0                  0x0
+ * 0x27[6:4]   OMUX2_SEL1       5                  0x5
+ * 0x28[1:0]   OMUX3_SEL0       0                  0x0
+ * 0x28[6:4]   OMUX3_SEL1       5                  0x5
+ * 0x29[1:0]   OMUX4_SEL0       0                  0x0
+ * 0x29[6:4]   OMUX4_SEL1       0                  0x0
+ * 0x2A[1:0]   OMUX5_SEL0       0                  0x0
+ * 0x2A[6:4]   OMUX5_SEL1       0                  0x0
+ * 0x2B[7:0]   HSDIV0A_DIV      16                 0x10
+ * 0x36[14:0]  ID0A_INTG        1920               0x0780
+ * 0x38[14:0]  ID0A_RES         640                0x0280
+ * 0x3A[14:0]  ID0A_DEN         1333               0x0535
+ * 0x3C[0]     ID0A_SS_ENA      0                  0x0
+ * 0x3C[2:1]   ID0A_SS_MODE     0                  0x0
+ * 0x48[0]     ID0B_SS_ENA      0                  0x0
+ * 0x48[2:1]   ID0B_SS_MODE     0                  0x0
+ * 0x54[0]     ID1A_SS_ENA      0                  0x0
+ * 0x54[2:1]   ID1A_SS_MODE     0                  0x0
+ * 0x60[0]     ID1B_SS_ENA      0                  0x0
+ * 0x60[2:1]   ID1B_SS_MODE     0                  0x0
+ * 0x67[14:0]  IDPA_INTG        6400               0x1900
+ * 0x69[14:0]  IDPA_RES         0                  0x0000
+ * 0x6B[14:0]  IDPA_DEN         1                  0x0001
+ * 0x73[1:0]   CLKIN_2_CLK_SEL  0                  0x0
+ * 0x74[1:0]   CLKIN_3_CLK_SEL  0                  0x0
+ * 0x75[4:0]   P_VAL            1                  0x01
+ * 0x7A[3:0]   OUT0_MODE        7                  0x7
+ * 0x7B[5:0]   OUT0_DIV         1                  0x01
+ * 0x7C[2:0]   OUT0_SKEW        0                  0x0
+ * 0x7D[0]     OUT0_STOP_HIGHZ  0                  0x0
+ * 0x7D[5:4]   OUT0_CMOS_INV    0                  0x0
+ * 0x7D[6]     OUT0_DIFF_INV    0                  0x0
+ * 0x7F[3:0]   OUT1_MODE        7                  0x7
+ * 0x80[5:0]   OUT1_DIV         1                  0x01
+ * 0x81[2:0]   OUT1_SKEW        0                  0x0
+ * 0x82[0]     OUT1_STOP_HIGHZ  0                  0x0
+ * 0x82[5:4]   OUT1_CMOS_INV    0                  0x0
+ * 0x82[6]     OUT1_DIFF_INV    0                  0x0
+ * 0x89[3:0]   OUT2_MODE        7                  0x7
+ * 0x8A[5:0]   OUT2_DIV         1                  0x01
+ * 0x8B[2:0]   OUT2_SKEW        0                  0x0
+ * 0x8C[0]     OUT2_STOP_HIGHZ  0                  0x0
+ * 0x8C[5:4]   OUT2_CMOS_INV    0                  0x0
+ * 0x8C[6]     OUT2_DIFF_INV    0                  0x0
+ * 0x8E[3:0]   OUT3_MODE        7                  0x7
+ * 0x8F[5:0]   OUT3_DIV         1                  0x01
+ * 0x90[2:0]   OUT3_SKEW        0                  0x0
+ * 0x91[0]     OUT3_STOP_HIGHZ  0                  0x0
+ * 0x91[5:4]   OUT3_CMOS_INV    0                  0x0
+ * 0x91[6]     OUT3_DIFF_INV    0                  0x0
+ * 0x98[3:0]   OUT4_MODE        7                  0x7
+ * 0x99[5:0]   OUT4_DIV         1                  0x01
+ * 0x9A[2:0]   OUT4_SKEW        0                  0x0
+ * 0x9B[0]     OUT4_STOP_HIGHZ  0                  0x0
+ * 0x9B[5:4]   OUT4_CMOS_INV    0                  0x0
+ * 0x9B[6]     OUT4_DIFF_INV    0                  0x0
+ * 0x9D[3:0]   OUT5_MODE        7                  0x7
+ * 0x9E[5:0]   OUT5_DIV         1                  0x01
+ * 0x9F[2:0]   OUT5_SKEW        0                  0x0
+ * 0xA0[0]     OUT5_STOP_HIGHZ  0                  0x0
+ * 0xA0[5:4]   OUT5_CMOS_INV    0                  0x0
+ * 0xA0[6]     OUT5_DIFF_INV    0                  0x0
+ * 0xA7[3:0]   OUT6_MODE        7                  0x7
+ * 0xA8[5:0]   OUT6_DIV         1                  0x01
+ * 0xA9[2:0]   OUT6_SKEW        0                  0x0
+ * 0xAA[0]     OUT6_STOP_HIGHZ  0                  0x0
+ * 0xAA[5:4]   OUT6_CMOS_INV    0                  0x0
+ * 0xAA[6]     OUT6_DIFF_INV    0                  0x0
+ * 0xAC[3:0]   OUT7_MODE        7                  0x7
+ * 0xAD[5:0]   OUT7_DIV         1                  0x01
+ * 0xAE[2:0]   OUT7_SKEW        0                  0x0
+ * 0xAF[0]     OUT7_STOP_HIGHZ  0                  0x0
+ * 0xAF[5:4]   OUT7_CMOS_INV    0                  0x0
+ * 0xAF[6]     OUT7_DIFF_INV    0                  0x0
+ * 0xB6[0]     OUT0_OE          1                  0x1
+ * 0xB6[1]     OUT1_OE          1                  0x1
+ * 0xB6[3]     OUT2_OE          1                  0x1
+ * 0xB6[4]     OUT3_OE          1                  0x1
+ * 0xB6[6]     OUT4_OE          1                  0x1
+ * 0xB6[7]     OUT5_OE          1                  0x1
+ * 0xB7[1]     OUT6_OE          1                  0x1
+ * 0xB7[2]     OUT7_OE          1                  0x1
+ * 0xB9[0]     XOSC_DIS         0                  0x0
+ * 0xB9[1]     IBUF0_DIS        1                  0x1
+ * 0xB9[2]     IBUF1_DIS        1                  0x1
+ * 0xB9[3]     IMUX_DIS         0                  0x0
+ * 0xB9[4]     PDIV_DIS         0                  0x0
+ * 0xB9[5]     PLL_DIS          0                  0x0
+ * 0xBA[5]     ID0_DIS          0                  0x0
+ * 0xBA[6]     ID1_DIS          1                  0x1
+ * 0xBA[0]     HSDIV0_DIS       0                  0x0
+ * 0xBA[1]     HSDIV1_DIS       1                  0x1
+ * 0xBA[2]     HSDIV2_DIS       1                  0x1
+ * 0xBA[3]     HSDIV3_DIS       1                  0x1
+ * 0xBA[4]     HSDIV4_DIS       1                  0x1
+ * 0xBB[0]     OMUX0_DIS        0                  0x0
+ * 0xBB[1]     OMUX1_DIS        0                  0x0
+ * 0xBB[2]     OMUX2_DIS        0                  0x0
+ * 0xBB[3]     OMUX3_DIS        0                  0x0
+ * 0xBB[4]     OMUX4_DIS        0                  0x0
+ * 0xBB[5]     OMUX5_DIS        0                  0x0
+ * 0xBC[0]     OUT0_DIS         0                  0x0
+ * 0xBC[1]     OUT1_DIS         0                  0x0
+ * 0xBC[3]     OUT2_DIS         0                  0x0
+ * 0xBC[4]     OUT3_DIS         0                  0x0
+ * 0xBC[6]     OUT4_DIS         0                  0x0
+ * 0xBC[7]     OUT5_DIS         0                  0x0
+ * 0xBD[1]     OUT6_DIS         0                  0x0
+ * 0xBD[2]     OUT7_DIS         0                  0x0
+ * 0xBE[7:0]   PLL_MODE         32                 0x20
+ *
+ *
+ */
+
+#endif
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_i2cm.h b/drivers/net/ntnic/nthw/core/include/nthw_i2cm.h
index eeb4dffe25..53aa3c018e 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_i2cm.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_i2cm.h
@@ -46,5 +46,6 @@ typedef struct nt_i2cm nthw_i2cm_t;
 
 int nthw_i2cm_read(nthw_i2cm_t *p, uint8_t dev_addr, uint8_t reg_addr, uint8_t *value);
 int nthw_i2cm_write(nthw_i2cm_t *p, uint8_t dev_addr, uint8_t reg_addr, uint8_t value);
+int nthw_i2cm_write16(nthw_i2cm_t *p, uint8_t dev_addr, uint8_t reg_addr, uint16_t value);
 
 #endif	/* __NTHW_II2CM_H__ */
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h b/drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h
new file mode 100644
index 0000000000..1e114886ca
--- /dev/null
+++ b/drivers/net/ntnic/nthw/core/include/nthw_pcm_nt400dxx.h
@@ -0,0 +1,14 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Napatech A/S
+ */
+#ifndef __NTHW_PCM_NT400DXX_H__
+#define __NTHW_PCM_NT400DXX_H__
+
+struct nthw_pcm_nt400_dxx {
+	int mn_module_minor_version;
+};
+
+typedef struct nthw_pcm_nt400_dxx nthw_pcm_nt400dxx_t;
+
+#endif  /* __NTHW_PCM_NT400DXX_H__ */
diff --git a/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h b/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
index 968d7eb74a..753717ba8a 100644
--- a/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
+++ b/drivers/net/ntnic/nthw/core/include/nthw_si5332_si5156.h
@@ -21,4 +21,40 @@ typedef struct nthw_pca9849 nthw_pca9849_t;
 
 int nthw_pca9849_set_channel(nthw_pca9849_t *p, uint8_t channel);
 
+/*
+ * Si5332 clock synthesizer
+ */
+
+struct nthw_si5332 {
+	nthw_i2cm_t *mp_nt_i2cm;
+	uint8_t m_dev_address;
+	nthw_pca9849_t *mp_pca9849;
+	uint8_t m_mux_channel;
+};
+
+typedef struct nthw_si5332 nthw_si5332_t;
+
+nthw_si5332_t *nthw_si5332_new(void);
+int nthw_si5332_init(nthw_si5332_t *p, nthw_i2cm_t *p_nt_i2cm, uint8_t dev_address,
+	nthw_pca9849_t *pca9849, uint8_t mux_channel);
+bool nthw_si5332_clock_active(nthw_si5332_t *p);
+void nthw_si5332_write(nthw_si5332_t *p, uint8_t address, uint8_t value);
+
+/*
+ * Si5156 MEMS Super TCXO
+ */
+struct nthw_si5156 {
+	nthw_i2cm_t *mp_nt_i2cm;
+	uint8_t m_dev_address;
+	nthw_pca9849_t *mp_pca9849;
+	uint8_t m_mux_channel;
+};
+
+typedef struct nthw_si5156 nthw_si5156_t;
+
+nthw_si5156_t *nthw_si5156_new(void);
+int nthw_si5156_init(nthw_si5156_t *p, nthw_i2cm_t *p_nt_i2cm, uint8_t dev_address,
+	nthw_pca9849_t *pca9849, uint8_t mux_channel);
+int nthw_si5156_write16(nthw_si5156_t *p, uint8_t address, uint16_t value);
+
 #endif	/* __NTHW_SI5332_SI5156_H__ */
diff --git a/drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c b/drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c
index 0a5add60e0..24118822c4 100644
--- a/drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c
+++ b/drivers/net/ntnic/nthw/core/nt400dxx/nthw_fpga_nt400dxx.c
@@ -2,10 +2,113 @@
  * SPDX-License-Identifier: BSD-3-Clause
  * Copyright(c) 2023 Napatech A/S
  */
-
+#include "ntlog.h"
 #include "nthw_fpga.h"
 #include "ntnic_mod_reg.h"
-#include "ntlog.h"
+#include "NT400D13_U62_Si5332-GM2-RevD-1_V5-Registers.h"
+
+static int nthw_fpga_nt400dxx_init_clock_synthesizers(struct fpga_info_s *p_fpga_info)
+{
+	const char *const p_adapter_id_str = p_fpga_info->mp_adapter_id_str;
+	int res = -1;
+
+	/* Clock synthesizer on address 0x6a on channel 2 */
+	p_fpga_info->mp_nthw_agx.p_si5332 = nthw_si5332_new();
+	res = nthw_si5332_init(p_fpga_info->mp_nthw_agx.p_si5332,
+			p_fpga_info->mp_nthw_agx.p_i2cm,
+			0x6A,
+			p_fpga_info->mp_nthw_agx.p_pca9849,
+			2);
+
+	if (res) {
+		NT_LOG(ERR, NTHW, "%s: %s: Failed to initialize Si5332 clock - res=%d",
+			p_adapter_id_str, __func__, res);
+		return res;
+	}
+
+	p_fpga_info->mp_nthw_agx.p_si5156 = nthw_si5156_new();
+	res = nthw_si5156_init(p_fpga_info->mp_nthw_agx.p_si5156,
+			p_fpga_info->mp_nthw_agx.p_i2cm,
+			0x60,
+			p_fpga_info->mp_nthw_agx.p_pca9849,
+			2);
+
+	if (res) {
+		NT_LOG(ERR, NTHW, "%s: %s: Failed to initialize Si5156 clock - res=%d",
+			p_adapter_id_str, __func__, res);
+		return res;
+	}
+
+	if (nthw_si5332_clock_active(p_fpga_info->mp_nthw_agx.p_si5332)) {
+		NT_LOG(INF,
+			NTHW,
+			"%s: Fpga clock already active, skipping clock initialisation.",
+			p_adapter_id_str);
+
+	} else {
+		NT_LOG(INF, NTHW,
+			"%s: Fpga clock not active, performing full clock initialisation.",
+			p_adapter_id_str);
+
+		for (int i = 0; i < SI5332_GM2_REVD_REG_CONFIG_NUM_REGS; i++) {
+			nthw_si5332_write(p_fpga_info->mp_nthw_agx.p_si5332,
+				(uint8_t)si5332_gm2_revd_registers[i].address,
+				(uint8_t)si5332_gm2_revd_registers[i].value);
+		}
+	}
+
+	/*
+	 * TCXO capable PCM version if minor version >= 3
+	 * Unfortunately, the module version is not readily
+	 * available in the FPGA_400D1x class.
+	 */
+	bool tcxo_capable = p_fpga_info->mp_nthw_agx.p_pcm->mn_module_minor_version >= 3;
+
+	/*
+	 * This method of determining the presence of a TCXO
+	 *  will only work until non SI5156 equipped boards
+	 *  use the vacant I2C address for something else...
+	 *
+	 * There's no other way, there's no other way
+	 * All that you can do is watch them play
+	 * Clean-up when GA HW is readily available
+	 */
+	if (nthw_si5156_write16(p_fpga_info->mp_nthw_agx.p_si5156, 0x1, 0x0400) != 0) {
+		p_fpga_info->mp_nthw_agx.tcxo_capable = false;
+		p_fpga_info->mp_nthw_agx.tcxo_present = false;
+
+	} else {
+		p_fpga_info->mp_nthw_agx.tcxo_capable = tcxo_capable;
+		p_fpga_info->mp_nthw_agx.tcxo_present = true;
+	}
+
+	return 0;
+}
+
+static int nthw_fpga_nt400dxx_init_sub_systems(struct fpga_info_s *p_fpga_info)
+{
+	int res;
+	NT_LOG(INF, NTHW, "%s: Initializing NT4GA subsystems...", p_fpga_info->mp_adapter_id_str);
+
+	/* RAB subsystem */
+	NT_LOG(DBG, NTHW, "%s: Initializing RAB subsystem: flush", p_fpga_info->mp_adapter_id_str);
+	res = nthw_rac_rab_flush(p_fpga_info->mp_nthw_rac);
+
+	if (res)
+		return res;
+
+	/* clock synthesizer subsystem */
+	NT_LOG(DBG,
+		NTHW,
+		"%s: Initializing clock synthesizer subsystem",
+		p_fpga_info->mp_adapter_id_str);
+	res = nthw_fpga_nt400dxx_init_clock_synthesizers(p_fpga_info);
+
+	if (res)
+		return res;
+
+	return 0;
+}
 
 static int nthw_fpga_nt400dxx_init(struct fpga_info_s *p_fpga_info)
 {
@@ -61,6 +164,14 @@ static int nthw_fpga_nt400dxx_init(struct fpga_info_s *p_fpga_info)
 		return res;
 	}
 
+	res = nthw_fpga_nt400dxx_init_sub_systems(p_fpga_info);
+
+	if (res) {
+		NT_LOG(ERR, NTHW, "%s: %s: FPGA=%04d Failed to init subsystems res=%d",
+		p_adapter_id_str, __func__, p_fpga_info->n_fpga_prod_id, res);
+		return res;
+	}
+
 	res = rst_nt400dxx_ops->nthw_fpga_rst_nt400dxx_reset(p_fpga_info);
 
 	if (res) {
diff --git a/drivers/net/ntnic/nthw/core/nthw_i2cm.c b/drivers/net/ntnic/nthw/core/nthw_i2cm.c
index b5f8e299ff..f7500b2e93 100644
--- a/drivers/net/ntnic/nthw/core/nthw_i2cm.c
+++ b/drivers/net/ntnic/nthw/core/nthw_i2cm.c
@@ -73,6 +73,47 @@ static int nthw_i2cm_write_internal(nthw_i2cm_t *p, uint8_t value)
 	return 0;
 }
 
+static int nthw_i2cm_write16_internal(nthw_i2cm_t *p, uint16_t value)
+{
+	const uint8_t count = 1;
+
+	for (int8_t i = count; i >= 0; i--) {
+		uint8_t byte_value = (uint8_t)(value >> ((uint8_t)i * 8)) & 0xffU;
+
+		/* Write data to data register */
+		nthw_field_set_val_flush32(p->mp_fld_data_data, byte_value);
+
+		if (i == 0) {
+			nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status,
+				NT_I2C_CMD_WR | NT_I2C_CMD_IRQ_ACK);
+
+		} else {
+			nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status, NT_I2C_CMD_WR);
+		}
+
+		if (!nthw_i2cm_ready(p, true)) {
+			nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status,
+				NT_I2C_CMD_STOP | NT_I2C_CMD_IRQ_ACK);
+			NT_LOG(ERR, NTHW, "%s: Time-out writing data %u", __PRETTY_FUNCTION__,
+				value);
+			return 1;
+		}
+	}
+
+	/* Generate stop condition and clear interrupt */
+	nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status,
+		NT_I2C_CMD_STOP | NT_I2C_CMD_IRQ_ACK);
+
+	if (!nthw_i2cm_ready(p, true)) {
+		nthw_field_set_val_flush32(p->mp_fld_cmd_status_cmd_status,
+			NT_I2C_CMD_STOP | NT_I2C_CMD_IRQ_ACK);
+		NT_LOG(ERR, NTHW, "%s: Time-out sending stop condition", __PRETTY_FUNCTION__);
+		return 1;
+	}
+
+	return 0;
+}
+
 static int nthw_i2cm_write_reg_addr_internal(nthw_i2cm_t *p, uint8_t dev_addr, uint8_t reg_addr,
 	bool send_stop)
 {
@@ -190,3 +231,19 @@ int nthw_i2cm_write(nthw_i2cm_t *p, uint8_t dev_addr, uint8_t reg_addr, uint8_t
 
 	return 0;
 }
+
+int nthw_i2cm_write16(nthw_i2cm_t *p, uint8_t dev_addr, uint8_t reg_addr, uint16_t value)
+{
+	int status;
+	status = nthw_i2cm_write_reg_addr_internal(p, dev_addr, reg_addr, false);
+
+	if (status != 0)
+		return status;
+
+	status = nthw_i2cm_write16_internal(p, value);
+
+	if (status != 0)
+		return status;
+
+	return 0;
+}
diff --git a/drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c b/drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c
index b5560e2990..b4a7b57bcb 100644
--- a/drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c
+++ b/drivers/net/ntnic/nthw/core/nthw_si5332_si5156.c
@@ -4,6 +4,7 @@
  */
 
 #include <pthread.h>
+#include "generic/rte_spinlock.h"
 #include "nt_util.h"
 #include "ntlog.h"
 
@@ -29,3 +30,95 @@ int nthw_pca9849_set_channel(nthw_pca9849_t *p, uint8_t channel)
 
 	return 0;
 }
+
+/*
+ * Si5332 clock synthesizer
+ */
+
+nthw_si5332_t *nthw_si5332_new(void)
+{
+	nthw_si5332_t *p = malloc(sizeof(nthw_si5332_t));
+
+	if (p)
+		memset(p, 0, sizeof(nthw_si5332_t));
+
+	return p;
+}
+
+int nthw_si5332_init(nthw_si5332_t *p, nthw_i2cm_t *p_nt_i2cm, uint8_t dev_address,
+	nthw_pca9849_t *pca9849, uint8_t mux_channel)
+{
+	p->mp_nt_i2cm = p_nt_i2cm;
+	p->m_dev_address = dev_address;
+	p->m_mux_channel = mux_channel;
+	p->mp_pca9849 = pca9849;
+	return 0;
+}
+
+bool nthw_si5332_clock_active(nthw_si5332_t *p)
+{
+	uint8_t ena1, ena2;
+
+	rte_spinlock_lock(&p->mp_nt_i2cm->i2cmmutex);
+	nthw_pca9849_set_channel(p->mp_pca9849, p->m_mux_channel);
+
+	nthw_i2cm_read(p->mp_nt_i2cm, p->m_dev_address, 0xB6, &ena1);
+	NT_LOG(DBG, NTHW, "Read %x from i2c dev 0x6A, reg 0xB6", ena1);
+
+	nthw_i2cm_read(p->mp_nt_i2cm, p->m_dev_address, 0xB7, &ena2);
+	NT_LOG(DBG, NTHW, "Read %x from i2c dev 0x6A, reg 0xB7", ena2);
+	rte_spinlock_unlock(&p->mp_nt_i2cm->i2cmmutex);
+
+	return ((ena1 & 0xDB) != 0) || ((ena2 & 0x06) != 0);
+}
+
+void nthw_si5332_write(nthw_si5332_t *p, uint8_t address, uint8_t value)
+{
+	rte_spinlock_lock(&p->mp_nt_i2cm->i2cmmutex);
+	nthw_pca9849_set_channel(p->mp_pca9849, p->m_mux_channel);
+	nthw_i2cm_write(p->mp_nt_i2cm, p->m_dev_address, address, value);
+	rte_spinlock_unlock(&p->mp_nt_i2cm->i2cmmutex);
+}
+
+/*
+ * Si5156 MEMS Super TCXO
+ */
+
+nthw_si5156_t *nthw_si5156_new(void)
+{
+	nthw_si5156_t *p = malloc(sizeof(nthw_si5156_t));
+
+	if (p)
+		memset(p, 0, sizeof(nthw_si5156_t));
+
+	return p;
+}
+
+int nthw_si5156_init(nthw_si5156_t *p, nthw_i2cm_t *p_nt_i2cm, uint8_t dev_address,
+	nthw_pca9849_t *pca9849, uint8_t mux_channel)
+{
+	p->mp_nt_i2cm = p_nt_i2cm;
+	p->m_dev_address = dev_address;
+	p->m_mux_channel = mux_channel;
+	p->mp_pca9849 = pca9849;
+	return 0;
+}
+
+int nthw_si5156_write16(nthw_si5156_t *p, uint8_t address, uint16_t value)
+{
+	int res = 0;
+	rte_spinlock_lock(&p->mp_nt_i2cm->i2cmmutex);
+	res = nthw_pca9849_set_channel(p->mp_pca9849, p->m_mux_channel);
+
+	if (res)
+		goto ERROR;
+
+	res = nthw_i2cm_write16(p->mp_nt_i2cm, p->m_dev_address, address, value);
+
+	if (res)
+		goto ERROR;
+
+ERROR:
+	rte_spinlock_unlock(&p->mp_nt_i2cm->i2cmmutex);
+	return res;
+}
diff --git a/drivers/net/ntnic/nthw/nthw_drv.h b/drivers/net/ntnic/nthw/nthw_drv.h
index a3c54846f5..1d5b750db9 100644
--- a/drivers/net/ntnic/nthw/nthw_drv.h
+++ b/drivers/net/ntnic/nthw/nthw_drv.h
@@ -12,8 +12,8 @@
 #include "nthw_si5332_si5156.h"
 #include "nthw_pcal6416a.h"
 #include "nthw_pca9532.h"
-#include "nthw_phy_tile.h"
 #include "nthw_rpf.h"
+#include "nthw_pcm_nt400dxx.h"
 #include "nthw_phy_tile.h"
 
 /*
@@ -24,8 +24,13 @@ typedef struct nthw_agx_s {
 	nthw_pca9849_t *p_pca9849;
 	nthw_pcal6416a_t *p_io_nim;	/* PCAL6416A I/O expander for controlling TS */
 	nthw_pca9532_t *p_pca9532_led;
+	nthw_si5332_t *p_si5332;
+	nthw_si5156_t *p_si5156;
+	nthw_pcm_nt400dxx_t *p_pcm;
 	nthw_phy_tile_t *p_phy_tile;
 	nthw_rpf_t *p_rpf;
+	bool tcxo_present;
+	bool tcxo_capable;
 } nthw_agx_t;
 
 typedef enum nt_meta_port_type_e {
-- 
2.45.0


  parent reply	other threads:[~2025-02-20 22:06 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-20 22:03 [PATCH v1 00/32] add new adapter NT400D13 Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 01/32] net/ntnic: add link agx 100g Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 02/32] net/ntnic: add link state machine Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 03/32] net/ntnic: add rpf and gfg init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 04/32] net/ntnic: add agx setup for port Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 05/32] net/ntnic: add host loopback init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 06/32] net/ntnic: add line " Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 07/32] net/ntnic: add 100 gbps port init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 08/32] net/ntnic: add port post init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 09/32] net/ntnic: add nim low power API Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 10/32] net/ntnic: add link handling API Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 11/32] net/ntnic: add port init to the state machine Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 12/32] net/ntnic: add port disable API Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 13/32] net/ntnic: add minimal initialization new NIC NT400D13 Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 14/32] net/ntnic: add minimal reset FPGA Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 15/32] net/ntnic: add FPGA modules and registers Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 16/32] net/ntnic: add setup for fpga reset Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 17/32] net/ntnic: add default reset setting for NT400D13 Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 18/32] net/ntnic: add DDR calibration to reset stage Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 19/32] net/ntnic: add PHY ftile reset Serhii Iliushyk
2025-02-20 22:03 ` Serhii Iliushyk [this message]
2025-03-05 17:03   ` [PATCH v1 20/32] net/ntnic: add clock init David Marchand
2025-03-07 10:20     ` Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 21/32] net/ntnic: add nt400d13 pcm init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 22/32] net/ntnic: add HIF clock test Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 23/32] net/ntnic: add nt400d13 PRM module init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 24/32] net/ntnic: add nt400d13 PRM module reset Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 25/32] net/ntnic: add SPI v3 support for FPGA Serhii Iliushyk
2025-02-22 19:21   ` Stephen Hemminger
2025-02-20 22:03 ` [PATCH v1 26/32] net/ntnic: add i2cm init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 27/32] net/ntnic: add pca init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 28/32] net/ntnic: add pcal init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 29/32] net/ntnic: add reset PHY init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 30/32] net/ntnic: add igam module init Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 31/32] net/ntnic: init IGAM and config PLL for FPGA Serhii Iliushyk
2025-02-20 22:03 ` [PATCH v1 32/32] net/ntnic: revert untrusted loop bound Serhii Iliushyk
2025-02-20 22:31   ` Stephen Hemminger
2025-02-20 23:49 ` [PATCH v1 00/32] add new adapter NT400D13 Stephen Hemminger
2025-02-22 21:41 ` Stephen Hemminger
2025-04-11 10:36   ` Serhii Iliushyk

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=20250220220406.3925597-21-sil-plv@napatech.com \
    --to=sil-plv@napatech.com \
    --cc=ckm@napatech.com \
    --cc=dev@dpdk.org \
    --cc=mko-plv@napatech.com \
    --cc=stephen@networkplumber.org \
    /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.