From patchwork Tue Nov 6 22:21:42 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 993961 X-Patchwork-Delegate: sjg@chromium.org Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=chromium.org Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 42qPXs4pNCz9sBk for ; Wed, 7 Nov 2018 09:36:29 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 45FD2C22779; Tue, 6 Nov 2018 22:31:07 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=RCVD_IN_DNSWL_BLOCKED autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 1AE3DC223DD; Tue, 6 Nov 2018 22:25:48 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 73AEDC22608; Tue, 6 Nov 2018 22:23:06 +0000 (UTC) Received: from mail-io1-f74.google.com (mail-io1-f74.google.com [209.85.166.74]) by lists.denx.de (Postfix) with ESMTPS id 09B09C223E9 for ; Tue, 6 Nov 2018 22:23:02 +0000 (UTC) Received: by mail-io1-f74.google.com with SMTP id q127-v6so16354902iod.17 for ; Tue, 06 Nov 2018 14:23:01 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=E+D41F+Sx6ed0+nVb+BaIH6poboWdNt+YNYhvnhcyu8=; b=ZLu/NrSpM/jEQsmm0xhkA3keeZYjzIGhfwgrkG4loOMa1mJysxB6/RSOjohmPOzb3M eppbG6qNac2tQgInbdkP640CZUJKd5f9f8LUOhjMfvW1fy+48lK+obWA+ihgYCLuOyfF 3IyJ6JyM1PuzM8eWq6FxD3UUeG1NY56c/KVmHhAXm2Hxm+WokSQlXGwigllN7j1nUoMu CAWqWEhr3OVjSbs9F52dLPUWyeScI+Ju7BVuQlyKBCrQ7N8npCIthkzj4D6UQktx5+Cy YUhyG/TtGuVp5ekTWcOj9sVrkP9msZBWdmhA1or2FvbOopiP68BedCjgVDrz0CUTtoFT QYtg== X-Gm-Message-State: AGRZ1gKj70BU4L1V7gSQ7ltGiKGwCVfT2T0SAbjdBIVP5cmJ1FZD12IH y8dy7KcA6QINQ+xlkpRYtbVcQ14= X-Google-Smtp-Source: AJdET5f0YXi6FICam8R+isXGTVY2J5laGxtlX+gIpGzAEfc8NU5Mjl6ss9mewyJ4OcJejjGtEBmfM2Y= X-Received: by 2002:a24:9703:: with SMTP id k3-v6mr2646066ite.29.1541542980912; Tue, 06 Nov 2018 14:23:00 -0800 (PST) Date: Tue, 6 Nov 2018 15:21:42 -0700 In-Reply-To: <20181106222142.94537-1-sjg@chromium.org> Message-Id: <20181106222142.94537-26-sjg@chromium.org> Mime-Version: 1.0 References: <20181106222142.94537-1-sjg@chromium.org> X-Mailer: git-send-email 2.19.1.930.g4563a0d9d0-goog From: Simon Glass To: U-Boot Mailing List Cc: Baruch Siach , Kishon Vijay Abraham I Subject: [U-Boot] [PATCH 25/25] mmc: Add hardware partition support X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" 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. Signed-off-by: Simon Glass --- 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);