Merge branch 'master' of https://source.denx.de/u-boot/custodians/u-boot-marvell

- mvebu: Boot support for 4K Native disks (Pali)
- a38x: Perform DDR training sequence again for 2nd boot (Tony)
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
index b1f2e97..ac484c7 100644
--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -381,6 +381,16 @@
 	  Value 0x0 = SLC flash = BBI at page 0 or page 1
 	  Value 0x1 = MLC flash = BBI at last page in the block
 
+config MVEBU_SPL_SATA_BLKSZ
+	int "SATA block size"
+	depends on MVEBU_SPL_BOOT_DEVICE_SATA
+	range 512 32768
+	default 512
+	help
+	  Block size of the SATA disk in bytes.
+	  Typically 512 bytes for majority of disks
+	  and 4096 bytes for 4K Native disks.
+
 config MVEBU_EFUSE
 	bool "Enable eFuse support"
 	depends on HAVE_MVEBU_EFUSE
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
index 90f8833..0584ed2 100644
--- a/arch/arm/mach-mvebu/Makefile
+++ b/arch/arm/mach-mvebu/Makefile
@@ -73,6 +73,11 @@
 KWB_CFG_NAND_BADBLK_LOCATION = $(CONFIG_MVEBU_SPL_NAND_BADBLK_LOCATION)
 endif
 
+ifneq ($(CONFIG_MVEBU_SPL_BOOT_DEVICE_SATA),)
+KWB_REPLACE += SATA_BLKSZ
+KWB_CFG_SATA_BLKSZ = $(CONFIG_MVEBU_SPL_SATA_BLKSZ)
+endif
+
 ifneq ($(CONFIG_SECURED_MODE_IMAGE),)
 KWB_REPLACE += CSK_INDEX
 KWB_CFG_CSK_INDEX = $(CONFIG_SECURED_MODE_CSK_INDEX)
diff --git a/arch/arm/mach-mvebu/kwbimage.cfg.in b/arch/arm/mach-mvebu/kwbimage.cfg.in
index 90cf00c..588c259 100644
--- a/arch/arm/mach-mvebu/kwbimage.cfg.in
+++ b/arch/arm/mach-mvebu/kwbimage.cfg.in
@@ -16,6 +16,9 @@
 #@NAND_BLKSZ
 #@NAND_BADBLK_LOCATION
 
+# SATA configuration
+#@SATA_BLKSZ
+
 # Enable BootROM output via DEBUG flag on SoCs which require it
 #@DEBUG
 
diff --git a/arch/arm/mach-mvebu/spl.c b/arch/arm/mach-mvebu/spl.c
index 6b8c72a..379daa8 100644
--- a/arch/arm/mach-mvebu/spl.c
+++ b/arch/arm/mach-mvebu/spl.c
@@ -208,10 +208,15 @@
 
 	/*
 	 * For SATA srcaddr is specified in number of sectors.
-	 * This expects that sector size is 512 bytes.
+	 * Retrieve block size of the first SCSI device (same
+	 * code used by the spl_sata_load_image_raw() function)
+	 * or fallback to default sector size of 512 bytes.
 	 */
-	if (IS_ENABLED(CONFIG_SPL_SATA) && mhdr->blockid == IBR_HDR_SATA_ID)
-		spl_image->offset *= 512;
+	if (IS_ENABLED(CONFIG_SPL_SATA) && mhdr->blockid == IBR_HDR_SATA_ID) {
+		struct blk_desc *blk_dev = blk_get_devnum_by_uclass_id(UCLASS_SCSI, 0);
+		unsigned long blksz = blk_dev ? blk_dev->blksz : 512;
+		spl_image->offset *= blksz;
+	}
 
 	if (spl_image->offset % 4 != 0) {
 		printf("ERROR: Wrong srcaddr (0x%08x) in kwbimage\n",
diff --git a/cmd/mvebu/bubt.c b/cmd/mvebu/bubt.c
index 37ff9c4..ca24a5c 100644
--- a/cmd/mvebu/bubt.c
+++ b/cmd/mvebu/bubt.c
@@ -924,8 +924,11 @@
 	offset = le32_to_cpu(hdr->srcaddr);
 	size = le32_to_cpu(hdr->blocksize);
 
-	if (hdr->blockid == 0x78) /* SATA id */
-		offset *= 512;
+	if (hdr->blockid == 0x78) { /* SATA id */
+		struct blk_desc *blk_dev = IS_ENABLED(BLK) ? blk_get_devnum_by_uclass_id(UCLASS_SCSI, 0) : NULL;
+		unsigned long blksz = blk_dev ? blk_dev->blksz : 512;
+		offset *= blksz;
+	}
 
 	if (offset % 4 != 0 || size < 4 || size % 4 != 0) {
 		printf("Error: Bad A38x image blocksize.\n");
diff --git a/drivers/ddr/marvell/a38x/mv_ddr_plat.c b/drivers/ddr/marvell/a38x/mv_ddr_plat.c
index 6e7949a..8ec9fb0 100644
--- a/drivers/ddr/marvell/a38x/mv_ddr_plat.c
+++ b/drivers/ddr/marvell/a38x/mv_ddr_plat.c
@@ -1363,13 +1363,6 @@
 			    DRAM_RESET_MASK_MASKED << DRAM_RESET_MASK_OFFS);
 	}
 
-	/* Check if DRAM is already initialized  */
-	if (reg_read(REG_BOOTROM_ROUTINE_ADDR) &
-	    (1 << REG_BOOTROM_ROUTINE_DRAM_INIT_OFFS)) {
-		printf("%s Training Sequence - 2nd boot - Skip\n", ddr_type);
-		return MV_OK;
-	}
-
 	/* Fix read ready phases for all SOC in reg 0x15c8 */
 	reg_val = reg_read(TRAINING_DBG_3_REG);
 
diff --git a/tools/aisimage.c b/tools/aisimage.c
index b8b3ee3..c5b33b5 100644
--- a/tools/aisimage.c
+++ b/tools/aisimage.c
@@ -113,7 +113,7 @@
 	return -1;
 }
 
-static void aisimage_print_header(const void *hdr)
+static void aisimage_print_header(const void *hdr, struct image_tool_params *params)
 {
 	struct ais_header *ais_hdr = (struct ais_header *)hdr;
 	uint32_t *ptr;
diff --git a/tools/atmelimage.c b/tools/atmelimage.c
index 7b3b243..6a2d9d8 100644
--- a/tools/atmelimage.c
+++ b/tools/atmelimage.c
@@ -182,7 +182,7 @@
 	printf("\t\t====================\n");
 }
 
-static void atmel_print_header(const void *ptr)
+static void atmel_print_header(const void *ptr, struct image_tool_params *params)
 {
 	uint32_t *ints = (uint32_t *)ptr;
 	size_t pos;
diff --git a/tools/default_image.c b/tools/default_image.c
index dc429ce..0e49ab3 100644
--- a/tools/default_image.c
+++ b/tools/default_image.c
@@ -41,6 +41,11 @@
 		(params->lflag && (params->dflag || params->fflag)));
 }
 
+static void image_print_header(const void *ptr, struct image_tool_params *params)
+{
+	image_print_contents(ptr);
+}
+
 static int image_verify_header(unsigned char *ptr, int image_size,
 			struct image_tool_params *params)
 {
@@ -201,7 +206,7 @@
 	(void *)&header,
 	image_check_params,
 	image_verify_header,
-	image_print_contents,
+	image_print_header,
 	image_set_header,
 	image_extract_subimage,
 	image_check_image_types,
diff --git a/tools/fit_common.c b/tools/fit_common.c
index 0164976..2d417d4 100644
--- a/tools/fit_common.c
+++ b/tools/fit_common.c
@@ -23,6 +23,11 @@
 #include <image.h>
 #include <u-boot/crc.h>
 
+void fit_print_header(const void *fit, struct image_tool_params *params)
+{
+	fit_print_contents(fit);
+}
+
 int fit_verify_header(unsigned char *ptr, int image_size,
 			struct image_tool_params *params)
 {
diff --git a/tools/fit_common.h b/tools/fit_common.h
index 920a16a..2da4b94 100644
--- a/tools/fit_common.h
+++ b/tools/fit_common.h
@@ -10,6 +10,8 @@
 #include "mkimage.h"
 #include <image.h>
 
+void fit_print_header(const void *fit, struct image_tool_params *params);
+
 /**
  * Verify the format of FIT header pointed to by ptr
  *
diff --git a/tools/fit_image.c b/tools/fit_image.c
index 8763a36..9fe69ea 100644
--- a/tools/fit_image.c
+++ b/tools/fit_image.c
@@ -944,7 +944,7 @@
 	(void *)&header,
 	fit_check_params,
 	fit_verify_header,
-	fit_print_contents,
+	fit_print_header,
 	NULL,
 	fit_extract_contents,
 	fit_check_image_types,
diff --git a/tools/gpimage.c b/tools/gpimage.c
index 27de4cf..d2bc79d 100644
--- a/tools/gpimage.c
+++ b/tools/gpimage.c
@@ -41,7 +41,7 @@
 	return gph_verify_header(gph, 1);
 }
 
-static void gpimage_print_header(const void *ptr)
+static void gpimage_print_header(const void *ptr, struct image_tool_params *params)
 {
 	const struct gp_header *gph = (struct gp_header *)ptr;
 
diff --git a/tools/imagetool.c b/tools/imagetool.c
index 87eee4a..b293211 100644
--- a/tools/imagetool.c
+++ b/tools/imagetool.c
@@ -66,7 +66,7 @@
 				 */
 				if ((*curr)->print_header) {
 					if (!params->quiet)
-						(*curr)->print_header(ptr);
+						(*curr)->print_header(ptr, params);
 				} else {
 					fprintf(stderr,
 						"%s: print_header undefined for %s\n",
@@ -103,7 +103,7 @@
 			 */
 			if (tparams->print_header) {
 				if (!params->quiet)
-					tparams->print_header(ptr);
+					tparams->print_header(ptr, params);
 			} else {
 				fprintf(stderr,
 					"%s: print_header undefined for %s\n",
diff --git a/tools/imagetool.h b/tools/imagetool.h
index fdceea4..a766aa2 100644
--- a/tools/imagetool.h
+++ b/tools/imagetool.h
@@ -132,7 +132,7 @@
 	 */
 	int (*verify_header) (unsigned char *, int, struct image_tool_params *);
 	/* Prints image information abstracting from image header */
-	void (*print_header) (const void *);
+	void (*print_header) (const void *, struct image_tool_params *);
 	/*
 	 * The header or image contents need to be set as per image type to
 	 * be generated using this callback function.
diff --git a/tools/imx8image.c b/tools/imx8image.c
index c25ea84..76d0cd6 100644
--- a/tools/imx8image.c
+++ b/tools/imx8image.c
@@ -30,7 +30,7 @@
 {
 }
 
-static void imx8image_print_header(const void *ptr)
+static void imx8image_print_header(const void *ptr, struct image_tool_params *params)
 {
 }
 
diff --git a/tools/imx8mimage.c b/tools/imx8mimage.c
index 3ca79d8..21075c2 100644
--- a/tools/imx8mimage.c
+++ b/tools/imx8mimage.c
@@ -60,7 +60,7 @@
 {
 }
 
-static void imx8mimage_print_header(const void *ptr)
+static void imx8mimage_print_header(const void *ptr, struct image_tool_params *params)
 {
 }
 
diff --git a/tools/imximage.c b/tools/imximage.c
index 354ee34..b3da1f2 100644
--- a/tools/imximage.c
+++ b/tools/imximage.c
@@ -813,7 +813,7 @@
 	return 0;
 }
 
-static void imximage_print_header(const void *ptr)
+static void imximage_print_header(const void *ptr, struct image_tool_params *params)
 {
 	struct imx_header *imx_hdr = (struct imx_header *) ptr;
 	uint32_t version = detect_imximage_version(imx_hdr);
diff --git a/tools/kwbimage.c b/tools/kwbimage.c
index 177084a..4dce495 100644
--- a/tools/kwbimage.c
+++ b/tools/kwbimage.c
@@ -116,6 +116,7 @@
 	IMAGE_CFG_NAND_BADBLK_LOCATION,
 	IMAGE_CFG_NAND_ECC_MODE,
 	IMAGE_CFG_NAND_PAGESZ,
+	IMAGE_CFG_SATA_BLKSZ,
 	IMAGE_CFG_CPU,
 	IMAGE_CFG_BINARY,
 	IMAGE_CFG_DATA,
@@ -147,6 +148,7 @@
 	[IMAGE_CFG_NAND_BADBLK_LOCATION] = "NAND_BADBLK_LOCATION",
 	[IMAGE_CFG_NAND_ECC_MODE] = "NAND_ECC_MODE",
 	[IMAGE_CFG_NAND_PAGESZ] = "NAND_PAGE_SIZE",
+	[IMAGE_CFG_SATA_BLKSZ] = "SATA_BLKSZ",
 	[IMAGE_CFG_CPU] = "CPU",
 	[IMAGE_CFG_BINARY] = "BINARY",
 	[IMAGE_CFG_DATA] = "DATA",
@@ -185,6 +187,7 @@
 		unsigned int nandbadblklocation;
 		unsigned int nandeccmode;
 		unsigned int nandpagesz;
+		unsigned int satablksz;
 		struct ext_hdr_v0_reg regdata;
 		unsigned int regdata_delay;
 		unsigned int baudrate;
@@ -992,13 +995,21 @@
 	return 1;
 }
 
+static unsigned int image_get_satablksz(void)
+{
+	struct image_cfg_element *e;
+	e = image_find_option(IMAGE_CFG_SATA_BLKSZ);
+	return e ? e->satablksz : 512;
+}
+
 static size_t image_headersz_align(size_t headersz, uint8_t blockid)
 {
 	/*
 	 * Header needs to be 4-byte aligned, which is already ensured by code
 	 * above. Moreover UART images must have header aligned to 128 bytes
 	 * (xmodem block size), NAND images to 256 bytes (ECC calculation),
-	 * and SATA and SDIO images to 512 bytes (storage block size).
+	 * SDIO images to 512 bytes (SDHC/SDXC fixed block size) and SATA
+	 * images to specified storage block size (default 512 bytes).
 	 * Note that SPI images do not have to have header size aligned
 	 * to 256 bytes because it is possible to read from SPI storage from
 	 * any offset (read offset does not have to be aligned to block size).
@@ -1007,8 +1018,10 @@
 		return ALIGN(headersz, 128);
 	else if (blockid == IBR_HDR_NAND_ID)
 		return ALIGN(headersz, 256);
-	else if (blockid == IBR_HDR_SATA_ID || blockid == IBR_HDR_SDIO_ID)
+	else if (blockid == IBR_HDR_SDIO_ID)
 		return ALIGN(headersz, 512);
+	else if (blockid == IBR_HDR_SATA_ID)
+		return ALIGN(headersz, image_get_satablksz());
 	else
 		return headersz;
 }
@@ -1076,12 +1089,11 @@
 	if (e)
 		main_hdr->nandbadblklocation = e->nandbadblklocation;
 
-	/*
-	 * For SATA srcaddr is specified in number of sectors.
-	 * This expects the sector size to be 512 bytes.
-	 */
-	if (main_hdr->blockid == IBR_HDR_SATA_ID)
-		main_hdr->srcaddr = cpu_to_le32(le32_to_cpu(main_hdr->srcaddr) / 512);
+	/* For SATA srcaddr is specified in number of sectors. */
+	if (main_hdr->blockid == IBR_HDR_SATA_ID) {
+		params->bl_len = image_get_satablksz();
+		main_hdr->srcaddr = cpu_to_le32(le32_to_cpu(main_hdr->srcaddr) / params->bl_len);
+	}
 
 	/* For PCIe srcaddr is not used and must be set to 0xFFFFFFFF. */
 	if (main_hdr->blockid == IBR_HDR_PEX_ID)
@@ -1533,12 +1545,11 @@
 	if (e)
 		main_hdr->flags = e->debug ? 0x1 : 0;
 
-	/*
-	 * For SATA srcaddr is specified in number of sectors.
-	 * This expects the sector size to be 512 bytes.
-	 */
-	if (main_hdr->blockid == IBR_HDR_SATA_ID)
-		main_hdr->srcaddr = cpu_to_le32(le32_to_cpu(main_hdr->srcaddr) / 512);
+	/* For SATA srcaddr is specified in number of sectors. */
+	if (main_hdr->blockid == IBR_HDR_SATA_ID) {
+		params->bl_len = image_get_satablksz();
+		main_hdr->srcaddr = cpu_to_le32(le32_to_cpu(main_hdr->srcaddr) / params->bl_len);
+	}
 
 	/* For PCIe srcaddr is not used and must be set to 0xFFFFFFFF. */
 	if (main_hdr->blockid == IBR_HDR_PEX_ID)
@@ -1702,6 +1713,13 @@
 	case IMAGE_CFG_NAND_PAGESZ:
 		el->nandpagesz = strtoul(value1, NULL, 16);
 		break;
+	case IMAGE_CFG_SATA_BLKSZ:
+		el->satablksz = strtoul(value1, NULL, 0);
+		if (el->satablksz & (el->satablksz-1)) {
+			fprintf(stderr, "Invalid SATA block size '%s'\n", value1);
+			return -1;
+		}
+		break;
 	case IMAGE_CFG_BINARY:
 		argi = 0;
 
@@ -1893,6 +1911,8 @@
 	struct stat s;
 	int ret;
 
+	params->bl_len = 1;
+
 	/*
 	 * Do not use sbuf->st_size as it contains size with padding.
 	 * We need original image data size, so stat original file.
@@ -1972,7 +1992,7 @@
 	free(image);
 }
 
-static void kwbimage_print_header(const void *ptr)
+static void kwbimage_print_header(const void *ptr, struct image_tool_params *params)
 {
 	struct main_hdr_v0 *mhdr = (struct main_hdr_v0 *)ptr;
 	struct bin_hdr_v0 *bhdr;
@@ -2004,10 +2024,11 @@
 	genimg_print_size(le32_to_cpu(mhdr->blocksize) - sizeof(uint32_t));
 	printf("Data Offset:  ");
 	if (mhdr->blockid == IBR_HDR_SATA_ID)
-		printf("%u Sector%s (LBA)\n", le32_to_cpu(mhdr->srcaddr),
+		printf("%u Sector%s (LBA) = ", le32_to_cpu(mhdr->srcaddr),
 		       le32_to_cpu(mhdr->srcaddr) != 1 ? "s" : "");
-	else
-		genimg_print_size(le32_to_cpu(mhdr->srcaddr));
+	genimg_print_size(le32_to_cpu(mhdr->srcaddr) * params->bl_len);
+	if (mhdr->blockid == IBR_HDR_SATA_ID)
+		printf("Sector Size:  %u Bytes\n", params->bl_len);
 	if (mhdr->blockid == IBR_HDR_SPI_ID && le32_to_cpu(mhdr->destaddr) == 0xFFFFFFFF) {
 		printf("Load Address: XIP\n");
 		printf("Execute Offs: %08x\n", le32_to_cpu(mhdr->execaddr));
@@ -2033,6 +2054,7 @@
 	uint32_t offset;
 	uint32_t size;
 	uint8_t csum;
+	int blksz;
 
 	if (header_size > 192*1024)
 		return -FDT_ERR_BADSTRUCTURE;
@@ -2091,12 +2113,28 @@
 		return -FDT_ERR_BADSTRUCTURE;
 	}
 
+	if (size < 4 || size % 4 != 0)
+		return -FDT_ERR_BADSTRUCTURE;
+
 	/*
 	 * For SATA srcaddr is specified in number of sectors.
-	 * This expects that sector size is 512 bytes.
+	 * Try all possible sector sizes which are power of two,
+	 * at least 512 bytes and up to the 32 kB.
 	 */
-	if (blockid == IBR_HDR_SATA_ID)
-		offset *= 512;
+	if (blockid == IBR_HDR_SATA_ID) {
+		for (blksz = 512; blksz < 0x10000; blksz *= 2) {
+			if (offset * blksz > image_size || offset * blksz + size > image_size)
+				break;
+
+			if (image_checksum32(ptr + offset * blksz, size - 4) ==
+			    *(uint32_t *)(ptr + offset * blksz + size - 4)) {
+				params->bl_len = blksz;
+				return 0;
+			}
+		}
+
+		return -FDT_ERR_BADSTRUCTURE;
+	}
 
 	/*
 	 * For PCIe srcaddr is always set to 0xFFFFFFFF.
@@ -2105,21 +2143,17 @@
 	if (blockid == IBR_HDR_PEX_ID && offset == 0xFFFFFFFF)
 		offset = header_size;
 
-	if (offset > image_size || offset % 4 != 0)
-		return -FDT_ERR_BADSTRUCTURE;
-
-	if (size < 4 || offset + size > image_size || size % 4 != 0)
+	if (offset % 4 != 0 || offset > image_size || offset + size > image_size)
 		return -FDT_ERR_BADSTRUCTURE;
 
 	if (image_checksum32(ptr + offset, size - 4) !=
 	    *(uint32_t *)(ptr + offset + size - 4))
 		return -FDT_ERR_BADSTRUCTURE;
 
+	params->bl_len = 1;
 	return 0;
 }
 
-static int kwbimage_align_size(int bootfrom, int alloc_len, struct stat s);
-
 static int kwbimage_generate(struct image_tool_params *params,
 			     struct image_type_params *tparams)
 {
@@ -2130,6 +2164,8 @@
 	int version;
 	void *hdr;
 	int ret;
+	int align, size;
+	unsigned int satablksz;
 
 	fcfg = fopen(params->imagename, "r");
 	if (!fcfg) {
@@ -2167,6 +2203,7 @@
 
 	bootfrom = image_get_bootfrom();
 	version = image_get_version();
+	satablksz = image_get_satablksz();
 	switch (version) {
 		/*
 		 * Fallback to version 0 if no version is provided in the
@@ -2212,39 +2249,43 @@
 	tparams->hdr = hdr;
 
 	/*
+	 * Final SATA images must be aligned to disk block size.
+	 * Final SDIO images must be aligned to 512 bytes.
+	 * Final SPI and NAND images must be aligned to 256 bytes.
+	 * Final UART image must be aligned to 128 bytes.
+	 */
+	if (bootfrom == IBR_HDR_SATA_ID)
+		align = satablksz;
+	else if (bootfrom == IBR_HDR_SDIO_ID)
+		align = 512;
+	else if (bootfrom == IBR_HDR_SPI_ID || bootfrom == IBR_HDR_NAND_ID)
+		align = 256;
+	else if (bootfrom == IBR_HDR_UART_ID)
+		align = 128;
+	else
+		align = 4;
+
+	/*
+	 * The resulting image needs to be 4-byte aligned. At least
+	 * the Marvell hdrparser tool complains if its unaligned.
+	 * After the image data is stored 4-byte checksum.
+	 */
+	size = 4 + (align - (alloc_len + s.st_size + 4) % align) % align;
+
+	/*
 	 * This function should return aligned size of the datafile.
 	 * When skipcpy is set (datafile is skipped) then return value of this
 	 * function is ignored, so we have to put required kwbimage aligning
 	 * into the preallocated header size.
 	 */
 	if (params->skipcpy) {
-		tparams->header_size += kwbimage_align_size(bootfrom, alloc_len, s);
+		tparams->header_size += size;
 		return 0;
 	} else {
-		return kwbimage_align_size(bootfrom, alloc_len, s);
+		return size;
 	}
 }
 
-static int kwbimage_align_size(int bootfrom, int alloc_len, struct stat s)
-{
-	/*
-	 * The resulting image needs to be 4-byte aligned. At least
-	 * the Marvell hdrparser tool complains if its unaligned.
-	 * After the image data is stored 4-byte checksum.
-	 * Final UART image must be aligned to 128 bytes.
-	 * Final SPI and NAND images must be aligned to 256 bytes.
-	 * Final SATA and SDIO images must be aligned to 512 bytes.
-	 */
-	if (bootfrom == IBR_HDR_SPI_ID || bootfrom == IBR_HDR_NAND_ID)
-		return 4 + (256 - (alloc_len + s.st_size + 4) % 256) % 256;
-	else if (bootfrom == IBR_HDR_SATA_ID || bootfrom == IBR_HDR_SDIO_ID)
-		return 4 + (512 - (alloc_len + s.st_size + 4) % 512) % 512;
-	else if (bootfrom == IBR_HDR_UART_ID)
-		return 4 + (128 - (alloc_len + s.st_size + 4) % 128) % 128;
-	else
-		return 4 + (4 - s.st_size % 4) % 4;
-}
-
 static int kwbimage_generate_config(void *ptr, struct image_tool_params *params)
 {
 	struct main_hdr_v0 *mhdr0 = (struct main_hdr_v0 *)ptr;
@@ -2306,6 +2347,9 @@
 	if (version == 0 && mhdr->blockid == IBR_HDR_SATA_ID)
 		fprintf(f, "SATA_PIO_MODE %u\n", (unsigned)mhdr0->satapiomode);
 
+	if (mhdr->blockid == IBR_HDR_SATA_ID)
+		fprintf(f, "SATA_BLKSZ %u\n", params->bl_len);
+
 	/*
 	 * Addresses and sizes which are specified by mkimage command line
 	 * arguments and not in kwbimage config file
@@ -2486,7 +2530,7 @@
 		offset = le32_to_cpu(mhdr->srcaddr);
 
 		if (mhdr->blockid == IBR_HDR_SATA_ID)
-			offset *= 512;
+			offset *= params->bl_len;
 
 		if (mhdr->blockid == IBR_HDR_PEX_ID && offset == 0xFFFFFFFF)
 			offset = header_size;
diff --git a/tools/kwboot.c b/tools/kwboot.c
index 348a320..6bef461 100644
--- a/tools/kwboot.c
+++ b/tools/kwboot.c
@@ -1991,6 +1991,39 @@
 	}
 }
 
+static int
+kwboot_img_guess_sata_blksz(void *img, uint32_t blkoff, uint32_t data_size, size_t total_size)
+{
+	uint32_t sum, *ptr, *end;
+	int blksz;
+
+	/*
+	 * Try all possible sector sizes which are power of two,
+	 * at least 512 bytes and up to the 32 kB.
+	 */
+	for (blksz = 512; blksz < 0x10000; blksz *= 2) {
+		if (blkoff * blksz > total_size ||
+		    blkoff * blksz + data_size > total_size ||
+		    data_size % 4)
+			break;
+
+		/*
+		 * Calculate data checksum and if it matches
+		 * then tried blksz should be correct.
+		 */
+		ptr = img + blkoff * blksz;
+		end = (void *)ptr + data_size - 4;
+		for (sum = 0; ptr < end; ptr++)
+			sum += *ptr;
+
+		if (sum == *end)
+			return blksz;
+	}
+
+	/* Fallback to 512 bytes */
+	return 512;
+}
+
 static const char *
 kwboot_img_type(uint8_t blockid)
 {
@@ -2049,7 +2082,7 @@
 
 	switch (hdr->blockid) {
 	case IBR_HDR_SATA_ID:
-		hdr->srcaddr = cpu_to_le32(srcaddr * 512);
+		hdr->srcaddr = cpu_to_le32(srcaddr * kwboot_img_guess_sata_blksz(img, srcaddr, le32_to_cpu(hdr->blocksize), *size));
 		break;
 
 	case IBR_HDR_PEX_ID:
diff --git a/tools/lpc32xximage.c b/tools/lpc32xximage.c
index 37931f9..715a55a 100644
--- a/tools/lpc32xximage.c
+++ b/tools/lpc32xximage.c
@@ -125,7 +125,7 @@
 	printf("header[%d] = %02x\n", ofs, hdr->data[ofs]);
 }
 
-static void lpc32xximage_print_header(const void *ptr)
+static void lpc32xximage_print_header(const void *ptr, struct image_tool_params *params)
 {
 	struct nand_page_0_boot_header *hdr =
 		(struct nand_page_0_boot_header *)ptr;
diff --git a/tools/mkimage.c b/tools/mkimage.c
index a92d9d5..6dfe3e1 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -790,7 +790,7 @@
 
 	/* Print the image information by processing image header */
 	if (tparams->print_header)
-		tparams->print_header (ptr);
+		tparams->print_header (ptr, &params);
 	else {
 		fprintf (stderr, "%s: Can't print header for %s\n",
 			params.cmdname, tparams->name);
diff --git a/tools/mtk_image.c b/tools/mtk_image.c
index 5ef9334..30f54c8 100644
--- a/tools/mtk_image.c
+++ b/tools/mtk_image.c
@@ -510,7 +510,7 @@
 	return -1;
 }
 
-static void mtk_image_print_header(const void *ptr)
+static void mtk_image_print_header(const void *ptr, struct image_tool_params *params)
 {
 	struct legacy_img_hdr *hdr = (struct legacy_img_hdr *)ptr;
 	union lk_hdr *lk = (union lk_hdr *)ptr;
diff --git a/tools/mxsimage.c b/tools/mxsimage.c
index fbe46c4..ead61d0 100644
--- a/tools/mxsimage.c
+++ b/tools/mxsimage.c
@@ -2239,7 +2239,7 @@
 	return mxsimage_verify_print_header(params->imagefile, 1);
 }
 
-static void mxsimage_print_header(const void *hdr)
+static void mxsimage_print_header(const void *hdr, struct image_tool_params *params)
 {
 	if (imagefile)
 		mxsimage_verify_print_header(imagefile, 0);
diff --git a/tools/omapimage.c b/tools/omapimage.c
index c59cdcc..b79c1c3 100644
--- a/tools/omapimage.c
+++ b/tools/omapimage.c
@@ -85,7 +85,7 @@
 		chs->flags);
 }
 
-static void omapimage_print_header(const void *ptr)
+static void omapimage_print_header(const void *ptr, struct image_tool_params *params)
 {
 	const struct ch_toc *toc = (struct ch_toc *)ptr;
 	const struct gp_header *gph =
diff --git a/tools/pblimage.c b/tools/pblimage.c
index bd639c2..6c4d360 100644
--- a/tools/pblimage.c
+++ b/tools/pblimage.c
@@ -254,7 +254,7 @@
 	return 0;
 }
 
-static void pblimage_print_header(const void *ptr)
+static void pblimage_print_header(const void *ptr, struct image_tool_params *params)
 {
 	printf("Image Type:   Freescale PBL Boot Image\n");
 }
diff --git a/tools/rkcommon.c b/tools/rkcommon.c
index 96efc11..12c27b3 100644
--- a/tools/rkcommon.c
+++ b/tools/rkcommon.c
@@ -481,7 +481,7 @@
 	return -ENOENT;
 }
 
-void rkcommon_print_header(const void *buf)
+void rkcommon_print_header(const void *buf, struct image_tool_params *params)
 {
 	struct header0_info header0;
 	struct header0_info_v2 header0_v2;
diff --git a/tools/rkcommon.h b/tools/rkcommon.h
index 49b6df3..5d2770a 100644
--- a/tools/rkcommon.h
+++ b/tools/rkcommon.h
@@ -68,7 +68,7 @@
  *
  * @buf:	Pointer to the image (can be a read-only file-mapping)
  */
-void rkcommon_print_header(const void *buf);
+void rkcommon_print_header(const void *buf, struct image_tool_params *params);
 
 /**
  * rkcommon_need_rc4_spl() - check if rc4 encoded spl is required
diff --git a/tools/socfpgaimage.c b/tools/socfpgaimage.c
index eba812f..953dfee 100644
--- a/tools/socfpgaimage.c
+++ b/tools/socfpgaimage.c
@@ -313,7 +313,7 @@
 	       le16_to_cpu(header->checksum));
 }
 
-static void socfpgaimage_print_header(const void *ptr)
+static void socfpgaimage_print_header(const void *ptr, struct image_tool_params *params)
 {
 	const void *header = ptr + HEADER_OFFSET;
 	struct socfpga_header_v0 *header_v0;
diff --git a/tools/stm32image.c b/tools/stm32image.c
index 18357c0..5c6991f 100644
--- a/tools/stm32image.c
+++ b/tools/stm32image.c
@@ -99,7 +99,7 @@
 	return 0;
 }
 
-static void stm32image_print_header(const void *ptr)
+static void stm32image_print_header(const void *ptr, struct image_tool_params *params)
 {
 	struct stm32_header *stm32hdr = (struct stm32_header *)ptr;
 
diff --git a/tools/sunxi_egon.c b/tools/sunxi_egon.c
index d45b6f5..a514427 100644
--- a/tools/sunxi_egon.c
+++ b/tools/sunxi_egon.c
@@ -82,7 +82,7 @@
 	return EXIT_SUCCESS;
 }
 
-static void egon_print_header(const void *buf)
+static void egon_print_header(const void *buf, struct image_tool_params *params)
 {
 	const struct boot_file_head *header = buf;
 
diff --git a/tools/sunxi_toc0.c b/tools/sunxi_toc0.c
index 7a8d74b..292649f 100644
--- a/tools/sunxi_toc0.c
+++ b/tools/sunxi_toc0.c
@@ -757,7 +757,7 @@
 	return "(unknown)";
 }
 
-static void toc0_print_header(const void *buf)
+static void toc0_print_header(const void *buf, struct image_tool_params *params)
 {
 	const struct toc0_main_info *main_info = buf;
 	const struct toc0_item_info *item_info = (void *)(main_info + 1);
diff --git a/tools/ublimage.c b/tools/ublimage.c
index 1d2e897..8f9b58c 100644
--- a/tools/ublimage.c
+++ b/tools/ublimage.c
@@ -202,7 +202,7 @@
 	return 0;
 }
 
-static void ublimage_print_header(const void *ptr)
+static void ublimage_print_header(const void *ptr, struct image_tool_params *params)
 {
 	struct ubl_header *ubl_hdr = (struct ubl_header *) ptr;
 
diff --git a/tools/vybridimage.c b/tools/vybridimage.c
index 94a6684..c38886f 100644
--- a/tools/vybridimage.c
+++ b/tools/vybridimage.c
@@ -134,7 +134,7 @@
 	printf("header.fcb[%d] = %08x\n", idx, hdr->fcb[idx]);
 }
 
-static void vybridimage_print_header(const void *ptr)
+static void vybridimage_print_header(const void *ptr, struct image_tool_params *params)
 {
 	struct nand_page_0_boot_header *hdr =
 		(struct nand_page_0_boot_header *)ptr;
diff --git a/tools/zynqimage.c b/tools/zynqimage.c
index d3f418b..359c93d 100644
--- a/tools/zynqimage.c
+++ b/tools/zynqimage.c
@@ -163,7 +163,7 @@
 	return 0;
 }
 
-static void zynqimage_print_header(const void *ptr)
+static void zynqimage_print_header(const void *ptr, struct image_tool_params *params)
 {
 	struct zynq_header *zynqhdr = (struct zynq_header *)ptr;
 	int i;
diff --git a/tools/zynqmpimage.c b/tools/zynqmpimage.c
index 19b2f02..5113ba8 100644
--- a/tools/zynqmpimage.c
+++ b/tools/zynqmpimage.c
@@ -209,7 +209,7 @@
 	printf("    Checksum   : 0x%08x\n", le32_to_cpu(ph->checksum));
 }
 
-void zynqmpimage_print_header(const void *ptr)
+void zynqmpimage_print_header(const void *ptr, struct image_tool_params *params)
 {
 	struct zynqmp_header *zynqhdr = (struct zynqmp_header *)ptr;
 	int i;
diff --git a/tools/zynqmpimage.h b/tools/zynqmpimage.h
index a1db819..9d526a1 100644
--- a/tools/zynqmpimage.h
+++ b/tools/zynqmpimage.h
@@ -133,6 +133,6 @@
 };
 
 void zynqmpimage_default_header(struct zynqmp_header *ptr);
-void zynqmpimage_print_header(const void *ptr);
+void zynqmpimage_print_header(const void *ptr, struct image_tool_params *params);
 
 #endif /* _ZYNQMPIMAGE_H_ */