xref: /netbsd-src/sys/dev/ic/pl181.c (revision 796c32c94f6e154afc9de0f63da35c91bb739b45)
1 /* $NetBSD: pl181.c,v 1.4 2017/06/04 15:08:30 jmcneill Exp $ */
2 
3 /*-
4  * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: pl181.c,v 1.4 2017/06/04 15:08:30 jmcneill Exp $");
31 
32 #include <sys/param.h>
33 #include <sys/bus.h>
34 #include <sys/device.h>
35 #include <sys/intr.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 
39 #include <dev/sdmmc/sdmmcvar.h>
40 #include <dev/sdmmc/sdmmcchip.h>
41 #include <dev/sdmmc/sdmmc_ioreg.h>
42 
43 #include <dev/ic/pl181reg.h>
44 #include <dev/ic/pl181var.h>
45 
46 /*
47  * Data length register is 16 bits for a maximum of 65535 bytes. Round
48  * maximum transfer size down to the nearest sector.
49  */
50 #define	PLMMC_MAXXFER	rounddown(65535, SDMMC_SECTOR_SIZE)
51 
52 static int	plmmc_host_reset(sdmmc_chipset_handle_t);
53 static uint32_t	plmmc_host_ocr(sdmmc_chipset_handle_t);
54 static int	plmmc_host_maxblklen(sdmmc_chipset_handle_t);
55 static int	plmmc_card_detect(sdmmc_chipset_handle_t);
56 static int	plmmc_write_protect(sdmmc_chipset_handle_t);
57 static int	plmmc_bus_power(sdmmc_chipset_handle_t, uint32_t);
58 static int	plmmc_bus_clock(sdmmc_chipset_handle_t, int);
59 static int	plmmc_bus_width(sdmmc_chipset_handle_t, int);
60 static int	plmmc_bus_rod(sdmmc_chipset_handle_t, int);
61 static void	plmmc_exec_command(sdmmc_chipset_handle_t,
62 				     struct sdmmc_command *);
63 static void	plmmc_card_enable_intr(sdmmc_chipset_handle_t, int);
64 static void	plmmc_card_intr_ack(sdmmc_chipset_handle_t);
65 
66 static int	plmmc_wait_status(struct plmmc_softc *, uint32_t, int);
67 static int	plmmc_pio_wait(struct plmmc_softc *,
68 				 struct sdmmc_command *);
69 static int	plmmc_pio_transfer(struct plmmc_softc *,
70 				     struct sdmmc_command *, int);
71 
72 static struct sdmmc_chip_functions plmmc_chip_functions = {
73 	.host_reset = plmmc_host_reset,
74 	.host_ocr = plmmc_host_ocr,
75 	.host_maxblklen = plmmc_host_maxblklen,
76 	.card_detect = plmmc_card_detect,
77 	.write_protect = plmmc_write_protect,
78 	.bus_power = plmmc_bus_power,
79 	.bus_clock = plmmc_bus_clock,
80 	.bus_width = plmmc_bus_width,
81 	.bus_rod = plmmc_bus_rod,
82 	.exec_command = plmmc_exec_command,
83 	.card_enable_intr = plmmc_card_enable_intr,
84 	.card_intr_ack = plmmc_card_intr_ack,
85 };
86 
87 #define MMCI_WRITE(sc, reg, val) \
88 	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
89 #define MMCI_READ(sc, reg) \
90 	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
91 
92 void
93 plmmc_init(struct plmmc_softc *sc)
94 {
95 	struct sdmmcbus_attach_args saa;
96 
97 	mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_BIO);
98 	cv_init(&sc->sc_intr_cv, "plmmcirq");
99 
100 #ifdef PLMMC_DEBUG
101 	device_printf(sc->sc_dev, "PeriphID %#x %#x %#x %#x\n",
102 	    MMCI_READ(sc, MMCI_PERIPH_ID0_REG),
103 	    MMCI_READ(sc, MMCI_PERIPH_ID1_REG),
104 	    MMCI_READ(sc, MMCI_PERIPH_ID2_REG),
105 	    MMCI_READ(sc, MMCI_PERIPH_ID3_REG));
106 	device_printf(sc->sc_dev, "PCellID %#x %#x %#x %#x\n",
107 	    MMCI_READ(sc, MMCI_PCELL_ID0_REG),
108 	    MMCI_READ(sc, MMCI_PCELL_ID1_REG),
109 	    MMCI_READ(sc, MMCI_PCELL_ID2_REG),
110 	    MMCI_READ(sc, MMCI_PCELL_ID3_REG));
111 #endif
112 
113 	plmmc_bus_clock(sc, 400);
114 	MMCI_WRITE(sc, MMCI_POWER_REG, 0);
115 	delay(10000);
116 	MMCI_WRITE(sc, MMCI_POWER_REG, MMCI_POWER_CTRL_POWERUP);
117 	delay(10000);
118 	MMCI_WRITE(sc, MMCI_POWER_REG, MMCI_POWER_CTRL_POWERON);
119 	plmmc_host_reset(sc);
120 
121 	memset(&saa, 0, sizeof(saa));
122 	saa.saa_busname = "sdmmc";
123 	saa.saa_sct = &plmmc_chip_functions;
124 	saa.saa_sch = sc;
125 	saa.saa_clkmin = 400;
126 	saa.saa_clkmax = sc->sc_max_freq > 0 ?
127 	    sc->sc_max_freq / 1000 : sc->sc_clock_freq / 1000;
128 	saa.saa_caps = SMC_CAPS_4BIT_MODE;
129 
130 	sc->sc_sdmmc_dev = config_found(sc->sc_dev, &saa, NULL);
131 }
132 
133 int
134 plmmc_intr(void *priv)
135 {
136 	struct plmmc_softc *sc = priv;
137 	uint32_t status;
138 
139 	mutex_enter(&sc->sc_intr_lock);
140 	status = MMCI_READ(sc, MMCI_STATUS_REG);
141 #ifdef PLMMC_DEBUG
142 	printf("%s: MMCI_STATUS_REG = %#x\n", __func__, status);
143 #endif
144 	if (!status) {
145 		mutex_exit(&sc->sc_intr_lock);
146 		return 0;
147 	}
148 
149 	sc->sc_intr_status |= status;
150 	cv_broadcast(&sc->sc_intr_cv);
151 
152 	mutex_exit(&sc->sc_intr_lock);
153 
154 	return 1;
155 }
156 
157 static int
158 plmmc_wait_status(struct plmmc_softc *sc, uint32_t mask, int timeout)
159 {
160 	int retry, error;
161 
162 	KASSERT(mutex_owned(&sc->sc_intr_lock));
163 
164 	if (sc->sc_intr_status & mask)
165 		return 0;
166 
167 	retry = timeout / hz;
168 	if (sc->sc_ih == NULL)
169 		retry *= 1000;
170 
171 	while (retry > 0) {
172 		if (sc->sc_ih == NULL) {
173 			sc->sc_intr_status |= MMCI_READ(sc, MMCI_STATUS_REG);
174 			if (sc->sc_intr_status & mask)
175 				return 0;
176 			delay(10000);
177 		} else {
178 			error = cv_timedwait(&sc->sc_intr_cv,
179 			    &sc->sc_intr_lock, hz);
180 			if (error && error != EWOULDBLOCK) {
181 				device_printf(sc->sc_dev,
182 				    "cv_timedwait returned %d\n", error);
183 				return error;
184 			}
185 			if (sc->sc_intr_status & mask)
186 				return 0;
187 		}
188 		--retry;
189 	}
190 
191 	device_printf(sc->sc_dev, "%s timeout, MMCI_STATUS_REG = %#x\n",
192 	    __func__, MMCI_READ(sc, MMCI_STATUS_REG));
193 
194 	return ETIMEDOUT;
195 }
196 
197 static int
198 plmmc_pio_wait(struct plmmc_softc *sc, struct sdmmc_command *cmd)
199 {
200 	uint32_t bit = (cmd->c_flags & SCF_CMD_READ) ?
201 	    MMCI_INT_RX_DATA_AVAIL : MMCI_INT_TX_FIFO_EMPTY;
202 
203 	MMCI_WRITE(sc, MMCI_CLEAR_REG, bit);
204 	const int error = plmmc_wait_status(sc,
205 		bit | MMCI_INT_DATA_END | MMCI_INT_DATA_BLOCK_END, hz*2);
206 	sc->sc_intr_status &= ~bit;
207 
208 	return error;
209 }
210 
211 static int
212 plmmc_pio_transfer(struct plmmc_softc *sc, struct sdmmc_command *cmd,
213     int xferlen)
214 {
215 	uint32_t *datap = (uint32_t *)cmd->c_buf;
216 	int i;
217 
218 	for (i = 0; i < xferlen / 4; i++) {
219 		if (plmmc_pio_wait(sc, cmd))
220 			return ETIMEDOUT;
221 		if (cmd->c_flags & SCF_CMD_READ) {
222 			datap[i] = MMCI_READ(sc, MMCI_FIFO_REG);
223 		} else {
224 			MMCI_WRITE(sc, MMCI_FIFO_REG, datap[i]);
225 		}
226 		cmd->c_resid -= 4;
227 		cmd->c_buf += 4;
228 	}
229 
230 	return 0;
231 }
232 
233 static int
234 plmmc_host_reset(sdmmc_chipset_handle_t sch)
235 {
236 	struct plmmc_softc *sc = sch;
237 
238 	MMCI_WRITE(sc, MMCI_MASK0_REG, 0);
239 	MMCI_WRITE(sc, MMCI_MASK1_REG, 0);
240 	MMCI_WRITE(sc, MMCI_CLEAR_REG, 0xffffffff);
241 
242 	return 0;
243 }
244 
245 static uint32_t
246 plmmc_host_ocr(sdmmc_chipset_handle_t sch)
247 {
248 	return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V;
249 }
250 
251 static int
252 plmmc_host_maxblklen(sdmmc_chipset_handle_t sch)
253 {
254 	return 2048;
255 }
256 
257 static int
258 plmmc_card_detect(sdmmc_chipset_handle_t sch)
259 {
260 	return 1;
261 }
262 
263 static int
264 plmmc_write_protect(sdmmc_chipset_handle_t sch)
265 {
266 	return 0;
267 }
268 
269 static int
270 plmmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr)
271 {
272 	return 0;
273 }
274 
275 static int
276 plmmc_bus_clock(sdmmc_chipset_handle_t sch, int freq)
277 {
278 	struct plmmc_softc *sc = sch;
279 	u_int pll_freq, clk_div;
280 	uint32_t clock;
281 
282 	clock = MMCI_CLOCK_PWRSAVE;
283 	if (freq) {
284 		pll_freq = sc->sc_clock_freq / 1000;
285 		clk_div = (howmany(pll_freq, freq) >> 1) - 1;
286 		clock |= __SHIFTIN(clk_div, MMCI_CLOCK_CLKDIV);
287 		clock |= MMCI_CLOCK_ENABLE;
288 	}
289 	MMCI_WRITE(sc, MMCI_CLOCK_REG, clock);
290 
291 	return 0;
292 }
293 
294 static int
295 plmmc_bus_width(sdmmc_chipset_handle_t sch, int width)
296 {
297 	return 0;
298 }
299 
300 static int
301 plmmc_bus_rod(sdmmc_chipset_handle_t sch, int on)
302 {
303 	struct plmmc_softc *sc = sch;
304 	uint32_t power;
305 
306 
307 	power = MMCI_READ(sc, MMCI_POWER_REG);
308 	if (on) {
309 		power |= MMCI_POWER_ROD;
310 	} else {
311 		power &= ~MMCI_POWER_ROD;
312 	}
313 	MMCI_WRITE(sc, MMCI_POWER_REG, power);
314 
315 	return 0;
316 }
317 
318 static void
319 plmmc_do_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
320 {
321 	struct plmmc_softc *sc = sch;
322 	uint32_t cmdval = MMCI_COMMAND_ENABLE;
323 
324 	KASSERT(mutex_owned(&sc->sc_intr_lock));
325 
326 	const int xferlen = min(cmd->c_resid, PLMMC_MAXXFER);
327 
328 #ifdef PLMMC_DEBUG
329 	device_printf(sc->sc_dev,
330 	    "opcode %d flags %#x datalen %d resid %d xferlen %d\n",
331 	    cmd->c_opcode, cmd->c_flags, cmd->c_datalen, cmd->c_resid, xferlen);
332 #endif
333 
334 	MMCI_WRITE(sc, MMCI_COMMAND_REG, 0);
335 	MMCI_WRITE(sc, MMCI_MASK0_REG, 0);
336 	MMCI_WRITE(sc, MMCI_CLEAR_REG, 0xffffffff);
337 	MMCI_WRITE(sc, MMCI_MASK0_REG,
338 	    MMCI_INT_CMD_TIMEOUT | MMCI_INT_DATA_TIMEOUT |
339 	    MMCI_INT_RX_DATA_AVAIL | MMCI_INT_TX_FIFO_EMPTY |
340 	    MMCI_INT_DATA_END | MMCI_INT_DATA_BLOCK_END |
341 	    MMCI_INT_CMD_RESP_END | MMCI_INT_CMD_SENT);
342 
343 	sc->sc_intr_status = 0;
344 
345 	if (cmd->c_flags & SCF_RSP_PRESENT)
346 		cmdval |= MMCI_COMMAND_RESPONSE;
347 	if (cmd->c_flags & SCF_RSP_136)
348 		cmdval |= MMCI_COMMAND_LONGRSP;
349 
350 	uint32_t arg = cmd->c_arg;
351 
352 	if (xferlen > 0) {
353 		unsigned int nblks = xferlen / cmd->c_blklen;
354 		if (nblks == 0 || (xferlen % cmd->c_blklen) != 0)
355 			++nblks;
356 
357 		const uint32_t dir = (cmd->c_flags & SCF_CMD_READ) ? 1 : 0;
358 		const uint32_t blksize = ffs(cmd->c_blklen) - 1;
359 
360 		MMCI_WRITE(sc, MMCI_DATA_TIMER_REG, 0xffffffff);
361 		MMCI_WRITE(sc, MMCI_DATA_LENGTH_REG, nblks * cmd->c_blklen);
362 		MMCI_WRITE(sc, MMCI_DATA_CTRL_REG,
363 		    __SHIFTIN(dir, MMCI_DATA_CTRL_DIRECTION) |
364 		    __SHIFTIN(blksize, MMCI_DATA_CTRL_BLOCKSIZE) |
365 		    MMCI_DATA_CTRL_ENABLE);
366 
367 		/* Adjust blkno if necessary */
368 		u_int blkoff =
369 		    (cmd->c_datalen - cmd->c_resid) / SDMMC_SECTOR_SIZE;
370 		if (!ISSET(cmd->c_flags, SCF_XFER_SDHC))
371 			blkoff <<= SDMMC_SECTOR_SIZE_SB;
372 		arg += blkoff;
373 	}
374 
375 	MMCI_WRITE(sc, MMCI_ARGUMENT_REG, arg);
376 	MMCI_WRITE(sc, MMCI_COMMAND_REG, cmdval | cmd->c_opcode);
377 
378 	if (xferlen > 0) {
379 		cmd->c_error = plmmc_pio_transfer(sc, cmd, xferlen);
380 		if (cmd->c_error) {
381 			device_printf(sc->sc_dev,
382 			    "error (%d) waiting for xfer\n", cmd->c_error);
383 			goto done;
384 		}
385 	}
386 
387 	if ((cmd->c_flags & SCF_RSP_PRESENT) && cmd->c_resid == 0) {
388 		cmd->c_error = plmmc_wait_status(sc,
389 		    MMCI_INT_CMD_RESP_END|MMCI_INT_CMD_TIMEOUT, hz * 2);
390 		if (cmd->c_error == 0 &&
391 		    (sc->sc_intr_status & MMCI_INT_CMD_TIMEOUT)) {
392 			cmd->c_error = ETIMEDOUT;
393 		}
394 		if (cmd->c_error) {
395 #ifdef PLMMC_DEBUG
396 			device_printf(sc->sc_dev,
397 			    "error (%d) waiting for resp\n", cmd->c_error);
398 #endif
399 			goto done;
400 		}
401 
402 		if (cmd->c_flags & SCF_RSP_136) {
403 			cmd->c_resp[3] = MMCI_READ(sc, MMCI_RESP0_REG);
404 			cmd->c_resp[2] = MMCI_READ(sc, MMCI_RESP1_REG);
405 			cmd->c_resp[1] = MMCI_READ(sc, MMCI_RESP2_REG);
406 			cmd->c_resp[0] = MMCI_READ(sc, MMCI_RESP3_REG);
407 			if (cmd->c_flags & SCF_RSP_CRC) {
408 				cmd->c_resp[0] = (cmd->c_resp[0] >> 8) |
409 				    (cmd->c_resp[1] << 24);
410 				cmd->c_resp[1] = (cmd->c_resp[1] >> 8) |
411 				    (cmd->c_resp[2] << 24);
412 				cmd->c_resp[2] = (cmd->c_resp[2] >> 8) |
413 				    (cmd->c_resp[3] << 24);
414 				cmd->c_resp[3] = (cmd->c_resp[3] >> 8);
415 			}
416 		} else {
417 			cmd->c_resp[0] = MMCI_READ(sc, MMCI_RESP0_REG);
418 		}
419 	}
420 
421 done:
422 	MMCI_WRITE(sc, MMCI_COMMAND_REG, 0);
423 	MMCI_WRITE(sc, MMCI_MASK0_REG, 0);
424 	MMCI_WRITE(sc, MMCI_CLEAR_REG, 0xffffffff);
425 	MMCI_WRITE(sc, MMCI_DATA_CNT_REG, 0);
426 
427 #ifdef PLMMC_DEBUG
428 	device_printf(sc->sc_dev, "MMCI_STATUS_REG = %#x\n",
429 	    MMCI_READ(sc, MMCI_STATUS_REG));
430 #endif
431 }
432 
433 static void
434 plmmc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd)
435 {
436 	struct plmmc_softc *sc = sch;
437 
438 #ifdef PLMMC_DEBUG
439 	device_printf(sc->sc_dev, "opcode %d flags %#x data %p datalen %d\n",
440 	    cmd->c_opcode, cmd->c_flags, cmd->c_data, cmd->c_datalen);
441 #endif
442 
443 	mutex_enter(&sc->sc_intr_lock);
444 	cmd->c_resid = cmd->c_datalen;
445 	cmd->c_buf = cmd->c_data;
446 	do {
447 		plmmc_do_command(sch, cmd);
448 
449 		if (cmd->c_resid > 0 && cmd->c_error == 0) {
450 			/*
451 			 * Multi block transfer and there is still data
452 			 * remaining. Send a stop cmd between transfers.
453 			 */
454 			struct sdmmc_command stop_cmd;
455 			memset(&stop_cmd, 0, sizeof(stop_cmd));
456 			stop_cmd.c_opcode = MMC_STOP_TRANSMISSION;
457 			stop_cmd.c_flags = SCF_CMD_AC | SCF_RSP_R1B |
458 			    SCF_RSP_SPI_R1B;
459 			plmmc_do_command(sch, &stop_cmd);
460 		}
461 	} while (cmd->c_resid > 0 && cmd->c_error == 0);
462 	cmd->c_flags |= SCF_ITSDONE;
463 	mutex_exit(&sc->sc_intr_lock);
464 }
465 
466 static void
467 plmmc_card_enable_intr(sdmmc_chipset_handle_t sch, int enable)
468 {
469 }
470 
471 static void
472 plmmc_card_intr_ack(sdmmc_chipset_handle_t sch)
473 {
474 }
475