MMC devices support multiple partitions, defined by the hardware. At
present U-Boot can only access partition zero. Add support for selecting
other partitions.

Also add a way to check if a partition is write-protected.

Note: There is existing support for this in the legacy MMC code, but this
is being removed soon.

Process-logs: sort, uniq
Signed-off-by: Simon Glass <s...@chromium.org>
---

Changes in v2:
- Drop changes previously applied
- Drop patch 'efi_loader: Don't enable in SPL/TPL by default'

 drivers/mmc/mmc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 include/mmc.h     | 31 +++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+)

diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index d6b9cdc9922..5b542524338 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -1128,6 +1128,52 @@ int mmc_hwpart_config(struct mmc *mmc,
 
        return 0;
 }
+
+int mmc_hwpart_access(struct mmc *mmc, int part)
+{
+       int err;
+       struct mmc_cmd cmd;
+
+       cmd.cmdidx = MMC_CMD_SWITCH;
+       cmd.resp_type = MMC_RSP_R1b;
+
+       /* Clear partition access bits */
+       cmd.cmdarg = (MMC_SWITCH_MODE_CLEAR_BITS << 24) |
+                       (EXT_CSD_PART_CONF << 16) |
+                       (EXT_CSD_PARTITION_ACCESS(0x7) << 8);
+
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err) {
+               debug("Failed to clear partition access bits\n");
+               return err;
+       }
+
+       /* Set partition access bits */
+       cmd.cmdarg = (MMC_SWITCH_MODE_SET_BITS << 24) |
+                       (EXT_CSD_PART_CONF << 16) |
+                       (EXT_CSD_PARTITION_ACCESS(part) << 8);
+
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err) {
+               debug("Failed to change partition\n");
+               return err;
+       }
+
+       return 0;
+}
+
+int mmc_get_boot_wp(struct mmc *mmc)
+{
+       ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);
+       int err;
+
+       err = mmc_send_ext_csd(mmc, ext_csd);
+       if (err)
+               return err;
+
+       return ext_csd[EXT_CSD_BOOT_WP] & (EXT_CSD_BOOT_WP_PWR_WP_EN
+                       | EXT_CSD_BOOT_WP_PERM_WP_EN);
+}
 #endif
 
 #if !CONFIG_IS_ENABLED(DM_MMC)
diff --git a/include/mmc.h b/include/mmc.h
index 95548e94c4d..1d0f978f8af 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -215,6 +215,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 #define EXT_CSD_WR_REL_PARAM           166     /* R */
 #define EXT_CSD_WR_REL_SET             167     /* R/W */
 #define EXT_CSD_RPMB_MULT              168     /* RO */
+#define EXT_CSD_BOOT_WP                        173     /* R/W */
 #define EXT_CSD_ERASE_GROUP_DEF                175     /* R/W */
 #define EXT_CSD_BOOT_BUS_WIDTH         177
 #define EXT_CSD_PART_CONF              179     /* R/W */
@@ -279,6 +280,15 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
 #define EXT_CSD_EXTRACT_BOOT_PART(x)           (((x) >> 3) & 0x7)
 #define EXT_CSD_EXTRACT_PARTITION_ACCESS(x)    ((x) & 0x7)
 
+/* Enable boot power-on write protect */
+#define EXT_CSD_BOOT_WP_PWR_WP_EN      BIT(0)
+/* Enable boot permanent write protect */
+#define EXT_CSD_BOOT_WP_PERM_WP_EN     BIT(2)
+/* Disable use of boot power-on write protect */
+#define EXT_CSD_BOOT_WP_PWR_WP_DIS     BIT(6)
+/* Bit 1 (Power-on) or Bit 3 (Permanent) selects the partition to protect */
+#define EXT_CSD_BOOT_WP_PART_SELECT    BIT(7)
+
 #define EXT_CSD_BOOT_BUS_WIDTH_MODE(x) (x << 3)
 #define EXT_CSD_BOOT_BUS_WIDTH_RESET(x)        (x << 2)
 #define EXT_CSD_BOOT_BUS_WIDTH_WIDTH(x)        (x)
@@ -735,6 +745,27 @@ int mmc_switch_part(struct mmc *mmc, unsigned int 
part_num);
 int mmc_hwpart_config(struct mmc *mmc, const struct mmc_hwpart_conf *conf,
                      enum mmc_hwpart_conf_mode mode);
 
+/**
+ * Get boot partition write protect status
+ *
+ * @param mmc  MMC to get status of
+ * @return     0 if WP is not asserted, non-zero if WP is asserted
+ */
+int mmc_get_boot_wp(struct mmc *mmc);
+
+/**
+ * Change MMC Partition
+ *
+ * Switch access to partition specified in part.  Unlike mmc_boot_part_access,
+ * this function will not affect the configured boot partition or boot ack
+ * settings.
+ *
+ * @param mmc  MMC to configure
+ * @param part Partition to access (one of PARTITION_ACCESS from spec)
+ * #return 0 on success, -ve on error
+ */
+int mmc_hwpart_access(struct mmc *mmc, int part);
+
 #if !CONFIG_IS_ENABLED(DM_MMC)
 int mmc_getcd(struct mmc *mmc);
 int board_mmc_getcd(struct mmc *mmc);
-- 
2.19.1.1215.g8438c0b245-goog

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
https://lists.denx.de/listinfo/u-boot

Reply via email to