Commit 1853367b authored by Parvathi Pudi's avatar Parvathi Pudi Committed by Jakub Kicinski
Browse files

net: ti: icssm-prueth: Adds IEP support for PRUETH on AM33x, AM43x and AM57x SOCs



Added API hooks for IEP module (legacy 32-bit model) to support
timestamping requests from application.

Reviewed-by: default avatarMohan Reddy Putluru <pmohan@couthit.com>
Signed-off-by: default avatarRoger Quadros <rogerq@ti.com>
Signed-off-by: default avatarAndrew F. Davis <afd@ti.com>
Signed-off-by: default avatarBasharath Hussain Khaja <basharath@couthit.com>
Signed-off-by: default avatarParvathi Pudi <parvathi@couthit.com>
Link: https://patch.msgid.link/20250912115443.529856-6-parvathi@couthit.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent e15472e8
Loading
Loading
Loading
Loading
+101 −0
Original line number Diff line number Diff line
@@ -982,11 +982,112 @@ static const struct icss_iep_plat_data am654_icss_iep_plat_data = {
	.config = &am654_icss_iep_regmap_config,
};

static const struct icss_iep_plat_data am57xx_icss_iep_plat_data = {
	.flags = ICSS_IEP_64BIT_COUNTER_SUPPORT |
		 ICSS_IEP_SLOW_COMPEN_REG_SUPPORT,
	.reg_offs = {
		[ICSS_IEP_GLOBAL_CFG_REG] = 0x00,
		[ICSS_IEP_COMPEN_REG] = 0x08,
		[ICSS_IEP_SLOW_COMPEN_REG] = 0x0c,
		[ICSS_IEP_COUNT_REG0] = 0x10,
		[ICSS_IEP_COUNT_REG1] = 0x14,
		[ICSS_IEP_CAPTURE_CFG_REG] = 0x18,
		[ICSS_IEP_CAPTURE_STAT_REG] = 0x1c,

		[ICSS_IEP_CAP6_RISE_REG0] = 0x50,
		[ICSS_IEP_CAP6_RISE_REG1] = 0x54,

		[ICSS_IEP_CAP7_RISE_REG0] = 0x60,
		[ICSS_IEP_CAP7_RISE_REG1] = 0x64,

		[ICSS_IEP_CMP_CFG_REG] = 0x70,
		[ICSS_IEP_CMP_STAT_REG] = 0x74,
		[ICSS_IEP_CMP0_REG0] = 0x78,
		[ICSS_IEP_CMP0_REG1] = 0x7c,
		[ICSS_IEP_CMP1_REG0] = 0x80,
		[ICSS_IEP_CMP1_REG1] = 0x84,

		[ICSS_IEP_CMP8_REG0] = 0xc0,
		[ICSS_IEP_CMP8_REG1] = 0xc4,
		[ICSS_IEP_SYNC_CTRL_REG] = 0x180,
		[ICSS_IEP_SYNC0_STAT_REG] = 0x188,
		[ICSS_IEP_SYNC1_STAT_REG] = 0x18c,
		[ICSS_IEP_SYNC_PWIDTH_REG] = 0x190,
		[ICSS_IEP_SYNC0_PERIOD_REG] = 0x194,
		[ICSS_IEP_SYNC1_DELAY_REG] = 0x198,
		[ICSS_IEP_SYNC_START_REG] = 0x19c,
	},
	.config = &am654_icss_iep_regmap_config,
};

static bool am335x_icss_iep_valid_reg(struct device *dev, unsigned int reg)
{
	switch (reg) {
	case ICSS_IEP_GLOBAL_CFG_REG ... ICSS_IEP_CAPTURE_STAT_REG:
	case ICSS_IEP_CAP6_RISE_REG0:
	case ICSS_IEP_CMP_CFG_REG ... ICSS_IEP_CMP0_REG0:
	case ICSS_IEP_CMP8_REG0 ... ICSS_IEP_SYNC_START_REG:
		return true;
	default:
		return false;
	}
}

static const struct regmap_config am335x_icss_iep_regmap_config = {
	.name = "icss iep",
	.reg_stride = 1,
	.reg_write = icss_iep_regmap_write,
	.reg_read = icss_iep_regmap_read,
	.writeable_reg = am335x_icss_iep_valid_reg,
	.readable_reg = am335x_icss_iep_valid_reg,
};

