xref: /OK3568_Linux_fs/u-boot/arch/arm/include/asm/arch-tegra/warmboot.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * (C) Copyright 2010, 2011
3*4882a593Smuzhiyun  * NVIDIA Corporation <www.nvidia.com>
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #ifndef _WARM_BOOT_H_
9*4882a593Smuzhiyun #define _WARM_BOOT_H_
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #define STRAP_OPT_A_RAM_CODE_SHIFT	4
12*4882a593Smuzhiyun #define STRAP_OPT_A_RAM_CODE_MASK	(0xf << STRAP_OPT_A_RAM_CODE_SHIFT)
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun /* Defines the supported operating modes */
15*4882a593Smuzhiyun enum fuse_operating_mode {
16*4882a593Smuzhiyun 	MODE_PRODUCTION = 3,
17*4882a593Smuzhiyun 	MODE_UNDEFINED,
18*4882a593Smuzhiyun };
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun /* Defines the CMAC-AES-128 hash length in 32 bit words. (128 bits = 4 words) */
21*4882a593Smuzhiyun enum {
22*4882a593Smuzhiyun 	HASH_LENGTH = 4
23*4882a593Smuzhiyun };
24*4882a593Smuzhiyun 
25*4882a593Smuzhiyun /* Defines the storage for a hash value (128 bits) */
26*4882a593Smuzhiyun struct hash {
27*4882a593Smuzhiyun 	u32 hash[HASH_LENGTH];
28*4882a593Smuzhiyun };
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun /*
31*4882a593Smuzhiyun  * Defines the code header information for the boot rom.
32*4882a593Smuzhiyun  *
33*4882a593Smuzhiyun  * The code immediately follows the code header.
34*4882a593Smuzhiyun  *
35*4882a593Smuzhiyun  * Note that the code header needs to be 16 bytes aligned to preserve
36*4882a593Smuzhiyun  * the alignment of relevant data for hash and decryption computations without
37*4882a593Smuzhiyun  * requiring extra copies to temporary memory areas.
38*4882a593Smuzhiyun  */
39*4882a593Smuzhiyun struct wb_header {
40*4882a593Smuzhiyun 	u32 length_insecure;	/* length of the code header */
41*4882a593Smuzhiyun 	u32 reserved[3];
42*4882a593Smuzhiyun 	struct hash hash;	/* hash of header+code, starts next field*/
43*4882a593Smuzhiyun 	struct hash random_aes_block;	/* a data block to aid security. */
44*4882a593Smuzhiyun 	u32 length_secure;	/* length of the code header */
45*4882a593Smuzhiyun 	u32 destination;	/* destination address to put the wb code */
46*4882a593Smuzhiyun 	u32 entry_point;	/* execution address of the wb code */
47*4882a593Smuzhiyun 	u32 code_length;	/* length of the code */
48*4882a593Smuzhiyun };
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun /*
51*4882a593Smuzhiyun  * The warm boot code needs direct access to these registers since it runs in
52*4882a593Smuzhiyun  * SRAM and cannot call other U-Boot code.
53*4882a593Smuzhiyun  */
54*4882a593Smuzhiyun union osc_ctrl_reg {
55*4882a593Smuzhiyun 	struct {
56*4882a593Smuzhiyun 		u32 xoe:1;
57*4882a593Smuzhiyun 		u32 xobp:1;
58*4882a593Smuzhiyun 		u32 reserved0:2;
59*4882a593Smuzhiyun 		u32 xofs:6;
60*4882a593Smuzhiyun 		u32 reserved1:2;
61*4882a593Smuzhiyun 		u32 xods:5;
62*4882a593Smuzhiyun 		u32 reserved2:3;
63*4882a593Smuzhiyun 		u32 oscfi_spare:8;
64*4882a593Smuzhiyun 		u32 pll_ref_div:2;
65*4882a593Smuzhiyun 		u32 osc_freq:2;
66*4882a593Smuzhiyun 	};
67*4882a593Smuzhiyun 	u32 word;
68*4882a593Smuzhiyun };
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun union pllx_base_reg {
71*4882a593Smuzhiyun 	struct {
72*4882a593Smuzhiyun 		u32 divm:5;
73*4882a593Smuzhiyun 		u32 reserved0:3;
74*4882a593Smuzhiyun 		u32 divn:10;
75*4882a593Smuzhiyun 		u32 reserved1:2;
76*4882a593Smuzhiyun 		u32 divp:3;
77*4882a593Smuzhiyun 		u32 reserved2:4;
78*4882a593Smuzhiyun 		u32 lock:1;
79*4882a593Smuzhiyun 		u32 reserved3:1;
80*4882a593Smuzhiyun 		u32 ref_dis:1;
81*4882a593Smuzhiyun 		u32 enable:1;
82*4882a593Smuzhiyun 		u32 bypass:1;
83*4882a593Smuzhiyun 	};
84*4882a593Smuzhiyun 	u32 word;
85*4882a593Smuzhiyun };
86*4882a593Smuzhiyun 
87*4882a593Smuzhiyun union pllx_misc_reg {
88*4882a593Smuzhiyun 	struct {
89*4882a593Smuzhiyun 		u32 vcocon:4;
90*4882a593Smuzhiyun 		u32 lfcon:4;
91*4882a593Smuzhiyun 		u32 cpcon:4;
92*4882a593Smuzhiyun 		u32 lock_sel:6;
93*4882a593Smuzhiyun 		u32 reserved0:1;
94*4882a593Smuzhiyun 		u32 lock_enable:1;
95*4882a593Smuzhiyun 		u32 reserved1:1;
96*4882a593Smuzhiyun 		u32 dccon:1;
97*4882a593Smuzhiyun 		u32 pts:2;
98*4882a593Smuzhiyun 		u32 reserved2:6;
99*4882a593Smuzhiyun 		u32 out1_div_byp:1;
100*4882a593Smuzhiyun 		u32 out1_inv_clk:1;
101*4882a593Smuzhiyun 	};
102*4882a593Smuzhiyun 	u32 word;
103*4882a593Smuzhiyun };
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun /*
106*4882a593Smuzhiyun  * TODO: This register is not documented in the TRM yet. We could move this
107*4882a593Smuzhiyun  * into the EMC and give it a proper interface, but not while it is
108*4882a593Smuzhiyun  * undocumented.
109*4882a593Smuzhiyun  */
110*4882a593Smuzhiyun union scratch3_reg {
111*4882a593Smuzhiyun 	struct {
112*4882a593Smuzhiyun 		u32 pllx_base_divm:5;
113*4882a593Smuzhiyun 		u32 pllx_base_divn:10;
114*4882a593Smuzhiyun 		u32 pllx_base_divp:3;
115*4882a593Smuzhiyun 		u32 pllx_misc_lfcon:4;
116*4882a593Smuzhiyun 		u32 pllx_misc_cpcon:4;
117*4882a593Smuzhiyun 	};
118*4882a593Smuzhiyun 	u32 word;
119*4882a593Smuzhiyun };
120*4882a593Smuzhiyun 
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun /**
123*4882a593Smuzhiyun  * Save warmboot memory settings for a later resume
124*4882a593Smuzhiyun  *
125*4882a593Smuzhiyun  * @return 0 if ok, -1 on error
126*4882a593Smuzhiyun  */
127*4882a593Smuzhiyun int warmboot_save_sdram_params(void);
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun int warmboot_prepare_code(u32 seg_address, u32 seg_length);
130*4882a593Smuzhiyun int sign_data_block(u8 *source, u32 length, u8 *signature);
131*4882a593Smuzhiyun void wb_start(void);	/* Start of WB assembly code */
132*4882a593Smuzhiyun void wb_end(void);	/* End of WB assembly code */
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun #endif
135