graugans / meta-udoo

:heartpulse: openembedded meta layer for the UDOO boards
MIT License
31 stars 19 forks source link

yocto don't boot on secoA62 emmc #19

Closed modjo756 closed 7 years ago

modjo756 commented 7 years ago

For the moment yocto don't boot on secoA62 emmc. Apparently a problem from uboot/SPL that is not the good version for the board. See here for more details

graugans commented 7 years ago

This is due to the fact the internal emmc is not yet activated in U-Boot

graugans commented 7 years ago

I have a preliminary patch available to activate eMMC in u-boot. At the moment the the devices are in the wrong order. U-Boot now tries to boot from emmc when booted from SD-Card... When this is sorted out I try booting from eMMC.

From 1b23a8c02d7ec0118e7bd8803e0284b51d670fa8 Mon Sep 17 00:00:00 2001
From: Christian Ege <k4230r6@gmail.com>
Date: Mon, 10 Oct 2016 21:21:38 +0200
Subject: [PATCH] Added preliminary eMMC support for Seco A62

Signed-off-by: Christian Ege <k4230r6@gmail.com>
---
 board/seco/mx6sbca62/mx6sbca62.c | 160 ++++++++++++++++++++++++++++++++++-----
 include/configs/secomx6sbca62.h  |   1 +
 2 files changed, 142 insertions(+), 19 deletions(-)

diff --git a/board/seco/mx6sbca62/mx6sbca62.c b/board/seco/mx6sbca62/mx6sbca62.c
index b8efedc..5ff4596 100644
--- a/board/seco/mx6sbca62/mx6sbca62.c
+++ b/board/seco/mx6sbca62/mx6sbca62.c
@@ -63,13 +63,38 @@ static iomux_v3_cfg_t const uart2_pads[] = {
    IOMUX_PADS(PAD_EIM_D27__UART2_RX_DATA | MUX_PAD_CTRL(UART_PAD_CTRL)),
 };