static const struct icss_iep_plat_data am335x_icss_iep_plat_data = {
	.flags = 0,
	.reg_offs = {
		[ICSS_IEP_GLOBAL_CFG_REG] = 0x00,
		[ICSS_IEP_COMPEN_REG] = 0x08,
		[ICSS_IEP_COUNT_REG0] = 0x0c,
		[ICSS_IEP_CAPTURE_CFG_REG] = 0x10,
		[ICSS_IEP_CAPTURE_STAT_REG] = 0x14,

		[ICSS_IEP_CAP6_RISE_REG0] = 0x30,

		[ICSS_IEP_CAP7_RISE_REG0] = 0x38,

		[ICSS_IEP_CMP_CFG_REG] = 0x40,
		[ICSS_IEP_CMP_STAT_REG] = 0x44,
		[ICSS_IEP_CMP0_REG0] = 0x48,

		[ICSS_IEP_CMP8_REG0] = 0x88,
		[ICSS_IEP_SYNC_CTRL_REG] = 0x100,
		[ICSS_IEP_SYNC0_STAT_REG] = 0x108,
		[ICSS_IEP_SYNC1_STAT_REG] = 0x10c,
		[ICSS_IEP_SYNC_PWIDTH_REG] = 0x110,
		[ICSS_IEP_SYNC0_PERIOD_REG] = 0x114,
		[ICSS_IEP_SYNC1_DELAY_REG] = 0x118,
		[ICSS_IEP_SYNC_START_REG] = 0x11c,
	},
	.config = &am335x_icss_iep_regmap_config,
};

static const struct of_device_id icss_iep_of_match[] = {
	{
		.compatible = "ti,am654-icss-iep",
		.data = &am654_icss_iep_plat_data,
	},
	{
		.compatible = "ti,am5728-icss-iep",
		.data = &am57xx_icss_iep_plat_data,
	},
	{
		.compatible = "ti,am4376-icss-iep",
		.data = &am335x_icss_iep_plat_data,
	},
	{
		.compatible = "ti,am3356-icss-iep",
		.data = &am335x_icss_iep_plat_data,
	},
	{},
};
MODULE_DEVICE_TABLE(of, icss_iep_of_match);
+72 −2
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@

#include "icssm_prueth.h"
#include "../icssg/icssg_mii_rt.h"
#include "../icssg/icss_iep.h"

#define OCMC_RAM_SIZE		(SZ_64K)

@@ -878,6 +879,48 @@ static int icssm_emac_request_irqs(struct prueth_emac *emac)
	return ret;
}

static void icssm_ptp_dram_init(struct prueth_emac *emac)
{
	void __iomem *sram = emac->prueth->mem[PRUETH_MEM_SHARED_RAM].va;
	u64 temp64;

	writew(0, sram + MII_RX_CORRECTION_OFFSET);
	writew(0, sram + MII_TX_CORRECTION_OFFSET);

	/* Initialize RCF to 1 (Linux N/A) */
	writel(1 * 1024, sram + TIMESYNC_TC_RCF_OFFSET);

	/* This flag will be set and cleared by firmware */
	/* Write Sync0 period for sync signal generation in PTP
	 * memory in shared RAM
	 */
	writel(200000000 / 50, sram + TIMESYNC_SYNC0_WIDTH_OFFSET);

	/* Write CMP1 period for sync signal generation in PTP
	 * memory in shared RAM
	 */
	temp64 = 1000000;
	memcpy_toio(sram + TIMESYNC_CMP1_CMP_OFFSET, &temp64, sizeof(temp64));

	/* Write Sync0 period for sync signal generation in PTP
	 * memory in shared RAM
	 */
	writel(1000000, sram + TIMESYNC_CMP1_PERIOD_OFFSET);

	/* Configures domainNumber list. Firmware supports 2 domains */
	writeb(0, sram + TIMESYNC_DOMAIN_NUMBER_LIST);
	writeb(0, sram + TIMESYNC_DOMAIN_NUMBER_LIST + 1);

	/* Configure 1-step/2-step */
	writeb(1, sram + DISABLE_SWITCH_SYNC_RELAY_OFFSET);

	/* Configures the setting to Link local frame without HSR tag */
	writeb(0, sram + LINK_LOCAL_FRAME_HAS_HSR_TAG);

	/* Enable E2E/UDP PTP message timestamping */
	writeb(1, sram + PTP_IPV4_UDP_E2E_ENABLE);
}

