Thu Jan 28 11:45:31 2021 UTC ()
port-arm/55957: Odroid C2 can not access eMMC card

A few changes to clock setup:
 - Disable clock while changing dividers
 - Set / clear DDR flag before changing clock
 - Adjust TX/RX/core phases


(jmcneill)
diff -r1.13 -r1.14 src/sys/arch/arm/amlogic/mesongx_mmc.c

cvs diff -r1.13 -r1.14 src/sys/arch/arm/amlogic/mesongx_mmc.c (expand / switch to unified diff)

--- src/sys/arch/arm/amlogic/mesongx_mmc.c 2021/01/27 03:10:18 1.13
+++ src/sys/arch/arm/amlogic/mesongx_mmc.c 2021/01/28 11:45:31 1.14
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: mesongx_mmc.c,v 1.13 2021/01/27 03:10:18 thorpej Exp $ */ 1/* $NetBSD: mesongx_mmc.c,v 1.14 2021/01/28 11:45:31 jmcneill Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca> 4 * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca>
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -17,27 +17,27 @@ @@ -17,27 +17,27 @@
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 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 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include <sys/cdefs.h> 29#include <sys/cdefs.h>
30__KERNEL_RCSID(0, "$NetBSD: mesongx_mmc.c,v 1.13 2021/01/27 03:10:18 thorpej Exp $"); 30__KERNEL_RCSID(0, "$NetBSD: mesongx_mmc.c,v 1.14 2021/01/28 11:45:31 jmcneill Exp $");
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/bus.h> 33#include <sys/bus.h>
34#include <sys/device.h> 34#include <sys/device.h>
35#include <sys/intr.h> 35#include <sys/intr.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/kernel.h> 37#include <sys/kernel.h>
38#include <sys/bitops.h> 38#include <sys/bitops.h>
39#include <sys/gpio.h> 39#include <sys/gpio.h>
40 40
41#include <dev/sdmmc/sdmmcvar.h> 41#include <dev/sdmmc/sdmmcvar.h>
42#include <dev/sdmmc/sdmmcchip.h> 42#include <dev/sdmmc/sdmmcchip.h>
43#include <dev/sdmmc/sdmmc_ioreg.h> 43#include <dev/sdmmc/sdmmc_ioreg.h>
@@ -486,43 +486,58 @@ mesongx_mmc_set_clock(struct mesongx_mmc @@ -486,43 +486,58 @@ mesongx_mmc_set_clock(struct mesongx_mmc
486 continue; 486 continue;
487 const int diff = target_rate - rate; 487 const int diff = target_rate - rate;
488 if (diff < best_diff) { 488 if (diff < best_diff) {
489 best_diff = diff; 489 best_diff = diff;
490 best_sel = sel; 490 best_sel = sel;
491 best_div = div; 491 best_div = div;
492 } 492 }
493 } 493 }
494 } 494 }
495 495
496 if (best_diff == INT_MAX) 496 if (best_diff == INT_MAX)
497 return ERANGE; 497 return ERANGE;
498 498
 499 val = MMC_READ(sc, SD_EMMC_CFG);
 500 val |= CFG_STOP_CLK;
 501 MMC_WRITE(sc, SD_EMMC_CFG, val);
 502
 503 val = MMC_READ(sc, SD_EMMC_CFG);
 504 if (ddr)
 505 val |= CFG_DDR;
 506 else
 507 val &= ~CFG_DDR;
 508 MMC_WRITE(sc, SD_EMMC_CFG, val);
 509
499 val = MMC_READ(sc, SD_EMMC_CLOCK); 510 val = MMC_READ(sc, SD_EMMC_CLOCK);
500 if (sc->sc_hwtype == MESONGX_MMC_V3) 511 if (sc->sc_hwtype == MESONGX_MMC_V3)
501 val |= CLOCK_CFG_V3_ALWAYS_ON; 512 val |= CLOCK_CFG_V3_ALWAYS_ON;
502 else 513 else
503 val |= CLOCK_CFG_V2_ALWAYS_ON; 514 val |= CLOCK_CFG_V2_ALWAYS_ON;
504 val &= ~CLOCK_CFG_RX_PHASE; 515 val &= ~CLOCK_CFG_RX_PHASE;
505 val |= __SHIFTIN(0, CLOCK_CFG_RX_PHASE); 516 val |= __SHIFTIN(0, CLOCK_CFG_RX_PHASE);
506 val &= ~CLOCK_CFG_TX_PHASE; 517 val &= ~CLOCK_CFG_TX_PHASE;
507 val |= __SHIFTIN(2, CLOCK_CFG_TX_PHASE); 518 val |= __SHIFTIN(0, CLOCK_CFG_TX_PHASE);
508 val &= ~CLOCK_CFG_CO_PHASE; 519 val &= ~CLOCK_CFG_CO_PHASE;
509 val |= __SHIFTIN(3, CLOCK_CFG_CO_PHASE); 520 val |= __SHIFTIN(2, CLOCK_CFG_CO_PHASE);
510 val &= ~CLOCK_CFG_SRC; 521 val &= ~CLOCK_CFG_SRC;
511 val |= __SHIFTIN(best_sel, CLOCK_CFG_SRC); 522 val |= __SHIFTIN(best_sel, CLOCK_CFG_SRC);
512 val &= ~CLOCK_CFG_DIV; 523 val &= ~CLOCK_CFG_DIV;
513 val |= __SHIFTIN(best_div, CLOCK_CFG_DIV); 524 val |= __SHIFTIN(best_div, CLOCK_CFG_DIV);
514 MMC_WRITE(sc, SD_EMMC_CLOCK, val); 525 MMC_WRITE(sc, SD_EMMC_CLOCK, val);
515 526
 527 val = MMC_READ(sc, SD_EMMC_CFG);
 528 val &= ~CFG_STOP_CLK;
 529 MMC_WRITE(sc, SD_EMMC_CFG, val);
 530
516 return 0; 531 return 0;
517} 532}
518 533
519static void 534static void
520mesongx_mmc_attach_i(device_t self) 535mesongx_mmc_attach_i(device_t self)
521{ 536{
522 struct mesongx_mmc_softc * const sc = device_private(self); 537 struct mesongx_mmc_softc * const sc = device_private(self);
523 struct sdmmcbus_attach_args saa; 538 struct sdmmcbus_attach_args saa;
524 uint32_t width; 539 uint32_t width;
525 540
526 if (sc->sc_pwrseq) 541 if (sc->sc_pwrseq)
527 fdtbus_mmc_pwrseq_pre_power_on(sc->sc_pwrseq); 542 fdtbus_mmc_pwrseq_pre_power_on(sc->sc_pwrseq);
528 543
@@ -723,41 +738,28 @@ mesongx_mmc_write_protect(sdmmc_chipset_ @@ -723,41 +738,28 @@ mesongx_mmc_write_protect(sdmmc_chipset_
723 return 0; 738 return 0;
724} 739}
725 740
726static int 741static int
727mesongx_mmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr) 742mesongx_mmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr)
728{ 743{
729 return 0; 744 return 0;
730} 745}
731 746
732static int 747static int
733mesongx_mmc_bus_clock(sdmmc_chipset_handle_t sch, int freq, bool ddr) 748mesongx_mmc_bus_clock(sdmmc_chipset_handle_t sch, int freq, bool ddr)
734{ 749{
735 struct mesongx_mmc_softc * const sc = sch; 750 struct mesongx_mmc_softc * const sc = sch;
736 uint32_t val; 
737 int error; 
738 
739 error = mesongx_mmc_set_clock(sc, freq, ddr); 
740 if (error != 0) 
741 return error; 
742 
743 val = MMC_READ(sc, SD_EMMC_CFG); 
744 if (ddr) 
745 val |= CFG_DDR;  
746 else 
747 val &= ~CFG_DDR; 
748 MMC_WRITE(sc, SD_EMMC_CFG, val); 
749 751
750 return 0; 752 return mesongx_mmc_set_clock(sc, freq, ddr);
751} 753}
752 754
753static int 755static int
754mesongx_mmc_bus_width(sdmmc_chipset_handle_t sch, int width) 756mesongx_mmc_bus_width(sdmmc_chipset_handle_t sch, int width)
755{ 757{
756 struct mesongx_mmc_softc *sc = sch; 758 struct mesongx_mmc_softc *sc = sch;
757 uint32_t val; 759 uint32_t val;
758 760
759 val = MMC_READ(sc, SD_EMMC_CFG); 761 val = MMC_READ(sc, SD_EMMC_CFG);
760 val &= ~CFG_BUS_WIDTH; 762 val &= ~CFG_BUS_WIDTH;
761 763
762 switch (width) { 764 switch (width) {
763 case 1: 765 case 1: