diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2012-12-07 16:43:12 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-12-07 16:43:12 +0100 |
commit | 0ae4b1e82778ac6df74a06eacffe2f9373b95ee3 (patch) | |
tree | 99c668fbb04a4f626f0e686c3aa1df9a64e464b6 /arch/arm/mach-imx/imx-bbu-internal.c | |
parent | c3a84a3f760b3892501591f5a6b037611477dc9f (diff) | |
parent | 2ff02e7aa1a4f9f59c8786e9fdade070a8e7fd79 (diff) | |
download | barebox-0ae4b1e82778ac6df74a06eacffe2f9373b95ee3.tar.gz barebox-0ae4b1e82778ac6df74a06eacffe2f9373b95ee3.tar.xz |
Merge branch 'for-next/imx'
Conflicts:
arch/arm/mach-imx/include/mach/devices-imx53.h
Diffstat (limited to 'arch/arm/mach-imx/imx-bbu-internal.c')
-rw-r--r-- | arch/arm/mach-imx/imx-bbu-internal.c | 119 |
1 files changed, 107 insertions, 12 deletions
diff --git a/arch/arm/mach-imx/imx-bbu-internal.c b/arch/arm/mach-imx/imx-bbu-internal.c index a78dde7526..bbc620a6a8 100644 --- a/arch/arm/mach-imx/imx-bbu-internal.c +++ b/arch/arm/mach-imx/imx-bbu-internal.c @@ -36,6 +36,7 @@ #define IMX_INTERNAL_FLAG_NAND (1 << 0) #define IMX_INTERNAL_FLAG_KEEP_DOSPART (1 << 1) +#define IMX_INTERNAL_FLAG_ERASE (1 << 2) struct imx_internal_bbu_handler { struct bbu_handler handler; @@ -60,6 +61,17 @@ static int imx_bbu_write_device(struct imx_internal_bbu_handler *imx_handler, if (fd < 0) return fd; + if (imx_handler->flags & IMX_INTERNAL_FLAG_ERASE) { + debug("%s: eraseing %s from 0 to 0x%08x\n", __func__, + data->devicefile, image_len); + ret = erase(fd, image_len, 0); + if (ret) { + printf("erasing %s failed with %s\n", data->devicefile, + strerror(-ret)); + goto err_close; + } + } + if (imx_handler->flags & IMX_INTERNAL_FLAG_KEEP_DOSPART) { void *mbr = xzalloc(512); @@ -357,8 +369,9 @@ static int imx_bbu_internal_v2_update(struct bbu_handler *handler, struct bbu_da flash_header->header.version = IVT_VERSION; flash_header->entry = imx_handler->app_dest + imx_pre_image_size; - flash_header->dcd_ptr = imx_handler->app_dest + flash_header_offset + - offsetof(struct imx_flash_header_v2, dcd); + if (imx_handler->dcdsize) + flash_header->dcd_ptr = imx_handler->app_dest + flash_header_offset + + offsetof(struct imx_flash_header_v2, dcd); flash_header->boot_data_ptr = imx_handler->app_dest + flash_header_offset + offsetof(struct imx_flash_header_v2, boot_data); flash_header->self = imx_handler->app_dest + flash_header_offset; @@ -366,10 +379,12 @@ static int imx_bbu_internal_v2_update(struct bbu_handler *handler, struct bbu_da flash_header->boot_data.start = imx_handler->app_dest; flash_header->boot_data.size = ALIGN(imx_pre_image_size + data->len, 4096);; - flash_header->dcd.header.tag = DCD_HEADER_TAG; - flash_header->dcd.header.length = cpu_to_be16(sizeof(struct imx_dcd) + - imx_handler->dcdsize); - flash_header->dcd.header.version = DCD_VERSION; + if (imx_handler->dcdsize) { + flash_header->dcd.header.tag = DCD_HEADER_TAG; + flash_header->dcd.header.length = cpu_to_be16(sizeof(struct imx_dcd) + + imx_handler->dcdsize); + flash_header->dcd.header.version = DCD_VERSION; + } /* Add dcd data */ memcpy((void *)flash_header + sizeof(*flash_header), imx_handler->dcd, imx_handler->dcdsize); @@ -453,7 +468,8 @@ static int __register_handler(struct imx_internal_bbu_handler *imx_handler) * Register a i.MX51 internal boot update handler for MMC/SD */ int imx51_bbu_internal_mmc_register_handler(const char *name, char *devicefile, - unsigned long flags, struct imx_dcd_entry *dcd, int dcdsize) + unsigned long flags, struct imx_dcd_entry *dcd, int dcdsize, + unsigned long app_dest) { struct imx_internal_bbu_handler *imx_handler; @@ -461,7 +477,12 @@ int imx51_bbu_internal_mmc_register_handler(const char *name, char *devicefile, imx_handler->dcd = dcd; imx_handler->dcdsize = dcdsize; imx_handler->flash_header_offset = FLASH_HEADER_OFFSET_MMC; - imx_handler->app_dest = 0x90000000; + + if (app_dest) + imx_handler->app_dest = app_dest; + else + imx_handler->app_dest = 0x90000000; + imx_handler->flags = IMX_INTERNAL_FLAG_KEEP_DOSPART; imx_handler->handler.handler = imx_bbu_internal_v1_update; @@ -476,6 +497,13 @@ static int imx53_bbu_internal_init_dcd(struct imx_internal_bbu_handler *imx_hand uint32_t *dcd32 = dcd; /* + * For boards which do not have a dcd (i.e. they do their SDRAM + * setup in C code) + */ + if (!dcd || !dcdsize) + return 0; + + /* * The DCD data we have compiled in does not have a DCD_WR_CMD at * the beginning. Instead it is contained in struct imx_flash_header_v2. * This is necessary to generate the DCD size at compile time. If @@ -507,14 +535,20 @@ static int imx53_bbu_internal_init_dcd(struct imx_internal_bbu_handler *imx_hand * Register a i.MX53 internal boot update handler for MMC/SD */ int imx53_bbu_internal_mmc_register_handler(const char *name, char *devicefile, - unsigned long flags, struct imx_dcd_v2_entry *dcd, int dcdsize) + unsigned long flags, struct imx_dcd_v2_entry *dcd, int dcdsize, + unsigned long app_dest) { struct imx_internal_bbu_handler *imx_handler; imx_handler = __init_handler(name, devicefile, flags); imx53_bbu_internal_init_dcd(imx_handler, dcd, dcdsize); imx_handler->flash_header_offset = FLASH_HEADER_OFFSET_MMC; - imx_handler->app_dest = 0x70000000; + + if (app_dest) + imx_handler->app_dest = app_dest; + else + imx_handler->app_dest = 0x70000000; + imx_handler->flags = IMX_INTERNAL_FLAG_KEEP_DOSPART; imx_handler->handler.handler = imx_bbu_internal_v2_update; @@ -522,18 +556,49 @@ int imx53_bbu_internal_mmc_register_handler(const char *name, char *devicefile, } /* + * Register a i.MX53 internal boot update handler for i2c/spi + * EEPROMs / flashes. Nearly the same as MMC/SD, but we do not need to + * keep a partition table. We have to erase the device beforehand though. + */ +int imx53_bbu_internal_spi_i2c_register_handler(const char *name, char *devicefile, + unsigned long flags, struct imx_dcd_v2_entry *dcd, int dcdsize, + unsigned long app_dest) +{ + struct imx_internal_bbu_handler *imx_handler; + + imx_handler = __init_handler(name, devicefile, flags); + imx53_bbu_internal_init_dcd(imx_handler, dcd, dcdsize); + imx_handler->flash_header_offset = FLASH_HEADER_OFFSET_MMC; + + if (app_dest) + imx_handler->app_dest = app_dest; + else + imx_handler->app_dest = 0x70000000; + + imx_handler->flags = IMX_INTERNAL_FLAG_ERASE; + imx_handler->handler.handler = imx_bbu_internal_v2_update; + + return __register_handler(imx_handler); +} + +/* * Register a i.MX53 internal boot update handler for NAND */ int imx53_bbu_internal_nand_register_handler(const char *name, unsigned long flags, struct imx_dcd_v2_entry *dcd, int dcdsize, - int partition_size) + int partition_size, unsigned long app_dest) { struct imx_internal_bbu_handler *imx_handler; imx_handler = __init_handler(name, NULL, flags); imx53_bbu_internal_init_dcd(imx_handler, dcd, dcdsize); imx_handler->flash_header_offset = 0x400; - imx_handler->app_dest = 0x70000000; + + if (app_dest) + imx_handler->app_dest = app_dest; + else + imx_handler->app_dest = 0x70000000; + imx_handler->handler.handler = imx_bbu_internal_v2_update; imx_handler->flags = IMX_INTERNAL_FLAG_NAND; imx_handler->handler.devicefile = "/dev/nand0"; @@ -541,3 +606,33 @@ int imx53_bbu_internal_nand_register_handler(const char *name, return __register_handler(imx_handler); } + +/* + * Register a i.MX6 internal boot update handler for MMC/SD + */ +int imx6_bbu_internal_mmc_register_handler(const char *name, char *devicefile, + unsigned long flags, struct imx_dcd_v2_entry *dcd, int dcdsize, + unsigned long app_dest) +{ + if (!app_dest) + app_dest = 0x10000000; + + return imx53_bbu_internal_mmc_register_handler(name, devicefile, + flags, dcd, dcdsize, app_dest); +} + +/* + * Register a i.MX53 internal boot update handler for i2c/spi + * EEPROMs / flashes. Nearly the same as MMC/SD, but we do not need to + * keep a partition table. We have to erase the device beforehand though. + */ +int imx6_bbu_internal_spi_i2c_register_handler(const char *name, char *devicefile, + unsigned long flags, struct imx_dcd_v2_entry *dcd, int dcdsize, + unsigned long app_dest) +{ + if (!app_dest) + app_dest = 0x10000000; + + return imx53_bbu_internal_spi_i2c_register_handler(name, devicefile, + flags, dcd, dcdsize, app_dest); +} |