From patchwork Mon Jan 31 08:47:45 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lei Wen X-Patchwork-Id: 81086 X-Patchwork-Delegate: afleming@freescale.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 7A78AB70E3 for ; Mon, 31 Jan 2011 19:42:43 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id CBBA3280DE; Mon, 31 Jan 2011 09:42:41 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id iBH72sRLxg7g; Mon, 31 Jan 2011 09:42:41 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id B69F8280D0; Mon, 31 Jan 2011 09:42:39 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 144FF280D0 for ; Mon, 31 Jan 2011 09:42:38 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id h0btgXe6opAk for ; Mon, 31 Jan 2011 09:42:36 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from dakia2.marvell.com (dakia2.marvell.com [65.219.4.35]) by theia.denx.de (Postfix) with ESMTPS id 05A0E280CF for ; Mon, 31 Jan 2011 09:42:34 +0100 (CET) X-ASG-Debug-ID: 1296463352-082bc7e00001-4l7tJC Received: from maili.marvell.com (maili.marvell.com [10.68.76.51]) by dakia2.marvell.com with ESMTP id junx4CeVqCyPGu7M; Mon, 31 Jan 2011 00:42:32 -0800 (PST) X-Barracuda-Envelope-From: leiwen@marvell.com Received: from localhost (unknown [10.38.164.83]) by maili.marvell.com (Postfix) with ESMTP id EB58D8A00C; Mon, 31 Jan 2011 00:42:31 -0800 (PST) From: Lei Wen To: Andy Fleming , u-boot@lists.denx.de X-ASG-Orig-Subj: [U-BOOT] [PATCH] mmc: enable switch partition function Date: Mon, 31 Jan 2011 16:47:45 +0800 X-ASG-Orig-Subj: [U-BOOT] [PATCH] mmc: enable switch partition function Message-Id: <1296463665-26551-1-git-send-email-leiwen@marvell.com> X-Mailer: git-send-email 1.7.0.4 X-Barracuda-Connect: maili.marvell.com[10.68.76.51] X-Barracuda-Start-Time: 1296463352 X-Barracuda-URL: http://10.68.76.222:80/cgi-mod/mark.cgi X-Barracuda-Spam-Score: -1002.00 X-Barracuda-Spam-Status: No, SCORE=-1002.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=1000.0 Subject: [U-Boot] [U-BOOT] [PATCH] mmc: enable switch partition function X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de For emmc, it may has upto 7 partitions: two boot partitions, one user partition, one RPMB partition and four general purpose partitions. (Refer to JESD84-A44.pdf/page 154) As bootloader may need to read out or reflashing images on those different partitions, it is better to enable the partition switch with console command support. Signed-off-by: Lei Wen --- common/cmd_mmc.c | 24 +++++++++++++++++++++++- drivers/mmc/mmc.c | 16 ++++++++++++++++ include/mmc.h | 5 +++++ 3 files changed, 44 insertions(+), 1 deletions(-) diff --git a/common/cmd_mmc.c b/common/cmd_mmc.c index 4323f76..2181e04 100644 --- a/common/cmd_mmc.c +++ b/common/cmd_mmc.c @@ -177,7 +177,6 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) case 0: case 1: - case 4: return cmd_usage(cmdtp); case 2: @@ -233,6 +232,28 @@ int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("%d blocks written: %s\n", n, (n == cnt) ? "OK" : "ERROR"); return (n == cnt) ? 0 : 1; + } else if (strcmp(argv[1], "sw_part") == 0) { + int dev = simple_strtoul(argv[2], NULL, 10); + struct mmc *mmc = find_mmc_device(dev); + int num = simple_strtoul(argv[3], NULL, 10); + int ret; + + if (num > PART_ACCESS_MASK) { + printf("#part_num shouldn't be larger than %d\n", + PART_ACCESS_MASK); + return 1; + } + + mmc_init(mmc); + if (mmc->part_config == MMCPART_NOAVAILABLE) { + printf("Card doesn't support part_switch\n"); + return 1; + } + + ret = mmc_switch_part(dev, num); + printf("switch to partions #%d, %s\n", + num, (!ret) ? "OK" : "ERROR"); + return (!ret) ? 0 : 1; } else rc = cmd_usage(cmdtp); @@ -247,5 +268,6 @@ U_BOOT_CMD( "mmc write addr blk# cnt\n" "mmc rescan \n" "mmc part - lists available partition on mmc\n" + "mmc sw_part - switch part support for emmc\n" "mmc list - lists available devices"); #endif diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 6805b33..f42b3fb 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -428,6 +428,18 @@ int mmc_change_freq(struct mmc *mmc) return 0; } +int mmc_switch_part(int dev_num, unsigned int part_num) +{ + struct mmc *mmc = find_mmc_device(dev_num); + + if (!mmc) + return -1; + + return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF, + (mmc->part_config & ~PART_ACCESS_MASK) + | (part_num & PART_ACCESS_MASK)); +} + int sd_switch(struct mmc *mmc, int mode, int group, u8 value, u8 *resp) { struct mmc_cmd cmd; @@ -725,6 +737,7 @@ int mmc_startup(struct mmc *mmc) if (err) return err; + mmc->part_config = MMCPART_NOAVAILABLE; if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) { /* check ext_csd version and capacity */ err = mmc_send_ext_csd(mmc, ext_csd); @@ -733,6 +746,9 @@ int mmc_startup(struct mmc *mmc) ext_csd[214] << 16 | ext_csd[215] << 24; mmc->capacity *= 512; } + /* store the partition info of emmc */ + if (ext_csd[160] & 0x1) + mmc->part_config = ext_csd[179]; } if (IS_SD(mmc)) diff --git a/include/mmc.h b/include/mmc.h index 74c0b1d..10dfafd 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -128,6 +128,7 @@ * EXT_CSD fields */ +#define EXT_CSD_PART_CONF 179 /* R/W */ #define EXT_CSD_BUS_WIDTH 183 /* R/W */ #define EXT_CSD_HS_TIMING 185 /* R/W */ #define EXT_CSD_CARD_TYPE 196 /* RO */ @@ -169,6 +170,8 @@ #define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) #define MMC_RSP_R7 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) +#define MMCPART_NOAVAILABLE (0xff) +#define PART_ACCESS_MASK (0x7) struct mmc_cid { unsigned long psn; @@ -265,6 +268,7 @@ struct mmc { uint csd[4]; uint cid[4]; ushort rca; + char part_config; uint tran_speed; uint read_bl_len; uint write_bl_len; @@ -285,6 +289,7 @@ struct mmc *find_mmc_device(int dev_num); int mmc_set_dev(int dev_num); void print_mmc_devices(char separator); int board_mmc_getcd(u8 *cd, struct mmc *mmc); +int mmc_switch_part(int dev_num, unsigned int part_num); #ifdef CONFIG_GENERIC_MMC int atmel_mci_init(void *regs);