~funderscore blog cgit wiki get in touch
aboutsummaryrefslogtreecommitdiff
blob: c5554d8d6b33ff14177e3fef66ff0332f82106eb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
U-Boot for Freescale i.MX6

This file contains information for the port of U-Boot to the Freescale i.MX6
SoC.

1. CONVENTIONS FOR FUSE ASSIGNMENTS
-----------------------------------

1.1 MAC Address: It is stored in fuse bank 4, with the 32 lsbs in word 2 and the
    16 msbs in word 3[15:0].
    For i.MX6SX and i.MX6UL, they have two MAC addresses. The second MAC address
    is stored in fuse bank 4, with the 16 lsb in word 3[31:16] and the 32 msbs in
    word 4.

Example:

For reading the MAC address fuses on a MX6Q:

- The MAC address is stored in two fuse addresses (the fuse addresses are
described in the Fusemap Descriptions table from the mx6q Reference Manual):

0x620[31:0] - MAC_ADDR[31:0]
0x630[15:0] - MAC_ADDR[47:32]

In order to use the fuse API, we need to pass the bank and word values, which
are calculated as below:

Fuse address for the lower MAC address: 0x620
Base address for the fuses: 0x400

(0x620 - 0x400)/0x10 = 0x22 = 34 decimal

As the fuses are arranged in banks of 8 words:

34 / 8 = 4 and the remainder is 2, so in this case:

bank = 4
word = 2

And the U-Boot command would be:

=> fuse read 4 2
Reading bank 4:

Word 0x00000002: 9f027772

Doing the same for the upper MAC address:

Fuse address for the upper MAC address: 0x630
Base address for the fuses: 0x400

(0x630 - 0x400)/0x10 = 0x23 = 35 decimal

As the fuses are arranged in banks of 8 words:

35 / 8 = 4 and the remainder is 3, so in this case:

bank = 4
word = 3

And the U-Boot command would be:

=> fuse read 4 3
Reading bank 4:

Word 0x00000003: 00000004

,which matches the ethaddr value:
=> echo ${ethaddr}
00:04:9f:02:77:72

Some other useful hints:

- The 'bank' and 'word' numbers can be easily obtained from the mx6 Reference
Manual. For the mx6quad case, please check the "46.5 OCOTP Memory Map/Register
Definition" from the "i.MX 6Dual/6Quad Applications Processor Reference Manual,
Rev. 1, 04/2013" document. For example, for the MAC fuses we have:

Address:
21B_C620	Value of OTP Bank4 Word2 (MAC Address)(OCOTP_MAC0)

21B_C630	Value of OTP Bank4 Word3 (MAC Address)(OCOTP_MAC1)

- The command '=> fuse read 4 2 2' reads the whole MAC addresses at once:

=> fuse read 4 2 2
Reading bank 4:

Word 0x00000002: 9f027772 00000004

NAND Boot on i.MX6 with SPL support
--------------------------------------

Writing/updating boot image in nand device is not straight forward in
i.MX6 platform and it requires boot control block(BCB) to be configured.

BCB contains two data structures, Firmware Configuration Block(FCB) and
Discovered Bad Block Table(DBBT). FCB has nand timings, DBBT search area,
and firmware. See IMX6DQRM Section 8.5.2.2
for more information.

We can't use 'nand write' command to write SPL/firmware image directly
like other platforms does. So we need special setup to write BCB block
as per IMX6QDL reference manual 'nandbcb update' command do that job.

for nand boot, up on reset bootrom look for FCB structure in
first block's if FCB found the nand timings are loaded for
further reads. once FCB read done, DTTB will be loaded and
finally firmware will be loaded which is boot image.

cmd_nandbcb will create FCB these structures
by taking mtd partition as an example.
- initial code will erase entire partition
- followed by FCB setup, like first 2 blocks for FCB/DBBT write,
  and next block for FW1/SPL
- write firmware at FW1 block and
- finally write fcb/dttb in first 2 block.

Typical NAND BCB layout:
=======================

   no.of blocks = partition size / erasesize
   no.of fcb/dbbt blocks = 2
   FW1 offset = no.of fcb/dbbt

block  0          1          2
        -------------------------------
       |FCB/DBBT 0|FCB/DBBT 1|  FW 1  |
       --------------------------------

On summary, nandbcb update will
- erase the entire partition
- create BCB by creating 2 FCB/BDDT block followed by
  1 FW blocks based on partition size and erasesize.
- fill FCB/DBBT structures
- write FW/SPL in FW1
- write FCB/DBBT in first 2 blocks

step-1: write SPL

icorem6qdl> ext4load mmc 0:1 $loadaddr SPL
39936 bytes read in 10 ms (3.8 MiB/s)

icorem6qdl> nandbcb update $loadaddr spl $filesize
device 0 offset 0x0, size 0x9c00
Erasing at 0x1c0000 -- 100% complete.
NAND fw write: 0x80000 offset, 0xb000 bytes written: OK

step-2: write u-boot-dtb.img

icorem6qdl> nand erase.part uboot

NAND erase.part: device 0 offset 0x200000, size 0x200000
Erasing at 0x3c0000 -- 100% complete.
OK

icorem6qdl> ext4load mmc 0:1 $loadaddr u-boot-dtb.img
589094 bytes read in 37 ms (15.2 MiB/s)

icorem6qdl> nand write ${loadaddr} uboot ${filesize}

NAND write: device 0 offset 0x200000, size 0x8fd26
 589094 bytes written: OK
icorem6qdl>

SPL Stack size and location notes
---------------------------------

If we have CONFIG_MX6_OCRAM_256KB then see Figure 8.4.1 in IMX6DQ Reference
manuals:
  - IMX6DQ OCRAM (IRAM) is from 0x00907000 to 0x0093FFFF
  - BOOT ROM stack is at 0x0093FFB8
  - if icache/dcache is enabled (eFuse/strapping controlled) then the
    IMX BOOT ROM will setup MMU table at 0x00938000, therefore we need to
    fit between 0x00907000 and 0x00938000.
  - Additionally the BOOT ROM loads what they consider the firmware image
    which consists of a 4K header in front of us that contains the IVT, DCD
    and some padding thus 'our' max size is really 0x00908000 - 0x00938000
    or 192KB
  - Pad SPL to 196KB (4KB header + 192KB max size). This allows to write the
    SPL/U-Boot combination generated with u-boot-with-spl.imx directly to a
    boot media (given that boot media specific offset is configured properly).
and if we don't, see Figure 8-3 in IMX6SDL Reference manuals:
  - IMX6SDL OCRAM (IRAM) is from 0x00907000 to 0x0091FFFF
  - BOOT ROM stack is at 0x0091FFB8
  - if icache/dcache is enabled (eFuse/strapping controlled) then the
    IMX BOOT ROM will setup MMU table at 0x00918000, therefore we need to
    fit between 0x00907000 and 0x00918000.
  - Additionally the BOOT ROM loads what they consider the firmware image
    which consists of a 4K header in front of us that contains the IVT, DCD
    and some padding thus 'our' max size is really 0x00908000 - 0x00918000
    or 64KB
  - Pad SPL to 68KB (4KB header + 64KB max size). This allows to write the
    SPL/U-Boot combination generated with u-boot-with-spl.imx directly to a
    boot media (given that boot media specific offset is configured properly).