xref: /openbmc/u-boot/drivers/mmc/mmc_boot.c (revision e8f80a5a)
1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2c40704f4SSimon Glass /*
3c40704f4SSimon Glass  * Copyright (C) 2016 Google, Inc
4c40704f4SSimon Glass  * Written by Amar <amarendra.xt@samsung.com>
5c40704f4SSimon Glass  */
6c40704f4SSimon Glass 
7c40704f4SSimon Glass #include <common.h>
8c40704f4SSimon Glass #include <mmc.h>
9c40704f4SSimon Glass #include "mmc_private.h"
10c40704f4SSimon Glass 
11c40704f4SSimon Glass /*
12c40704f4SSimon Glass  * This function changes the size of boot partition and the size of rpmb
13c40704f4SSimon Glass  * partition present on EMMC devices.
14c40704f4SSimon Glass  *
15c40704f4SSimon Glass  * Input Parameters:
16c40704f4SSimon Glass  * struct *mmc: pointer for the mmc device strcuture
17c40704f4SSimon Glass  * bootsize: size of boot partition
18c40704f4SSimon Glass  * rpmbsize: size of rpmb partition
19c40704f4SSimon Glass  *
20c40704f4SSimon Glass  * Returns 0 on success.
21c40704f4SSimon Glass  */
22c40704f4SSimon Glass 
mmc_boot_partition_size_change(struct mmc * mmc,unsigned long bootsize,unsigned long rpmbsize)23c40704f4SSimon Glass int mmc_boot_partition_size_change(struct mmc *mmc, unsigned long bootsize,
24c40704f4SSimon Glass 				unsigned long rpmbsize)
25c40704f4SSimon Glass {
26c40704f4SSimon Glass 	int err;
27c40704f4SSimon Glass 	struct mmc_cmd cmd;
28c40704f4SSimon Glass 
29c40704f4SSimon Glass 	/* Only use this command for raw EMMC moviNAND. Enter backdoor mode */
30c40704f4SSimon Glass 	cmd.cmdidx = MMC_CMD_RES_MAN;
31c40704f4SSimon Glass 	cmd.resp_type = MMC_RSP_R1b;
32c40704f4SSimon Glass 	cmd.cmdarg = MMC_CMD62_ARG1;
33c40704f4SSimon Glass 
34c40704f4SSimon Glass 	err = mmc_send_cmd(mmc, &cmd, NULL);
35c40704f4SSimon Glass 	if (err) {
36c40704f4SSimon Glass 		debug("mmc_boot_partition_size_change: Error1 = %d\n", err);
37c40704f4SSimon Glass 		return err;
38c40704f4SSimon Glass 	}
39c40704f4SSimon Glass 
40c40704f4SSimon Glass 	/* Boot partition changing mode */
41c40704f4SSimon Glass 	cmd.cmdidx = MMC_CMD_RES_MAN;
42c40704f4SSimon Glass 	cmd.resp_type = MMC_RSP_R1b;
43c40704f4SSimon Glass 	cmd.cmdarg = MMC_CMD62_ARG2;
44c40704f4SSimon Glass 
45c40704f4SSimon Glass 	err = mmc_send_cmd(mmc, &cmd, NULL);
46c40704f4SSimon Glass 	if (err) {
47c40704f4SSimon Glass 		debug("mmc_boot_partition_size_change: Error2 = %d\n", err);
48c40704f4SSimon Glass 		return err;
49c40704f4SSimon Glass 	}
50c40704f4SSimon Glass 	/* boot partition size is multiple of 128KB */
51c40704f4SSimon Glass 	bootsize = (bootsize * 1024) / 128;
52c40704f4SSimon Glass 
53c40704f4SSimon Glass 	/* Arg: boot partition size */
54c40704f4SSimon Glass 	cmd.cmdidx = MMC_CMD_RES_MAN;
55c40704f4SSimon Glass 	cmd.resp_type = MMC_RSP_R1b;
56c40704f4SSimon Glass 	cmd.cmdarg = bootsize;
57c40704f4SSimon Glass 
58c40704f4SSimon Glass 	err = mmc_send_cmd(mmc, &cmd, NULL);
59c40704f4SSimon Glass 	if (err) {
60c40704f4SSimon Glass 		debug("mmc_boot_partition_size_change: Error3 = %d\n", err);
61c40704f4SSimon Glass 		return err;
62c40704f4SSimon Glass 	}
63c40704f4SSimon Glass 	/* RPMB partition size is multiple of 128KB */
64c40704f4SSimon Glass 	rpmbsize = (rpmbsize * 1024) / 128;
65c40704f4SSimon Glass 	/* Arg: RPMB partition size */
66c40704f4SSimon Glass 	cmd.cmdidx = MMC_CMD_RES_MAN;
67c40704f4SSimon Glass 	cmd.resp_type = MMC_RSP_R1b;
68c40704f4SSimon Glass 	cmd.cmdarg = rpmbsize;
69c40704f4SSimon Glass 
70c40704f4SSimon Glass 	err = mmc_send_cmd(mmc, &cmd, NULL);
71c40704f4SSimon Glass 	if (err) {
72c40704f4SSimon Glass 		debug("mmc_boot_partition_size_change: Error4 = %d\n", err);
73c40704f4SSimon Glass 		return err;
74c40704f4SSimon Glass 	}
75c40704f4SSimon Glass 	return 0;
76c40704f4SSimon Glass }
77c40704f4SSimon Glass 
78c40704f4SSimon Glass /*
79c40704f4SSimon Glass  * Modify EXT_CSD[177] which is BOOT_BUS_WIDTH
80c40704f4SSimon Glass  * based on the passed in values for BOOT_BUS_WIDTH, RESET_BOOT_BUS_WIDTH
81c40704f4SSimon Glass  * and BOOT_MODE.
82c40704f4SSimon Glass  *
83c40704f4SSimon Glass  * Returns 0 on success.
84c40704f4SSimon Glass  */
mmc_set_boot_bus_width(struct mmc * mmc,u8 width,u8 reset,u8 mode)85c40704f4SSimon Glass int mmc_set_boot_bus_width(struct mmc *mmc, u8 width, u8 reset, u8 mode)
86c40704f4SSimon Glass {
8724f5aec3SMasahiro Yamada 	return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_BUS_WIDTH,
88c40704f4SSimon Glass 			  EXT_CSD_BOOT_BUS_WIDTH_MODE(mode) |
89c40704f4SSimon Glass 			  EXT_CSD_BOOT_BUS_WIDTH_RESET(reset) |
90c40704f4SSimon Glass 			  EXT_CSD_BOOT_BUS_WIDTH_WIDTH(width));
91c40704f4SSimon Glass }
92c40704f4SSimon Glass 
93c40704f4SSimon Glass /*
94c40704f4SSimon Glass  * Modify EXT_CSD[179] which is PARTITION_CONFIG (formerly BOOT_CONFIG)
95c40704f4SSimon Glass  * based on the passed in values for BOOT_ACK, BOOT_PARTITION_ENABLE and
96c40704f4SSimon Glass  * PARTITION_ACCESS.
97c40704f4SSimon Glass  *
98c40704f4SSimon Glass  * Returns 0 on success.
99c40704f4SSimon Glass  */
mmc_set_part_conf(struct mmc * mmc,u8 ack,u8 part_num,u8 access)100c40704f4SSimon Glass int mmc_set_part_conf(struct mmc *mmc, u8 ack, u8 part_num, u8 access)
101c40704f4SSimon Glass {
102bdb60996SAngelo Dureghello 	int ret;
103bdb60996SAngelo Dureghello 	u8 part_conf;
104bdb60996SAngelo Dureghello 
105bdb60996SAngelo Dureghello 	part_conf = EXT_CSD_BOOT_ACK(ack) |
106c40704f4SSimon Glass 		    EXT_CSD_BOOT_PART_NUM(part_num) |
107bdb60996SAngelo Dureghello 		    EXT_CSD_PARTITION_ACCESS(access);
108bdb60996SAngelo Dureghello 
109bdb60996SAngelo Dureghello 	ret = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_PART_CONF,
110bdb60996SAngelo Dureghello 			 part_conf);
111bdb60996SAngelo Dureghello 	if (!ret)
112bdb60996SAngelo Dureghello 		mmc->part_config = part_conf;
113bdb60996SAngelo Dureghello 
114bdb60996SAngelo Dureghello 	return ret;
115c40704f4SSimon Glass }
116c40704f4SSimon Glass 
117c40704f4SSimon Glass /*
118c40704f4SSimon Glass  * Modify EXT_CSD[162] which is RST_n_FUNCTION based on the given value
119c40704f4SSimon Glass  * for enable.  Note that this is a write-once field for non-zero values.
120c40704f4SSimon Glass  *
121c40704f4SSimon Glass  * Returns 0 on success.
122c40704f4SSimon Glass  */
mmc_set_rst_n_function(struct mmc * mmc,u8 enable)123c40704f4SSimon Glass int mmc_set_rst_n_function(struct mmc *mmc, u8 enable)
124c40704f4SSimon Glass {
125c40704f4SSimon Glass 	return mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_RST_N_FUNCTION,
126c40704f4SSimon Glass 			  enable);
127c40704f4SSimon Glass }
128