net: phy: nxp-c45-tja11xx: add TJA1120 support
authorRadu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
Mon, 31 Jul 2023 09:16:13 +0000 (12:16 +0300)
committerJakub Kicinski <kuba@kernel.org>
Wed, 2 Aug 2023 04:06:25 +0000 (21:06 -0700)
Add TJA1120 driver entry and its driver_data.

Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://lore.kernel.org/r/20230731091619.77961-6-radu-nicolae.pirea@oss.nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/phy/Kconfig
drivers/net/phy/nxp-c45-tja11xx.c

index 67aaeb7..107880d 100644 (file)
@@ -306,7 +306,7 @@ config NXP_C45_TJA11XX_PHY
        depends on PTP_1588_CLOCK_OPTIONAL
        help
          Enable support for NXP C45 TJA11XX PHYs.
-         Currently supports only the TJA1103 PHY.
+         Currently supports the TJA1103 and TJA1120 PHYs.
 
 config NXP_TJA11XX_PHY
        tristate "NXP TJA11xx PHYs support"
index 573083f..dbfaf1e 100644 (file)
 #include <linux/net_tstamp.h>
 
 #define PHY_ID_TJA_1103                        0x001BB010
+#define PHY_ID_TJA_1120                        0x001BB031
 
 #define VEND1_DEVICE_CONTROL           0x0040
 #define DEVICE_CONTROL_RESET           BIT(15)
 #define DEVICE_CONTROL_CONFIG_GLOBAL_EN        BIT(14)
 #define DEVICE_CONTROL_CONFIG_ALL_EN   BIT(13)
 
+#define VEND1_DEVICE_CONFIG            0x0048
+
+#define TJA1120_VEND1_EXT_TS_MODE      0x1012
+
 #define VEND1_PHY_IRQ_ACK              0x80A0
 #define VEND1_PHY_IRQ_EN               0x80A1
 #define VEND1_PHY_IRQ_STATUS           0x80A2
 #define MII_BASIC_CONFIG_RMII          0x5
 #define MII_BASIC_CONFIG_MII           0x4
 
+#define VEND1_SYMBOL_ERROR_CNT_XTD     0x8351
+#define EXTENDED_CNT_EN                        BIT(15)
+#define VEND1_MONITOR_STATUS           0xAC80
+#define MONITOR_RESET                  BIT(15)
+#define VEND1_MONITOR_CONFIG           0xAC86
+#define LOST_FRAMES_CNT_EN             BIT(9)
+#define ALL_FRAMES_CNT_EN              BIT(8)
+
 #define VEND1_SYMBOL_ERROR_COUNTER     0x8350
 #define VEND1_LINK_DROP_COUNTER                0x8352
 #define VEND1_LINK_LOSSES_AND_FAILURES 0x8353
 #define VEND1_RX_TS_INSRT_CTRL         0x114D
 #define TJA1103_RX_TS_INSRT_MODE2      0x02
 
+#define TJA1120_RX_TS_INSRT_CTRL       0x9012
+#define TJA1120_RX_TS_INSRT_EN         BIT(15)
+#define TJA1120_TS_INSRT_MODE          BIT(4)
+
 #define VEND1_EGR_RING_DATA_0          0x114E
 #define VEND1_EGR_RING_CTRL            0x1154
 
 #define PORT_PTP_CONTROL_BYPASS                BIT(11)
 
 #define PTP_CLK_PERIOD_100BT1          15ULL
+#define PTP_CLK_PERIOD_1000BT1         8ULL
 
 #define EVENT_MSG_FILT_ALL             0x0F
 #define EVENT_MSG_FILT_NONE            0x00
@@ -929,6 +947,27 @@ static const struct nxp_c45_phy_stats tja1103_hw_stats[] = {
                NXP_C45_REG_FIELD(0xAFD1, MDIO_MMD_VEND1, 0, 9), },
 };
 
