[PATCH v2 8/8] net: ti: icssg-prueth: Wire up support for SR1.0
Diogo Ivo
diogo.ivo at siemens.com
Wed Jan 17 08:15:02 PST 2024
Add the function calls to enable operation for SR1.0.
Based on the work of Roger Quadros, Vignesh Raghavendra and
Grygorii Strashko in TI's 5.10 SDK [1].
[1]: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/?h=ti-linux-5.10.y
Co-developed-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
Signed-off-by: Diogo Ivo <diogo.ivo at siemens.com>
---
Changes in v2:
- Removed explicit references to SR2.0
drivers/net/ethernet/ti/icssg/icssg_prueth.c | 299 +++++++++++++++----
1 file changed, 239 insertions(+), 60 deletions(-)
diff --git a/drivers/net/ethernet/ti/icssg/icssg_prueth.c b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
index db15c8680741..352fb1cb3aba 100644
--- a/drivers/net/ethernet/ti/icssg/icssg_prueth.c
+++ b/drivers/net/ethernet/ti/icssg/icssg_prueth.c
@@ -169,6 +169,13 @@ static int emac_tx_complete_packets(struct prueth_emac *emac, int chn,
desc_dma);
swdata = cppi5_hdesc_get_swdata(desc_tx);
+ /* was this command's TX complete? */
+ if (emac->is_sr1 && *(swdata) == emac->cmd_data) {
+ prueth_xmit_free(tx_chn, desc_tx);
+ budget++; /* not a data packet */
+ continue;
+ }
+
skb = *(swdata);
prueth_xmit_free(tx_chn, desc_tx);
@@ -344,6 +351,7 @@ static int prueth_init_rx_chns(struct prueth_emac *emac,
struct net_device *ndev = emac->ndev;
u32 fdqring_id, hdesc_size;
int i, ret = 0, slice;
+ int flow_id_base;
slice = prueth_emac_slice(emac);
if (slice < 0)
@@ -384,8 +392,14 @@ static int prueth_init_rx_chns(struct prueth_emac *emac,
goto fail;
}
- emac->rx_flow_id_base = k3_udma_glue_rx_get_flow_id_base(rx_chn->rx_chn);
- netdev_dbg(ndev, "flow id base = %d\n", emac->rx_flow_id_base);
+ flow_id_base = k3_udma_glue_rx_get_flow_id_base(rx_chn->rx_chn);
+ if (!strcmp(name, "rxmgm")) {
+ emac->rx_mgm_flow_id_base = flow_id_base;
+ netdev_dbg(ndev, "mgm flow id base = %d\n", flow_id_base);
+ } else {
+ emac->rx_flow_id_base = flow_id_base;
+ netdev_dbg(ndev, "flow id base = %d\n", flow_id_base);
+ }
fdqring_id = K3_RINGACC_RING_ID_ANY;
for (i = 0; i < rx_cfg.flow_id_num; i++) {
@@ -494,10 +508,14 @@ static void emac_rx_timestamp(struct prueth_emac *emac,
struct skb_shared_hwtstamps *ssh;
u64 ns;
- u32 hi_sw = readl(emac->prueth->shram.va +
- TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET);
- ns = icssg_ts_to_ns(hi_sw, psdata[1], psdata[0],
- IEP_DEFAULT_CYCLE_TIME_NS);
+ if (emac->is_sr1) {
+ ns = (u64)psdata[1] << 32 | psdata[0];
+ } else {
+ u32 hi_sw = readl(emac->prueth->shram.va +
+ TIMESYNC_FW_WC_COUNT_HI_SW_OFFSET_OFFSET);
+ ns = icssg_ts_to_ns(hi_sw, psdata[1], psdata[0],
+ IEP_DEFAULT_CYCLE_TIME_NS);
+ }
ssh = skb_hwtstamps(skb);
memset(ssh, 0, sizeof(*ssh));
@@ -1119,6 +1137,17 @@ struct icssg_firmwares {
char *txpru;
};
+static struct icssg_firmwares icssg_emac_firmwares_sr1[] = {
+ {
+ .pru = "ti-pruss/am65x-pru0-prueth-fw.elf",
+ .rtu = "ti-pruss/am65x-rtu0-prueth-fw.elf",
+ },
+ {
+ .pru = "ti-pruss/am65x-pru1-prueth-fw.elf",
+ .rtu = "ti-pruss/am65x-rtu1-prueth-fw.elf",
+ }
+};
+
static struct icssg_firmwares icssg_emac_firmwares[] = {
{
.pru = "ti-pruss/am65x-sr2-pru0-prueth-fw.elf",
@@ -1138,7 +1167,8 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
struct device *dev = prueth->dev;
int slice, ret;
- firmwares = icssg_emac_firmwares;
+ firmwares = prueth->pdata.is_sr1 ? icssg_emac_firmwares_sr1
+ : icssg_emac_firmwares;
slice = prueth_emac_slice(emac);
if (slice < 0) {
@@ -1164,11 +1194,15 @@ static int prueth_emac_start(struct prueth *prueth, struct prueth_emac *emac)
goto halt_pru;
}
- ret = rproc_set_firmware(prueth->txpru[slice], firmwares[slice].txpru);
- ret = rproc_boot(prueth->txpru[slice]);
- if (ret) {
- dev_err(dev, "failed to boot TX_PRU%d: %d\n", slice, ret);
- goto halt_rtu;
+ if (!emac->is_sr1) {
+ ret = rproc_set_firmware(prueth->txpru[slice],
+ firmwares[slice].txpru);
+ ret = rproc_boot(prueth->txpru[slice]);
+ if (ret) {
+ dev_err(dev, "failed to boot TX_PRU%d: %d\n",
+ slice, ret);
+ goto halt_rtu;
+ }
}
emac->fw_running = 1;
@@ -1201,7 +1235,8 @@ static void prueth_emac_stop(struct prueth_emac *emac)
}
emac->fw_running = 0;
- rproc_shutdown(prueth->txpru[slice]);
+ if (!emac->is_sr1)
+ rproc_shutdown(prueth->txpru[slice]);
rproc_shutdown(prueth->rtu[slice]);
rproc_shutdown(prueth->pru[slice]);
}
@@ -1269,11 +1304,15 @@ static void emac_adjust_link(struct net_device *ndev)
icssg_config_ipg(emac);
spin_unlock_irqrestore(&emac->lock, flags);
icssg_config_set_speed(emac);
- emac_set_port_state(emac, ICSSG_EMAC_PORT_FORWARD);
+ if (!emac->is_sr1)
+ emac_set_port_state(emac, ICSSG_EMAC_PORT_FORWARD);
- } else {
+ } else if (!emac->is_sr1) {
emac_set_port_state(emac, ICSSG_EMAC_PORT_DISABLE);
}
+
+ if (emac->is_sr1 && emac->link)
+ emac_change_port_speed_duplex_sr1(emac);
}
if (emac->link) {
@@ -1288,8 +1327,10 @@ static void emac_adjust_link(struct net_device *ndev)
static int emac_napi_rx_poll(struct napi_struct *napi_rx, int budget)
{
struct prueth_emac *emac = prueth_napi_to_emac(napi_rx);
- int rx_flow = PRUETH_RX_FLOW_DATA;
- int flow = PRUETH_MAX_RX_FLOWS;
+ int rx_flow = emac->is_sr1 ?
+ PRUETH_RX_FLOW_DATA_SR1 : PRUETH_RX_FLOW_DATA;
+ int flow = emac->is_sr1 ?
+ PRUETH_MAX_RX_FLOWS_SR1 : PRUETH_MAX_RX_FLOWS;
int num_rx = 0;
int cur_budget;
int ret;
@@ -1553,11 +1594,19 @@ static int emac_ndo_open(struct net_device *ndev)
memset_io(prueth->shram.va, 0, ICSSG_CONFIG_OFFSET_SLICE1 * PRUETH_NUM_MACS);
}
+ if (emac->is_sr1) {
+ /* For SR1, high priority channel is used exclusively for
+ * management messages. Do reduce number of data channels.
+ */
+ num_data_chn--;
+ }
+
/* set h/w MAC as user might have re-configured */
ether_addr_copy(emac->mac_addr, ndev->dev_addr);
icssg_class_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
- icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
+ if (!emac->is_sr1)
+ icssg_ft1_set_mac_addr(prueth->miig_rt, slice, emac->mac_addr);
icssg_class_default(prueth->miig_rt, slice, 0, emac->is_sr1);
@@ -1575,7 +1624,8 @@ static int emac_ndo_open(struct net_device *ndev)
return ret;
}
- max_rx_flows = PRUETH_MAX_RX_FLOWS;
+ max_rx_flows = emac->is_sr1 ?
+ PRUETH_MAX_RX_FLOWS_SR1 : PRUETH_MAX_RX_FLOWS;
ret = prueth_init_rx_chns(emac, &emac->rx_chns, "rx",
max_rx_flows, PRUETH_MAX_RX_DESC);
if (ret) {
@@ -1583,12 +1633,24 @@ static int emac_ndo_open(struct net_device *ndev)
goto cleanup_tx;
}
+ if (emac->is_sr1) {
+ ret = prueth_init_rx_chns(emac, &emac->rx_mgm_chn, "rxmgm",
+ PRUETH_MAX_RX_MGM_FLOWS,
+ PRUETH_MAX_RX_MGM_DESC);
+ if (ret) {
+ dev_err(dev, "failed to init rx mgmt channel: %d\n",
+ ret);
+ goto cleanup_rx;
+ }
+ }
+
ret = prueth_ndev_add_tx_napi(emac);
if (ret)
- goto cleanup_rx;
+ goto cleanup_rx_mgm;
/* we use only the highest priority flow for now i.e. @irq[3] */
- rx_flow = PRUETH_RX_FLOW_DATA;
+ rx_flow = emac->is_sr1 ?
+ PRUETH_RX_FLOW_DATA_SR1 : PRUETH_RX_FLOW_DATA;
ret = request_irq(emac->rx_chns.irq[rx_flow], prueth_rx_irq,
IRQF_TRIGGER_HIGH, dev_name(dev), emac);
if (ret) {
@@ -1596,31 +1658,66 @@ static int emac_ndo_open(struct net_device *ndev)
goto cleanup_napi;
}
+ if (!emac->is_sr1)
+ goto skip_mgm_irq;
+
+ ret = request_threaded_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_RESPONSE],
+ NULL, prueth_rx_mgm_rsp_thread,
+ IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
+ dev_name(dev), emac);
+ if (ret) {
+ dev_err(dev, "unable to request RX Management RSP IRQ\n");
+ goto free_rx_irq;
+ }
+
+ ret = request_threaded_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_TIMESTAMP],
+ NULL, prueth_rx_mgm_ts_thread_sr1,
+ IRQF_ONESHOT | IRQF_TRIGGER_HIGH,
+ dev_name(dev), emac);
+ if (ret) {
+ dev_err(dev, "unable to request RX Management TS IRQ\n");
+ goto free_rx_mgm_rsp_irq;
+ }
+
+skip_mgm_irq:
/* reset and start PRU firmware */
ret = prueth_emac_start(prueth, emac);
if (ret)
- goto free_rx_irq;
+ goto free_rx_mgmt_ts_irq;
icssg_mii_update_mtu(prueth->mii_rt, slice, ndev->max_mtu);
- if (!prueth->emacs_initialized) {
+ if (!emac->is_sr1 && !prueth->emacs_initialized) {
ret = icss_iep_init(emac->iep, &prueth_iep_clockops,
emac, IEP_DEFAULT_CYCLE_TIME_NS);
}
- ret = request_threaded_irq(emac->tx_ts_irq, NULL, prueth_tx_ts_irq,
- IRQF_ONESHOT, dev_name(dev), emac);
- if (ret)
- goto stop;
+ if (!emac->is_sr1) {
+ ret = request_threaded_irq(emac->tx_ts_irq, NULL,
+ prueth_tx_ts_irq, IRQF_ONESHOT,
+ dev_name(dev), emac);
+ if (ret)
+ goto stop;
+ }
/* Prepare RX */
ret = prueth_prepare_rx_chan(emac, &emac->rx_chns, PRUETH_MAX_PKT_SIZE);
if (ret)
goto free_tx_ts_irq;
+ if (emac->is_sr1) {
+ ret = prueth_prepare_rx_chan(emac, &emac->rx_mgm_chn, 64);
+ if (ret)
+ goto reset_rx_chn;
+
+ ret = k3_udma_glue_enable_rx_chn(emac->rx_mgm_chn.rx_chn);
+ if (ret)
+ goto reset_rx_chn;
+ }
+
ret = k3_udma_glue_enable_rx_chn(emac->rx_chns.rx_chn);
if (ret)
- goto reset_rx_chn;
+ goto reset_rx_mgm_chn;
for (i = 0; i < emac->tx_ch_num; i++) {
ret = k3_udma_glue_enable_tx_chn(emac->tx_chns[i].tx_chn);
@@ -1647,16 +1744,33 @@ static int emac_ndo_open(struct net_device *ndev)
* any SKB for completion. So set false to free_skb
*/
prueth_reset_tx_chan(emac, i, false);
+reset_rx_mgm_chn:
+ if (emac->is_sr1)
+ prueth_reset_rx_chan(&emac->rx_mgm_chn,
+ PRUETH_MAX_RX_MGM_FLOWS, true);
reset_rx_chn:
prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, false);
free_tx_ts_irq:
- free_irq(emac->tx_ts_irq, emac);
+ if (!emac->is_sr1)
+ free_irq(emac->tx_ts_irq, emac);
stop:
prueth_emac_stop(emac);
+free_rx_mgmt_ts_irq:
+ if (emac->is_sr1)
+ free_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_TIMESTAMP],
+ emac);
+free_rx_mgm_rsp_irq:
+ if (emac->is_sr1)
+ free_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_RESPONSE],
+ emac);
free_rx_irq:
free_irq(emac->rx_chns.irq[rx_flow], emac);
cleanup_napi:
prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
+cleanup_rx_mgm:
+ if (emac->is_sr1)
+ prueth_cleanup_rx_chns(emac, &emac->rx_mgm_chn,
+ PRUETH_MAX_RX_MGM_FLOWS);
cleanup_rx:
prueth_cleanup_rx_chns(emac, &emac->rx_chns, max_rx_flows);
cleanup_tx:
@@ -1677,7 +1791,8 @@ static int emac_ndo_stop(struct net_device *ndev)
{
struct prueth_emac *emac = netdev_priv(ndev);
struct prueth *prueth = emac->prueth;
- int rx_flow = PRUETH_RX_FLOW_DATA;
+ int rx_flow = emac->is_sr1 ? PRUETH_RX_FLOW_DATA_SR1 :
+ PRUETH_RX_FLOW_DATA;
int max_rx_flows;
int ret, i;
@@ -1690,6 +1805,9 @@ static int emac_ndo_stop(struct net_device *ndev)
icssg_class_disable(prueth->miig_rt, prueth_emac_slice(emac));
+ if (emac->is_sr1)
+ emac_send_command_sr1(emac, ICSSG_SHUTDOWN_CMD);
+
atomic_set(&emac->tdown_cnt, emac->tx_ch_num);
/* ensure new tdown_cnt value is visible */
smp_mb__after_atomic();
@@ -1707,10 +1825,17 @@ static int emac_ndo_stop(struct net_device *ndev)
for (i = 0; i < emac->tx_ch_num; i++)
napi_disable(&emac->tx_chns[i].napi_tx);
- max_rx_flows = PRUETH_MAX_RX_FLOWS;
+ max_rx_flows = emac->is_sr1 ?
+ PRUETH_MAX_RX_FLOWS_SR1 : PRUETH_MAX_RX_FLOWS;
k3_udma_glue_tdown_rx_chn(emac->rx_chns.rx_chn, true);
prueth_reset_rx_chan(&emac->rx_chns, max_rx_flows, true);
+ if (emac->is_sr1) {
+ /* Teardown RX MGM channel */
+ k3_udma_glue_tdown_rx_chn(emac->rx_mgm_chn.rx_chn, true);
+ prueth_reset_rx_chan(&emac->rx_mgm_chn,
+ PRUETH_MAX_RX_MGM_FLOWS, true);
+ }
napi_disable(&emac->napi_rx);
@@ -1722,18 +1847,28 @@ static int emac_ndo_stop(struct net_device *ndev)
/* stop PRUs */
prueth_emac_stop(emac);
- if (prueth->emacs_initialized == 1)
+ if (!emac->is_sr1 && prueth->emacs_initialized == 1)
icss_iep_exit(emac->iep);
/* stop PRUs */
prueth_emac_stop(emac);
- free_irq(emac->tx_ts_irq, emac);
+ if (!emac->is_sr1)
+ free_irq(emac->tx_ts_irq, emac);
+ if (emac->is_sr1) {
+ free_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_TIMESTAMP],
+ emac);
+ free_irq(emac->rx_mgm_chn.irq[PRUETH_RX_MGM_FLOW_RESPONSE],
+ emac);
+ }
free_irq(emac->rx_chns.irq[rx_flow], emac);
prueth_ndev_del_tx_napi(emac, emac->tx_ch_num);
prueth_cleanup_tx_chns(emac);
+ if (emac->is_sr1)
+ prueth_cleanup_rx_chns(emac, &emac->rx_mgm_chn,
+ PRUETH_MAX_RX_MGM_FLOWS);
prueth_cleanup_rx_chns(emac, &emac->rx_chns, max_rx_flows);
prueth_cleanup_tx_chns(emac);
@@ -1814,7 +1949,10 @@ static void emac_ndo_set_rx_mode(struct net_device *ndev)
{
struct prueth_emac *emac = netdev_priv(ndev);
- queue_work(emac->cmd_wq, &emac->rx_mode_work);
+ if (emac->is_sr1)
+ emac_ndo_set_rx_mode_sr1(ndev);
+ else
+ queue_work(emac->cmd_wq, &emac->rx_mode_work);
}
static int emac_set_ts_config(struct net_device *ndev, struct ifreq *ifr)
@@ -1994,6 +2132,10 @@ static int prueth_netdev_init(struct prueth *prueth,
if (mac == PRUETH_MAC_INVALID)
return -EINVAL;
+ /* Use 1 channel for management messages on SR1 */
+ if (prueth->pdata.is_sr1)
+ num_tx_chn--;
+
ndev = alloc_etherdev_mq(sizeof(*emac), num_tx_chn);
if (!ndev)
return -ENOMEM;
@@ -2021,7 +2163,15 @@ static int prueth_netdev_init(struct prueth *prueth,
goto free_wq;
}
+ emac->is_sr1 = prueth->pdata.is_sr1;
emac->tx_ch_num = 1;
+ if (emac->is_sr1) {
+ /* use a dedicated high priority channel for management
+ * messages which is +1 of highest priority data channel.
+ */
+ emac->tx_ch_num++;
+ goto skip_irq;
+ }
irq_name = "tx_ts0";
if (emac->port_id == PRUETH_PORT_MII1)
@@ -2032,6 +2182,7 @@ static int prueth_netdev_init(struct prueth *prueth,
goto free;
}
+skip_irq:
SET_NETDEV_DEV(ndev, prueth->dev);
spin_lock_init(&emac->lock);
mutex_init(&emac->cmd_lock);
@@ -2158,7 +2309,7 @@ static int prueth_get_cores(struct prueth *prueth, int slice)
idx = 0;
break;
case ICSS_SLICE1:
- idx = 3;
+ idx = prueth->pdata.is_sr1 ? 2 : 3;
break;
default:
return -EINVAL;
@@ -2180,6 +2331,9 @@ static int prueth_get_cores(struct prueth *prueth, int slice)
return dev_err_probe(dev, ret, "unable to get RTU%d\n", slice);
}
+ if (prueth->pdata.is_sr1)
+ return 0;
+
idx++;
prueth->txpru[slice] = pru_rproc_get(np, idx, NULL);
if (IS_ERR(prueth->txpru[slice])) {
@@ -2329,14 +2483,20 @@ static int prueth_probe(struct platform_device *pdev)
goto put_mem;
}
- msmc_ram_size = MSMC_RAM_SIZE;
+ msmc_ram_size = prueth->pdata.is_sr1 ? MSMC_RAM_SIZE_SR1 : MSMC_RAM_SIZE;
- /* NOTE: FW bug needs buffer base to be 64KB aligned */
- prueth->msmcram.va =
- (void __iomem *)gen_pool_alloc_algo(prueth->sram_pool,
- msmc_ram_size,
- gen_pool_first_fit_align,
- &gp_data);
+ if (prueth->pdata.is_sr1) {
+ prueth->msmcram.va =
+ (void __iomem *)gen_pool_alloc(prueth->sram_pool,
+ msmc_ram_size);
+ } else {
+ /* NOTE: FW bug needs buffer base to be 64KB aligned */
+ prueth->msmcram.va =
+ (void __iomem *)gen_pool_alloc_algo(prueth->sram_pool,
+ msmc_ram_size,
+ gen_pool_first_fit_align,
+ &gp_data);
+ }
if (!prueth->msmcram.va) {
ret = -ENOMEM;
@@ -2350,17 +2510,19 @@ static int prueth_probe(struct platform_device *pdev)
dev_dbg(dev, "sram: pa %llx va %p size %zx\n", prueth->msmcram.pa,
prueth->msmcram.va, prueth->msmcram.size);
- prueth->iep0 = icss_iep_get_idx(np, 0);
- if (IS_ERR(prueth->iep0)) {
- ret = dev_err_probe(dev, PTR_ERR(prueth->iep0), "iep0 get failed\n");
- prueth->iep0 = NULL;
- goto free_pool;
- }
+ if (!prueth->pdata.is_sr1) {
+ prueth->iep0 = icss_iep_get_idx(np, 0);
+ if (IS_ERR(prueth->iep0)) {
+ ret = dev_err_probe(dev, PTR_ERR(prueth->iep0), "iep0 get failed\n");
+ prueth->iep0 = NULL;
+ goto free_pool;
+ }
- prueth->iep1 = icss_iep_get_idx(np, 1);
- if (IS_ERR(prueth->iep1)) {
- ret = dev_err_probe(dev, PTR_ERR(prueth->iep1), "iep1 get failed\n");
- goto put_iep0;
+ prueth->iep1 = icss_iep_get_idx(np, 1);
+ if (IS_ERR(prueth->iep1)) {
+ ret = dev_err_probe(dev, PTR_ERR(prueth->iep1), "iep1 get failed\n");
+ goto put_iep0;
+ }
}
if (prueth->pdata.quirk_10m_link_issue) {
@@ -2382,7 +2544,8 @@ static int prueth_probe(struct platform_device *pdev)
if (of_find_property(eth0_node, "ti,half-duplex-capable", NULL))
prueth->emac[PRUETH_MAC0]->half_duplex = 1;
- prueth->emac[PRUETH_MAC0]->iep = prueth->iep0;
+ if (!prueth->pdata.is_sr1)
+ prueth->emac[PRUETH_MAC0]->iep = prueth->iep0;
}
if (eth1_node) {
@@ -2396,7 +2559,8 @@ static int prueth_probe(struct platform_device *pdev)
if (of_find_property(eth1_node, "ti,half-duplex-capable", NULL))
prueth->emac[PRUETH_MAC1]->half_duplex = 1;
- prueth->emac[PRUETH_MAC1]->iep = prueth->iep0;
+ if (!prueth->pdata.is_sr1)
+ prueth->emac[PRUETH_MAC1]->iep = prueth->iep0;
}
/* register the network devices */
@@ -2457,10 +2621,13 @@ static int prueth_probe(struct platform_device *pdev)
exit_iep:
if (prueth->pdata.quirk_10m_link_issue)
icss_iep_exit_fw(prueth->iep1);
- icss_iep_put(prueth->iep1);
+
+ if (!prueth->pdata.is_sr1)
+ icss_iep_put(prueth->iep1);
put_iep0:
- icss_iep_put(prueth->iep0);
+ if (!prueth->pdata.is_sr1)
+ icss_iep_put(prueth->iep0);
prueth->iep0 = NULL;
prueth->iep1 = NULL;
@@ -2511,15 +2678,21 @@ static void prueth_remove(struct platform_device *pdev)
prueth_netdev_exit(prueth, eth_node);
}
- if (prueth->pdata.quirk_10m_link_issue)
+ if (prueth->pdata.is_sr1) {
+ icss_iep_exit(prueth->iep1);
+ icss_iep_exit(prueth->iep0);
+ } else if (prueth->pdata.quirk_10m_link_issue) {
icss_iep_exit_fw(prueth->iep1);
+ }
- icss_iep_put(prueth->iep1);
- icss_iep_put(prueth->iep0);
+ if (!prueth->pdata.is_sr1) {
+ icss_iep_put(prueth->iep1);
+ icss_iep_put(prueth->iep0);
+ }
gen_pool_free(prueth->sram_pool,
(unsigned long)prueth->msmcram.va,
- MSMC_RAM_SIZE);
+ prueth->pdata.is_sr1 ? MSMC_RAM_SIZE_SR1 : MSMC_RAM_SIZE);
pruss_release_mem_region(prueth->pruss, &prueth->shram);
@@ -2588,6 +2761,11 @@ static const struct dev_pm_ops prueth_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(prueth_suspend, prueth_resume)
};
+static const struct prueth_pdata am654_icssg_pdata_sr1 = {
+ .fdqring_mode = K3_RINGACC_RING_MODE_MESSAGE,
+ .is_sr1 = 1,
+};
+
static const struct prueth_pdata am654_icssg_pdata = {
.fdqring_mode = K3_RINGACC_RING_MODE_MESSAGE,
.quirk_10m_link_issue = 1,
@@ -2598,6 +2776,7 @@ static const struct prueth_pdata am64x_icssg_pdata = {
};
static const struct of_device_id prueth_dt_match[] = {
+ { .compatible = "ti,am654-sr1-icssg-prueth", .data = &am654_icssg_pdata_sr1 },
{ .compatible = "ti,am654-icssg-prueth", .data = &am654_icssg_pdata },
{ .compatible = "ti,am642-icssg-prueth", .data = &am64x_icssg_pdata },
{ /* sentinel */ }
--
2.43.0
More information about the linux-arm-kernel
mailing list