Search This Blog

Sep 22, 2011

MX508 RD3 board Nand flash boot support


HW rework

We choose KPP as Nand flash raw interface. Four places need to rework in the board.
NANDF_CLE --> KEY_COL0 (default: EIM_DA8)
NANDF_ALE --> KEY_ROW0 (default: EIM_DA9)
NANDF_CS0 --> KEY_COL1 (default: EIM_DA10)
NANDF_RB --> KEY_COL3 (default: EIM_DA14)

Get source code

Get kernel source code

 linux-2.6.35.3

Get u-boot source code

 u-boot-2009.08

Modify u-boot code to support Nand flash

Change environment store place in Nand flash instead of MMC
diff --git a/include/configs/mx50_rd3.h b/include/configs/mx50_rd3.h
index 58229a1..01f0fa5 100644
--- a/include/configs/mx50_rd3.h
+++ b/include/configs/mx50_rd3.h
@@ -281,7 +281,8 @@
 #define CONFIG_SYS_NO_FLASH
 
 /* Monitor at beginning of flash */
-#define CONFIG_FSL_ENV_IN_MMC
+//#define CONFIG_FSL_ENV_IN_MMC
+#define CONFIG_FSL_ENV_IN_NAND
 
 #define CONFIG_ENV_SECT_SIZE    (128 * 1024)
 #define CONFIG_ENV_SIZE         CONFIG_ENV_SECT_SIZE
U-boot default MFG setting config doesn't contain GPMI nand flash support, we need add all those configuration in mx50_rd3_mfg.h
diff --git a/include/configs/mx50_rd3_mfg.h b/include/configs/mx50_rd3_mfg.h
index 4c13fc9..8c73c4b 100644
--- a/include/configs/mx50_rd3_mfg.h
+++ b/include/configs/mx50_rd3_mfg.h
@@ -197,6 +197,35 @@
  #define CONFIG_BOOT_PARTITION_ACCESS
 
 #endif
+
+/*
+ * GPMI Nand Configs
+ */
+#define CONFIG_CMD_NAND
+
+#ifdef CONFIG_CMD_NAND
+ #define CONFIG_NAND_GPMI
+ #define CONFIG_GPMI_NFC_SWAP_BLOCK_MARK
+ #define CONFIG_GPMI_NFC_V2
+
+ #define CONFIG_GPMI_REG_BASE GPMI_BASE_ADDR
+ #define CONFIG_BCH_REG_BASE BCH_BASE_ADDR
+
+ #define NAND_MAX_CHIPS  8
+ #define CONFIG_SYS_NAND_BASE  0x40000000
+ #define CONFIG_SYS_MAX_NAND_DEVICE 1
+#endif
+
+/*
+ * APBH DMA Configs
+ */
+#define CONFIG_APBH_DMA
+
+#ifdef CONFIG_APBH_DMA
+ #define CONFIG_APBH_DMA_V2
+ #define CONFIG_MXS_DMA_REG_BASE ABPHDMA_BASE_ADDR
+#endif
+
 /*-----------------------------------------------------------------------
  * Stack sizes
  *

Modify kernel code to support Nand flash

Since our Nand flash CLE,ALE,R/B,CE0 is difference from default IOMUX, we need make modification in arch/arm/mach-mx5/mx50_rdp.c, remove I/O conflict with LCD panel. And also we change first MTD partition size from 20MB to 16MB.
diff --git a/arch/arm/mach-mx5/mx50_rdp.c b/arch/arm/mach-mx5/mx50_rdp.c
index 1c58290..39f99af 100644
--- a/arch/arm/mach-mx5/mx50_rdp.c
+++ b/arch/arm/mach-mx5/mx50_rdp.c
@@ -305,13 +305,15 @@ static iomux_v3_cfg_t mx50_rdp[] = {
  MX50_PAD_UART3_RXD__GPIO_6_15,
 
  /* Keypad */
+    /* 
  MX50_PAD_KEY_COL0__KEY_COL0,
  MX50_PAD_KEY_ROW0__KEY_ROW0,
- MX50_PAD_KEY_COL1__KEY_COL1,
+    MX50_PAD_KEY_COL1__KEY_COL1,
+    */
  MX50_PAD_KEY_ROW1__KEY_ROW1,
  MX50_PAD_KEY_COL2__KEY_COL2,
  MX50_PAD_KEY_ROW2__KEY_ROW2,
