summaryrefslogtreecommitdiff
path: root/drivers/mmc/octeontx_hsmmc.h
blob: 70844b1cbabeed0376927bb171ff81b8accf7afd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
/* SPDX-License-Identifier:    GPL-2.0
 *
 * Copyright (C) 2019 Marvell International Ltd.
 *
 * https://spdx.org/licenses
 */
#ifndef __OCTEONTX_HSMMC_H__
#define __OCTEONTX_HSMMC_H__
#include <asm/gpio.h>

/** Name of our driver */
#define OCTEONTX_MMC_DRIVER_NAME	"octeontx-hsmmc"

/** Maximum supported MMC slots */
#define OCTEONTX_MAX_MMC_SLOT		3

#define POWER_ON_TIME			40 /** See SD 4.1 spec figure 6-5 */

/**
 * Timeout used when waiting for commands to complete.  We need to keep this
 * above the hardware watchdog timeout which is usually limited to 1000ms
 */
#define WATCHDOG_COUNT			(1100)	/* in msecs */

/**
 * Long timeout for commands which might take a while to complete.
 */
#define MMC_TIMEOUT_LONG		1000

/**
 * Short timeout used for most commands in msecs
 */
#define MMC_TIMEOUT_SHORT		20

#define NSEC_PER_SEC			1000000000L

#define MAX_NO_OF_TAPS			64

#define EXT_CSD_POWER_CLASS		187	/* R/W */

/* default HS400 tuning block number */
#define DEFAULT_HS400_TUNING_BLOCK	1

struct octeontx_mmc_host;

/** MMC/SD slot data structure */
struct octeontx_mmc_slot {
	struct mmc		mmc;
	struct mmc_config	cfg;
	struct octeontx_mmc_host *host;
	struct udevice		*dev;
	void			*base_addr;	/** Same as host base_addr */
	u64			clock;
	int			bus_id;		/** slot number */
	uint			bus_width;
	uint			max_width;
	int			hs200_tap_adj;
	int			hs400_tap_adj;
	int			hs400_tuning_block;
	struct gpio_desc	cd_gpio;
	struct gpio_desc	wp_gpio;
	struct gpio_desc	power_gpio;
	enum bus_mode		mode;
	union mio_emm_switch	cached_switch;
	union mio_emm_switch	want_switch;
	union mio_emm_rca	cached_rca;
	union mio_emm_timing	taps;	/* otx2: MIO_EMM_TIMING */
	union mio_emm_timing	hs200_taps;
	union mio_emm_timing	hs400_taps;
	/* These are used to see if our tuning is still valid or not */
	enum bus_mode		last_mode;
	u32			last_clock;
	u32			block_len;
	u32			block_count;
	int			cmd_clk_skew;
	int			dat_clk_skew;
	uint			cmd_cnt;	/* otx: sample cmd in delay */
	uint			dat_cnt;	/* otx: sample data in delay */
	uint			drive;		/* Current drive */
	uint			slew;		/* clock skew */
	uint			cmd_out_hs200_delay;
	uint			data_out_hs200_delay;
	uint			cmd_out_hs400_delay;
	uint			data_out_hs400_delay;
	uint			clk_period;
	bool			valid:1;
	bool			is_acmd:1;
	bool			tuned:1;
	bool			hs200_tuned:1;
	bool			hs400_tuned:1;
	bool			is_1_8v:1;
	bool			is_3_3v:1;
	bool			is_ddr:1;
	bool			is_asim:1;
	bool			is_emul:1;
	bool			cd_inverted:1;
	bool			wp_inverted:1;
	bool			disable_ddr:1;
	bool			non_removable:1;
};

struct octeontx_mmc_cr_mods {
	u8 ctype_xor;
	u8 rtype_xor;
};

struct octeontx_mmc_cr {
	u8 c;
	u8 r;
};

struct octeontx_sd_mods {
	struct octeontx_mmc_cr mmc;
	struct octeontx_mmc_cr sd;
	struct octeontx_mmc_cr sdacmd;
};

