18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Driver for Marvell NETA network controller Buffer Manager.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Copyright (C) 2015 Marvell
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Marcin Wojtas <mw@semihalf.com>
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci * This file is licensed under the terms of the GNU General Public
98c2ecf20Sopenharmony_ci * License version 2. This program is licensed "as is" without any
108c2ecf20Sopenharmony_ci * warranty of any kind, whether express or implied.
118c2ecf20Sopenharmony_ci */
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#ifndef _MVNETA_BM_H_
148c2ecf20Sopenharmony_ci#define _MVNETA_BM_H_
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci/* BM Configuration Register */
178c2ecf20Sopenharmony_ci#define MVNETA_BM_CONFIG_REG			0x0
188c2ecf20Sopenharmony_ci#define    MVNETA_BM_STATUS_MASK		0x30
198c2ecf20Sopenharmony_ci#define    MVNETA_BM_ACTIVE_MASK		BIT(4)
208c2ecf20Sopenharmony_ci#define    MVNETA_BM_MAX_IN_BURST_SIZE_MASK	0x60000
218c2ecf20Sopenharmony_ci#define    MVNETA_BM_MAX_IN_BURST_SIZE_16BP	BIT(18)
228c2ecf20Sopenharmony_ci#define    MVNETA_BM_EMPTY_LIMIT_MASK		BIT(19)
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci/* BM Activation Register */
258c2ecf20Sopenharmony_ci#define MVNETA_BM_COMMAND_REG			0x4
268c2ecf20Sopenharmony_ci#define    MVNETA_BM_START_MASK			BIT(0)
278c2ecf20Sopenharmony_ci#define    MVNETA_BM_STOP_MASK			BIT(1)
288c2ecf20Sopenharmony_ci#define    MVNETA_BM_PAUSE_MASK			BIT(2)
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci/* BM Xbar interface Register */
318c2ecf20Sopenharmony_ci#define MVNETA_BM_XBAR_01_REG			0x8
328c2ecf20Sopenharmony_ci#define MVNETA_BM_XBAR_23_REG			0xc
338c2ecf20Sopenharmony_ci#define MVNETA_BM_XBAR_POOL_REG(pool)		\
348c2ecf20Sopenharmony_ci		(((pool) < 2) ? MVNETA_BM_XBAR_01_REG : MVNETA_BM_XBAR_23_REG)
358c2ecf20Sopenharmony_ci#define     MVNETA_BM_TARGET_ID_OFFS(pool)	(((pool) & 1) ? 16 : 0)
368c2ecf20Sopenharmony_ci#define     MVNETA_BM_TARGET_ID_MASK(pool)	\
378c2ecf20Sopenharmony_ci		(0xf << MVNETA_BM_TARGET_ID_OFFS(pool))
388c2ecf20Sopenharmony_ci#define     MVNETA_BM_TARGET_ID_VAL(pool, id)	\
398c2ecf20Sopenharmony_ci		((id) << MVNETA_BM_TARGET_ID_OFFS(pool))
408c2ecf20Sopenharmony_ci#define     MVNETA_BM_XBAR_ATTR_OFFS(pool)	(((pool) & 1) ? 20 : 4)
418c2ecf20Sopenharmony_ci#define     MVNETA_BM_XBAR_ATTR_MASK(pool)	\
428c2ecf20Sopenharmony_ci		(0xff << MVNETA_BM_XBAR_ATTR_OFFS(pool))
438c2ecf20Sopenharmony_ci#define     MVNETA_BM_XBAR_ATTR_VAL(pool, attr)	\
448c2ecf20Sopenharmony_ci		((attr) << MVNETA_BM_XBAR_ATTR_OFFS(pool))
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci/* Address of External Buffer Pointers Pool Register */
478c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_BASE_REG(pool)		(0x10 + ((pool) << 4))
488c2ecf20Sopenharmony_ci#define     MVNETA_BM_POOL_ENABLE_MASK		BIT(0)
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_ci/* External Buffer Pointers Pool RD pointer Register */
518c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_READ_PTR_REG(pool)	(0x14 + ((pool) << 4))
528c2ecf20Sopenharmony_ci#define     MVNETA_BM_POOL_SET_READ_PTR_MASK	0xfffc
538c2ecf20Sopenharmony_ci#define     MVNETA_BM_POOL_GET_READ_PTR_OFFS	16
548c2ecf20Sopenharmony_ci#define     MVNETA_BM_POOL_GET_READ_PTR_MASK	0xfffc0000
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci/* External Buffer Pointers Pool WR pointer */
578c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_WRITE_PTR_REG(pool)	(0x18 + ((pool) << 4))
588c2ecf20Sopenharmony_ci#define     MVNETA_BM_POOL_SET_WRITE_PTR_OFFS	0
598c2ecf20Sopenharmony_ci#define     MVNETA_BM_POOL_SET_WRITE_PTR_MASK	0xfffc
608c2ecf20Sopenharmony_ci#define     MVNETA_BM_POOL_GET_WRITE_PTR_OFFS	16
618c2ecf20Sopenharmony_ci#define     MVNETA_BM_POOL_GET_WRITE_PTR_MASK	0xfffc0000
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci/* External Buffer Pointers Pool Size Register */
648c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_SIZE_REG(pool)		(0x1c + ((pool) << 4))
658c2ecf20Sopenharmony_ci#define     MVNETA_BM_POOL_SIZE_MASK		0x3fff
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci/* BM Interrupt Cause Register */
688c2ecf20Sopenharmony_ci#define MVNETA_BM_INTR_CAUSE_REG		(0x50)
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci/* BM interrupt Mask Register */
718c2ecf20Sopenharmony_ci#define MVNETA_BM_INTR_MASK_REG			(0x54)
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci/* Other definitions */
748c2ecf20Sopenharmony_ci#define MVNETA_BM_SHORT_PKT_SIZE		256
758c2ecf20Sopenharmony_ci#define MVNETA_BM_POOLS_NUM			4
768c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_CAP_MIN			128
778c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_CAP_DEF			2048
788c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_CAP_MAX			\
798c2ecf20Sopenharmony_ci		(16 * 1024 - MVNETA_BM_POOL_CAP_ALIGN)
808c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_CAP_ALIGN		32
818c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_PTR_ALIGN		32
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci#define MVNETA_BM_POOL_ACCESS_OFFS		8
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci#define MVNETA_BM_BPPI_SIZE			0x100000
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci#define MVNETA_RX_BUF_SIZE(pkt_size)   ((pkt_size) + NET_SKB_PAD)
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_cienum mvneta_bm_type {
908c2ecf20Sopenharmony_ci	MVNETA_BM_FREE,
918c2ecf20Sopenharmony_ci	MVNETA_BM_LONG,
928c2ecf20Sopenharmony_ci	MVNETA_BM_SHORT
938c2ecf20Sopenharmony_ci};
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_cistruct mvneta_bm {
968c2ecf20Sopenharmony_ci	void __iomem *reg_base;
978c2ecf20Sopenharmony_ci	struct clk *clk;
988c2ecf20Sopenharmony_ci	struct platform_device *pdev;
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	struct gen_pool *bppi_pool;
1018c2ecf20Sopenharmony_ci	/* BPPI virtual base address */
1028c2ecf20Sopenharmony_ci	void __iomem *bppi_virt_addr;
1038c2ecf20Sopenharmony_ci	/* BPPI physical base address */
1048c2ecf20Sopenharmony_ci	dma_addr_t bppi_phys_addr;
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci	/* BM pools */
1078c2ecf20Sopenharmony_ci	struct mvneta_bm_pool *bm_pools;
1088c2ecf20Sopenharmony_ci};
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_cistruct mvneta_bm_pool {
1118c2ecf20Sopenharmony_ci	struct hwbm_pool hwbm_pool;
1128c2ecf20Sopenharmony_ci	/* Pool number in the range 0-3 */
1138c2ecf20Sopenharmony_ci	u8 id;
1148c2ecf20Sopenharmony_ci	enum mvneta_bm_type type;
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	/* Packet size */
1178c2ecf20Sopenharmony_ci	int pkt_size;
1188c2ecf20Sopenharmony_ci	/* Size of the buffer acces through DMA*/
1198c2ecf20Sopenharmony_ci	u32 buf_size;
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_ci	/* BPPE virtual base address */
1228c2ecf20Sopenharmony_ci	u32 *virt_addr;
1238c2ecf20Sopenharmony_ci	/* BPPE physical base address */
1248c2ecf20Sopenharmony_ci	dma_addr_t phys_addr;
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci	/* Ports using BM pool */
1278c2ecf20Sopenharmony_ci	u8 port_map;
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci	struct mvneta_bm *priv;
1308c2ecf20Sopenharmony_ci};
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci/* Declarations and definitions */
1338c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_MVNETA_BM)
1348c2ecf20Sopenharmony_cistruct mvneta_bm *mvneta_bm_get(struct device_node *node);
1358c2ecf20Sopenharmony_civoid mvneta_bm_put(struct mvneta_bm *priv);
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_civoid mvneta_bm_pool_destroy(struct mvneta_bm *priv,
1388c2ecf20Sopenharmony_ci			    struct mvneta_bm_pool *bm_pool, u8 port_map);
1398c2ecf20Sopenharmony_civoid mvneta_bm_bufs_free(struct mvneta_bm *priv, struct mvneta_bm_pool *bm_pool,
1408c2ecf20Sopenharmony_ci			 u8 port_map);
1418c2ecf20Sopenharmony_ciint mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf);
1428c2ecf20Sopenharmony_ciint mvneta_bm_pool_refill(struct mvneta_bm *priv,
1438c2ecf20Sopenharmony_ci			  struct mvneta_bm_pool *bm_pool);
1448c2ecf20Sopenharmony_cistruct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,
1458c2ecf20Sopenharmony_ci					  enum mvneta_bm_type type, u8 port_id,
1468c2ecf20Sopenharmony_ci					  int pkt_size);
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_cistatic inline void mvneta_bm_pool_put_bp(struct mvneta_bm *priv,
1498c2ecf20Sopenharmony_ci					 struct mvneta_bm_pool *bm_pool,
1508c2ecf20Sopenharmony_ci					 dma_addr_t buf_phys_addr)
1518c2ecf20Sopenharmony_ci{
1528c2ecf20Sopenharmony_ci	writel_relaxed(buf_phys_addr, priv->bppi_virt_addr +
1538c2ecf20Sopenharmony_ci		       (bm_pool->id << MVNETA_BM_POOL_ACCESS_OFFS));
1548c2ecf20Sopenharmony_ci}
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_cistatic inline u32 mvneta_bm_pool_get_bp(struct mvneta_bm *priv,
1578c2ecf20Sopenharmony_ci					struct mvneta_bm_pool *bm_pool)
1588c2ecf20Sopenharmony_ci{
1598c2ecf20Sopenharmony_ci	return readl_relaxed(priv->bppi_virt_addr +
1608c2ecf20Sopenharmony_ci			     (bm_pool->id << MVNETA_BM_POOL_ACCESS_OFFS));
1618c2ecf20Sopenharmony_ci}
1628c2ecf20Sopenharmony_ci#else
1638c2ecf20Sopenharmony_cistatic inline void mvneta_bm_pool_destroy(struct mvneta_bm *priv,
1648c2ecf20Sopenharmony_ci					  struct mvneta_bm_pool *bm_pool,
1658c2ecf20Sopenharmony_ci					  u8 port_map) {}
1668c2ecf20Sopenharmony_cistatic inline void mvneta_bm_bufs_free(struct mvneta_bm *priv,
1678c2ecf20Sopenharmony_ci				       struct mvneta_bm_pool *bm_pool,
1688c2ecf20Sopenharmony_ci				       u8 port_map) {}
1698c2ecf20Sopenharmony_cistatic inline int mvneta_bm_construct(struct hwbm_pool *hwbm_pool, void *buf)
1708c2ecf20Sopenharmony_ci{ return 0; }
1718c2ecf20Sopenharmony_cistatic inline int mvneta_bm_pool_refill(struct mvneta_bm *priv,
1728c2ecf20Sopenharmony_ci					struct mvneta_bm_pool *bm_pool)
1738c2ecf20Sopenharmony_ci{ return 0; }
1748c2ecf20Sopenharmony_cistatic inline struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv,
1758c2ecf20Sopenharmony_ci							u8 pool_id,
1768c2ecf20Sopenharmony_ci							enum mvneta_bm_type type,
1778c2ecf20Sopenharmony_ci							u8 port_id,
1788c2ecf20Sopenharmony_ci							int pkt_size)
1798c2ecf20Sopenharmony_ci{ return NULL; }
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_cistatic inline void mvneta_bm_pool_put_bp(struct mvneta_bm *priv,
1828c2ecf20Sopenharmony_ci					 struct mvneta_bm_pool *bm_pool,
1838c2ecf20Sopenharmony_ci					 dma_addr_t buf_phys_addr) {}
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_cistatic inline u32 mvneta_bm_pool_get_bp(struct mvneta_bm *priv,
1868c2ecf20Sopenharmony_ci					struct mvneta_bm_pool *bm_pool)
1878c2ecf20Sopenharmony_ci{ return 0; }
1888c2ecf20Sopenharmony_cistatic inline struct mvneta_bm *mvneta_bm_get(struct device_node *node)
1898c2ecf20Sopenharmony_ci{ return NULL; }
1908c2ecf20Sopenharmony_cistatic inline void mvneta_bm_put(struct mvneta_bm *priv) {}
1918c2ecf20Sopenharmony_ci#endif /* CONFIG_MVNETA_BM */
1928c2ecf20Sopenharmony_ci#endif
193