Merge branch 'u-boot-samsung/master' into 'u-boot-arm/master'
authorAlbert ARIBAUD <albert.u.boot@aribaud.net>
Wed, 19 Jun 2013 10:53:59 +0000 (12:53 +0200)
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>
Wed, 19 Jun 2013 10:53:59 +0000 (12:53 +0200)
Conflicts:
spl/Makefile

1  2 
drivers/mmc/mmc.c
include/mmc.h
spl/Makefile

index 0a2f5358e2fe386a322a151fdb93cbd5ea50f497,9c0652d9abcf9683d2d5dcc168b482a70bacc562..a492bbb41f5faef7b0d6369de605a8bc5d163d91
@@@ -1444,6 -1372,139 +1444,140 @@@ int mmc_initialize(bd_t *bis
  
        print_mmc_devices(',');
  
 +      do_preinit();
        return 0;
  }
+ #ifdef CONFIG_SUPPORT_EMMC_BOOT
+ /*
+  * This function changes the size of boot partition and the size of rpmb
+  * partition present on EMMC devices.
+  *
+  * Input Parameters:
+  * struct *mmc: pointer for the mmc device strcuture
+  * bootsize: size of boot partition
+  * rpmbsize: size of rpmb partition
+  *
+  * Returns 0 on success.
+  */
+ int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
+                               unsigned long rpmbsize)
+ {
+       int err;
+       struct mmc_cmd cmd;
+       /* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
+       cmd.cmdidx = MMC_CMD_RES_MAN;
+       cmd.resp_type = MMC_RSP_R1b;
+       cmd.cmdarg = MMC_CMD62_ARG1;
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err) {
+               debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
+               return err;
+       }
+       /* Boot partition changing mode */
+       cmd.cmdidx = MMC_CMD_RES_MAN;
+       cmd.resp_type = MMC_RSP_R1b;
+       cmd.cmdarg = MMC_CMD62_ARG2;
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err) {
+               debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
+               return err;
+       }
+       /* boot partition size is multiple of 128KB */
+       bootsize = (bootsize * 1024) / 128;
+       /* Arg: boot partition size */
+       cmd.cmdidx = MMC_CMD_RES_MAN;
+       cmd.resp_type = MMC_RSP_R1b;
+       cmd.cmdarg = bootsize;
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err) {
+               debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
+               return err;
+       }
+       /* RPMB partition size is multiple of 128KB */
+       rpmbsize = (rpmbsize * 1024) / 128;
+       /* Arg: RPMB partition size */
+       cmd.cmdidx = MMC_CMD_RES_MAN;
+       cmd.resp_type = MMC_RSP_R1b;
+       cmd.cmdarg = rpmbsize;
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err) {
+               debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
+               return err;
+       }
+       return 0;
+ }
+ /*
+  * This function shall form and send the commands to open / close the
+  * boot partition specified by user.
+  *
+  * Input Parameters:
+  * ack: 0x0 - No boot acknowledge sent (default)
+  *    0x1 - Boot acknowledge sent during boot operation
+  * part_num: User selects boot data that will be sent to master
+  *    0x0 - Device not boot enabled (default)
+  *    0x1 - Boot partition 1 enabled for boot
+  *    0x2 - Boot partition 2 enabled for boot
+  * access: User selects partitions to access
+  *    0x0 : No access to boot partition (default)
+  *    0x1 : R/W boot partition 1
+  *    0x2 : R/W boot partition 2
+  *    0x3 : R/W Replay Protected Memory Block (RPMB)
+  *
+  * Returns 0 on success.
+  */
+ int mmc_boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
+ {
+       int err;
+       struct mmc_cmd cmd;
+       /* Boot ack enable, boot partition enable , boot partition access */
+       cmd.cmdidx = MMC_CMD_SWITCH;
+       cmd.resp_type = MMC_RSP_R1b;
+       cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+                       (EXT_CSD_PART_CONF << 16) |
+                       ((EXT_CSD_BOOT_ACK(ack) |
+                       EXT_CSD_BOOT_PART_NUM(part_num) |
+                       EXT_CSD_PARTITION_ACCESS(access)) << 8);
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err) {
+               if (access) {
+                       debug("mmc boot partition#%d open fail:Error1 = %d\n",
+                             part_num, err);
+               } else {
+                       debug("mmc boot partition#%d close fail:Error = %d\n",
+                             part_num, err);
+               }
+               return err;
+       }
+       if (access) {
+               /* 4bit transfer mode at booting time. */
+               cmd.cmdidx = MMC_CMD_SWITCH;
+               cmd.resp_type = MMC_RSP_R1b;
+               cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
+                               (EXT_CSD_BOOT_BUS_WIDTH << 16) |
+                               ((1 << 0) << 8);
+               err = mmc_send_cmd(mmc, &cmd, NULL);
+               if (err) {
+                       debug("mmc boot partition#%d open fail:Error2 = %d\n",
+                             part_num, err);
+                       return err;
+               }
+       }
+       return 0;
+ }
+ #endif
diff --cc include/mmc.h
index 566db59ac9fdd5e682f5866b34673164e49e8d15,21d0937d5c92b6b57020636db0057371906314f2..f88f672f111fee172e655167b0284e5b7521774d
@@@ -291,32 -307,12 +312,37 @@@ int mmc_switch_part(int dev_num, unsign
  int mmc_getcd(struct mmc *mmc);
  int mmc_getwp(struct mmc *mmc);
  void spl_mmc_load(void) __noreturn;
+ /* Function to change the size of boot partition and rpmb partitions */
+ int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
+                                       unsigned long rpmbsize);
+ /* Function to send commands to open/close the specified boot partition */
+ int mmc_boot_part_access(struct mmc *mmc, u8 ack, u8 part_num, u8 access);
  
 +/**
 + * Start device initialization and return immediately; it does not block on
 + * polling OCR (operation condition register) status.  Then you should call
 + * mmc_init, which would block on polling OCR status and complete the device
 + * initializatin.
 + *
 + * @param mmc Pointer to a MMC device struct
 + * @return 0 on success, IN_PROGRESS on waiting for OCR status, <0 on error.
 + */
 +int mmc_start_init(struct mmc *mmc);
 +
 +/**
 + * Set preinit flag of mmc device.
 + *
 + * This will cause the device to be pre-inited during mmc_initialize(),
 + * which may save boot time if the device is not accessed until later.
 + * Some eMMC devices take 200-300ms to init, but unfortunately they
 + * must be sent a series of commands to even get them to start preparing
 + * for operation.
 + *
 + * @param mmc         Pointer to a MMC device struct
 + * @param preinit     preinit flag value
 + */
 +void mmc_set_preinit(struct mmc *mmc, int preinit);
 +
  #ifdef CONFIG_GENERIC_MMC
  #define mmc_host_is_spi(mmc)  ((mmc)->host_caps & MMC_MODE_SPI)
  struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
diff --cc spl/Makefile
Simple merge