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