blob: c093dee0c9256ea8d1771d76b565f6ef2e33a9d7 [file] [log] [blame]
Bichao Zheng8951e442023-07-13 13:21:29 +08001/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
2/*
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 */
5
6#ifndef _PAGE_INFO_H_
7#define _PAGE_INFO_H_
8
9#include <linux/mtd/spinand.h>
10#include <linux/mtd/nand.h>
11#include <amlogic/aml_mtd.h>
12#include <amlogic/aml_rsv.h>
13#include <spi_flash.h>
14#include <spi.h>
15#include "common.h"
16#include "string.h"
17#include <amlogic/blxx2bl33_param.h>
18#include <asm/amlogic/arch/cpu_config.h>
19#include <amlogic/cpu_id.h>
Feng Chenaa371df2024-01-12 20:20:53 +080020#include <amlogic/nfc.h>
Bichao Zheng8951e442023-07-13 13:21:29 +080021
22//#define __PXP_DEBUG__
23#define PAGEINFO_QUICK_INIT
24#define MAX_BYTES_IN_BOOTINFO (512)
25
26#ifdef __PXP_DEBUG__
27#define NFC_Print(x, y) { \
28 pr_info(x); \
29 pr_info(" = %x\n", y); \
30}
31
32#define DUMP_BUFFER(buffer, size, loop, actual) \
33{ \
34 unsigned char *info; \
35 unsigned int _loop = loop; \
36 unsigned int i, j, each_size = (size) / _loop; \
37 for (i = 0; i < _loop; i++) { \
38 info = (unsigned char *)((unsigned long)(buffer) + i * each_size); \
39 for (j = 0; j < (actual); j++, info++) {\
40 pr_info(" "); \
41 pr_info("%02x", *info); \
42 } \
43 pr_info("\n"); \
44 } \
45}
46#else
47#define NFC_Print(x, y)
48#define DUMP_BUFFER(buffer, size, loop, actual)
49#endif
50
51#define MAX_CLK_PROVIDER 13
52
53enum BL2_LAYOUT_VERS {
54 LAYOUT_VER0,
55 LAYOUT_VER1,
56 LAYOUT_VER2,
57 LAYOUT_VER3,
58 LAYOUT_VER_MAX,
59};
60
61enum PAGE_INFO_V {
62 PAGE_INFO_V1 = 1,
63 PAGE_INFO_V2,
64 PAGE_INFO_V3
65};
66
67#define PAGE_ERROR_MODE(mod, num) ((uint32_t)((((mod) << 16) | (num))))
68#define ERR_PAGE_INFO PAGE_ERROR_MODE(1, 1)
69
70#define MAX_PAGEINFO_COUNT 21
71
72extern struct boot_info *page_info;
73extern unsigned short pageinfo_located[MAX_PAGEINFO_COUNT];
74
75struct boot_info {
76#define BOOTINFO_MAGIC "BOOTINFO"
77#define BOOTINFO_INFO_VER 1
78 char magic[8];
79 unsigned char version; /* need to greater than or equal to 2 */
80 unsigned char reserved[3]; /* reserve zero */
81 struct {
82 /* from SPI NAND datasheet */
83 unsigned int page_size;
84 /* bit0~3: planes_per_lun bit4~7: plane_shift */
85 unsigned char planes_per_lun;
86 /* bit0~3: bus_width bit4~7: cache_plane_shift */
87 /* 0, 1, 2, 3 buswidth, 2: 4 wires; 3: 8 wires */
88 unsigned char bus_width;
89 } dev_cfg0;
90
91 /* the checksum of the whole boot_info struct */
92 unsigned int checksum;
93
94 struct {
95 /* frequency index, which is used to select the frequency and
96 * timing mode. we provide a array of fixed clock providers in
97 * ROM, such as the definition of clk_provider[] in nfc.c. only
98 * if a worse board used. otherwise these items should be prior
99 * of using. we considered some common frequency and timing
100 * points.
101 * 0xFF: it follows the old method to select the frequency
102 * which means EFUSE. EFUSE can bring four type [16MHZ,
103 * 20MHZ, 41MHZ, 83MHZ] and the adjust index is also from
104 * EFUSE bits.
105 * !0xFF: bit6-0 indicates the index of the array clk_provider[].
106 * if bit7 of frequency index is 0, we will use the fixed
107 * timing parameters such as core divider, spi clock
108 * divider form the fixed value defined in clk_provider[];
109 * but if bit7 of frequency index is 1, we use these timing
110 * parameters form page info.
111 */
112 unsigned char frequency_index;
113 /* core clock divider */
114 unsigned char core_div;
115 /* SPI clock divider */
116 unsigned char bus_cycle;
117 /* bit6-7: mode select
118 * spi nor/nand only support mode0 and mode3
119 */
120 /* bit5-0: rx adjust index, to adjust the sampling point */
121 unsigned char mode_rx_adj;
122 /* delay value for each line */
123 unsigned int lines_delay[2];
124 /* decide the ECC/ran mode of bl2 pages, satisfy */
125 /* only used by spi nand at now */
126 unsigned int n2m_cmd;
127 /* bit0 :disable the built-in ECC of SPI nand */
128 unsigned char device_ecc_disable;
129 } host_cfg;
130
131 struct {
132 /* unusable now */
133 unsigned char high_speed_mode;
134 /* bit3-0: command lanes bit7-4: address lanes */
135 unsigned char ca_lanes;
136 /* chip deselect time that needs from datasheet, variable */
137 unsigned char cs_deselect_time;
138 /* dummy clock needs by spi nor octal mode */
139 unsigned char dummy_cycles;
140 /* it is not used in ROM, instead used in BL2(core).
141 * because we have quick initialization in BL2(core) which
142 * reuse the page info reading in ROM stage, we don't want
143 * to read it from SPI storage again.
144 * bit31-24 : BBT page number bit23-0 : BBT start page
145 */
146 unsigned int bbt_start_page;
147 /* from SPI NAND datasheet */
148 unsigned int block_size;
149#ifdef BOOTINFO_PROGRAMMER_SUPPORT
150#define MAX_F_BAD_BLOCK_NUM 64
151#else
152#define MAX_F_BAD_BLOCK_NUM 16
153#endif
154 unsigned short bbt[MAX_F_BAD_BLOCK_NUM];
155 /* when enable_bbt == 1, the bad block skipping mechanism is
156 * enabled and bbt[] array is used.
157 */
158 unsigned char enable_bbt;
159#ifdef BOOTINFO_PROGRAMMER_SUPPORT
160 /* decide usb update or gang programmer */
161 unsigned char is_gang_programer;
162 /*bit15-0 xor bbt start block */
163 /*bit23-16 xor bbt block number */
164 /*bit31-24 xor bbt pages */
165 unsigned int xor_bbt_start_block;
166 /* bit15-0 total blocks in chip */
167 unsigned int block_num_in_chip;
168#endif
169 } dev_cfg1;
170
171 struct {
172 /* layout_method[bit0-3]: decide the layout of bootloader
173 * 0: the old method that we already supported.
174 * bootloader is discrete, [bl2 + fip] or [1stblob + bl2e/x +
175 * {ddrfip} + devfip]; and one page info is at the head
176 * of bl2 or 1stblob. 1024 pages size of BL2 or 1stblob
177 * is wasting too much space, and discreteness of bootloader
178 * cause a more difficult design.
179 * 1: no discreteness of bootloader. one page info is at the head
180 * of each bootloader. we can store each u-boot.bin as a whole
181 * in nand array.
182 * 2: no discreteness of bootloader. the difference between
183 * layout_method 1 and 2 is that we separate the page info from
184 * each bootloader and each page info is stored in one blocks.
185 * so the MTD bootloader is like MTD normal that we don't need
186 * to register two nand device or handle the different interfaces.
187 * but obviously, the copy number of page info is equal to the
188 * copy number of bootloader, and bootloaders are separate by each
189 * page info.
190 * 3: no discreteness of bootloader. the difference between
191 * layout_method 2 and 3 is that bootloaders are not separate
192 * by each page info and the copy number of page info is
193 * maximum 4, which does not follow the copy number of bootloaders.
194 * bit7-4: boot copies
195 */
196 unsigned char layout_method;
197 unsigned char reserved[3]; /* reserve zero */
198 /* which must be block align. in layout_method 1, the boot size
199 * is equal to <the size of each bootloader adds one page zie>
200 * in layout_method 2 and 3, the boot size is equal to the size
201 * of each bootloader,
202 */
203 unsigned int boot_size;
204 } boot_layout;
205};
206
207/* *NOTE* Change the setting for different SOCs */
208// 2 << 20 : code1code0(10b')
209// 1 << 19 : rand enable
210// 1 << 17 : read, not write
211// 7 << 14 : ECC mode which is from 0 to 7; Maybe different setting here,
212// : such as 2 for AXG serials, 7 for g12a.
213// : 0->none
214// : 1->BCH8/512
215// : 2->BCH8/1024
216// : 3->BCH24/1024
217// : 4->BCH30/1024
218// : 5->BCH40/1024
219// : 6->BCH50/1024
220// : 7->BCH60/1024
221// 1 << 13 : short mode enable
222// 48 << 6 : ECC page size
223// 1 << 0 : ECC page number
224#define DEFAULT_ECC_MODE \
225( \
226 (2 << 20) | \
227 (0 << 19) | \
228 (1 << 17) | \
229 (1 << 14) | \
230 (0 << 13) | \
231 (0 << 6) | \
232 (1 << 0) \
233)
234
235/*
236 * The 2KB head of the buffer may be overwritten
237 * by NAND DMA because of BL2_SIZE misaligment with nand page.
238 * so add 2KB!!!
239 */
240//#define NFC_PAGE0_SIZE (512)
241//#define NFC_PAGE0_BUF (BL2_NAND_PAGE_BUFFER + 0x800)
242//#define NFC_INFO_BUF (NFC_PAGE0_BUF + NFC_PAGE0_SIZE)
243
244#define LANE_INVALID(x, y, z) ((x) > 3 || (y) > 3 || (z) > 3)
245#define MODE_INVALID(x) (__extension__ ({ \
246 __typeof__(x) _x = (x); \
247 (_x != 0 || _x != 3); \
248}))
249#define STEPS_INVALID(x) (__extension__ ({ \
250 __typeof__(x) _x = (x); \
251 (_x == 0 || _x > 16); \
252}))
253#define BUS_CYCLE_INVALID(x) (__extension__ ({ \
254 __typeof__(x) _x = (x); \
255 (_x == 1 || _x > 31); \
256}))
257#define FREQUENCY_INDEX_INVALID(x) (__extension__ ({ \
258 __typeof__(x) _x = (x); \
259 (_x != 0xFF && (_x & 0x7F) >= MAX_CLK_PROVIDER); \
260}))
261#define PAGE_SIZE_INVALID(x) (__extension__ ({ \
262 __typeof__(x) _x = (x); \
263 (_x != 0x800 && _x != 0x1000 && _x != 0x2000); \
264}))
265#define BLOCK_SIZE_INVALID(x) (__extension__ ({ \
266 __typeof__(x) _x = (x); \
267 (_x != 0x20000 && _x != 0x40000 && _x != 0x80000); \
268}))
269#define PAGEC_PLANE_SHIFT_INVALID(x) (__extension__ ({ \
270 __typeof__(x) _x = (x); \
271 (_x != 0 && _x != 12 && _x != 13 && _x != 14); \
272}))
273#define BLOCK_PLANE_SHIFT_INVALID(x) (__extension__ ({ \
274 __typeof__(x) _x = (x); \
275 (_x != 0 && _x != 6 && _x != 7 && _x != 8); \
276}))
277#define PLANE_NUMBER_INVALID(x) (__extension__ ({ \
278 __typeof__(x) _x = (x); \
279 (_x != 1 && _x != 2); \
280}))
281
282void page_info_set_addr(unsigned long pi_addr);
283unsigned char page_info_get_data_lanes_mode(void);
284unsigned char page_info_get_cmd_lanes_mode(void);
285unsigned char page_info_get_addr_lanes_mode(void);
286unsigned char page_info_get_frequency_index(void);
287unsigned char page_info_get_adj_index(void);
288unsigned char page_info_get_work_mode(void);
289unsigned char page_info_get_line_delay1(void);
290unsigned char page_info_get_line_delay2(void);
291unsigned char page_info_get_core_div(void);
292unsigned char page_info_get_bus_cycle(void);
293unsigned char page_info_get_device_ecc_disable(void);
294unsigned char page_info_get_host_ecc_disable(void);
295unsigned int page_info_get_n2m_command(void);
296unsigned int page_info_get_page_size(void);
297unsigned char page_info_get_planes(void);
298unsigned char page_info_get_plane_shift(void);
299unsigned char page_info_get_cache_plane_shift(void);
300unsigned char page_info_get_layout_method(void);
301unsigned char page_info_get_cs_deselect_time(void);
302unsigned char page_info_get_dummy_cycles(void);
303unsigned int page_info_get_block_size(void);
304unsigned int page_info_get_boot_size(void);
305unsigned int page_info_get_pages_in_block(void);
306unsigned char page_info_get_enable_bbt(void);
307unsigned short *page_info_get_bbt(void);
308unsigned int page_info_get_pages_in_boot(void);
Bichao Zheng67f32e42023-08-16 15:05:24 +0800309void page_info_initialize(unsigned int default_n2m,
310 unsigned char bus_width,
311 unsigned char ca);
Bichao Zheng8951e442023-07-13 13:21:29 +0800312int page_info_pre_init(void);
313#endif