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