xref: /OK3568_Linux_fs/u-boot/tools/rkspi.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /*
2  * (C) Copyright 2015 Google,  Inc
3  * Written by Simon Glass <sjg@chromium.org>
4  *
5  * SPDX-License-Identifier:	GPL-2.0+
6  *
7  * See README.rockchip for details of the rkspi format
8  */
9 
10 #include "imagetool.h"
11 #include <image.h>
12 #include <rc4.h>
13 #include "mkimage.h"
14 #include "rkcommon.h"
15 
16 enum {
17 	RKSPI_SECT_LEN		= RK_BLK_SIZE * 4,
18 };
19 
rkspi_set_header(void * buf,struct stat * sbuf,int ifd,struct image_tool_params * params)20 static void rkspi_set_header(void *buf, struct stat *sbuf, int ifd,
21 			     struct image_tool_params *params)
22 {
23 	int sector;
24 	unsigned int size;
25 
26 	size = params->orig_file_size;
27 
28 	rkcommon_set_header(buf, sbuf, ifd, params);
29 
30 	/*
31 	 * Spread the image out so we only use the first 2KB of each 4KB
32 	 * region. This is a feature of the SPI format required by the Rockchip
33 	 * boot ROM. Its rationale is unknown.
34 	 */
35 	if (params->vflag)
36 		fprintf(stderr, "Spreading spi image from %u to %u\n",
37 			size, params->file_size);
38 
39 	for (sector = size / RKSPI_SECT_LEN - 1; sector >= 0; sector--) {
40 		debug("sector %u\n", sector);
41 		memmove(buf + sector * RKSPI_SECT_LEN * 2,
42 			buf + sector * RKSPI_SECT_LEN,
43 			RKSPI_SECT_LEN);
44 		memset(buf + sector * RKSPI_SECT_LEN * 2 + RKSPI_SECT_LEN,
45 		       '\0', RKSPI_SECT_LEN);
46 	}
47 }
48 
rkspi_check_image_type(uint8_t type)49 static int rkspi_check_image_type(uint8_t type)
50 {
51 	if (type == IH_TYPE_RKSPI)
52 		return EXIT_SUCCESS;
53 	else
54 		return EXIT_FAILURE;
55 }
56 
57 /*
58  * The SPI payload needs to make space for odd half-sector layout used in flash
59  * (i.e. only the first 2K of each 4K sector is used).
60  */
rkspi_vrec_header(struct image_tool_params * params,struct image_type_params * tparams)61 static int rkspi_vrec_header(struct image_tool_params *params,
62 			     struct image_type_params *tparams)
63 {
64 	rkcommon_vrec_header(params, tparams);
65 
66 	/*
67 	 * Converting to the SPI format (i.e. splitting each 4K page into two
68 	 * 2K subpages and then padding these 2K pages up to take a complete
69 	 * 4K sector again) which will double the image size.
70 	 */
71 	params->file_size = ROUND(params->file_size, RKSPI_SECT_LEN) << 1;
72 
73 	/* Ignoring pad len, since we are using our own copy_image() */
74 	return 0;
75 }
76 
77 /*
78  * rk_spi parameters
79  */
80 U_BOOT_IMAGE_TYPE(
81 	rkspi,
82 	"Rockchip SPI Boot Image support",
83 	0,
84 	NULL,
85 	rkcommon_check_params,
86 	rkcommon_verify_header,
87 	rkcommon_print_header,
88 	rkspi_set_header,
89 	NULL,
90 	rkspi_check_image_type,
91 	NULL,
92 	rkspi_vrec_header
93 );
94