Commit f1fe5dff authored by Radu Pirea (NXP OSS)'s avatar Radu Pirea (NXP OSS) Committed by Jakub Kicinski
Browse files

net: phy: nxp-c45-tja11xx: add TJA1120 support

parent 369da333
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -306,7 +306,7 @@ config NXP_C45_TJA11XX_PHY
	depends on PTP_1588_CLOCK_OPTIONAL
	depends on PTP_1588_CLOCK_OPTIONAL
	help
	help
	  Enable support for NXP C45 TJA11XX PHYs.
	  Enable support for NXP C45 TJA11XX PHYs.
	  Currently supports only the TJA1103 PHY.
	  Currently supports the TJA1103 and TJA1120 PHYs.


config NXP_TJA11XX_PHY
config NXP_TJA11XX_PHY
	tristate "NXP TJA11xx PHYs support"
	tristate "NXP TJA11xx PHYs support"
+159 −0
Original line number Original line Diff line number Diff line
@@ -18,12 +18,17 @@
#include <linux/net_tstamp.h>
#include <linux/net_tstamp.h>


#define PHY_ID_TJA_1103			0x001BB010
#define PHY_ID_TJA_1103			0x001BB010
#define PHY_ID_TJA_1120			0x001BB031


#define VEND1_DEVICE_CONTROL		0x0040
#define VEND1_DEVICE_CONTROL		0x0040
#define DEVICE_CONTROL_RESET		BIT(15)
#define DEVICE_CONTROL_RESET		BIT(15)
#define DEVICE_CONTROL_CONFIG_GLOBAL_EN	BIT(14)
#define DEVICE_CONTROL_CONFIG_GLOBAL_EN	BIT(14)
#define DEVICE_CONTROL_CONFIG_ALL_EN	BIT(13)
#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_ACK		0x80A0
#define VEND1_PHY_IRQ_EN		0x80A1
#define VEND1_PHY_IRQ_EN		0x80A1
#define VEND1_PHY_IRQ_STATUS		0x80A2
#define VEND1_PHY_IRQ_STATUS		0x80A2
@@ -76,6 +81,14 @@
#define MII_BASIC_CONFIG_RMII		0x5
#define MII_BASIC_CONFIG_RMII		0x5
#define MII_BASIC_CONFIG_MII		0x4
#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_SYMBOL_ERROR_COUNTER	0x8350
#define VEND1_LINK_DROP_COUNTER		0x8352
#define VEND1_LINK_DROP_COUNTER		0x8352
#define VEND1_LINK_LOSSES_AND_FAILURES	0x8353
#define VEND1_LINK_LOSSES_AND_FAILURES	0x8353
@@ -94,6 +107,10 @@
#define VEND1_RX_TS_INSRT_CTRL		0x114D
#define VEND1_RX_TS_INSRT_CTRL		0x114D
#define TJA1103_RX_TS_INSRT_MODE2	0x02
#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_DATA_0		0x114E
#define VEND1_EGR_RING_CTRL		0x1154
#define VEND1_EGR_RING_CTRL		0x1154


@@ -110,6 +127,7 @@
#define PORT_PTP_CONTROL_BYPASS		BIT(11)
#define PORT_PTP_CONTROL_BYPASS		BIT(11)


#define PTP_CLK_PERIOD_100BT1		15ULL
#define PTP_CLK_PERIOD_100BT1		15ULL
#define PTP_CLK_PERIOD_1000BT1		8ULL


#define EVENT_MSG_FILT_ALL		0x0F
#define EVENT_MSG_FILT_ALL		0x0F
#define EVENT_MSG_FILT_NONE		0x00
#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), },
		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)
static int nxp_c45_get_sset_count(struct phy_device *phydev)
{
{
	const struct nxp_c45_phy_data *phy_data = nxp_c45_get_data(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,
	.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[] = {
static struct phy_driver nxp_c45_driver[] = {
	{
	{
		PHY_ID_MATCH_MODEL(PHY_ID_TJA_1103),
		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,
		.get_sqi_max		= nxp_c45_get_sqi_max,
		.remove			= nxp_c45_remove,
		.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);
module_phy_driver(nxp_c45_driver);


static struct mdio_device_id __maybe_unused nxp_c45_tbl[] = {
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_1103) },
	{ PHY_ID_MATCH_MODEL(PHY_ID_TJA_1120) },
	{ /*sentinel*/ },
	{ /*sentinel*/ },
};
};