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