diff options
Diffstat (limited to 'arch/arm/mach-imx/imx-bbu-internal.c')
-rw-r--r-- | arch/arm/mach-imx/imx-bbu-internal.c | 158 |
1 files changed, 80 insertions, 78 deletions
diff --git a/arch/arm/mach-imx/imx-bbu-internal.c b/arch/arm/mach-imx/imx-bbu-internal.c index f6f66364c0..8cdaab5c16 100644 --- a/arch/arm/mach-imx/imx-bbu-internal.c +++ b/arch/arm/mach-imx/imx-bbu-internal.c @@ -1,19 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-only +// SPDX-FileCopyrightText: 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix + /* * imx-bbu-internal.c - i.MX specific update functions for internal boot - * - * Copyright (c) 2012 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 - * as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. */ #include <common.h> @@ -28,17 +17,17 @@ #include <linux/stat.h> #include <ioctl.h> #include <environment.h> -#include <mach/bbu.h> -#include <mach/generic.h> +#include <mach/imx/bbu.h> +#include <mach/imx/generic.h> +#include <mach/imx/imx-header.h> #include <libfile.h> -#define IMX_INTERNAL_FLAG_ERASE BIT(30) - struct imx_internal_bbu_handler { struct bbu_handler handler; int (*write_device)(struct imx_internal_bbu_handler *, struct bbu_data *); unsigned long flash_header_offset; + unsigned long filetype_offset; size_t device_size; enum filetype expected_type; }; @@ -46,7 +35,7 @@ struct imx_internal_bbu_handler { static bool imx_bbu_erase_required(struct imx_internal_bbu_handler *imx_handler) { - return imx_handler->handler.flags & IMX_INTERNAL_FLAG_ERASE; + return imx_handler->handler.flags & IMX_BBU_FLAG_ERASE; } static int imx_bbu_protect(int fd, struct imx_internal_bbu_handler *imx_handler, @@ -174,8 +163,8 @@ static int imx_bbu_check_prereq(struct imx_internal_bbu_handler *imx_handler, if (expected_type == filetype_unknown) break; - blob = data->image + imx_handler->flash_header_offset; - len = data->len - imx_handler->flash_header_offset; + blob = data->image + imx_handler->filetype_offset; + len = data->len - imx_handler->filetype_offset; type = file_detect_type(blob, len); if (type != expected_type) { @@ -387,16 +376,33 @@ static enum filetype imx_bbu_expected_filetype(void) static unsigned long imx_bbu_flash_header_offset_mmc(void) { - unsigned long offset = SZ_1K; + /* + * i.MX8MQ moved the header by 32K to accomodate for GPT partition + * tables. The offset to the IVT is 1KiB. + */ + if (cpu_is_mx8mm() || cpu_is_mx8mq()) + return SZ_32K + SZ_1K; + + /* + * i.MX8MN/P moved the header by 32K to accomodate for GPT partition + * tables, but the IVT is right at the beginning of the image. + */ + if (cpu_is_mx8mn() || cpu_is_mx8mp()) + return SZ_32K; + + return SZ_1K; +} +static unsigned long imx_bbu_flash_header_offset_mmcboot(unsigned long *flags) +{ /* - * i.MX8MQ moved the header by 32K to accomodate for GPT - * partition tables + * i.MX8MN/P places IVT directly at start of eMMC boot partition. IVT + * in eMMC user partition and SD is at 32K offset. */ - if (cpu_is_mx8m()) - offset += SZ_32K; + if (cpu_is_mx8mn() || cpu_is_mx8mp()) + *flags |= IMX_BBU_FLAG_PARTITION_STARTS_AT_HEADER; - return offset; + return imx_bbu_flash_header_offset_mmc(); } static int imx_bbu_update(struct bbu_handler *handler, struct bbu_data *data) @@ -416,54 +422,12 @@ static int imx_bbu_update(struct bbu_handler *handler, struct bbu_data *data) static int imx_bbu_internal_mmcboot_update(struct bbu_handler *handler, struct bbu_data *data) { - struct bbu_data _data = *data; int ret; - char *bootpartvar; - const char *bootpart; - char *devicefile; - const char *devname = devpath_to_name(data->devicefile); - - ret = device_detect_by_name(devname); - if (ret) { - pr_err("Couldn't detect device '%s'\n", devname); - return ret; - } - - ret = asprintf(&bootpartvar, "%s.boot", devname); - if (ret < 0) - return ret; - - bootpart = getenv(bootpartvar); - if (!bootpart) { - pr_err("Couldn't read the value of '%s'\n", bootpartvar); - ret = -ENOENT; - goto free_bootpartvar; - } - - if (!strcmp(bootpart, "boot0")) { - bootpart = "boot1"; - } else { - bootpart = "boot0"; - } - ret = asprintf(&devicefile, "/dev/%s.%s", devname, bootpart); - if (ret < 0) - goto free_bootpartvar; + ret = bbu_mmcboot_handler(handler, data, imx_bbu_update); - _data.devicefile = devicefile; - - ret = imx_bbu_update(handler, &_data); - if (ret) - goto free_devicefile; - - /* on success switch boot source */ - ret = setenv(bootpartvar, bootpart); - -free_devicefile: - free(devicefile); - -free_bootpartvar: - free(bootpartvar); + if (ret == -ENOENT) + pr_err("Couldn't read the value of .boot parameter\n"); return ret; } @@ -508,6 +472,7 @@ imx_bbu_internal_mmc_register_handler(const char *name, const char *devicefile, imx_handler = __init_handler(name, devicefile, flags | IMX_BBU_FLAG_KEEP_HEAD); imx_handler->flash_header_offset = imx_bbu_flash_header_offset_mmc(); + imx_handler->filetype_offset = imx_handler->flash_header_offset; return __register_handler(imx_handler); } @@ -520,8 +485,9 @@ imx_bbu_internal_spi_i2c_register_handler(const char *name, struct imx_internal_bbu_handler *imx_handler; imx_handler = __init_handler(name, devicefile, flags | - IMX_INTERNAL_FLAG_ERASE); + IMX_BBU_FLAG_ERASE); imx_handler->flash_header_offset = imx_bbu_flash_header_offset_mmc(); + imx_handler->filetype_offset = imx_handler->flash_header_offset; return __register_handler(imx_handler); } @@ -567,6 +533,7 @@ int imx53_bbu_internal_nand_register_handler(const char *name, imx_handler = __init_handler(name, "/dev/nand0", flags); imx_handler->flash_header_offset = imx_bbu_flash_header_offset_mmc(); + imx_handler->filetype_offset = imx_handler->flash_header_offset; imx_handler->device_size = partition_size; imx_handler->write_device = imx_bbu_internal_v2_write_nand_dbbt; @@ -591,9 +558,9 @@ int vf610_bbu_internal_mmc_register_handler(const char *name, __alias(imx6_bbu_internal_mmc_register_handler); /* - * Register an i.MX8MQ internal boot update handler for MMC/SD + * Register an i.MX8M* internal boot update handler for MMC/SD */ -int imx8mq_bbu_internal_mmc_register_handler(const char *name, +int imx8m_bbu_internal_mmc_register_handler(const char *name, const char *devicefile, unsigned long flags) __alias(imx6_bbu_internal_mmc_register_handler); @@ -612,9 +579,13 @@ static int imx_bbu_internal_mmcboot_register_handler(const char *name, unsigned long flags) { struct imx_internal_bbu_handler *imx_handler; + unsigned long flash_header_offset; + + flash_header_offset = imx_bbu_flash_header_offset_mmcboot(&flags); imx_handler = __init_handler(name, devicefile, flags); - imx_handler->flash_header_offset = imx_bbu_flash_header_offset_mmc(); + imx_handler->flash_header_offset = flash_header_offset; + imx_handler->filetype_offset = flash_header_offset; imx_handler->handler.handler = imx_bbu_internal_mmcboot_update; @@ -641,7 +612,7 @@ int imx7_bbu_internal_mmcboot_register_handler(const char *name, unsigned long flags) __alias(imx_bbu_internal_mmcboot_register_handler); -int imx8mq_bbu_internal_mmcboot_register_handler(const char *name, +int imx8m_bbu_internal_mmcboot_register_handler(const char *name, const char *devicefile, unsigned long flags) __alias(imx_bbu_internal_mmcboot_register_handler); @@ -679,9 +650,40 @@ int imx_bbu_external_nor_register_handler(const char *name, struct imx_internal_bbu_handler *imx_handler; imx_handler = __init_handler(name, devicefile, flags | - IMX_INTERNAL_FLAG_ERASE); + IMX_BBU_FLAG_ERASE); imx_handler->expected_type = filetype_unknown; return __register_handler(imx_handler); } + +static unsigned long imx_bbu_filetype_offset_flexspi(void) +{ + unsigned int sd_flash_header_gap = SZ_32K; + + if (cpu_is_mx8mm()) + return sd_flash_header_gap; + + return sd_flash_header_gap + SZ_1K; +} + +static int +imx_bbu_internal_flexspi_nor_register_handler(const char *name, + const char *devicefile, + unsigned long flags) +{ + struct imx_internal_bbu_handler *imx_handler; + + flags |= IMX_BBU_FLAG_ERASE | IMX_BBU_FLAG_PARTITION_STARTS_AT_HEADER; + imx_handler = __init_handler(name, devicefile, flags); + imx_handler->flash_header_offset = SZ_32K; + imx_handler->expected_type = filetype_nxp_fspi_image; + imx_handler->filetype_offset = imx_bbu_filetype_offset_flexspi(); + + return __register_handler(imx_handler); +} + +int imx8m_bbu_internal_flexspi_nor_register_handler(const char *name, + const char *devicefile, + unsigned long flags) + __alias(imx_bbu_internal_flexspi_nor_register_handler); |