+static const struct nxp_c45_phy_stats tja1120_hw_stats[] = {
+       { "phy_symbol_error_cnt_ext",
+               NXP_C45_REG_FIELD(0x8351, MDIO_MMD_VEND1, 0, 14) },
+       { "tx_frames_xtd",
+               NXP_C45_REG_FIELD(0xACA1, MDIO_MMD_VEND1, 0, 8), },
+       { "tx_frames",
+               NXP_C45_REG_FIELD(0xACA0, MDIO_MMD_VEND1, 0, 16), },
+       { "rx_frames_xtd",
+               NXP_C45_REG_FIELD(0xACA3, MDIO_MMD_VEND1, 0, 8), },
+       { "rx_frames",
+               NXP_C45_REG_FIELD(0xACA2, MDIO_MMD_VEND1, 0, 16), },
+       { "tx_lost_frames_xtd",
+               NXP_C45_REG_FIELD(0xACA5, MDIO_MMD_VEND1, 0, 8), },
+       { "tx_lost_frames",
+               NXP_C45_REG_FIELD(0xACA4, MDIO_MMD_VEND1, 0, 16), },
+       { "rx_lost_frames_xtd",
+               NXP_C45_REG_FIELD(0xACA7, MDIO_MMD_VEND1, 0, 8), },
+       { "rx_lost_frames",
+               NXP_C45_REG_FIELD(0xACA6, MDIO_MMD_VEND1, 0, 16), },
+};
+
 static int nxp_c45_get_sset_count(struct phy_device *phydev)
 {
        const struct nxp_c45_phy_data *phy_data = nxp_c45_get_data(phydev);
@@ -1511,6 +1550,101 @@ static const struct nxp_c45_phy_data tja1103_phy_data = {
        .ptp_enable = tja1103_ptp_enable,
 };
 
+static void tja1120_counters_enable(struct phy_device *phydev)
+{
+       phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_SYMBOL_ERROR_CNT_XTD,
+                        EXTENDED_CNT_EN);
+       phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_MONITOR_STATUS,
+                        MONITOR_RESET);
+       phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_MONITOR_CONFIG,
+                        ALL_FRAMES_CNT_EN | LOST_FRAMES_CNT_EN);
+}
+
+static void tja1120_ptp_init(struct phy_device *phydev)
+{
+       phy_write_mmd(phydev, MDIO_MMD_VEND1, TJA1120_RX_TS_INSRT_CTRL,
+                     TJA1120_RX_TS_INSRT_EN | TJA1120_TS_INSRT_MODE);
+       phy_write_mmd(phydev, MDIO_MMD_VEND1, TJA1120_VEND1_EXT_TS_MODE,
+                     TJA1120_TS_INSRT_MODE);
+       phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, VEND1_DEVICE_CONFIG,
+                        PTP_ENABLE);
+}
+
+static void tja1120_ptp_enable(struct phy_device *phydev, bool enable)
+{
+       if (enable)
+               phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+                                VEND1_PORT_FUNC_ENABLES,
+                                PTP_ENABLE);
+       else
+               phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+                                  VEND1_PORT_FUNC_ENABLES,
+                                  PTP_ENABLE);
+}
+
+static const struct nxp_c45_regmap tja1120_regmap = {
+       .vend1_ptp_clk_period   = 0x1020,
+       .vend1_event_msg_filt   = 0x9010,
+       .pps_enable             =
+               NXP_C45_REG_FIELD(0x1006, MDIO_MMD_VEND1, 4, 1),
+       .pps_polarity           =
+               NXP_C45_REG_FIELD(0x1006, MDIO_MMD_VEND1, 5, 1),
+       .ltc_lock_ctrl          =
+               NXP_C45_REG_FIELD(0x1006, MDIO_MMD_VEND1, 2, 1),
+       .ltc_read               =
+               NXP_C45_REG_FIELD(0x1000, MDIO_MMD_VEND1, 1, 1),
+       .ltc_write              =
+               NXP_C45_REG_FIELD(0x1000, MDIO_MMD_VEND1, 2, 1),
+       .vend1_ltc_wr_nsec_0    = 0x1040,
+       .vend1_ltc_wr_nsec_1    = 0x1041,
+       .vend1_ltc_wr_sec_0     = 0x1042,
+       .vend1_ltc_wr_sec_1     = 0x1043,
+       .vend1_ltc_rd_nsec_0    = 0x1048,
+       .vend1_ltc_rd_nsec_1    = 0x1049,
+       .vend1_ltc_rd_sec_0     = 0x104A,
+       .vend1_ltc_rd_sec_1     = 0x104B,
+       .vend1_rate_adj_subns_0 = 0x1030,
+       .vend1_rate_adj_subns_1 = 0x1031,
+       .irq_egr_ts_en          =
+               NXP_C45_REG_FIELD(0x900A, MDIO_MMD_VEND1, 1, 1),
+       .irq_egr_ts_status      =
+               NXP_C45_REG_FIELD(0x900C, MDIO_MMD_VEND1, 1, 1),
+       .domain_number          =
+               NXP_C45_REG_FIELD(0x9061, MDIO_MMD_VEND1, 8, 8),
+       .msg_type               =
+               NXP_C45_REG_FIELD(0x9061, MDIO_MMD_VEND1, 4, 4),
+       .sequence_id            =
+               NXP_C45_REG_FIELD(0x9062, MDIO_MMD_VEND1, 0, 16),
+       .sec_1_0                =
+               NXP_C45_REG_FIELD(0x9065, MDIO_MMD_VEND1, 0, 2),
+       .sec_4_2                =
+               NXP_C45_REG_FIELD(0x9065, MDIO_MMD_VEND1, 2, 3),
+       .nsec_15_0              =
+               NXP_C45_REG_FIELD(0x9063, MDIO_MMD_VEND1, 0, 16),
+       .nsec_29_16             =
+               NXP_C45_REG_FIELD(0x9064, MDIO_MMD_VEND1, 0, 14),
+       .vend1_ext_trg_data_0   = 0x1071,
+       .vend1_ext_trg_data_1   = 0x1072,
+       .vend1_ext_trg_data_2   = 0x1073,
+       .vend1_ext_trg_data_3   = 0x1074,
+       .vend1_ext_trg_ctrl     = 0x1075,
+       .cable_test             = 0x8360,
+       .cable_test_valid       =
+               NXP_C45_REG_FIELD(0x8361, MDIO_MMD_VEND1, 15, 1),
+       .cable_test_result      =
+               NXP_C45_REG_FIELD(0x8361, MDIO_MMD_VEND1, 0, 3),
+};
+
+static const struct nxp_c45_phy_data tja1120_phy_data = {
+       .regmap = &tja1120_regmap,
+       .stats = tja1120_hw_stats,
+       .n_stats = ARRAY_SIZE(tja1120_hw_stats),
+       .ptp_clk_period = PTP_CLK_PERIOD_1000BT1,
+       .counters_enable = tja1120_counters_enable,
+       .ptp_init = tja1120_ptp_init,
+       .ptp_enable = tja1120_ptp_enable,
+};
+
 static struct phy_driver nxp_c45_driver[] = {
        {
                PHY_ID_MATCH_MODEL(PHY_ID_TJA_1103),
@@ -1536,12 +1670,37 @@ static struct phy_driver nxp_c45_driver[] = {
                .get_sqi_max            = nxp_c45_get_sqi_max,
                .remove                 = nxp_c45_remove,
        },
+       {
+               PHY_ID_MATCH_MODEL(PHY_ID_TJA_1120),
+               .name                   = "NXP C45 TJA1120",
+               .get_features           = nxp_c45_get_features,
+               .driver_data            = &tja1120_phy_data,
+               .probe                  = nxp_c45_probe,
+               .soft_reset             = nxp_c45_soft_reset,
+               .config_aneg            = genphy_c45_config_aneg,
+               .config_init            = nxp_c45_config_init,
+               .config_intr            = nxp_c45_config_intr,
+               .handle_interrupt       = nxp_c45_handle_interrupt,
+               .read_status            = genphy_c45_read_status,
+               .suspend                = genphy_c45_pma_suspend,
+               .resume                 = genphy_c45_pma_resume,
+               .get_sset_count         = nxp_c45_get_sset_count,
+               .get_strings            = nxp_c45_get_strings,
+               .get_stats              = nxp_c45_get_stats,
+               .cable_test_start       = nxp_c45_cable_test_start,
+               .cable_test_get_status  = nxp_c45_cable_test_get_status,
+               .set_loopback           = genphy_c45_loopback,
+               .get_sqi                = nxp_c45_get_sqi,
+               .get_sqi_max            = nxp_c45_get_sqi_max,
+               .remove                 = nxp_c45_remove,
+       },
 };
 
 module_phy_driver(nxp_c45_driver);
 
 static struct mdio_device_id __maybe_unused nxp_c45_tbl[] = {
        { PHY_ID_MATCH_MODEL(PHY_ID_TJA_1103) },
+       { PHY_ID_MATCH_MODEL(PHY_ID_TJA_1120) },
        { /*sentinel*/ },
 };