- MX50_PAD_KEY_COL3__KEY_COL3,
+ // MX50_PAD_KEY_COL3__KEY_COL3, 
  MX50_PAD_KEY_ROW3__KEY_ROW3,
  MX50_PAD_EIM_DA0__KEY_COL4,
  MX50_PAD_EIM_DA1__KEY_ROW4,
@@ -352,13 +354,20 @@ static iomux_v3_cfg_t mx50_rd3_adjust[] = {
 };
 
 static iomux_v3_cfg_t mx50_gpmi_nand[] = {
+#if 0 
  MX50_PIN_EIM_DA8__NANDF_CLE,
  MX50_PIN_EIM_DA9__NANDF_ALE,
  MX50_PIN_EIM_DA10__NANDF_CE0,
+#else
+    MX50_PAD_KEY_COL0__NANDF_CLE,
+    MX50_PAD_KEY_ROW0__NANDF_ALE,
+    MX50_PAD_KEY_COL1__NANDF_CE0,
+#endif
  MX50_PIN_EIM_DA11__NANDF_CE1,
  MX50_PIN_EIM_DA12__NANDF_CE2,
  MX50_PIN_EIM_DA13__NANDF_CE3,
- MX50_PIN_EIM_DA14__NANDF_READY,
+// MX50_PIN_EIM_DA14__NANDF_READY,
+    MX50_PAD_KEY_COL3__NANDF_READY, 
  MX50_PIN_EIM_DA15__NANDF_DQS,
  MX50_PIN_SD3_D4__NANDF_D0,
  MX50_PIN_SD3_D5__NANDF_D1,
@@ -1300,6 +1309,7 @@ static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
  },
 };
 