/**
 * icssm_emac_ndo_open - EMAC device open
 * @ndev: network adapter device
@@ -900,9 +943,18 @@ static int icssm_emac_ndo_open(struct net_device *ndev)

	icssm_prueth_emac_config(emac);

	if (!prueth->emac_configured) {
		icssm_ptp_dram_init(emac);
		ret = icss_iep_init(prueth->iep, NULL, NULL, 0);
		if (ret) {
			netdev_err(ndev, "Failed to initialize iep: %d\n", ret);
			goto iep_exit;
		}
	}

	ret = icssm_emac_set_boot_pru(emac, ndev);
	if (ret)
		return ret;
		goto iep_exit;

	ret = icssm_emac_request_irqs(emac);
	if (ret)
@@ -926,6 +978,10 @@ static int icssm_emac_ndo_open(struct net_device *ndev)
rproc_shutdown:
	rproc_shutdown(emac->pru);

iep_exit:
	if (!prueth->emac_configured)
		icss_iep_exit(prueth->iep);

	return ret;
}

@@ -1442,12 +1498,19 @@ static int icssm_prueth_probe(struct platform_device *pdev)
		}
	}

	prueth->iep = icss_iep_get(np);
	if (IS_ERR(prueth->iep)) {
		ret = PTR_ERR(prueth->iep);
		dev_err(dev, "unable to get IEP\n");
		goto netdev_exit;
	}

	/* register the network devices */
	if (eth0_node) {
		ret = register_netdev(prueth->emac[PRUETH_MAC0]->ndev);
		if (ret) {
			dev_err(dev, "can't register netdev for port MII0");
			goto netdev_exit;
			goto iep_put;
		}

		prueth->registered_netdevs[PRUETH_MAC0] =
@@ -1481,6 +1544,10 @@ static int icssm_prueth_probe(struct platform_device *pdev)
		unregister_netdev(prueth->registered_netdevs[i]);
	}

iep_put:
	icss_iep_put(prueth->iep);
	prueth->iep = NULL;

netdev_exit:
	for (i = 0; i < PRUETH_NUM_MACS; i++) {
		eth_node = prueth->eth_node[i];
@@ -1549,6 +1616,9 @@ static void icssm_prueth_remove(struct platform_device *pdev)
						 &prueth->mem[i]);
	}

	icss_iep_put(prueth->iep);
	prueth->iep = NULL;

	pruss_put(prueth->pruss);

	if (prueth->eth_node[PRUETH_MAC0])
+2 −0
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/remoteproc/pruss.h>

#include "icssm_switch.h"
#include "icssm_prueth_ptp.h"

