xref: /OK3568_Linux_fs/kernel/drivers/rkflash/sfc_nor_boot.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 /* Copyright (c) 2018 Rockchip Electronics Co. Ltd. */
4 
5 #include <linux/kernel.h>
6 #include <linux/slab.h>
7 #include <crypto/skcipher.h>
8 #include <linux/scatterlist.h>
9 
10 #include "sfc_nor.h"
11 #include "rkflash_api.h"
12 #include "rkflash_debug.h"
13 
14 #define VENDOR_PART_NUM			4
15 
16 #define	FLASH_VENDOR_PART_START		8
17 #define FLASH_VENDOR_PART_SIZE		8
18 #define FLASH_VENDOR_ITEM_NUM		62
19 #define	FLASH_VENDOR_PART_END		\
20 	(FLASH_VENDOR_PART_START +\
21 	FLASH_VENDOR_PART_SIZE * VENDOR_PART_NUM - 1)
22 
23 #define IDB_ALIGN_64			128	/* 64 KB */
24 #define IDB_ALIGN_32			64	/* 32 KB */
25 
26 struct SFNOR_DEV *sfnor_dev;
27 
28 /* SFNOR_DEV sfnor_dev is in the sfc_nor.h */
spi_nor_init(void __iomem * reg_addr)29 static int spi_nor_init(void __iomem *reg_addr)
30 {
31 	int ret;
32 	struct id_block_tag *idb_tag;
33 	struct snor_info_packet *packet;
34 
35 	if (!sfnor_dev)
36 		sfnor_dev = kzalloc(sizeof(*sfnor_dev), GFP_KERNEL);
37 
38 	if (!sfnor_dev)
39 		return -ENOMEM;
40 
41 	sfc_init(reg_addr);
42 	ret = snor_init(sfnor_dev);
43 	if (ret == SFC_OK && sfnor_dev->read_lines == DATA_LINES_X1) {
44 		struct crypto_sync_skcipher *tfm_arc4;
45 
46 		tfm_arc4 = crypto_alloc_sync_skcipher("ecb(arc4)", 0, 0);
47 		if (IS_ERR(tfm_arc4)) {
48 			crypto_free_sync_skcipher(tfm_arc4);
49 			return SFC_OK;
50 		}
51 
52 		idb_tag = kzalloc(NOR_SECS_PAGE * 512, GFP_KERNEL);
53 		if (!idb_tag) {
54 			crypto_free_sync_skcipher(tfm_arc4);
55 			return SFC_OK;
56 		}
57 
58 		if (sfc_get_version() >= SFC_VER_4)
59 			snor_read(sfnor_dev, IDB_ALIGN_32, NOR_SECS_PAGE,
60 				  idb_tag);
61 		else
62 			snor_read(sfnor_dev, IDB_ALIGN_64, NOR_SECS_PAGE,
63 				  idb_tag);
64 		packet = (struct snor_info_packet *)&idb_tag->dev_param[0];
65 		if (idb_tag->id == IDB_BLOCK_TAG_ID) {
66 			SYNC_SKCIPHER_REQUEST_ON_STACK(req, tfm_arc4);
67 			u8 key[16] = {124, 78, 3, 4, 85, 5, 9, 7,
68 				      45, 44, 123, 56, 23, 13, 23, 17};
69 			struct scatterlist sg;
70 			u32 len = sizeof(struct id_block_tag);
71 
72 			crypto_sync_skcipher_setkey(tfm_arc4, key, 16);
73 			sg_init_one(&sg, idb_tag, len + 4);
74 			skcipher_request_set_sync_tfm(req, tfm_arc4);
75 			skcipher_request_set_callback(req, 0, NULL, NULL);
76 			skcipher_request_set_crypt(req, &sg, &sg, len + 4,
77 						   NULL);
78 			ret = crypto_skcipher_encrypt(req);
79 			if (!ret) {
80 				snor_reinit_from_table_packet(sfnor_dev,
81 							      packet);
82 				rkflash_print_error("snor reinit, ret= %d\n", ret);
83 			}
84 		}
85 		crypto_free_sync_skcipher(tfm_arc4);
86 		kfree(idb_tag);
87 	}
88 
89 	return ret;
90 }
91 
snor_read_lba(u32 sec,u32 n_sec,void * p_data)92 static int snor_read_lba(u32 sec, u32 n_sec, void *p_data)
93 {
94 	int ret = 0;
95 	u32 count, offset;
96 	char *buf;
97 
98 	if (sec + n_sec - 1 < FLASH_VENDOR_PART_START ||
99 	    sec > FLASH_VENDOR_PART_END) {
100 		ret = snor_read(sfnor_dev, sec, n_sec, p_data);
101 	} else {
102 		memset(p_data, 0, 512 * n_sec);
103 		if (sec < FLASH_VENDOR_PART_START) {
104 			count = FLASH_VENDOR_PART_START - sec;
105 			buf = p_data;
106 			ret = snor_read(sfnor_dev, sec, count, buf);
107 		}
108 		if ((sec + n_sec - 1) > FLASH_VENDOR_PART_END) {
109 			count = sec + n_sec - 1 - FLASH_VENDOR_PART_END;
110 			offset = FLASH_VENDOR_PART_END - sec + 1;
111 			buf = p_data + offset * 512;
112 			ret = snor_read(sfnor_dev,
113 					FLASH_VENDOR_PART_END + 1,
114 					count, buf);
115 		}
116 	}
117 
118 	return (u32)ret == n_sec ? 0 : ret;
119 }
120 
snor_write_lba(u32 sec,u32 n_sec,void * p_data)121 static int snor_write_lba(u32 sec, u32 n_sec, void *p_data)
122 {
123 	int ret = 0;
124 
125 	ret = snor_write(sfnor_dev, sec, n_sec, p_data);
126 
127 	return (u32)ret == n_sec ? 0 : ret;
128 }
129 
snor_vendor_read(u32 sec,u32 n_sec,void * p_data)130 static int snor_vendor_read(u32 sec, u32 n_sec, void *p_data)
131 {
132 	int ret = 0;
133 
134 	ret = snor_read(sfnor_dev, sec, n_sec, p_data);
135 
136 	return (u32)ret == n_sec ? 0 : ret;
137 }
138 
snor_vendor_write(u32 sec,u32 n_sec,void * p_data)139 static int snor_vendor_write(u32 sec, u32 n_sec, void *p_data)
140 {
141 	int ret = 0;
142 
143 	ret = snor_write(sfnor_dev, sec, n_sec, p_data);
144 
145 	return (u32)ret == n_sec ? 0 : ret;
146 }
147 
snor_gc(void)148 static int snor_gc(void)
149 {
150 	return 0;
151 }
152 
snor_capacity(void)153 static unsigned int snor_capacity(void)
154 {
155 	return snor_get_capacity(sfnor_dev);
156 }
157 
snor_deinit(void)158 static void snor_deinit(void)
159 {
160 	snor_disable_QE(sfnor_dev);
161 	snor_reset_device();
162 	kfree(sfnor_dev);
163 }
164 
snor_resume(void __iomem * reg_addr)165 static int snor_resume(void __iomem *reg_addr)
166 {
167 	return spi_nor_init(reg_addr);
168 }
169 
170 const struct flash_boot_ops sfc_nor_ops = {
171 	spi_nor_init,
172 	snor_read_lba,
173 	snor_write_lba,
174 	snor_capacity,
175 	snor_deinit,
176 	snor_resume,
177 	snor_vendor_read,
178 	snor_vendor_write,
179 	snor_gc,
180 	NULL,
181 };
182