-static iomux_v3_cfg_t const usdhc3_pads[] = {
-   IOMUX_PADS(PAD_SD3_CLK__SD3_CLK    | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
-   IOMUX_PADS(PAD_SD3_CMD__SD3_CMD    | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
-   IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
-   IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
-   IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
-   IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+/*  __________________________________________________________________________
+ * |                                                                          |
+ * |                            ON BOARD uSD                             |
+ * |__________________________________________________________________________|
+ */
+iomux_v3_cfg_t const usdhc3_pads[] = {
+   IOMUX_PADS(PAD_SD3_CLK__SD3_CLK     | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+   IOMUX_PADS(PAD_SD3_CMD__SD3_CMD     | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+   IOMUX_PADS(PAD_SD3_DAT0__SD3_DATA0  | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+   IOMUX_PADS(PAD_SD3_DAT1__SD3_DATA1  | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+   IOMUX_PADS(PAD_SD3_DAT2__SD3_DATA2  | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+   IOMUX_PADS(PAD_SD3_DAT3__SD3_DATA3  | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+   IOMUX_PADS(PAD_SD3_DAT5__GPIO7_IO00 | MUX_PAD_CTRL(NO_PAD_CTRL)),     // CD
+   IOMUX_PADS(PAD_NANDF_D5__GPIO2_IO05 | MUX_PAD_CTRL(NO_PAD_CTRL)),     // PWR
+};
+
+/*  __________________________________________________________________________
+ * |                                                                          |
+ * |                             eMMC                            |
+ * |__________________________________________________________________________|
+ */
+iomux_v3_cfg_t const usdhc4_pads[] = {
+   IOMUX_PADS(PAD_SD4_CLK__SD4_CLK     | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+   IOMUX_PADS(PAD_SD4_CMD__SD4_CMD     | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+   IOMUX_PADS(PAD_SD4_DAT0__SD4_DATA0  | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+   IOMUX_PADS(PAD_SD4_DAT1__SD4_DATA1  | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+   IOMUX_PADS(PAD_SD4_DAT2__SD4_DATA2  | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+   IOMUX_PADS(PAD_SD4_DAT3__SD4_DATA3  | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+   IOMUX_PADS(PAD_SD4_DAT4__SD4_DATA4  | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+   IOMUX_PADS(PAD_SD4_DAT5__SD4_DATA5  | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+   IOMUX_PADS(PAD_SD4_DAT6__SD4_DATA6  | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
+   IOMUX_PADS(PAD_SD4_DAT7__SD4_DATA7  | MUX_PAD_CTRL(USDHC_PAD_CTRL)),
 };

 static iomux_v3_cfg_t const wdog_pads[] = {
@@ -242,12 +267,117 @@ static void setup_iomux_wdog(void)
    gpio_direction_input(WDT_TRG);
 }

-static struct fsl_esdhc_cfg usdhc_cfg = { USDHC3_BASE_ADDR };

-int board_mmc_getcd(struct mmc *mmc)
-{
-   return 1; /* Always present */
+/*  __________________________________________________________________________
+ * |                                                                          |
+ * |                                   USDHC                                  |
+ * |__________________________________________________________________________|
+ */
+#ifdef CONFIG_FSL_ESDHC
+
+#define USDHC3_CD_GPIO IMX_GPIO_NR(7, 0)
+#define USDHC3_PWR_GPIO IMX_GPIO_NR(2, 5)
+
+/* USDHC map:
+ *     USDHC4  -->  eMMC  -->  FSL_SDHC: 0
+ *     USDHC3  -->  uSD   -->  FSL_SDHC: 1
+ */
+
+struct fsl_esdhc_cfg usdhc_cfg[CONFIG_SYS_FSL_USDHC_NUM] = {
+   {USDHC4_BASE_ADDR, 0, 8},
+   {USDHC3_BASE_ADDR, 0, 4},
+};
+
+enum mxc_clock usdhc_clk[CONFIG_SYS_FSL_USDHC_NUM] = {
+   MXC_ESDHC4_CLK,
+   MXC_ESDHC3_CLK,
+};
+
+/* map the usdhc controller id to the devno given to the board device */
+int usdhc_devno[4] = { -1, -1, 1, 0};
+
+int board_mmc_getcd (struct mmc *mmc) {
+   struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+   int ret = 0;
+
+   switch (cfg->esdhc_base) {
+       case USDHC3_BASE_ADDR:
+           ret = !gpio_get_value(USDHC3_CD_GPIO);
+           break;
+       case USDHC4_BASE_ADDR:
+           ret = 1; /* eMMC/uSDHC4 is always present */
+           break;
+   }
+
+   return ret;
+}
+
+int check_mmc_autodetect (void) {
+   char *autodetect_str = getenv ("mmcautodetect");
+
+   if ( (autodetect_str != NULL) &&
+       (strcmp(autodetect_str, "yes") == 0) ) {
+       return 1;
+   }
+
+   return 0;
+}
+
+int board_mmc_init(bd_t *bis){
+#ifndef CONFIG_SPL_BUILD
+   int ret;
+   int i;
+   for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
+       switch (i) {
+       case 0:
+           SETUP_IOMUX_PADS(usdhc4_pads);
+           usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
+           break;          
+       case 1:
+           SETUP_IOMUX_PADS(usdhc3_pads);
+           usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);      
+           gpio_direction_input(USDHC3_CD_GPIO);
+           gpio_direction_output(USDHC3_PWR_GPIO, 1);
+           break;
+           
+       default:
+           printf("Warning: you configured more USDHC controllers"
+                  "(%d) then supported by the board (%d)\n",
+                  i + 1, CONFIG_SYS_FSL_USDHC_NUM);
+           return -EINVAL;
+       }
+
+       ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]);
+       if (ret)
+           return ret;
+   }
+
+   return 0;
+#else
+   struct src *psrc = (struct src *)SRC_BASE_ADDR;
+   unsigned reg_smbr1 = readl(&psrc->sbmr1);
+   unsigned reg = readl(&psrc->sbmr1) >> 11;   
+
+   printf("mmc port %d\n", reg & 0x3);
+
+   if ((reg_smbr1 & 0x0820) == 0x0820) {
+      /* Setup eMMC */
+      SETUP_IOMUX_PADS(usdhc4_pads);
+      usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
+      return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
+   } else {
+      /* Setup uSD */
+      SETUP_IOMUX_PADS(usdhc3_pads);
+      usdhc_cfg[1].esdhc_base = USDHC3_BASE_ADDR;
+      usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+      gpio_direction_input(USDHC3_CD_GPIO);
+      gpio_direction_output(USDHC3_PWR_GPIO, 1);
+      gd->arch.sdhc_clk = usdhc_cfg[1].sdhc_clk;
+      return fsl_esdhc_initialize(bis, &usdhc_cfg[1]);
+   }
+#endif
 }
+#endif /*  CONFIG_FSL_ESDHC  */

 int board_eth_init(bd_t *bis)
 {
@@ -283,14 +413,6 @@ free_bus:
    return ret;
 }

-int board_mmc_init(bd_t *bis)
-{
-   SETUP_IOMUX_PADS(usdhc3_pads);
-   usdhc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
-   usdhc_cfg.max_bus_width = 4;
-
-   return fsl_esdhc_initialize(bis, &usdhc_cfg);
-}

 int board_early_init_f(void)
 {
diff --git a/include/configs/secomx6sbca62.h b/include/configs/secomx6sbca62.h
index 5767b40..c44cbd1 100644
--- a/include/configs/secomx6sbca62.h
+++ b/include/configs/secomx6sbca62.h
@@ -83,6 +83,7 @@
 #define CONFIG_SYS_MEMTEST_END     (CONFIG_SYS_MEMTEST_START + 500 * SZ_1M)

 /* MMC Configuration */
+#define CONFIG_SYS_FSL_USDHC_NUM 2
 #define CONFIG_SYS_FSL_ESDHC_ADDR  0

 #define CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
-- 
2.1.4

It looks like the mapping is based on the ordering of registering the mmc device.

graugans commented 7 years ago

After changing the order the board boots at least from uSD card but eMMC still fails, because the loading of the kernel tries to load from uSD. This needs more investigation

U-Boot SPL 2016.01-seco-a62-v2016.01+g654be7a (Oct 11 2016 - 22:20:50)
Trying to boot from MMC
mmc port 3

U-Boot 2016.01-seco-a62-v2016.01+g654be7a (Oct 11 2016 - 22:20:50 +0200)

CPU:   Freescale i.MX6DL rev1.1 at 792 MHz
Reset cause: POR
Board: Seco SBC-A62-J-LITE
       Watchdog enabled
I2C:   ready
DRAM:  1 GiB
MMC:   FSL_SDHC: 0, FSL_SDHC: 1
MMC: no card present
*** Warning - MMC init failed, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   using phy at 6
FEC [PRIME]
Hit any key to stop autoboot:  0 
MMC: no card present
MMC: no card present
Booting from net ...
BOOTP broadcast 1
BOOTP broadcast 2
BOOTP broadcast 3
*** Unhandled DHCP Option in OFFER/ACK: 42
*** Unhandled DHCP Option in OFFER/ACK: 158
*** Unhandled DHCP Option in OFFER/ACK: 42
*** Unhandled DHCP Option in OFFER/ACK: 158
DHCP client bound to address 192.168.23.174 (1029 ms)
Using FEC device
TFTP from server 192.168.23.1; our IP address is 192.168.23.174
Filename 'zImage'.
Load address: 0x12000000
Loading: *
modjo756 commented 7 years ago

Thanks for the details of your job !

graugans commented 7 years ago

I just updated the patch. If you want to test the latest image you can download a command line only image here

There is the eMMC resizing missing. This need adjustment in the rootfs resizing script.

modjo756 commented 7 years ago

Nice work ! tested and approved :+1: the card boot on emmc when i removed the jumper (just resizing script not work apparently). If i replug the jumper, the card boot on sd !

graugans commented 7 years ago

Another topic might be the u-boot environment location. But this is low prio I think because the way to go is using uEnv.txt in /boot partition

graugans commented 7 years ago

I did some test yesterday based on the resize script. I have to rework the script to use the kernel command line to detect the rootfs partition relying on the disk label does not work because sometimes I get the label from the uSD card. From meta-mali

root_partition=$(cat /proc/cmdline | tr " " "\n" | grep "root=" | cut -f 2 -d '='| cut -f 3 -d '/')
root_device="/dev/$(dirname $(readlink /sys/class/block/${root_partition}) | grep -o '[^/]*$')"
modjo756 commented 7 years ago

After a test with u-boot-fslc the card boot on emmc but for that i need at boot to do that : setenv mmcroot /dev/mmcblk0p1 saveenv after the card boot on emmc and your resize script work fine. But if i remove the sdcard and try to boot, i have this error : _U-Boot SPL 2016.07+fslc+ge6b4241 (Nov 15 2016 - 17:35:18) Trying to boot from MMC1 Card did not respond to voltage select! spl: mmc init failed with error: -17 SPL: failed to boot from all boot devices

ERROR ### Please RESET the board ###_

It would be great to boot on emmc without sdcard.

graugans commented 7 years ago

Yes, this is caused due to the different logic of boot selection. I have to check why u-boot fails to boot from emmc....

graugans commented 7 years ago

This was fixed with commit 30a6fc0e74c7971fc7bd8457f5d64528a8133079

modjo756 commented 7 years ago

Good, i will try tomorrow and let you known.

modjo756 commented 7 years ago

tested this morning and work fine. Nice job !