162306a36Sopenharmony_ci/*
262306a36Sopenharmony_ci * Driver for MMC and SSD cards for Cavium OCTEON and ThunderX SOCs.
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
562306a36Sopenharmony_ci * License.  See the file "COPYING" in the main directory of this archive
662306a36Sopenharmony_ci * for more details.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Copyright (C) 2012-2017 Cavium Inc.
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#ifndef _CAVIUM_MMC_H_
1262306a36Sopenharmony_ci#define _CAVIUM_MMC_H_
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/bitops.h>
1562306a36Sopenharmony_ci#include <linux/clk.h>
1662306a36Sopenharmony_ci#include <linux/gpio/consumer.h>
1762306a36Sopenharmony_ci#include <linux/io.h>
1862306a36Sopenharmony_ci#include <linux/mmc/host.h>
1962306a36Sopenharmony_ci#include <linux/of.h>
2062306a36Sopenharmony_ci#include <linux/scatterlist.h>
2162306a36Sopenharmony_ci#include <linux/semaphore.h>
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#define CAVIUM_MAX_MMC		4
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci/* DMA register addresses */
2662306a36Sopenharmony_ci#define MIO_EMM_DMA_FIFO_CFG(x)	(0x00 + x->reg_off_dma)
2762306a36Sopenharmony_ci#define MIO_EMM_DMA_FIFO_ADR(x)	(0x10 + x->reg_off_dma)
2862306a36Sopenharmony_ci#define MIO_EMM_DMA_FIFO_CMD(x)	(0x18 + x->reg_off_dma)
2962306a36Sopenharmony_ci#define MIO_EMM_DMA_CFG(x)	(0x20 + x->reg_off_dma)
3062306a36Sopenharmony_ci#define MIO_EMM_DMA_ADR(x)	(0x28 + x->reg_off_dma)
3162306a36Sopenharmony_ci#define MIO_EMM_DMA_INT(x)	(0x30 + x->reg_off_dma)
3262306a36Sopenharmony_ci#define MIO_EMM_DMA_INT_W1S(x)	(0x38 + x->reg_off_dma)
3362306a36Sopenharmony_ci#define MIO_EMM_DMA_INT_ENA_W1S(x) (0x40 + x->reg_off_dma)
3462306a36Sopenharmony_ci#define MIO_EMM_DMA_INT_ENA_W1C(x) (0x48 + x->reg_off_dma)
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci/* register addresses */
3762306a36Sopenharmony_ci#define MIO_EMM_CFG(x)		(0x00 + x->reg_off)
3862306a36Sopenharmony_ci#define MIO_EMM_SWITCH(x)	(0x48 + x->reg_off)
3962306a36Sopenharmony_ci#define MIO_EMM_DMA(x)		(0x50 + x->reg_off)
4062306a36Sopenharmony_ci#define MIO_EMM_CMD(x)		(0x58 + x->reg_off)
4162306a36Sopenharmony_ci#define MIO_EMM_RSP_STS(x)	(0x60 + x->reg_off)
4262306a36Sopenharmony_ci#define MIO_EMM_RSP_LO(x)	(0x68 + x->reg_off)
4362306a36Sopenharmony_ci#define MIO_EMM_RSP_HI(x)	(0x70 + x->reg_off)
4462306a36Sopenharmony_ci#define MIO_EMM_INT(x)		(0x78 + x->reg_off)
4562306a36Sopenharmony_ci#define MIO_EMM_INT_EN(x)	(0x80 + x->reg_off)
4662306a36Sopenharmony_ci#define MIO_EMM_WDOG(x)		(0x88 + x->reg_off)
4762306a36Sopenharmony_ci#define MIO_EMM_SAMPLE(x)	(0x90 + x->reg_off)
4862306a36Sopenharmony_ci#define MIO_EMM_STS_MASK(x)	(0x98 + x->reg_off)
4962306a36Sopenharmony_ci#define MIO_EMM_RCA(x)		(0xa0 + x->reg_off)
5062306a36Sopenharmony_ci#define MIO_EMM_INT_EN_SET(x)	(0xb0 + x->reg_off)
5162306a36Sopenharmony_ci#define MIO_EMM_INT_EN_CLR(x)	(0xb8 + x->reg_off)
5262306a36Sopenharmony_ci#define MIO_EMM_BUF_IDX(x)	(0xe0 + x->reg_off)
5362306a36Sopenharmony_ci#define MIO_EMM_BUF_DAT(x)	(0xe8 + x->reg_off)
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistruct cvm_mmc_host {
5662306a36Sopenharmony_ci	struct device *dev;
5762306a36Sopenharmony_ci	void __iomem *base;
5862306a36Sopenharmony_ci	void __iomem *dma_base;
5962306a36Sopenharmony_ci	int reg_off;
6062306a36Sopenharmony_ci	int reg_off_dma;
6162306a36Sopenharmony_ci	u64 emm_cfg;
6262306a36Sopenharmony_ci	u64 n_minus_one;	/* OCTEON II workaround location */
6362306a36Sopenharmony_ci	int last_slot;
6462306a36Sopenharmony_ci	struct clk *clk;
6562306a36Sopenharmony_ci	int sys_freq;
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	struct mmc_request *current_req;
6862306a36Sopenharmony_ci	struct sg_mapping_iter smi;
6962306a36Sopenharmony_ci	bool dma_active;
7062306a36Sopenharmony_ci	bool use_sg;
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	bool has_ciu3;
7362306a36Sopenharmony_ci	bool big_dma_addr;
7462306a36Sopenharmony_ci	bool need_irq_handler_lock;
7562306a36Sopenharmony_ci	spinlock_t irq_handler_lock;
7662306a36Sopenharmony_ci	struct semaphore mmc_serializer;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	struct gpio_desc *global_pwr_gpiod;
7962306a36Sopenharmony_ci	atomic_t shared_power_users;
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci	struct cvm_mmc_slot *slot[CAVIUM_MAX_MMC];
8262306a36Sopenharmony_ci	struct platform_device *slot_pdev[CAVIUM_MAX_MMC];
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	void (*set_shared_power)(struct cvm_mmc_host *, int);
8562306a36Sopenharmony_ci	void (*acquire_bus)(struct cvm_mmc_host *);
8662306a36Sopenharmony_ci	void (*release_bus)(struct cvm_mmc_host *);
8762306a36Sopenharmony_ci	void (*int_enable)(struct cvm_mmc_host *, u64);
8862306a36Sopenharmony_ci	/* required on some MIPS models */
8962306a36Sopenharmony_ci	void (*dmar_fixup)(struct cvm_mmc_host *, struct mmc_command *,
9062306a36Sopenharmony_ci			   struct mmc_data *, u64);
9162306a36Sopenharmony_ci	void (*dmar_fixup_done)(struct cvm_mmc_host *);
9262306a36Sopenharmony_ci};
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_cistruct cvm_mmc_slot {
9562306a36Sopenharmony_ci	struct mmc_host *mmc;		/* slot-level mmc_core object */
9662306a36Sopenharmony_ci	struct cvm_mmc_host *host;	/* common hw for all slots */
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	u64 clock;
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	u64 cached_switch;
10162306a36Sopenharmony_ci	u64 cached_rca;
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci	unsigned int cmd_cnt;		/* sample delay */
10462306a36Sopenharmony_ci	unsigned int dat_cnt;		/* sample delay */
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci	int bus_id;
10762306a36Sopenharmony_ci};
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_cistruct cvm_mmc_cr_type {
11062306a36Sopenharmony_ci	u8 ctype;
11162306a36Sopenharmony_ci	u8 rtype;
11262306a36Sopenharmony_ci};
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_cistruct cvm_mmc_cr_mods {
11562306a36Sopenharmony_ci	u8 ctype_xor;
11662306a36Sopenharmony_ci	u8 rtype_xor;
11762306a36Sopenharmony_ci};
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci/* Bitfield definitions */
12062306a36Sopenharmony_ci#define MIO_EMM_DMA_FIFO_CFG_CLR	BIT_ULL(16)
12162306a36Sopenharmony_ci#define MIO_EMM_DMA_FIFO_CFG_INT_LVL	GENMASK_ULL(12, 8)
12262306a36Sopenharmony_ci#define MIO_EMM_DMA_FIFO_CFG_COUNT	GENMASK_ULL(4, 0)
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci#define MIO_EMM_DMA_FIFO_CMD_RW		BIT_ULL(62)
12562306a36Sopenharmony_ci#define MIO_EMM_DMA_FIFO_CMD_INTDIS	BIT_ULL(60)
12662306a36Sopenharmony_ci#define MIO_EMM_DMA_FIFO_CMD_SWAP32	BIT_ULL(59)
12762306a36Sopenharmony_ci#define MIO_EMM_DMA_FIFO_CMD_SWAP16	BIT_ULL(58)
12862306a36Sopenharmony_ci#define MIO_EMM_DMA_FIFO_CMD_SWAP8	BIT_ULL(57)
12962306a36Sopenharmony_ci#define MIO_EMM_DMA_FIFO_CMD_ENDIAN	BIT_ULL(56)
13062306a36Sopenharmony_ci#define MIO_EMM_DMA_FIFO_CMD_SIZE	GENMASK_ULL(55, 36)
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci#define MIO_EMM_CMD_SKIP_BUSY		BIT_ULL(62)
13362306a36Sopenharmony_ci#define MIO_EMM_CMD_BUS_ID		GENMASK_ULL(61, 60)
13462306a36Sopenharmony_ci#define MIO_EMM_CMD_VAL			BIT_ULL(59)
13562306a36Sopenharmony_ci#define MIO_EMM_CMD_DBUF		BIT_ULL(55)
13662306a36Sopenharmony_ci#define MIO_EMM_CMD_OFFSET		GENMASK_ULL(54, 49)
13762306a36Sopenharmony_ci#define MIO_EMM_CMD_CTYPE_XOR		GENMASK_ULL(42, 41)
13862306a36Sopenharmony_ci#define MIO_EMM_CMD_RTYPE_XOR		GENMASK_ULL(40, 38)
13962306a36Sopenharmony_ci#define MIO_EMM_CMD_IDX			GENMASK_ULL(37, 32)
14062306a36Sopenharmony_ci#define MIO_EMM_CMD_ARG			GENMASK_ULL(31, 0)
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci#define MIO_EMM_DMA_SKIP_BUSY		BIT_ULL(62)
14362306a36Sopenharmony_ci#define MIO_EMM_DMA_BUS_ID		GENMASK_ULL(61, 60)
14462306a36Sopenharmony_ci#define MIO_EMM_DMA_VAL			BIT_ULL(59)
14562306a36Sopenharmony_ci#define MIO_EMM_DMA_SECTOR		BIT_ULL(58)
14662306a36Sopenharmony_ci#define MIO_EMM_DMA_DAT_NULL		BIT_ULL(57)
14762306a36Sopenharmony_ci#define MIO_EMM_DMA_THRES		GENMASK_ULL(56, 51)
14862306a36Sopenharmony_ci#define MIO_EMM_DMA_REL_WR		BIT_ULL(50)
14962306a36Sopenharmony_ci#define MIO_EMM_DMA_RW			BIT_ULL(49)
15062306a36Sopenharmony_ci#define MIO_EMM_DMA_MULTI		BIT_ULL(48)
15162306a36Sopenharmony_ci#define MIO_EMM_DMA_BLOCK_CNT		GENMASK_ULL(47, 32)
15262306a36Sopenharmony_ci#define MIO_EMM_DMA_CARD_ADDR		GENMASK_ULL(31, 0)
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci#define MIO_EMM_DMA_CFG_EN		BIT_ULL(63)
15562306a36Sopenharmony_ci#define MIO_EMM_DMA_CFG_RW		BIT_ULL(62)
15662306a36Sopenharmony_ci#define MIO_EMM_DMA_CFG_CLR		BIT_ULL(61)
15762306a36Sopenharmony_ci#define MIO_EMM_DMA_CFG_SWAP32		BIT_ULL(59)
15862306a36Sopenharmony_ci#define MIO_EMM_DMA_CFG_SWAP16		BIT_ULL(58)
15962306a36Sopenharmony_ci#define MIO_EMM_DMA_CFG_SWAP8		BIT_ULL(57)
16062306a36Sopenharmony_ci#define MIO_EMM_DMA_CFG_ENDIAN		BIT_ULL(56)
16162306a36Sopenharmony_ci#define MIO_EMM_DMA_CFG_SIZE		GENMASK_ULL(55, 36)
16262306a36Sopenharmony_ci#define MIO_EMM_DMA_CFG_ADR		GENMASK_ULL(35, 0)
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci#define MIO_EMM_INT_SWITCH_ERR		BIT_ULL(6)
16562306a36Sopenharmony_ci#define MIO_EMM_INT_SWITCH_DONE		BIT_ULL(5)
16662306a36Sopenharmony_ci#define MIO_EMM_INT_DMA_ERR		BIT_ULL(4)
16762306a36Sopenharmony_ci#define MIO_EMM_INT_CMD_ERR		BIT_ULL(3)
16862306a36Sopenharmony_ci#define MIO_EMM_INT_DMA_DONE		BIT_ULL(2)
16962306a36Sopenharmony_ci#define MIO_EMM_INT_CMD_DONE		BIT_ULL(1)
17062306a36Sopenharmony_ci#define MIO_EMM_INT_BUF_DONE		BIT_ULL(0)
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_BUS_ID		GENMASK_ULL(61, 60)
17362306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_CMD_VAL		BIT_ULL(59)
17462306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_SWITCH_VAL	BIT_ULL(58)
17562306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_DMA_VAL		BIT_ULL(57)
17662306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_DMA_PEND	BIT_ULL(56)
17762306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_DBUF_ERR	BIT_ULL(28)
17862306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_DBUF		BIT_ULL(23)
17962306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_BLK_TIMEOUT	BIT_ULL(22)
18062306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_BLK_CRC_ERR	BIT_ULL(21)
18162306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_RSP_BUSYBIT	BIT_ULL(20)
18262306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_STP_TIMEOUT	BIT_ULL(19)
18362306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_STP_CRC_ERR	BIT_ULL(18)
18462306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_STP_BAD_STS	BIT_ULL(17)
18562306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_STP_VAL		BIT_ULL(16)
18662306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_RSP_TIMEOUT	BIT_ULL(15)
18762306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_RSP_CRC_ERR	BIT_ULL(14)
18862306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_RSP_BAD_STS	BIT_ULL(13)
18962306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_RSP_VAL		BIT_ULL(12)
19062306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_RSP_TYPE	GENMASK_ULL(11, 9)
19162306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_CMD_TYPE	GENMASK_ULL(8, 7)
19262306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_CMD_IDX		GENMASK_ULL(6, 1)
19362306a36Sopenharmony_ci#define MIO_EMM_RSP_STS_CMD_DONE	BIT_ULL(0)
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_ci#define MIO_EMM_SAMPLE_CMD_CNT		GENMASK_ULL(25, 16)
19662306a36Sopenharmony_ci#define MIO_EMM_SAMPLE_DAT_CNT		GENMASK_ULL(9, 0)
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci#define MIO_EMM_SWITCH_BUS_ID		GENMASK_ULL(61, 60)
19962306a36Sopenharmony_ci#define MIO_EMM_SWITCH_EXE		BIT_ULL(59)
20062306a36Sopenharmony_ci#define MIO_EMM_SWITCH_ERR0		BIT_ULL(58)
20162306a36Sopenharmony_ci#define MIO_EMM_SWITCH_ERR1		BIT_ULL(57)
20262306a36Sopenharmony_ci#define MIO_EMM_SWITCH_ERR2		BIT_ULL(56)
20362306a36Sopenharmony_ci#define MIO_EMM_SWITCH_HS_TIMING	BIT_ULL(48)
20462306a36Sopenharmony_ci#define MIO_EMM_SWITCH_BUS_WIDTH	GENMASK_ULL(42, 40)
20562306a36Sopenharmony_ci#define MIO_EMM_SWITCH_POWER_CLASS	GENMASK_ULL(35, 32)
20662306a36Sopenharmony_ci#define MIO_EMM_SWITCH_CLK_HI		GENMASK_ULL(31, 16)
20762306a36Sopenharmony_ci#define MIO_EMM_SWITCH_CLK_LO		GENMASK_ULL(15, 0)
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci/* Protoypes */
21062306a36Sopenharmony_ciirqreturn_t cvm_mmc_interrupt(int irq, void *dev_id);
21162306a36Sopenharmony_ciint cvm_mmc_of_slot_probe(struct device *dev, struct cvm_mmc_host *host);
21262306a36Sopenharmony_ciint cvm_mmc_of_slot_remove(struct cvm_mmc_slot *slot);
21362306a36Sopenharmony_ciextern const char *cvm_mmc_irq_names[];
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci#endif
216