xref: /OK3568_Linux_fs/kernel/drivers/net/ethernet/marvell/mvneta_bm.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Driver for Marvell NETA network controller Buffer Manager.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright (C) 2015 Marvell
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Marcin Wojtas <mw@semihalf.com>
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * This file is licensed under the terms of the GNU General Public
9*4882a593Smuzhiyun  * License version 2. This program is licensed "as is" without any
10*4882a593Smuzhiyun  * warranty of any kind, whether express or implied.
11*4882a593Smuzhiyun  */
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #ifndef _MVNETA_BM_H_
14*4882a593Smuzhiyun #define _MVNETA_BM_H_
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun /* BM Configuration Register */
17*4882a593Smuzhiyun #define MVNETA_BM_CONFIG_REG			0x0
18*4882a593Smuzhiyun #define    MVNETA_BM_STATUS_MASK		0x30
19*4882a593Smuzhiyun #define    MVNETA_BM_ACTIVE_MASK		BIT(4)
20*4882a593Smuzhiyun #define    MVNETA_BM_MAX_IN_BURST_SIZE_MASK	0x60000
21*4882a593Smuzhiyun #define    MVNETA_BM_MAX_IN_BURST_SIZE_16BP	BIT(18)
22*4882a593Smuzhiyun #define    MVNETA_BM_EMPTY_LIMIT_MASK		BIT(19)
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun /* BM Activation Register */
25*4882a593Smuzhiyun #define MVNETA_BM_COMMAND_REG			0x4
26*4882a593Smuzhiyun #define    MVNETA_BM_START_MASK			BIT(0)
27*4882a593Smuzhiyun #define    MVNETA_BM_STOP_MASK			BIT(1)
28*4882a593Smuzhiyun #define    MVNETA_BM_PAUSE_MASK			BIT(2)
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun /* BM Xbar interface Register */
31*4882a593Smuzhiyun #define MVNETA_BM_XBAR_01_REG			0x8
32*4882a593Smuzhiyun #define MVNETA_BM_XBAR_23_REG			0xc
33*4882a593Smuzhiyun #define MVNETA_BM_XBAR_POOL_REG(pool)		\
34*4882a593Smuzhiyun 		(((pool) < 2) ? MVNETA_BM_XBAR_01_REG : MVNETA_BM_XBAR_23_REG)
35*4882a593Smuzhiyun #define     MVNETA_BM_TARGET_ID_OFFS(pool)	(((pool) & 1) ? 16 : 0)
36*4882a593Smuzhiyun #define     MVNETA_BM_TARGET_ID_MASK(pool)	\
37*4882a593Smuzhiyun 		(0xf << MVNETA_BM_TARGET_ID_OFFS(pool))
38*4882a593Smuzhiyun #define     MVNETA_BM_TARGET_ID_VAL(pool, id)	\
39*4882a593Smuzhiyun 		((id) << MVNETA_BM_TARGET_ID_OFFS(pool))
40*4882a593Smuzhiyun #define     MVNETA_BM_XBAR_ATTR_OFFS(pool)	(((pool) & 1) ? 20 : 4)
41*4882a593Smuzhiyun #define     MVNETA_BM_XBAR_ATTR_MASK(pool)	\
42*4882a593Smuzhiyun 		(0xff << MVNETA_BM_XBAR_ATTR_OFFS(pool))
43*4882a593Smuzhiyun #define     MVNETA_BM_XBAR_ATTR_VAL(pool, attr)	\
44*4882a593Smuzhiyun 		((attr) << MVNETA_BM_XBAR_ATTR_OFFS(pool))
45*4882a593Smuzhiyun 
46*4882a593Smuzhiyun /* Address of External Buffer Pointers Pool Register */
47*4882a593Smuzhiyun #define MVNETA_BM_POOL_BASE_REG(pool)		(0x10 + ((pool) << 4))
48*4882a593Smuzhiyun #define     MVNETA_BM_POOL_ENABLE_MASK		BIT(0)
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun /* External Buffer Pointers Pool RD pointer Register */
51*4882a593Smuzhiyun #define MVNETA_BM_POOL_READ_PTR_REG(pool)	(0x14 + ((pool) << 4))
52*4882a593Smuzhiyun #define     MVNETA_BM_POOL_SET_READ_PTR_MASK	0xfffc
53*4882a593Smuzhiyun #define     MVNETA_BM_POOL_GET_READ_PTR_OFFS	16
54*4882a593Smuzhiyun #define     MVNETA_BM_POOL_GET_READ_PTR_MASK	0xfffc0000
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun /* External Buffer Pointers Pool WR pointer */
57*4882a593Smuzhiyun #define MVNETA_BM_POOL_WRITE_PTR_REG(pool)	(0x18 + ((pool) << 4))
58*4882a593Smuzhiyun #define     MVNETA_BM_POOL_SET_WRITE_PTR_OFFS	0
59*4882a593Smuzhiyun #define     MVNETA_BM_POOL_SET_WRITE_PTR_MASK	0xfffc
60*4882a593Smuzhiyun #define     MVNETA_BM_POOL_GET_WRITE_PTR_OFFS	16
61*4882a593Smuzhiyun #define     MVNETA_BM_POOL_GET_WRITE_PTR_MASK	0xfffc0000
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun /* External Buffer Pointers Pool Size Register */
64*4882a593Smuzhiyun #define MVNETA_BM_POOL_SIZE_REG(pool)		(0x1c + ((pool) << 4))
65*4882a593Smuzhiyun #define     MVNETA_BM_POOL_SIZE_MASK		0x3fff
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun /* BM Interrupt Cause Register */
68*4882a593Smuzhiyun #define MVNETA_BM_INTR_CAUSE_REG		(0x50)
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun /* BM interrupt Mask Register */
71*4882a593Smuzhiyun #define MVNETA_BM_INTR_MASK_REG			(0x54)
72*4882a593Smuzhiyun 
73*4882a593Smuzhiyun /* Other definitions */
74*4882a593Smuzhiyun #define MVNETA_BM_SHORT_PKT_SIZE		256
75*4882a593Smuzhiyun #define MVNETA_BM_POOLS_NUM			4
76*4882a593Smuzhiyun #define MVNETA_BM_POOL_CAP_MIN			128
77*4882a593Smuzhiyun #define MVNETA_BM_POOL_CAP_DEF			2048
78*4882a593Smuzhiyun #define MVNETA_BM_POOL_CAP_MAX			\
79*4882a593Smuzhiyun 		(16 * 1024 - MVNETA_BM_POOL_CAP_ALIGN)
80*4882a593Smuzhiyun #define MVNETA_BM_POOL_CAP_ALIGN		32
81*4882a593Smuzhiyun #define MVNETA_BM_POOL_PTR_ALIGN		32
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun #define MVNETA_BM_POOL_ACCESS_OFFS		8
84*4882a593Smuzhiyun 
85*4882a593Smuzhiyun #define MVNETA_BM_BPPI_SIZE			0x100000
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun #define MVNETA_RX_BUF_SIZE(pkt_size)   ((pkt_size) + NET_SKB_PAD)
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun enum mvneta_bm_type {
90*4882a593Smuzhiyun 	MVNETA_BM_FREE,
91*4882a593Smuzhiyun 	MVNETA_BM_LONG,
92*4882a593Smuzhiyun 	MVNETA_BM_SHORT
93*4882a593Smuzhiyun };
94*4882a593Smuzhiyun 
95*4882a593Smuzhiyun struct mvneta_bm {
96*4882a593Smuzhiyun 	void __iomem *reg_base;
97*4882a593Smuzhiyun 	struct clk *clk;
98*4882a593Smuzhiyun 	struct platform_device *pdev;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	struct gen_pool *bppi_pool;
101*4882a593Smuzhiyun 	/* BPPI virtual base address */
102*4882a593Smuzhiyun 	void __iomem *bppi_virt_addr;
103*4882a593Smuzhiyun 	/* BPPI physical base address */
104*4882a593Smuzhiyun 	dma_addr_t bppi_phys_addr;
105*4882a593Smuzhiyun 
106*4882a593Smuzhiyun 	/* BM pools */
107*4882a593Smuzhiyun 	struct mvneta_bm_pool *bm_pools;
108*4882a593Smuzhiyun };
109*4882a593Smuzhiyun 
110*4882a593Smuzhiyun struct mvneta_bm_pool {
111*4882a593Smuzhiyun 	struct hwbm_pool hwbm_pool;
112*4882a593Smuzhiyun 	/* Pool number in the range 0-3 */
113*4882a593Smuzhiyun 	u8 id;
114*4882a593Smuzhiyun 	enum mvneta_bm_type type;
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	/* Packet size */
117*4882a593Smuzhiyun 	int pkt_size;
118*4882a593Smuzhiyun 	/* Size of the buffer acces through DMA*/
119*4882a593Smuzhiyun 	u32 buf_size;
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 	/* BPPE virtual base address */
122*4882a593Smuzhiyun 	u32 *virt_addr;
123*4882a593Smuzhiyun 	/* BPPE physical base address */
124*4882a593Smuzhiyun 	dma_addr_t phys_addr;
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	/* Ports using BM pool */
127*4882a593Smuzhiyun 	u8 port_map;
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	struct mvneta_bm *priv;
130*4882a593Smuzhiyun };
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun /* Declarations and definitions */
133*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_MVNETA_BM)
134*4882a593Smuzhiyun struct mvneta_bm *mvneta_bm_get(struct device_node *node);
135*4882a593Smuzhiyun void mvneta_bm_put(struct mvneta_bm *priv);
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun void mvneta_bm_pool_destroy(struct mvneta_bm *priv,
138*4882a593Smuzhiyun 			    struct mvneta_bm_pool *bm_pool, u8 port_map);
139*4882a593Smuzhiyun void mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
140*4882a593Smuzhiyun 			 u8 port_map);
141*4882a593Smuzhiyun int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf);
142*4882a593Smuzhiyun int mvneta_bm_pool_refill(struct mvneta_bm *priv,
143*4882a593Smuzhiyun 			  struct mvneta_bm_pool *bm_pool);
144*4882a593Smuzhiyun struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,
145*4882a593Smuzhiyun 					  enum mvneta_bm_type type, u8 port_id,
146*4882a593Smuzhiyun 					  int pkt_size);
147*4882a593Smuzhiyun 
mvneta_bm_pool_put_bp(struct mvneta_bm * priv,struct mvneta_bm_pool * bm_pool,dma_addr_t buf_phys_addr)148*4882a593Smuzhiyun static inline void mvneta_bm_pool_put_bp(struct mvneta_bm *priv,
149*4882a593Smuzhiyun 					 struct mvneta_bm_pool *bm_pool,
150*4882a593Smuzhiyun 					 dma_addr_t buf_phys_addr)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun 	writel_relaxed(buf_phys_addr, priv->bppi_virt_addr +
153*4882a593Smuzhiyun 		       (bm_pool->id << MVNETA_BM_POOL_ACCESS_OFFS));
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun 
mvneta_bm_pool_get_bp(struct mvneta_bm * priv,struct mvneta_bm_pool * bm_pool)156*4882a593Smuzhiyun static inline u32 mvneta_bm_pool_get_bp(struct mvneta_bm *priv,
157*4882a593Smuzhiyun 					struct mvneta_bm_pool *bm_pool)
158*4882a593Smuzhiyun {
159*4882a593Smuzhiyun 	return readl_relaxed(priv->bppi_virt_addr +
160*4882a593Smuzhiyun 			     (bm_pool->id << MVNETA_BM_POOL_ACCESS_OFFS));
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun #else
mvneta_bm_pool_destroy(struct mvneta_bm * priv,struct mvneta_bm_pool * bm_pool,u8 port_map)163*4882a593Smuzhiyun static inline void mvneta_bm_pool_destroy(struct mvneta_bm *priv,
164*4882a593Smuzhiyun 					  struct mvneta_bm_pool *bm_pool,
165*4882a593Smuzhiyun 					  u8 port_map) {}
mvneta_bm_bufs_free(struct mvneta_bm * priv,struct mvneta_bm_pool * bm_pool,u8 port_map)166*4882a593Smuzhiyun static inline void mvneta_bm_bufs_free(struct mvneta_bm *priv,
167*4882a593Smuzhiyun 				       struct mvneta_bm_pool *bm_pool,
168*4882a593Smuzhiyun 				       u8 port_map) {}
mvneta_bm_construct(struct hwbm_pool * hwbm_pool,void * buf)169*4882a593Smuzhiyun static inline int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf)
170*4882a593Smuzhiyun { return 0; }
mvneta_bm_pool_refill(struct mvneta_bm * priv,struct mvneta_bm_pool * bm_pool)171*4882a593Smuzhiyun static inline int mvneta_bm_pool_refill(struct mvneta_bm *priv,
172*4882a593Smuzhiyun 					struct mvneta_bm_pool *bm_pool)
173*4882a593Smuzhiyun { return 0; }
mvneta_bm_pool_use(struct mvneta_bm * priv,u8 pool_id,enum mvneta_bm_type type,u8 port_id,int pkt_size)174*4882a593Smuzhiyun static inline struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv,
175*4882a593Smuzhiyun 							u8 pool_id,
176*4882a593Smuzhiyun 							enum mvneta_bm_type type,
177*4882a593Smuzhiyun 							u8 port_id,
178*4882a593Smuzhiyun 							int pkt_size)
179*4882a593Smuzhiyun { return NULL; }
180*4882a593Smuzhiyun 
mvneta_bm_pool_put_bp(struct mvneta_bm * priv,struct mvneta_bm_pool * bm_pool,dma_addr_t buf_phys_addr)181*4882a593Smuzhiyun static inline void mvneta_bm_pool_put_bp(struct mvneta_bm *priv,
182*4882a593Smuzhiyun 					 struct mvneta_bm_pool *bm_pool,
183*4882a593Smuzhiyun 					 dma_addr_t buf_phys_addr) {}
184*4882a593Smuzhiyun 
mvneta_bm_pool_get_bp(struct mvneta_bm * priv,struct mvneta_bm_pool * bm_pool)185*4882a593Smuzhiyun static inline u32 mvneta_bm_pool_get_bp(struct mvneta_bm *priv,
186*4882a593Smuzhiyun 					struct mvneta_bm_pool *bm_pool)
187*4882a593Smuzhiyun { return 0; }
mvneta_bm_get(struct device_node * node)188*4882a593Smuzhiyun static inline struct mvneta_bm *mvneta_bm_get(struct device_node *node)
189*4882a593Smuzhiyun { return NULL; }
mvneta_bm_put(struct mvneta_bm * priv)190*4882a593Smuzhiyun static inline void mvneta_bm_put(struct mvneta_bm *priv) {}
191*4882a593Smuzhiyun #endif /* CONFIG_MVNETA_BM */
192*4882a593Smuzhiyun #endif
193