|
@@ -239,7 +239,9 @@ static int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd)
|
|
*/
|
|
*/
|
|
static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
|
static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
|
{
|
|
{
|
|
- int err = 0;
|
|
|
|
|
|
+ int err = 0, idx;
|
|
|
|
+ unsigned int part_size;
|
|
|
|
+ u8 hc_erase_grp_sz = 0, hc_wp_grp_sz = 0;
|
|
|
|
|
|
BUG_ON(!card);
|
|
BUG_ON(!card);
|
|
|
|
|
|
@@ -340,7 +342,14 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
|
* There are two boot regions of equal size, defined in
|
|
* There are two boot regions of equal size, defined in
|
|
* multiples of 128K.
|
|
* multiples of 128K.
|
|
*/
|
|
*/
|
|
- card->ext_csd.boot_size = ext_csd[EXT_CSD_BOOT_MULT] << 17;
|
|
|
|
|
|
+ if (ext_csd[EXT_CSD_BOOT_MULT] && mmc_boot_partition_access(card->host)) {
|
|
|
|
+ for (idx = 0; idx < MMC_NUM_BOOT_PARTITION; idx++) {
|
|
|
|
+ part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17;
|
|
|
|
+ mmc_part_add(card, part_size,
|
|
|
|
+ EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx,
|
|
|
|
+ "boot%d", idx, true);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
card->ext_csd.raw_hc_erase_gap_size =
|
|
card->ext_csd.raw_hc_erase_gap_size =
|
|
@@ -362,9 +371,9 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
|
card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT];
|
|
card->ext_csd.raw_partition_support = ext_csd[EXT_CSD_PARTITION_SUPPORT];
|
|
if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) &&
|
|
if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) &&
|
|
(ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) {
|
|
(ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) {
|
|
- u8 hc_erase_grp_sz =
|
|
|
|
|
|
+ hc_erase_grp_sz =
|
|
ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
|
|
ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
|
|
- u8 hc_wp_grp_sz =
|
|
|
|
|
|
+ hc_wp_grp_sz =
|
|
ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
|
|
ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
|
|
|
|
|
|
card->ext_csd.enhanced_area_en = 1;
|
|
card->ext_csd.enhanced_area_en = 1;
|
|
@@ -393,6 +402,41 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
|
|
card->ext_csd.enhanced_area_offset = -EINVAL;
|
|
card->ext_csd.enhanced_area_offset = -EINVAL;
|
|
card->ext_csd.enhanced_area_size = -EINVAL;
|
|
card->ext_csd.enhanced_area_size = -EINVAL;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * General purpose partition feature support --
|
|
|
|
+ * If ext_csd has the size of general purpose partitions,
|
|
|
|
+ * set size, part_cfg, partition name in mmc_part.
|
|
|
|
+ */
|
|
|
|
+ if (ext_csd[EXT_CSD_PARTITION_SUPPORT] &
|
|
|
|
+ EXT_CSD_PART_SUPPORT_PART_EN) {
|
|
|
|
+ if (card->ext_csd.enhanced_area_en != 1) {
|
|
|
|
+ hc_erase_grp_sz =
|
|
|
|
+ ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE];
|
|
|
|
+ hc_wp_grp_sz =
|
|
|
|
+ ext_csd[EXT_CSD_HC_WP_GRP_SIZE];
|
|
|
|
+
|
|
|
|
+ card->ext_csd.enhanced_area_en = 1;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for (idx = 0; idx < MMC_NUM_GP_PARTITION; idx++) {
|
|
|
|
+ if (!ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3] &&
|
|
|
|
+ !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1] &&
|
|
|
|
+ !ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2])
|
|
|
|
+ continue;
|
|
|
|
+ part_size =
|
|
|
|
+ (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 2]
|
|
|
|
+ << 16) +
|
|
|
|
+ (ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3 + 1]
|
|
|
|
+ << 8) +
|
|
|
|
+ ext_csd[EXT_CSD_GP_SIZE_MULT + idx * 3];
|
|
|
|
+ part_size *= (size_t)(hc_erase_grp_sz *
|
|
|
|
+ hc_wp_grp_sz);
|
|
|
|
+ mmc_part_add(card, part_size << 19,
|
|
|
|
+ EXT_CSD_PART_CONFIG_ACC_GP0 + idx,
|
|
|
|
+ "gp%d", idx, false);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
card->ext_csd.sec_trim_mult =
|
|
card->ext_csd.sec_trim_mult =
|
|
ext_csd[EXT_CSD_SEC_TRIM_MULT];
|
|
ext_csd[EXT_CSD_SEC_TRIM_MULT];
|
|
card->ext_csd.sec_erase_mult =
|
|
card->ext_csd.sec_erase_mult =
|