mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-03-22 07:27:12 +08:00
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: Mohan Reddy Putluru <pmohan@couthit.com> Signed-off-by: Roger Quadros <rogerq@ti.com> Signed-off-by: Andrew F. Davis <afd@ti.com> Signed-off-by: Basharath Hussain Khaja <basharath@couthit.com> Signed-off-by: Parvathi Pudi <parvathi@couthit.com> Link: https://patch.msgid.link/20250912115443.529856-6-parvathi@couthit.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
e15472e8f2
commit
1853367b76
@@ -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);
|
||||
|
||||
@@ -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 @@ netdev_unregister:
|
||||
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])
|
||||
|
||||
@@ -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
drivers/net/ethernet/ti/icssm/icssm_prueth_ptp.h
Normal file
85
drivers/net/ethernet/ti/icssm/icssm_prueth_ptp.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/* 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 */
|
||||
Reference in New Issue
Block a user