/** Host controller data structure */
struct octeontx_mmc_host {
	struct		udevice *dev;
	void		*base_addr;
	struct octeontx_mmc_slot slots[OCTEONTX_MAX_MMC_SLOT + 1];
	pci_dev_t	pdev;
	u64		sys_freq;
	union mio_emm_cfg emm_cfg;
	u64		timing_taps;
	struct mmc	*last_mmc;	/** Last mmc used */
	ofnode		node;
	int		cur_slotid;
	int		last_slotid;
	int		max_width;
	uint		per_tap_delay;
	uint		num_slots;
	uint		dma_wait_delay;	/* Delay before polling DMA in usecs */
	bool		initialized:1;
	bool		timing_calibrated:1;
	bool		is_asim:1;
	bool		is_emul:1;
	bool		calibrate_glitch:1;
	bool		cond_clock_glitch:1;
	bool		tap_requires_noclk:1;
	bool		hs400_skew_needed:1;
};

/*
 * NOTE: This was copied from the Linux kernel.
 *
 * MMC status in R1, for native mode (SPI bits are different)
 * Type
 *	e:error bit
 *	s:status bit
 *	r:detected and set for the actual command response
 *	x:detected and set during command execution. the host must poll
 *	    the card by sending status command in order to read these bits.
 * Clear condition
 *	a:according to the card state
 *	b:always related to the previous command. Reception of
 *	    a valid command will clear it (with a delay of one command)
 *	c:clear by read
 */
#define R1_OUT_OF_RANGE		BIT(31)		/* er, c */
#define R1_ADDRESS_ERROR	BIT(30)		/* erx, c */
#define R1_BLOCK_LEN_ERROR	BIT(29)		/* er, c */
#define R1_ERASE_SEQ_ERROR	BIT(28)		/* er, c */
#define R1_ERASE_PARAM          BIT(27)		/* ex, c */
#define R1_WP_VIOLATION		BIT(26)		/* erx, c */
#define R1_CARD_IS_LOCKED	BIT(25)		/* sx, a */
#define R1_LOCK_UNLOCK_FAILED	BIT(24)		/* erx, c */
#define R1_COM_CRC_ERROR	BIT(23)		/* er, b */
/*#define R1_ILLEGAL_COMMAND	BIT(22)*/		/* er, b */
#define R1_CARD_ECC_FAILED	BIT(21)		/* ex, c */
#define R1_CC_ERROR		BIT(20)		/* erx, c */
#define R1_ERROR		BIT(19)		/* erx, c */
#define R1_UNDERRUN		BIT(18)		/* ex, c */
#define R1_OVERRUN		BIT(17)		/* ex, c */
#define R1_CID_CSD_OVERWRITE	BIT(16)		/* erx, c, CID/CSD overwrite */
#define R1_WP_ERASE_SKIP	BIT(15)		/* sx, c */
#define R1_CARD_ECC_DISABLED	BIT(14)		/* sx, a */
#define R1_ERASE_RESET		BIT(13)		/* sr, c */
#define R1_STATUS(x)		((x) & 0xFFFFE000)
#define R1_CURRENT_STATE(x)	(((x) & 0x00001E00) >> 9) /* sx, b (4 bits) */
#define R1_READY_FOR_DATA	BIT(8)		/* sx, a */
#define R1_SWITCH_ERROR		BIT(7)		/* sx, c */

#define R1_BLOCK_READ_MASK	R1_OUT_OF_RANGE |	\
				R1_ADDRESS_ERROR |	\
				R1_BLOCK_LEN_ERROR |	\
				R1_CARD_IS_LOCKED |	\
				R1_COM_CRC_ERROR |	\
				R1_ILLEGAL_COMMAND |	\
				R1_CARD_ECC_FAILED |	\
				R1_CC_ERROR |		\
				R1_ERROR
#define R1_BLOCK_WRITE_MASK	R1_OUT_OF_RANGE |	\
				R1_ADDRESS_ERROR |	\
				R1_BLOCK_LEN_ERROR |	\
				R1_WP_VIOLATION |	\
				R1_CARD_IS_LOCKED |	\
				R1_COM_CRC_ERROR |	\
				R1_ILLEGAL_COMMAND |	\
				R1_CARD_ECC_FAILED |	\
				R1_CC_ERROR |		\
				R1_ERROR |		\
				R1_UNDERRUN |		\
				R1_OVERRUN

#endif /* __OCTEONTX_HSMMC_H__ */