mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-13 00:17:02 +04:00
qualcommax: add EDMA driver
EDMA dataplane ethernet driver for Qualcomm IPQ platforms. Signed-off-by: John Crispin <john@phrozen.org> [ rework Makefile for external repository, dependency ] Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> [ rework for in-tree ] Link: https://github.com/openwrt/openwrt/pull/22381 Signed-off-by: Robert Marko <robimarko@gmail.com>
This commit is contained in:
1 parent
142104bb90
commit
bdb0b722b7
5 files changed
+1649
No files matched your search
@@ -415,6 +415,7 @@ CONFIG_QCOM_BAM_DMA=y
|
||||
# CONFIG_QCOM_CPR is not set
|
||||
# CONFIG_QCOM_CPUCP_MBOX is not set
|
||||
# CONFIG_QCOM_EBI2 is not set
|
||||
# CONFIG_QCOM_EDMA is not set
|
||||
# CONFIG_QCOM_FASTRPC is not set
|
||||
# CONFIG_QCOM_GENI_SE is not set
|
||||
# CONFIG_QCOM_GSBI is not set
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,259 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2016, 2018-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __QCA_EDMA_H__
|
||||
#define __QCA_EDMA_H__
|
||||
|
||||
#include <linux/dsa/oob.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <net/page_pool/helpers.h>
|
||||
|
||||
#define EDMA_HW_RESET_ID "edma_rst"
|
||||
|
||||
/* Global / control registers */
|
||||
#define EDMA_REG_MAS_CTRL 0x0
|
||||
#define EDMA_REG_PORT_CTRL 0x4
|
||||
#define EDMA_REG_RXDESC2FILL_MAP_0 0x18
|
||||
#define EDMA_REG_RXDESC2FILL_MAP_1 0x1c
|
||||
#define EDMA_REG_DMAR_CTRL 0x48
|
||||
#define EDMA_REG_AXIW_CTRL 0x50
|
||||
#define EDMA_REG_MISC_INT_STAT 0x5c
|
||||
#define EDMA_REG_MISC_INT_MASK 0x60
|
||||
|
||||
#define EDMA_PORT_PAD_EN 0x1
|
||||
#define EDMA_PORT_EDMA_EN 0x2
|
||||
|
||||
#define EDMA_DMAR_REQ_PRI_MASK 0x7
|
||||
#define EDMA_DMAR_REQ_PRI_SHIFT 0
|
||||
#define EDMA_DMAR_BURST_LEN_MASK 0x1
|
||||
#define EDMA_DMAR_BURST_LEN_SHIFT 3
|
||||
#define EDMA_DMAR_TXDATA_NUM_MASK 0x1f
|
||||
#define EDMA_DMAR_TXDATA_NUM_SHIFT 4
|
||||
#define EDMA_DMAR_TXDESC_NUM_MASK 0x7
|
||||
#define EDMA_DMAR_TXDESC_NUM_SHIFT 9
|
||||
#define EDMA_DMAR_RXFILL_NUM_MASK 0x7
|
||||
#define EDMA_DMAR_RXFILL_NUM_SHIFT 12
|
||||
|
||||
#define EDMA_DMAR_REQ_PRI_SET(x) \
|
||||
(((x)&EDMA_DMAR_REQ_PRI_MASK) << EDMA_DMAR_REQ_PRI_SHIFT)
|
||||
#define EDMA_DMAR_TXDATA_NUM_SET(x) \
|
||||
(((x)&EDMA_DMAR_TXDATA_NUM_MASK) << EDMA_DMAR_TXDATA_NUM_SHIFT)
|
||||
#define EDMA_DMAR_TXDESC_NUM_SET(x) \
|
||||
(((x)&EDMA_DMAR_TXDESC_NUM_MASK) << EDMA_DMAR_TXDESC_NUM_SHIFT)
|
||||
#define EDMA_DMAR_RXFILL_NUM_SET(x) \
|
||||
(((x)&EDMA_DMAR_RXFILL_NUM_MASK) << EDMA_DMAR_RXFILL_NUM_SHIFT)
|
||||
#define EDMA_DMAR_BURST_LEN_SET(x) \
|
||||
(((x)&EDMA_DMAR_BURST_LEN_MASK) << EDMA_DMAR_BURST_LEN_SHIFT)
|
||||
|
||||
#define EDMA_AXIW_MAX_WR_SIZE_EN 0x400
|
||||
|
||||
/* TX descriptor ring registers */
|
||||
#define EDMA_REG_TXDESC_BA(n) (0x1000 + (0x1000 * (n)))
|
||||
#define EDMA_REG_TXDESC_PROD_IDX(n) (0x1004 + (0x1000 * (n)))
|
||||
#define EDMA_REG_TXDESC_CONS_IDX(n) (0x1008 + (0x1000 * (n)))
|
||||
#define EDMA_REG_TXDESC_RING_SIZE(n) (0x100c + (0x1000 * (n)))
|
||||
#define EDMA_REG_TXDESC_CTRL(n) (0x1010 + (0x1000 * (n)))
|
||||
|
||||
#define EDMA_TXDESC_PROD_IDX_MASK 0xffff
|
||||
#define EDMA_TXDESC_CONS_IDX_MASK 0xffff
|
||||
#define EDMA_TXDESC_RING_SIZE_MASK 0xffff
|
||||
#define EDMA_TXDESC_TX_EN 0x1
|
||||
|
||||
/* TX completion ring registers */
|
||||
#define EDMA_REG_TXCMPL_BA(b, n) ((b) + (0x1000 * (n)))
|
||||
#define EDMA_REG_TXCMPL_PROD_IDX(b, n) ((b) + 0x004 + (0x1000 * (n)))
|
||||
#define EDMA_REG_TXCMPL_CONS_IDX(b, n) ((b) + 0x008 + (0x1000 * (n)))
|
||||
#define EDMA_REG_TXCMPL_RING_SIZE(b, n) ((b) + 0x00c + (0x1000 * (n)))
|
||||
#define EDMA_REG_TXCMPL_CTRL(b, n) ((b) + 0x014 + (0x1000 * (n)))
|
||||
|
||||
#define EDMA_TXCMPL_PROD_IDX_MASK 0xffff
|
||||
#define EDMA_TXCMPL_CONS_IDX_MASK 0xffff
|
||||
#define EDMA_TXCMPL_RETMODE_OPAQUE 0x0
|
||||
|
||||
/* TX interrupt registers */
|
||||
#define EDMA_REG_TX_INT_STAT(b, n) ((b) + (0x1000 * (n)))
|
||||
#define EDMA_REG_TX_INT_MASK(b, n) ((b) + 0x004 + (0x1000 * (n)))
|
||||
#define EDMA_REG_TX_MOD_TIMER(b, n) ((b) + 0x008 + (0x1000 * (n)))
|
||||
#define EDMA_REG_TX_INT_CTRL(b, n) ((b) + 0x00c + (0x1000 * (n)))
|
||||
|
||||
#define EDMA_TX_INT_MASK 0x3
|
||||
#define EDMA_TX_MOD_TIMER 150
|
||||
|
||||
/* RX fill ring registers */
|
||||
#define EDMA_REG_RXFILL_BA(n) (0x29000 + (0x1000 * (n)))
|
||||
#define EDMA_REG_RXFILL_PROD_IDX(n) (0x29004 + (0x1000 * (n)))
|
||||
#define EDMA_REG_RXFILL_CONS_IDX(n) (0x29008 + (0x1000 * (n)))
|
||||
#define EDMA_REG_RXFILL_RING_SIZE(n) (0x2900c + (0x1000 * (n)))
|
||||
#define EDMA_REG_RXFILL_RING_EN(n) (0x2901c + (0x1000 * (n)))
|
||||
|
||||
#define EDMA_RXFILL_PROD_IDX_MASK 0xffff
|
||||
#define EDMA_RXFILL_CONS_IDX_MASK 0xffff
|
||||
#define EDMA_RXFILL_RING_SIZE_MASK 0xffff
|
||||
#define EDMA_RXFILL_BUF_SIZE_MASK 0x3fff
|
||||
#define EDMA_RXFILL_RING_EN 0x1
|
||||
#define EDMA_RXFILL_INT_MASK 0x1
|
||||
|
||||
/* RX fill ring interrupt registers */
|
||||
#define EDMA_REG_RXFILL_INT_STAT(n) (0x31000 + (0x1000 * (n)))
|
||||
#define EDMA_REG_RXFILL_INT_MASK(n) (0x31004 + (0x1000 * (n)))
|
||||
|
||||
/* RX descriptor ring registers */
|
||||
#define EDMA_REG_RXDESC_BA(n) (0x39000 + (0x1000 * (n)))
|
||||
#define EDMA_REG_RXDESC_PROD_IDX(n) (0x39004 + (0x1000 * (n)))
|
||||
#define EDMA_REG_RXDESC_CONS_IDX(n) (0x39008 + (0x1000 * (n)))
|
||||
#define EDMA_REG_RXDESC_RING_SIZE(n) (0x3900c + (0x1000 * (n)))
|
||||
#define EDMA_REG_RXDESC_CTRL(n) (0x39018 + (0x1000 * (n)))
|
||||
|
||||
#define EDMA_RXDESC_PROD_IDX_MASK 0xffff
|
||||
#define EDMA_RXDESC_CONS_IDX_MASK 0xffff
|
||||
#define EDMA_RXDESC_RING_SIZE_MASK 0xffff
|
||||
#define EDMA_RXDESC_PL_OFFSET_MASK 0x1ff
|
||||
#define EDMA_RXDESC_PL_OFFSET_SHIFT 16
|
||||
#define EDMA_RXDESC_RX_EN 0x1
|
||||
#define EDMA_RXDESC_PACKET_LEN_MASK 0x3fff
|
||||
|
||||
/* RX descriptor ring interrupt registers */
|
||||
#define EDMA_REG_RXDESC_INT_STAT(n) (0x49000 + (0x1000 * (n)))
|
||||
#define EDMA_REG_RXDESC_INT_MASK(n) (0x49004 + (0x1000 * (n)))
|
||||
#define EDMA_REG_RX_MOD_TIMER(n) (0x49008 + (0x1000 * (n)))
|
||||
#define EDMA_REG_RX_INT_CTRL(n) (0x4900c + (0x1000 * (n)))
|
||||
|
||||
#define EDMA_RXDESC_INT_MASK_PKT_INT 0x1
|
||||
#define EDMA_RX_MOD_TIMER_INIT 1000
|
||||
|
||||
/* QID to ring mapping */
|
||||
#define EDMA_QID2RID_TABLE_MEM(q) (0x5a000 + (0x4 * (q)))
|
||||
|
||||
/* TXDESC to TXCMPL ring mapping */
|
||||
#define EDMA_REG_TXDESC2CMPL_MAP(n) (0x0c + 0x4 * (n))
|
||||
|
||||
/* Misc error interrupt masks */
|
||||
#define EDMA_MISC_AXI_RD_ERR_MASK_EN 0x1
|
||||
#define EDMA_MISC_AXI_WR_ERR_MASK_EN 0x2
|
||||
#define EDMA_MISC_RX_DESC_FIFO_FULL_MASK_EN 0x4
|
||||
#define EDMA_MISC_RX_ERR_BUF_SIZE_MASK_EN 0x8
|
||||
#define EDMA_MISC_TX_SRAM_FULL_MASK_EN 0x10
|
||||
#define EDMA_MISC_TX_CMPL_BUF_FULL_MASK_EN 0x20
|
||||
#define EDMA_MISC_DATA_LEN_ERR_MASK_EN 0x40
|
||||
#define EDMA_MISC_TX_TIMEOUT_MASK_EN 0x80
|
||||
|
||||
/* Sizes and ring configuration */
|
||||
#define EDMA_RX_BUFFER_SIZE 1984
|
||||
#define EDMA_RX_PREHDR_SIZE (sizeof(struct edma_rx_preheader))
|
||||
#define EDMA_TX_PREHDR_SIZE (sizeof(struct edma_tx_preheader))
|
||||
#define EDMA_TX_RING_SIZE 128
|
||||
#define EDMA_RX_RING_SIZE 2048
|
||||
#define EDMA_TX_RING_THRESH 16
|
||||
|
||||
/* Descriptor accessors */
|
||||
#define EDMA_GET_DESC(R, i, type) (&(((type *)((R)->desc))[i]))
|
||||
#define EDMA_RXFILL_DESC(R, i) EDMA_GET_DESC(R, i, struct edma_rxfill_desc)
|
||||
#define EDMA_RXDESC_DESC(R, i) EDMA_GET_DESC(R, i, struct edma_rxdesc)
|
||||
#define EDMA_TXDESC_DESC(R, i) EDMA_GET_DESC(R, i, struct edma_txdesc)
|
||||
#define EDMA_TXCMPL_DESC(R, i) EDMA_GET_DESC(R, i, struct edma_txcmpl)
|
||||
|
||||
/* TX descriptor fields */
|
||||
#define EDMA_TXDESC_PREHEADER_SHIFT 29
|
||||
#define EDMA_TXDESC_DATA_OFFSET_SHIFT 16
|
||||
#define EDMA_TXDESC_DATA_OFFSET_MASK 0xff
|
||||
#define EDMA_TXDESC_DATA_LENGTH_MASK 0xffff
|
||||
|
||||
/* Preheader fields */
|
||||
#define EDMA_DST_PORT_TYPE 0x20
|
||||
#define EDMA_DST_PORT_ID_MASK 0x1f
|
||||
#define EDMA_SRC_PORT_MASK 0x0fff
|
||||
#define EDMA_PREHDR_DSTINFO_PORTID_IND 0x20
|
||||
#define EDMA_RXPH_SRC_INFO_TYPE_GET(rxph) (((rxph)->src_info >> 8) & 0xf0)
|
||||
|
||||
struct edma_txdesc {
|
||||
u32 buffer_addr;
|
||||
u32 word1;
|
||||
};
|
||||
|
||||
struct edma_txcmpl {
|
||||
u32 buffer_addr;
|
||||
u32 status;
|
||||
};
|
||||
|
||||
struct edma_rxdesc {
|
||||
u32 buffer_addr;
|
||||
u32 status;
|
||||
};
|
||||
|
||||
struct edma_rxfill_desc {
|
||||
u32 buffer_addr;
|
||||
u32 word1;
|
||||
};
|
||||
|
||||
struct edma_tx_preheader {
|
||||
u32 opaque;
|
||||
u16 src_info;
|
||||
u16 dst_info;
|
||||
u32 tx_pre2;
|
||||
u32 tx_pre3;
|
||||
u32 tx_pre4;
|
||||
u32 tx_pre5;
|
||||
u32 tx_pre6;
|
||||
u32 tx_pre7;
|
||||
};
|
||||
|
||||
struct edma_rx_preheader {
|
||||
u32 opaque;
|
||||
u16 src_info;
|
||||
u16 dst_info;
|
||||
u32 rx_pre2;
|
||||
u32 rx_pre3;
|
||||
u32 rx_pre4;
|
||||
u32 rx_pre5;
|
||||
u32 rx_pre6;
|
||||
u32 rx_pre7;
|
||||
};
|
||||
|
||||
struct edma_soc_data {
|
||||
u32 txcmpl_base;
|
||||
u32 tx_int_base;
|
||||
u32 misc_int_mask;
|
||||
u8 txdesc_ring;
|
||||
u8 txcmpl_ring;
|
||||
u8 rxfill_ring;
|
||||
u8 rxdesc_ring;
|
||||
u8 tx_min_size;
|
||||
bool burst_enable;
|
||||
bool axiw_enable;
|
||||
};
|
||||
|
||||
struct edma_ring {
|
||||
void *desc;
|
||||
dma_addr_t dma;
|
||||
u16 count;
|
||||
struct sk_buff **skb_store;
|
||||
};
|
||||
|
||||
struct edma_priv {
|
||||
const struct edma_soc_data *soc;
|
||||
struct napi_struct tx_napi;
|
||||
struct napi_struct rx_napi;
|
||||
struct net_device *netdev;
|
||||
struct platform_device *pdev;
|
||||
struct regmap *regmap;
|
||||
struct reset_control *rst;
|
||||
struct page_pool *page_pool;
|
||||
|
||||
struct edma_ring txdesc_ring;
|
||||
struct edma_ring txcmpl_ring;
|
||||
struct edma_ring rxfill_ring;
|
||||
struct edma_ring rxdesc_ring;
|
||||
|
||||
spinlock_t tx_lock;
|
||||
|
||||
int txcmpl_irq;
|
||||
int rxfill_irq;
|
||||
int rxdesc_irq;
|
||||
int misc_irq;
|
||||
};
|
||||
|
||||
#endif /* __QCA_EDMA_H__ */
|
||||
@@ -0,0 +1,110 @@
|
||||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/net/qualcomm,ipq-edma.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm IPQ EDMA Ethernet Controller
|
||||
|
||||
maintainers:
|
||||
- John Crispin <john@phrozen.org>
|
||||
|
||||
description: |
|
||||
The Enhanced Direct Memory Access (EDMA) controller in Qualcomm IPQ6018 and
|
||||
IPQ8074 SoCs provides the dataplane for the PPE (Packet Processing Engine)
|
||||
switch. It registers a network device that serves as the DSA conduit
|
||||
interface. The EDMA handles packet DMA between the PPE hardware and the
|
||||
host CPU through dedicated TX/RX descriptor and completion rings.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qualcomm,ipq6018-edma
|
||||
- qualcomm,ipq8074-edma
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
interrupts:
|
||||
items:
|
||||
- description: TX completion interrupt
|
||||
- description: RX fill interrupt
|
||||
- description: RX descriptor interrupt
|
||||
- description: Miscellaneous interrupt
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: EDMA core clock
|
||||
- description: EDMA configuration clock
|
||||
- description: PPE core clock
|
||||
- description: PPE configuration clock
|
||||
- description: NSSNOC PPE clock
|
||||
- description: NSSNOC PPE configuration clock
|
||||
- description: NSS NOC clock
|
||||
- description: NSSNOC SNOC clock
|
||||
- description: NOC interconnect clock (SoC-specific)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: nss_edma_clk
|
||||
- const: nss_edma_cfg_clk
|
||||
- const: nss_ppe_clk
|
||||
- const: nss_ppe_cfg_clk
|
||||
- const: nssnoc_ppe_clk
|
||||
- const: nssnoc_ppe_cfg_clk
|
||||
- const: gcc_nss_noc_clk
|
||||
- const: gcc_nssnoc_snoc_clk
|
||||
- enum:
|
||||
- gcc_mem_noc_nss_axi_clk
|
||||
- gcc_snoc_nssnoc_clk
|
||||
|
||||
resets:
|
||||
maxItems: 1
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: edma_rst
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- interrupts
|
||||
- clocks
|
||||
- clock-names
|
||||
- resets
|
||||
- reset-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-ipq8074.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
edma@3ab00000 {
|
||||
compatible = "qualcomm,ipq8074-edma";
|
||||
reg = <0x3ab00000 0xb0000>;
|
||||
|
||||
interrupts = <GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
clocks = <&gcc GCC_NSS_EDMA_CLK>,
|
||||
<&gcc GCC_NSS_EDMA_CFG_CLK>,
|
||||
<&gcc GCC_NSS_PPE_CLK>,
|
||||
<&gcc GCC_NSS_PPE_CFG_CLK>,
|
||||
<&gcc GCC_NSSNOC_PPE_CLK>,
|
||||
<&gcc GCC_NSSNOC_PPE_CFG_CLK>,
|
||||
<&gcc GCC_NSS_NOC_CLK>,
|
||||
<&gcc GCC_NSSNOC_SNOC_CLK>,
|
||||
<&gcc GCC_MEM_NOC_NSS_AXI_CLK>;
|
||||
clock-names = "nss_edma_clk", "nss_edma_cfg_clk",
|
||||
"nss_ppe_clk", "nss_ppe_cfg_clk",
|
||||
"nssnoc_ppe_clk", "nssnoc_ppe_cfg_clk",
|
||||
"gcc_nss_noc_clk", "gcc_nssnoc_snoc_clk",
|
||||
"gcc_mem_noc_nss_axi_clk";
|
||||
|
||||
resets = <&gcc GCC_EDMA_HW_RESET>;
|
||||
reset-names = "edma_rst";
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
--- a/drivers/net/ethernet/qualcomm/Kconfig
|
||||
+++ b/drivers/net/ethernet/qualcomm/Kconfig
|
||||
@@ -67,6 +67,11 @@ config QCOM_80211AX_PPE
|
||||
help
|
||||
Driver for Qualcomm 802.11ax PPE (Packet Processing Engine) switches.
|
||||
|
||||
+config QCOM_EDMA
|
||||
+ tristate "EDMA dataplane ethernet driver for Qualcomm IPQ platforms"
|
||||
+ help
|
||||
+ EDMA dataplane ethernet driver for Qualcomm IPQ platforms.
|
||||
+
|
||||
|
||||
source "drivers/net/ethernet/qualcomm/rmnet/Kconfig"
|
||||
|
||||
--- a/drivers/net/ethernet/qualcomm/Makefile
|
||||
+++ b/drivers/net/ethernet/qualcomm/Makefile
|
||||
@@ -10,6 +10,7 @@ obj-$(CONFIG_QCA7000_UART) += qcauart.o
|
||||
qcauart-objs := qca_uart.o
|
||||
obj-$(CONFIG_QCOM_80211AX_PPE) += qca_ppe.o
|
||||
qca_ppe-objs := qca_ppe_main.o qca_ppe_vlan.o qca_ppe_scheduler.o
|
||||
+obj-$(CONFIG_QCOM_EDMA) += qca_edma.o
|
||||
|
||||
obj-y += emac/
|
||||
|
||||
Reference in new issue
Block a user