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