/* ICSSM size of redundancy tag */
#define ICSSM_LRE_TAG_SIZE	6
@@ -238,6 +239,7 @@ struct prueth {
	struct pruss_mem_region mem[PRUETH_MEM_MAX];
	struct gen_pool *sram_pool;
	struct regmap *mii_rt;
	struct icss_iep *iep;

	const struct prueth_private_data *fw_data;
	struct prueth_fw_offsets *fw_offsets;
+85 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (C) 2020-2021 Texas Instruments Incorporated - https://www.ti.com
 */
#ifndef PRUETH_PTP_H
#define PRUETH_PTP_H

#define RX_SYNC_TIMESTAMP_OFFSET_P1		0x8    /* 8 bytes */
#define RX_PDELAY_REQ_TIMESTAMP_OFFSET_P1	0x14   /* 12 bytes */

#define DISABLE_PTP_FRAME_FORWARDING_CTRL_OFFSET 0x14	/* 1 byte */

#define RX_PDELAY_RESP_TIMESTAMP_OFFSET_P1	0x20   /* 12 bytes */
#define RX_SYNC_TIMESTAMP_OFFSET_P2		0x2c   /* 12 bytes */
#define RX_PDELAY_REQ_TIMESTAMP_OFFSET_P2	0x38   /* 12 bytes */
#define RX_PDELAY_RESP_TIMESTAMP_OFFSET_P2	0x44   /* 12 bytes */
#define TIMESYNC_DOMAIN_NUMBER_LIST		0x50   /* 2 bytes */
#define P1_SMA_LINE_DELAY_OFFSET		0x52   /* 4 bytes */
#define P2_SMA_LINE_DELAY_OFFSET		0x56   /* 4 bytes */
#define TIMESYNC_SECONDS_COUNT_OFFSET		0x5a   /* 6 bytes */
#define TIMESYNC_TC_RCF_OFFSET			0x60   /* 4 bytes */
#define DUT_IS_MASTER_OFFSET			0x64   /* 1 byte */
#define MASTER_PORT_NUM_OFFSET			0x65   /* 1 byte */
#define SYNC_MASTER_MAC_OFFSET			0x66   /* 6 bytes */
#define TX_TS_NOTIFICATION_OFFSET_SYNC_P1	0x6c   /* 1 byte */
#define TX_TS_NOTIFICATION_OFFSET_PDEL_REQ_P1	0x6d   /* 1 byte */
#define TX_TS_NOTIFICATION_OFFSET_PDEL_RES_P1	0x6e   /* 1 byte */
#define TX_TS_NOTIFICATION_OFFSET_SYNC_P2	0x6f   /* 1 byte */
#define TX_TS_NOTIFICATION_OFFSET_PDEL_REQ_P2	0x70   /* 1 byte */
#define TX_TS_NOTIFICATION_OFFSET_PDEL_RES_P2	0x71   /* 1 byte */
#define TX_SYNC_TIMESTAMP_OFFSET_P1		0x72   /* 12 bytes */
#define TX_PDELAY_REQ_TIMESTAMP_OFFSET_P1	0x7e   /* 12 bytes */
#define TX_PDELAY_RESP_TIMESTAMP_OFFSET_P1	0x8a   /* 12 bytes */
#define TX_SYNC_TIMESTAMP_OFFSET_P2		0x96   /* 12 bytes */
#define TX_PDELAY_REQ_TIMESTAMP_OFFSET_P2	0xa2   /* 12 bytes */
#define TX_PDELAY_RESP_TIMESTAMP_OFFSET_P2	0xae   /* 12 bytes */
#define TIMESYNC_CTRL_VAR_OFFSET		0xba   /* 1 byte */
#define DISABLE_SWITCH_SYNC_RELAY_OFFSET	0xbb   /* 1 byte */
#define MII_RX_CORRECTION_OFFSET		0xbc   /* 2 bytes */
#define MII_TX_CORRECTION_OFFSET		0xbe   /* 2 bytes */
#define TIMESYNC_CMP1_CMP_OFFSET		0xc0   /* 8 bytes */
#define TIMESYNC_SYNC0_CMP_OFFSET		0xc8   /* 8 bytes */
#define TIMESYNC_CMP1_PERIOD_OFFSET		0xd0   /* 4 bytes */
#define TIMESYNC_SYNC0_WIDTH_OFFSET		0xd4   /* 4 bytes */
#define SINGLE_STEP_IEP_OFFSET_P1		0xd8   /* 8 bytes */
#define SINGLE_STEP_SECONDS_OFFSET_P1		0xe0   /* 8 bytes */
#define SINGLE_STEP_IEP_OFFSET_P2		0xe8   /* 8 bytes */
#define SINGLE_STEP_SECONDS_OFFSET_P2		0xf0   /* 8 bytes */
#define LINK_LOCAL_FRAME_HAS_HSR_TAG		0xf8   /* 1 bytes */
#define PTP_PREV_TX_TIMESTAMP_P1		0xf9  /* 8 bytes */
#define PTP_PREV_TX_TIMESTAMP_P2		0x101  /* 8 bytes */
#define PTP_CLK_IDENTITY_OFFSET			0x109  /* 8 bytes */
#define PTP_SCRATCH_MEM				0x111  /* 16 byte */
#define PTP_IPV4_UDP_E2E_ENABLE			0x121  /* 1 byte */

enum {
	PRUETH_PTP_SYNC,
	PRUETH_PTP_DLY_REQ,
	PRUETH_PTP_DLY_RESP,
	PRUETH_PTP_TS_EVENTS,
};

#define PRUETH_PTP_TS_SIZE		12
#define PRUETH_PTP_TS_NOTIFY_SIZE	1
#define PRUETH_PTP_TS_NOTIFY_MASK	0xff

/* Bit definitions for TIMESYNC_CTRL */
#define TIMESYNC_CTRL_BG_ENABLE    BIT(0)
#define TIMESYNC_CTRL_FORCED_2STEP BIT(1)

static inline u32 icssm_prueth_tx_ts_offs_get(u8 port, u8 event)
{
	return TX_SYNC_TIMESTAMP_OFFSET_P1 + port *
		PRUETH_PTP_TS_EVENTS * PRUETH_PTP_TS_SIZE +
		event * PRUETH_PTP_TS_SIZE;
}

static inline u32 icssm_prueth_tx_ts_notify_offs_get(u8 port, u8 event)
{
	return TX_TS_NOTIFICATION_OFFSET_SYNC_P1 +
		PRUETH_PTP_TS_EVENTS * PRUETH_PTP_TS_NOTIFY_SIZE * port +
		event * PRUETH_PTP_TS_NOTIFY_SIZE;
}

#endif /* PRUETH_PTP_H */