+
 static struct mtd_partition mxc_dataflash_partitions[] = {
  {
   .name = "bootloader",
@@ -1311,6 +1321,7 @@ static struct mtd_partition mxc_dataflash_partitions[] = {
   .size = MTDPART_SIZ_FULL,},
 };
 
+#if 0 
 static struct flash_platform_data mxc_spi_flash_data[] = {
  {
   .name = "mxc_dataflash",
@@ -1342,7 +1353,7 @@ static struct spi_board_info m25pxx_dataflash_device[] __initdata = {
   .chip_select = 1,
   .platform_data = &mxc_spi_flash_data[1],},
 };
-
+#endif
 static int sdhc_write_protect(struct device *dev)
 {
  unsigned short rc = 0;
@@ -1493,10 +1504,12 @@ static void wvga_reset(void)
 
 static void wvga_reset__on_j12(void)
 {
+#if 0  
  mxc_iomux_v3_setup_pad(MX50_PAD_KEY_ROW0__GPIO_4_1);
 
  gpio_request(LCD_PWR_EN, "power_en");
  gpio_direction_output(LCD_PWR_EN, 1);
+#endif
 }
 
 /* Use same pinmux on HDMI */
@@ -1688,9 +1701,9 @@ static struct gpmi_nfc_platform_data  gpmi_nfc_platform_data = {
  .min_prop_delay_in_ns    = 5,
  .max_prop_delay_in_ns    = 9,
  .max_chip_count          = 2,
- .boot_area_size_in_bytes = 20 * SZ_1M,
+ .boot_area_size_in_bytes = 16 * SZ_1M,
  .partition_source_types  = gpmi_nfc_partition_source_types,
- .partitions              = 0,
+ .partitions              = 0, 
  .partition_count         = 0,
 };
 
@@ -1971,12 +1984,14 @@ static void __init mxc_board_init(void)
  mxc_register_device(&mxc_ssi1_device, NULL);
  mxc_register_device(&mxc_ssi2_device, NULL);
  mxc_register_device(&mxc_fec_device, &fec_data);
+#if 0  
  if (board_is_mx50_rd3())
   spi_register_board_info(m25pxx_dataflash_device,
     ARRAY_SIZE(m25pxx_dataflash_device));
  else
   spi_register_board_info(mxc_dataflash_device,
     ARRAY_SIZE(mxc_dataflash_device));
+#endif 
  i2c_register_board_info(0, mxc_i2c0_board_info,
     ARRAY_SIZE(mxc_i2c0_board_info));
  i2c_register_board_info(1, mxc_i2c1_board_info,
Add new IOMUX definition for Nand flash ALE,CLE,CE0,R/B in arch/arm/plat-mxc/include/mach/iomux-mx50.h.
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx50.h b/arch/arm/plat-mxc/include/mach/iomux-mx50.h
index 6220b96..d0025a9 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx50.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx50.h
@@ -587,6 +587,11 @@
       NO_PAD_CTRL)
 
 /* NAND */
+#define MX50_PAD_KEY_COL0__NANDF_CLE IOMUX_PAD(0x2CC, 0x20, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_KEY_ROW0__NANDF_ALE IOMUX_PAD(0x2D0, 0x24, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_KEY_COL1__NANDF_CE0  IOMUX_PAD(0x2D4, 0x28, 2, 0x0, 0, PAD_CTL_DSE_HIGH)
+#define MX50_PAD_KEY_COL3__NANDF_READY IOMUX_PAD(0x2E4, 0x38, 2, 0x7B4, 0, PAD_CTL_PKE|PAD_CTL_PUE|PAD_CTL_PUS_100K_UP)
+
 #define MX50_PIN_EIM_DA8__NANDF_CLE IOMUX_PAD(0x618, 0x27C, 2, 0x0, 0, \
       PAD_CTL_DSE_HIGH)
 #define MX50_PIN_EIM_DA9__NANDF_ALE IOMUX_PAD(0x61C, 0x280, 2, 0x0, 0, \
Our kernel GPMI driver doesn't support Nand with MX50 configuration, we need commit it out.
diff --git a/drivers/mtd/nand/gpmi-nfc/gpmi-nfc-main.c b/drivers/mtd/nand/gpmi-nfc/gpmi-nfc-main.c
index 32bc081..27654c3 100644
--- a/drivers/mtd/nand/gpmi-nfc/gpmi-nfc-main.c
+++ b/drivers/mtd/nand/gpmi-nfc/gpmi-nfc-main.c
@@ -1690,7 +1690,6 @@ static int gpmi_nfc_probe(struct platform_device *pdev)
  /* Validate the platform device data. */
 
  error = validate_the_platform(pdev);
-
  if (error)
   goto exit_validate_platform;
 
@@ -1849,8 +1848,8 @@ static int __init gpmi_nfc_init(void)
  pr_info("i.MX GPMI NFC\n");
 
 #ifdef CONFIG_ARCH_MX50
- if (enable_gpmi_nand == 0)
-  return 0;
+// if (enable_gpmi_nand == 0)  // Mark.Ding hide it
+//  return 0;
 #endif
 
  /* Register this driver with the platform management system. */
Our driver default create two MTD partition, however, in our case, we need create 3 MTD parttion, MTD0 for u-boot, MTD1 for kernel, MTD2 for rootfs, make modifcation in drivers/mtd/nand/gpmi-nfc/gpmi-nfc-mil.c
diff --git a/drivers/mtd/nand/gpmi-nfc/gpmi-nfc-mil.c b/drivers/mtd/nand/gpmi-nfc/gpmi-nfc-mil.c
index efb0f93..d78ff60 100644
--- a/drivers/mtd/nand/gpmi-nfc/gpmi-nfc-mil.c
+++ b/drivers/mtd/nand/gpmi-nfc/gpmi-nfc-mil.c
@@ -1254,7 +1254,7 @@ static int mil_boot_areas_init(struct gpmi_nfc_data *this)
    * | Boot |                    General Use                     |
    * +------+----------------------------------------------------+
    */
-
+#if 0   
   /* Chip 0 Boot */
   partitions[0].name       = chip_0_boot_name;
   partitions[0].offset     = 0;
@@ -1269,7 +1269,28 @@ static int mil_boot_areas_init(struct gpmi_nfc_data *this)
 
   /* Construct and register the partitions. */
   add_mtd_partitions(mtd, partitions, 2);
+#else
+  /* bootloader */
+  partitions[0].name       = "bootloader";
+  partitions[0].offset     = 0;
+  partitions[0].size       = rom->boot_area_size_in_bytes;
+  partitions[0].mask_flags = 0;
+
+  /* kernel */
+  partitions[1].name       = "nand.kernel";
+  partitions[1].offset     = MTDPART_OFS_APPEND;
+  partitions[1].size       = 5 * 1024 * 1024;
+  partitions[1].mask_flags = 0;
+
+  /* rootfs */
+  partitions[2].name       = general_use_name;
+  partitions[2].offset     = MTDPART_OFS_APPEND;
+  partitions[2].size       = MTDPART_SIZ_FULL;
+  partitions[2].mask_flags = 0;
 
+  /* Construct and register the partitions. */
+  add_mtd_partitions(mtd, partitions, 3);
+#endif
   /* Find the general use MTD. */
   i = 0;
   while ((search_mtd = get_mtd_device(0, i))) {

Modify MFG tool ucl.xml to support Nand flash

We choose Mfgtools-Rel-11.06.00_ER_MX50_UPDATER, its default ucl.xml doesn't support Nand flash for imx508, We need add a totaly new section to support it. Open "Profiles\MX50 Linux Update\OS Firmware\ucl.xml" and add below code below
 "NAND(UBI)" desc="Choose Nand as media with UBI File System to Flash">
    "find" body="Recovery" timeout="180"/>
    "boot" body="Recovery" file ="u-boot.bin" >Running plugin to init LPDDR2 Memory.
    "load" file="uImage" address="0x70800000" loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" >Doing Kernel.
    "load" file="initramfs.cpio.gz.uboot" address="0x70B00000" loadSection="OTH" setSection="OTH" HasFlashHeader="FALSE" >Doing Initramfs.
    "jump" onError="ignore" > Jumping to OS image. 
    "find" body="Updater" timeout="180"/>
    "push" body="mknod class/mtd,mtd0,/dev/mtd0"/>
    "push" body="mknod class/mtd,mtd1,/dev/mtd1"/>
    "push" body="mknod block,mtdblock0,/dev/mtdblock0,block"/>
    "push" body="mknod block,mtdblock1,/dev/mtdblock1,block"/>
    "push" body="send" file="files/u-boot.bin">Sending U-Boot
    "push" body="$ echo 1 > /sys/devices/platform/gpmi-nfc.0/ignorebad">Ignore bad block
    "push" body="$ kobs-ng init --chip_0_device_path=/dev/mtd0 $FILE">Flashing Bootloader
    "push" body="$ echo 0 > /sys/devices/platform/gpmi-nfc.0/ignorebad">Care bad block
    "push" body="$ flash_eraseall /dev/mtd1">Erasing Kernel partition
    "push" body="send" file="files/uImage">Sending Kernel Image
    "push" body="$ nandwrite /dev/mtd1 -p $FILE">Flashing Kernel
    "push" body="$ echo Update Complete!">Done
  

Build u-boot

$ cd u-boot-2009.08
$ make distclean
$ make mx50_rd3_config
$ export CROSS_COMPILE=/opt/freescale/usr/local/arm-eabi-4.4.0/bin/arm-eabi-
$ make -j2
We will get u-boot.bin in directory u-boot-2009.08, copy this file to directory "Mfgtools-Rel-11.06.00_ER_MX50_UPDATER\Profiles\MX50 Linux Update\OS Firmware\files", this is u-boot download into Nand flash

Build u-boot for MFG

$ cd u-boot-2009.08
$ make distclean
$ make mx50_rd3_mfg_config
$ export CROSS_COMPILE=/opt/freescale/usr/local/arm-eabi-4.4.0/bin/arm-eabi-
$ make -j2
We will get u-boot.bin in directory u-boot-2009.08, copy this file to directory "Mfgtools-Rel-11.06.00_ER_MX50_UPDATER\Profiles\MX50 Linux Update\OS Firmware", this is u-boot for MFG tool usage.

Build kernel

$ cd linux-2.6.35.3
$ make distclean
$ make imx5_defconfig
$ export CROSS_COMPILE=/opt/freescale/usr/local/arm-eabi-4.4.3/bin/arm-eabi-
$ make uImage -j2
We will get uImage in directory linux-2.6.35.3/arch/arm/boot, copy this file to directory "Mfgtools-Rel-11.06.00_ER_MX50_UPDATER\Profiles\MX50 Linux Update\OS Firmware\files", this is kernel download into Nand flash

Build kernel for MFG

$ cd linux-2.6.35.3
$ make distclean
$ make imx5_updater_defconfig
$ export CROSS_COMPILE=/opt/freescale/usr/local/arm-eabi-4.4.3/bin/arm-eabi-
$ make uImage -j2
We will get uImage in directory linux-2.6.35.3/arch/arm/boot, copy this file to directory "Mfgtools-Rel-11.06.00_ER_MX50_UPDATER\Profiles\MX50 Linux Update\OS Firmware", this is kernel for MFG tool usage.

boot mode setting

For Raw Nand on KPP
SW5=0x81SW3=0x00SW4=0x01
For SD card boot
SW5=0x40SW3=0x00SW4=0x00

Boot cmd setting

$ setenv loadaddr 0x70800000
$ setenv loadkernel 'nand read ${loadaddr} 0x1000000 0x400000'
$ setenv bootcmd 'run loadkernel;bootm ${loadaddr}'
$ saveenv