1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright 2011, Marvell Semiconductor Inc.
3*4882a593Smuzhiyun * Lei Wen <leiwen@marvell.com>
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Back ported to the 8xx platform (from the 8260 platform) by
8*4882a593Smuzhiyun * Murray.Jensen@cmst.csiro.au, 27-Jan-01.
9*4882a593Smuzhiyun */
10*4882a593Smuzhiyun #ifndef __SDHCI_HW_H
11*4882a593Smuzhiyun #define __SDHCI_HW_H
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #include <asm/io.h>
14*4882a593Smuzhiyun #include <mmc.h>
15*4882a593Smuzhiyun #include <asm/gpio.h>
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun /*
18*4882a593Smuzhiyun * Controller registers
19*4882a593Smuzhiyun */
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun #define SDHCI_DMA_ADDRESS 0x00
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #define SDHCI_BLOCK_SIZE 0x04
24*4882a593Smuzhiyun #define SDHCI_MAKE_BLKSZ(dma, blksz) (((dma & 0x7) << 12) | (blksz & 0xFFF))
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #define SDHCI_BLOCK_COUNT 0x06
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun #define SDHCI_ARGUMENT 0x08
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #define SDHCI_TRANSFER_MODE 0x0C
31*4882a593Smuzhiyun #define SDHCI_TRNS_DMA BIT(0)
32*4882a593Smuzhiyun #define SDHCI_TRNS_BLK_CNT_EN BIT(1)
33*4882a593Smuzhiyun #define SDHCI_TRNS_ACMD12 BIT(2)
34*4882a593Smuzhiyun #define SDHCI_TRNS_READ BIT(4)
35*4882a593Smuzhiyun #define SDHCI_TRNS_MULTI BIT(5)
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun #define SDHCI_COMMAND 0x0E
38*4882a593Smuzhiyun #define SDHCI_CMD_RESP_MASK 0x03
39*4882a593Smuzhiyun #define SDHCI_CMD_CRC 0x08
40*4882a593Smuzhiyun #define SDHCI_CMD_INDEX 0x10
41*4882a593Smuzhiyun #define SDHCI_CMD_DATA 0x20
42*4882a593Smuzhiyun #define SDHCI_CMD_ABORTCMD 0xC0
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun #define SDHCI_CMD_RESP_NONE 0x00
45*4882a593Smuzhiyun #define SDHCI_CMD_RESP_LONG 0x01
46*4882a593Smuzhiyun #define SDHCI_CMD_RESP_SHORT 0x02
47*4882a593Smuzhiyun #define SDHCI_CMD_RESP_SHORT_BUSY 0x03
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun #define SDHCI_MAKE_CMD(c, f) (((c & 0xff) << 8) | (f & 0xff))
50*4882a593Smuzhiyun #define SDHCI_GET_CMD(c) ((c>>8) & 0x3f)
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun #define SDHCI_RESPONSE 0x10
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun #define SDHCI_BUFFER 0x20
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun #define SDHCI_PRESENT_STATE 0x24
57*4882a593Smuzhiyun #define SDHCI_CMD_INHIBIT BIT(0)
58*4882a593Smuzhiyun #define SDHCI_DATA_INHIBIT BIT(1)
59*4882a593Smuzhiyun #define SDHCI_DOING_WRITE BIT(8)
60*4882a593Smuzhiyun #define SDHCI_DOING_READ BIT(9)
61*4882a593Smuzhiyun #define SDHCI_SPACE_AVAILABLE BIT(10)
62*4882a593Smuzhiyun #define SDHCI_DATA_AVAILABLE BIT(11)
63*4882a593Smuzhiyun #define SDHCI_CARD_PRESENT BIT(16)
64*4882a593Smuzhiyun #define SDHCI_CARD_STATE_STABLE BIT(17)
65*4882a593Smuzhiyun #define SDHCI_CARD_DETECT_PIN_LEVEL BIT(18)
66*4882a593Smuzhiyun #define SDHCI_WRITE_PROTECT BIT(19)
67*4882a593Smuzhiyun #define SDHCI_DATA_0_LVL BIT(20)
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun #define SDHCI_HOST_CONTROL 0x28
70*4882a593Smuzhiyun #define SDHCI_CTRL_LED BIT(0)
71*4882a593Smuzhiyun #define SDHCI_CTRL_4BITBUS BIT(1)
72*4882a593Smuzhiyun #define SDHCI_CTRL_HISPD BIT(2)
73*4882a593Smuzhiyun #define SDHCI_CTRL_DMA_MASK 0x18
74*4882a593Smuzhiyun #define SDHCI_CTRL_SDMA 0x00
75*4882a593Smuzhiyun #define SDHCI_CTRL_ADMA1 0x08
76*4882a593Smuzhiyun #define SDHCI_CTRL_ADMA32 0x10
77*4882a593Smuzhiyun #define SDHCI_CTRL_ADMA64 0x18
78*4882a593Smuzhiyun #define SDHCI_CTRL_8BITBUS BIT(5)
79*4882a593Smuzhiyun #define SDHCI_CTRL_CD_TEST_INS BIT(6)
80*4882a593Smuzhiyun #define SDHCI_CTRL_CD_TEST BIT(7)
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun #define SDHCI_POWER_CONTROL 0x29
83*4882a593Smuzhiyun #define SDHCI_POWER_ON 0x01
84*4882a593Smuzhiyun #define SDHCI_POWER_180 0x0A
85*4882a593Smuzhiyun #define SDHCI_POWER_300 0x0C
86*4882a593Smuzhiyun #define SDHCI_POWER_330 0x0E
87*4882a593Smuzhiyun
88*4882a593Smuzhiyun #define SDHCI_BLOCK_GAP_CONTROL 0x2A
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun #define SDHCI_WAKE_UP_CONTROL 0x2B
91*4882a593Smuzhiyun #define SDHCI_WAKE_ON_INT BIT(0)
92*4882a593Smuzhiyun #define SDHCI_WAKE_ON_INSERT BIT(1)
93*4882a593Smuzhiyun #define SDHCI_WAKE_ON_REMOVE BIT(2)
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun #define SDHCI_CLOCK_CONTROL 0x2C
96*4882a593Smuzhiyun #define SDHCI_DIVIDER_SHIFT 8
97*4882a593Smuzhiyun #define SDHCI_DIVIDER_HI_SHIFT 6
98*4882a593Smuzhiyun #define SDHCI_DIV_MASK 0xFF
99*4882a593Smuzhiyun #define SDHCI_DIV_MASK_LEN 8
100*4882a593Smuzhiyun #define SDHCI_DIV_HI_MASK 0x300
101*4882a593Smuzhiyun #define SDHCI_PROG_CLOCK_MODE BIT(5)
102*4882a593Smuzhiyun #define SDHCI_CLOCK_CARD_EN BIT(2)
103*4882a593Smuzhiyun #define SDHCI_CLOCK_INT_STABLE BIT(1)
104*4882a593Smuzhiyun #define SDHCI_CLOCK_INT_EN BIT(0)
105*4882a593Smuzhiyun
106*4882a593Smuzhiyun #define SDHCI_TIMEOUT_CONTROL 0x2E
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun #define SDHCI_SOFTWARE_RESET 0x2F
109*4882a593Smuzhiyun #define SDHCI_RESET_ALL 0x01
110*4882a593Smuzhiyun #define SDHCI_RESET_CMD 0x02
111*4882a593Smuzhiyun #define SDHCI_RESET_DATA 0x04
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun #define SDHCI_INT_STATUS 0x30
114*4882a593Smuzhiyun #define SDHCI_INT_ENABLE 0x34
115*4882a593Smuzhiyun #define SDHCI_SIGNAL_ENABLE 0x38
116*4882a593Smuzhiyun #define SDHCI_INT_RESPONSE BIT(0)
117*4882a593Smuzhiyun #define SDHCI_INT_DATA_END BIT(1)
118*4882a593Smuzhiyun #define SDHCI_INT_DMA_END BIT(3)
119*4882a593Smuzhiyun #define SDHCI_INT_SPACE_AVAIL BIT(4)
120*4882a593Smuzhiyun #define SDHCI_INT_DATA_AVAIL BIT(5)
121*4882a593Smuzhiyun #define SDHCI_INT_CARD_INSERT BIT(6)
122*4882a593Smuzhiyun #define SDHCI_INT_CARD_REMOVE BIT(7)
123*4882a593Smuzhiyun #define SDHCI_INT_CARD_INT BIT(8)
124*4882a593Smuzhiyun #define SDHCI_INT_ERROR BIT(15)
125*4882a593Smuzhiyun #define SDHCI_INT_TIMEOUT BIT(16)
126*4882a593Smuzhiyun #define SDHCI_INT_CRC BIT(17)
127*4882a593Smuzhiyun #define SDHCI_INT_END_BIT BIT(18)
128*4882a593Smuzhiyun #define SDHCI_INT_INDEX BIT(19)
129*4882a593Smuzhiyun #define SDHCI_INT_DATA_TIMEOUT BIT(20)
130*4882a593Smuzhiyun #define SDHCI_INT_DATA_CRC BIT(21)
131*4882a593Smuzhiyun #define SDHCI_INT_DATA_END_BIT BIT(22)
132*4882a593Smuzhiyun #define SDHCI_INT_BUS_POWER BIT(23)
133*4882a593Smuzhiyun #define SDHCI_INT_ACMD12ERR BIT(24)
134*4882a593Smuzhiyun #define SDHCI_INT_ADMA_ERROR BIT(25)
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun #define SDHCI_INT_NORMAL_MASK 0x00007FFF
137*4882a593Smuzhiyun #define SDHCI_INT_ERROR_MASK 0xFFFF8000
138*4882a593Smuzhiyun
139*4882a593Smuzhiyun #define SDHCI_INT_CMD_MASK (SDHCI_INT_RESPONSE | SDHCI_INT_TIMEOUT | \
140*4882a593Smuzhiyun SDHCI_INT_CRC | SDHCI_INT_END_BIT | SDHCI_INT_INDEX)
141*4882a593Smuzhiyun #define SDHCI_INT_DATA_MASK (SDHCI_INT_DATA_END | SDHCI_INT_DMA_END | \
142*4882a593Smuzhiyun SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
143*4882a593Smuzhiyun SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
144*4882a593Smuzhiyun SDHCI_INT_DATA_END_BIT | SDHCI_INT_ADMA_ERROR)
145*4882a593Smuzhiyun #define SDHCI_INT_ALL_MASK ((unsigned int)-1)
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun #define SDHCI_ACMD12_ERR 0x3C
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun /* 3E-3F reserved */
150*4882a593Smuzhiyun #define SDHCI_HOST_CONTROL2 0x3E
151*4882a593Smuzhiyun #define SDHCI_CTRL_UHS_MASK 0x0007
152*4882a593Smuzhiyun #define SDHCI_CTRL_UHS_SDR12 0x0000
153*4882a593Smuzhiyun #define SDHCI_CTRL_UHS_SDR25 0x0001
154*4882a593Smuzhiyun #define SDHCI_CTRL_UHS_SDR50 0x0002
155*4882a593Smuzhiyun #define SDHCI_CTRL_UHS_SDR104 0x0003
156*4882a593Smuzhiyun #define SDHCI_CTRL_UHS_DDR50 0x0004
157*4882a593Smuzhiyun #define SDHCI_CTRL_HS400 0x0005
158*4882a593Smuzhiyun #define SDHCI_CTRL_VDD_180 0x0008
159*4882a593Smuzhiyun #define SDHCI_CTRL_DRV_TYPE_MASK 0x0030
160*4882a593Smuzhiyun #define SDHCI_CTRL_DRV_TYPE_B 0x0000
161*4882a593Smuzhiyun #define SDHCI_CTRL_DRV_TYPE_A 0x0010
162*4882a593Smuzhiyun #define SDHCI_CTRL_DRV_TYPE_C 0x0020
163*4882a593Smuzhiyun #define SDHCI_CTRL_DRV_TYPE_D 0x0030
164*4882a593Smuzhiyun #define SDHCI_CTRL_EXEC_TUNING 0x0040
165*4882a593Smuzhiyun #define SDHCI_CTRL_TUNED_CLK 0x0080
166*4882a593Smuzhiyun #define SDHCI_CTRL_PRESET_VAL_ENABLE 0x8000
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun #define SDHCI_CAPABILITIES 0x40
169*4882a593Smuzhiyun #define SDHCI_TIMEOUT_CLK_MASK 0x0000003F
170*4882a593Smuzhiyun #define SDHCI_TIMEOUT_CLK_SHIFT 0
171*4882a593Smuzhiyun #define SDHCI_TIMEOUT_CLK_UNIT 0x00000080
172*4882a593Smuzhiyun #define SDHCI_CLOCK_BASE_MASK 0x00003F00
173*4882a593Smuzhiyun #define SDHCI_CLOCK_V3_BASE_MASK 0x0000FF00
174*4882a593Smuzhiyun #define SDHCI_CLOCK_BASE_SHIFT 8
175*4882a593Smuzhiyun #define SDHCI_MAX_BLOCK_MASK 0x00030000
176*4882a593Smuzhiyun #define SDHCI_MAX_BLOCK_SHIFT 16
177*4882a593Smuzhiyun #define SDHCI_CAN_DO_8BIT BIT(18)
178*4882a593Smuzhiyun #define SDHCI_CAN_DO_ADMA2 BIT(19)
179*4882a593Smuzhiyun #define SDHCI_CAN_DO_ADMA1 BIT(20)
180*4882a593Smuzhiyun #define SDHCI_CAN_DO_HISPD BIT(21)
181*4882a593Smuzhiyun #define SDHCI_CAN_DO_SDMA BIT(22)
182*4882a593Smuzhiyun #define SDHCI_CAN_VDD_330 BIT(24)
183*4882a593Smuzhiyun #define SDHCI_CAN_VDD_300 BIT(25)
184*4882a593Smuzhiyun #define SDHCI_CAN_VDD_180 BIT(26)
185*4882a593Smuzhiyun #define SDHCI_CAN_64BIT BIT(28)
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun #define SDHCI_CAPABILITIES_1 0x44
188*4882a593Smuzhiyun #define SDHCI_CLOCK_MUL_MASK 0x00FF0000
189*4882a593Smuzhiyun #define SDHCI_CLOCK_MUL_SHIFT 16
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun #define SDHCI_MAX_CURRENT 0x48
192*4882a593Smuzhiyun
193*4882a593Smuzhiyun /* 4C-4F reserved for more max current */
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun #define SDHCI_SET_ACMD12_ERROR 0x50
196*4882a593Smuzhiyun #define SDHCI_SET_INT_ERROR 0x52
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun #define SDHCI_ADMA_ERROR 0x54
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun /* 55-57 reserved */
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun #define SDHCI_ADMA_ADDRESS 0x58
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun /* 60-FB reserved */
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun #define SDHCI_SLOT_INT_STATUS 0xFC
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun #define SDHCI_HOST_VERSION 0xFE
209*4882a593Smuzhiyun #define SDHCI_VENDOR_VER_MASK 0xFF00
210*4882a593Smuzhiyun #define SDHCI_VENDOR_VER_SHIFT 8
211*4882a593Smuzhiyun #define SDHCI_SPEC_VER_MASK 0x00FF
212*4882a593Smuzhiyun #define SDHCI_SPEC_VER_SHIFT 0
213*4882a593Smuzhiyun #define SDHCI_SPEC_100 0
214*4882a593Smuzhiyun #define SDHCI_SPEC_200 1
215*4882a593Smuzhiyun #define SDHCI_SPEC_300 2
216*4882a593Smuzhiyun
217*4882a593Smuzhiyun #define SDHCI_GET_VERSION(x) (x->version & SDHCI_SPEC_VER_MASK)
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun /*
220*4882a593Smuzhiyun * End of controller registers.
221*4882a593Smuzhiyun */
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun #define SDHCI_MAX_DIV_SPEC_200 256
224*4882a593Smuzhiyun #define SDHCI_MAX_DIV_SPEC_300 2046
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun /*
227*4882a593Smuzhiyun * quirks
228*4882a593Smuzhiyun */
229*4882a593Smuzhiyun #define SDHCI_QUIRK_32BIT_DMA_ADDR (1 << 0)
230*4882a593Smuzhiyun #define SDHCI_QUIRK_REG32_RW (1 << 1)
231*4882a593Smuzhiyun #define SDHCI_QUIRK_BROKEN_R1B (1 << 2)
232*4882a593Smuzhiyun #define SDHCI_QUIRK_NO_HISPD_BIT (1 << 3)
233*4882a593Smuzhiyun #define SDHCI_QUIRK_BROKEN_VOLTAGE (1 << 4)
234*4882a593Smuzhiyun #define SDHCI_QUIRK_WAIT_SEND_CMD (1 << 6)
235*4882a593Smuzhiyun #define SDHCI_QUIRK_USE_WIDE8 (1 << 8)
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun /* to make gcc happy */
238*4882a593Smuzhiyun struct sdhci_host;
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun /*
241*4882a593Smuzhiyun * Host SDMA buffer boundary. Valid values from 4K to 512K in powers of 2.
242*4882a593Smuzhiyun */
243*4882a593Smuzhiyun #define SDHCI_DEFAULT_BOUNDARY_SIZE (512 * 1024)
244*4882a593Smuzhiyun #define SDHCI_DEFAULT_BOUNDARY_ARG (7)
245*4882a593Smuzhiyun struct sdhci_ops {
246*4882a593Smuzhiyun #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
247*4882a593Smuzhiyun u32 (*read_l)(struct sdhci_host *host, int reg);
248*4882a593Smuzhiyun u16 (*read_w)(struct sdhci_host *host, int reg);
249*4882a593Smuzhiyun u8 (*read_b)(struct sdhci_host *host, int reg);
250*4882a593Smuzhiyun void (*write_l)(struct sdhci_host *host, u32 val, int reg);
251*4882a593Smuzhiyun void (*write_w)(struct sdhci_host *host, u16 val, int reg);
252*4882a593Smuzhiyun void (*write_b)(struct sdhci_host *host, u8 val, int reg);
253*4882a593Smuzhiyun #endif
254*4882a593Smuzhiyun int (*get_cd)(struct sdhci_host *host);
255*4882a593Smuzhiyun void (*set_control_reg)(struct sdhci_host *host);
256*4882a593Smuzhiyun void (*set_ios_post)(struct sdhci_host *host);
257*4882a593Smuzhiyun int (*set_clock)(struct sdhci_host *host, unsigned int clock);
258*4882a593Smuzhiyun void (*set_clock_ext)(struct sdhci_host *host, u32 div);
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun /**
261*4882a593Smuzhiyun * set_enhanced_strobe() - Set HS400 Enhanced Strobe config
262*4882a593Smuzhiyun *
263*4882a593Smuzhiyun * This is called after setting the card speed and mode to
264*4882a593Smuzhiyun * HS400 ES, and should set any host-specific configuration
265*4882a593Smuzhiyun * necessary for it.
266*4882a593Smuzhiyun *
267*4882a593Smuzhiyun * @host: SDHCI host structure
268*4882a593Smuzhiyun * Return: 0 if successful, -ve on error
269*4882a593Smuzhiyun */
270*4882a593Smuzhiyun int (*set_enhanced_strobe)(struct sdhci_host *host);
271*4882a593Smuzhiyun };
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun struct sdhci_host {
274*4882a593Smuzhiyun const char *name;
275*4882a593Smuzhiyun void *ioaddr;
276*4882a593Smuzhiyun unsigned int quirks;
277*4882a593Smuzhiyun unsigned int host_caps;
278*4882a593Smuzhiyun unsigned int version;
279*4882a593Smuzhiyun unsigned int max_clk; /* Maximum Base Clock frequency */
280*4882a593Smuzhiyun unsigned int clk_mul; /* Clock Multiplier value */
281*4882a593Smuzhiyun unsigned int clock;
282*4882a593Smuzhiyun struct mmc *mmc;
283*4882a593Smuzhiyun const struct sdhci_ops *ops;
284*4882a593Smuzhiyun int index;
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun int bus_width;
287*4882a593Smuzhiyun struct gpio_desc pwr_gpio; /* Power GPIO */
288*4882a593Smuzhiyun struct gpio_desc cd_gpio; /* Card Detect GPIO */
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun uint voltages;
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun struct mmc_config cfg;
293*4882a593Smuzhiyun };
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun void sdhci_enable_clk(struct sdhci_host *host, u16 clk);
296*4882a593Smuzhiyun int sdhci_set_clock(struct sdhci_host *host, unsigned int clock);
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun #ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
299*4882a593Smuzhiyun
sdhci_writel(struct sdhci_host * host,u32 val,int reg)300*4882a593Smuzhiyun static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun if (unlikely(host->ops->write_l))
303*4882a593Smuzhiyun host->ops->write_l(host, val, reg);
304*4882a593Smuzhiyun else
305*4882a593Smuzhiyun writel(val, host->ioaddr + reg);
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun
sdhci_writew(struct sdhci_host * host,u16 val,int reg)308*4882a593Smuzhiyun static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg)
309*4882a593Smuzhiyun {
310*4882a593Smuzhiyun if (unlikely(host->ops->write_w))
311*4882a593Smuzhiyun host->ops->write_w(host, val, reg);
312*4882a593Smuzhiyun else
313*4882a593Smuzhiyun writew(val, host->ioaddr + reg);
314*4882a593Smuzhiyun }
315*4882a593Smuzhiyun
sdhci_writeb(struct sdhci_host * host,u8 val,int reg)316*4882a593Smuzhiyun static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
317*4882a593Smuzhiyun {
318*4882a593Smuzhiyun if (unlikely(host->ops->write_b))
319*4882a593Smuzhiyun host->ops->write_b(host, val, reg);
320*4882a593Smuzhiyun else
321*4882a593Smuzhiyun writeb(val, host->ioaddr + reg);
322*4882a593Smuzhiyun }
323*4882a593Smuzhiyun
sdhci_readl(struct sdhci_host * host,int reg)324*4882a593Smuzhiyun static inline u32 sdhci_readl(struct sdhci_host *host, int reg)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun if (unlikely(host->ops->read_l))
327*4882a593Smuzhiyun return host->ops->read_l(host, reg);
328*4882a593Smuzhiyun else
329*4882a593Smuzhiyun return readl(host->ioaddr + reg);
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun
sdhci_readw(struct sdhci_host * host,int reg)332*4882a593Smuzhiyun static inline u16 sdhci_readw(struct sdhci_host *host, int reg)
333*4882a593Smuzhiyun {
334*4882a593Smuzhiyun if (unlikely(host->ops->read_w))
335*4882a593Smuzhiyun return host->ops->read_w(host, reg);
336*4882a593Smuzhiyun else
337*4882a593Smuzhiyun return readw(host->ioaddr + reg);
338*4882a593Smuzhiyun }
339*4882a593Smuzhiyun
sdhci_readb(struct sdhci_host * host,int reg)340*4882a593Smuzhiyun static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
341*4882a593Smuzhiyun {
342*4882a593Smuzhiyun if (unlikely(host->ops->read_b))
343*4882a593Smuzhiyun return host->ops->read_b(host, reg);
344*4882a593Smuzhiyun else
345*4882a593Smuzhiyun return readb(host->ioaddr + reg);
346*4882a593Smuzhiyun }
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun #else
349*4882a593Smuzhiyun
sdhci_writel(struct sdhci_host * host,u32 val,int reg)350*4882a593Smuzhiyun static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg)
351*4882a593Smuzhiyun {
352*4882a593Smuzhiyun writel(val, host->ioaddr + reg);
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun
sdhci_writew(struct sdhci_host * host,u16 val,int reg)355*4882a593Smuzhiyun static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg)
356*4882a593Smuzhiyun {
357*4882a593Smuzhiyun writew(val, host->ioaddr + reg);
358*4882a593Smuzhiyun }
359*4882a593Smuzhiyun
sdhci_writeb(struct sdhci_host * host,u8 val,int reg)360*4882a593Smuzhiyun static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
361*4882a593Smuzhiyun {
362*4882a593Smuzhiyun writeb(val, host->ioaddr + reg);
363*4882a593Smuzhiyun }
sdhci_readl(struct sdhci_host * host,int reg)364*4882a593Smuzhiyun static inline u32 sdhci_readl(struct sdhci_host *host, int reg)
365*4882a593Smuzhiyun {
366*4882a593Smuzhiyun return readl(host->ioaddr + reg);
367*4882a593Smuzhiyun }
368*4882a593Smuzhiyun
sdhci_readw(struct sdhci_host * host,int reg)369*4882a593Smuzhiyun static inline u16 sdhci_readw(struct sdhci_host *host, int reg)
370*4882a593Smuzhiyun {
371*4882a593Smuzhiyun return readw(host->ioaddr + reg);
372*4882a593Smuzhiyun }
373*4882a593Smuzhiyun
sdhci_readb(struct sdhci_host * host,int reg)374*4882a593Smuzhiyun static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
375*4882a593Smuzhiyun {
376*4882a593Smuzhiyun return readb(host->ioaddr + reg);
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun #endif
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun #ifdef CONFIG_BLK
381*4882a593Smuzhiyun /**
382*4882a593Smuzhiyun * sdhci_setup_cfg() - Set up the configuration for DWMMC
383*4882a593Smuzhiyun *
384*4882a593Smuzhiyun * This is used to set up an SDHCI device when you are using CONFIG_BLK.
385*4882a593Smuzhiyun *
386*4882a593Smuzhiyun * This should be called from your MMC driver's probe() method once you have
387*4882a593Smuzhiyun * the information required.
388*4882a593Smuzhiyun *
389*4882a593Smuzhiyun * Generally your driver will have a platform data structure which holds both
390*4882a593Smuzhiyun * the configuration (struct mmc_config) and the MMC device info (struct mmc).
391*4882a593Smuzhiyun * For example:
392*4882a593Smuzhiyun *
393*4882a593Smuzhiyun * struct msm_sdhc_plat {
394*4882a593Smuzhiyun * struct mmc_config cfg;
395*4882a593Smuzhiyun * struct mmc mmc;
396*4882a593Smuzhiyun * };
397*4882a593Smuzhiyun *
398*4882a593Smuzhiyun * ...
399*4882a593Smuzhiyun *
400*4882a593Smuzhiyun * Inside U_BOOT_DRIVER():
401*4882a593Smuzhiyun * .platdata_auto_alloc_size = sizeof(struct msm_sdhc_plat),
402*4882a593Smuzhiyun *
403*4882a593Smuzhiyun * To access platform data:
404*4882a593Smuzhiyun * struct msm_sdhc_plat *plat = dev_get_platdata(dev);
405*4882a593Smuzhiyun *
406*4882a593Smuzhiyun * See msm_sdhci.c for an example.
407*4882a593Smuzhiyun *
408*4882a593Smuzhiyun * @cfg: Configuration structure to fill in (generally &plat->mmc)
409*4882a593Smuzhiyun * @host: SDHCI host structure
410*4882a593Smuzhiyun * @f_max: Maximum supported clock frequency in HZ (0 for default)
411*4882a593Smuzhiyun * @f_min: Minimum supported clock frequency in HZ (0 for default)
412*4882a593Smuzhiyun */
413*4882a593Smuzhiyun int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
414*4882a593Smuzhiyun u32 f_max, u32 f_min);
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun /**
417*4882a593Smuzhiyun * sdhci_bind() - Set up a new MMC block device
418*4882a593Smuzhiyun *
419*4882a593Smuzhiyun * This is used to set up an SDHCI block device when you are using CONFIG_BLK.
420*4882a593Smuzhiyun * It should be called from your driver's bind() method.
421*4882a593Smuzhiyun *
422*4882a593Smuzhiyun * See msm_sdhci.c for an example.
423*4882a593Smuzhiyun *
424*4882a593Smuzhiyun * @dev: Device to set up
425*4882a593Smuzhiyun * @mmc: Pointer to mmc structure (normally &plat->mmc)
426*4882a593Smuzhiyun * @cfg: Empty configuration structure (generally &plat->cfg). This is
427*4882a593Smuzhiyun * normally all zeroes at this point. The only purpose of passing
428*4882a593Smuzhiyun * this in is to set mmc->cfg to it.
429*4882a593Smuzhiyun * @return 0 if OK, -ve if the block device could not be created
430*4882a593Smuzhiyun */
431*4882a593Smuzhiyun int sdhci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg);
432*4882a593Smuzhiyun #else
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun /**
435*4882a593Smuzhiyun * add_sdhci() - Add a new SDHCI interface
436*4882a593Smuzhiyun *
437*4882a593Smuzhiyun * This is used when you are not using CONFIG_BLK. Convert your driver over!
438*4882a593Smuzhiyun *
439*4882a593Smuzhiyun * @host: SDHCI host structure
440*4882a593Smuzhiyun * @f_max: Maximum supported clock frequency in HZ (0 for default)
441*4882a593Smuzhiyun * @f_min: Minimum supported clock frequency in HZ (0 for default)
442*4882a593Smuzhiyun * @return 0 if OK, -ve on error
443*4882a593Smuzhiyun */
444*4882a593Smuzhiyun int add_sdhci(struct sdhci_host *host, u32 f_max, u32 f_min);
445*4882a593Smuzhiyun #endif /* !CONFIG_BLK */
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun #ifdef CONFIG_DM_MMC
448*4882a593Smuzhiyun /* Export the operations to drivers */
449*4882a593Smuzhiyun int sdhci_probe(struct udevice *dev);
450*4882a593Smuzhiyun extern const struct dm_mmc_ops sdhci_ops;
451*4882a593Smuzhiyun #else
452*4882a593Smuzhiyun #endif
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun #endif /* __SDHCI_HW_H */
455