xref: /OK3568_Linux_fs/buildroot/board/atmel/nandflash.tcl (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1# ----------------------------------------------------------------------------
2#         ATMEL Microcontroller
3# ----------------------------------------------------------------------------
4# Copyright (c) 2015, Atmel Corporation
5#
6# All rights reserved.
7#
8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions are met:
10#
11# - Redistributions of source code must retain the above copyright notice,
12# this list of conditions and the disclaimer below.
13#
14# Atmel's name may not be used to endorse or promote products derived from
15# this software without specific prior written permission.
16#
17# DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
18# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
20# DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23# OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27# ----------------------------------------------------------------------------
28
29################################################################################
30#  Script data
31################################################################################
32# DBGU address for rm9200, 9260/9g20, 9261/9g10, 9rl, 9x5
33set at91_base_dbgu0 0xfffff200
34# DBGU address for 9263, 9g45, sama5d3
35set at91_base_dbgu1 0xffffee00
36# DBGU address for sama5d4
37set at91_base_dbgu2 0xfc069000
38
39set arch_exid_offset 0x44
40
41# arch id
42set arch_id_at91sam9g20 0x019905a0
43set arch_id_at91sam9g45 0x819b05a0
44set arch_id_at91sam9x5  0x819a05a0
45set arch_id_at91sam9n12 0x819a07a0
46set arch_id_sama5d3     0x8a5c07c0
47
48## Find out at91sam9x5 variant to load the corresponding dtb file
49array set at91sam9x5_variant {
50   0x00000000 at91sam9g15
51   0x00000001 at91sam9g35
52   0x00000002 at91sam9x35
53   0x00000003 at91sam9g25
54   0x00000004 at91sam9x25
55}
56
57## Find out sama5d3 variant to load the corresponding dtb file
58array set sama5d3_variant {
59   0x00444300 sama5d31
60   0x00414300 sama5d33
61   0x00414301 sama5d34
62   0x00584300 sama5d35
63   0x00004301 sama5d36
64}
65
66## Find out sama5d4 variant
67array set sama5d4_variant {
68   0x00000001 sama5d41
69   0x00000002 sama5d42
70   0x00000003 sama5d43
71   0x00000004 sama5d44
72}
73
74################################################################################
75#  proc uboot_env: Convert u-boot variables in a string ready to be flashed
76#                  in the region reserved for environment variables
77################################################################################
78proc set_uboot_env {nameOfLstOfVar} {
79    upvar $nameOfLstOfVar lstOfVar
80
81    # sector size is the size defined in u-boot CFG_ENV_SIZE
82    set sectorSize [expr 0x20000 - 5]
83
84    set strEnv [join $lstOfVar "\0"]
85    while {[string length $strEnv] < $sectorSize} {
86        append strEnv "\0"
87    }
88    # \0 between crc and strEnv is the flag value for redundant environment
89    set strCrc [binary format i [::vfs::crc $strEnv]]
90    return "$strCrc\0$strEnv"
91}
92
93################################################################################
94proc find_variant_name {boardType} {
95   global at91_base_dbgu0
96   global at91_base_dbgu1
97   global at91_base_dbgu2
98   global arch_exid_offset
99   global at91sam9x5_variant
100   global sama5d3_variant
101   global sama5d4_variant
102   set socName "none"
103
104   switch $boardType {
105      at91sam9x5ek {
106         set exidAddr [expr {$at91_base_dbgu0 + $arch_exid_offset}]
107         set chip_variant [format "0x%08x" [read_int $exidAddr]]
108
109         foreach {key value} [array get at91sam9x5_variant] {
110            if {$key == $chip_variant} {
111               set socName "$value"
112               break;
113            }
114         }
115      }
116      sama5d3xek {
117         set exidAddr [expr {$at91_base_dbgu1 + $arch_exid_offset}]
118         set chip_variant [format "0x%08x" [read_int $exidAddr]]
119
120         foreach {key value} [array get sama5d3_variant] {
121            #puts "-I- === $chip_variant ? $key ($value) ==="
122            if {$key == $chip_variant} {
123               set socName "$value"
124               break;
125            }
126         }
127      }
128      sama5d3_xplained {
129         set exidAddr [expr {$at91_base_dbgu1 + $arch_exid_offset}]
130         set chip_variant [format "0x%08x" [read_int $exidAddr]]
131
132         foreach {key value} [array get sama5d3_variant] {
133            #puts "-I- === $chip_variant ? $key ($value) ==="
134            if {$key == $chip_variant} {
135               set socName "$value"
136               break;
137            }
138         }
139      }
140      sama5d4ek {
141         set exidAddr [expr {$at91_base_dbgu2 + $arch_exid_offset}]
142         set chip_variant [format "0x%08x" [read_int $exidAddr]]
143
144         foreach {key value} [array get sama5d4_variant] {
145            #puts "-I- === $chip_variant ? $key ($value) ==="
146            if {$key == $chip_variant} {
147               set socName "$value"
148               break;
149            }
150         }
151      }
152      sama5d4_xplained {
153         set exidAddr [expr {$at91_base_dbgu2 + $arch_exid_offset}]
154         set chip_variant [format "0x%08x" [read_int $exidAddr]]
155
156         foreach {key value} [array get sama5d4_variant] {
157            #puts "-I- === $chip_variant ? $key ($value) ==="
158            if {$key == $chip_variant} {
159               set socName "$value"
160               break;
161            }
162         }
163      }
164   }
165
166   return "$socName"
167}
168
169proc find_variant_ecc {boardType} {
170   set eccType "none"
171
172   switch $boardType {
173      at91sam9x5ek {
174         set eccType 0xc0c00405
175      }
176      at91sam9n12ek {
177         set eccType 0xc0c00405
178      }
179      sama5d3xek {
180         set eccType 0xc0902405
181      }
182      sama5d3_xplained {
183         set eccType 0xc0902405
184      }
185      sama5d4ek {
186         set eccType 0xc1e04e07
187      }
188      sama5d4_xplained {
189         set eccType 0xc1e04e07
190      }
191   }
192
193   puts "-I- === eccType is $eccType ==="
194   return $eccType
195}
196
197proc get_kernel_load_addr {boardType} {
198   set kernel_load_addr 0x22000000
199
200   switch $boardType {
201      at91sam9m10g45ek {
202         set kernel_load_addr 0x72000000
203      }
204   }
205
206   return $kernel_load_addr
207}
208
209proc get_dtb_load_addr {boardType} {
210   set dtb_load_addr 0x21000000
211
212   switch $boardType {
213      at91sam9m10g45ek {
214         set dtb_load_addr 0x71000000
215      }
216   }
217
218   return $dtb_load_addr
219}
220
221################################################################################
222#  Main script: Load the linux demo in NandFlash,
223#               Update the environment variables
224################################################################################
225
226################################################################################
227
228# check for proper variable initialization
229if {! [info exists boardFamily]} {
230   puts "-I- === Parsing script arguments ==="
231   if {! [info exists env(O)]} {
232      puts "-E- === Binaries path not defined ==="
233      exit
234   }
235
236   set bootstrapFile   "$env(O)/at91bootstrap.bin"
237   set ubootFile       "$env(O)/u-boot.bin"
238   set kernelFile      "$env(O)/zImage"
239   set rootfsFile      "$env(O)/rootfs.ubi"
240   set build_uboot_env "yes"
241
242   set i 1
243   foreach arg $::argv {
244      puts "argument $i is $arg"
245      switch $i {
246         4 { set boardFamily $arg }
247         5 { set dtbFile "$env(O)/$arg" }
248         6 { set videoMode $arg }
249      }
250      incr i
251    }
252}
253
254puts "-I- === Board Family is $boardFamily ==="
255
256set pmeccConfig [find_variant_ecc $boardFamily]
257
258## Now check for the needed files
259if {! [file exists $bootstrapFile]} {
260   puts "-E- === AT91Bootstrap file not found ==="
261   exit
262}
263
264if {! [file exists $ubootFile]} {
265   puts "-E- === U-Boot file not found ==="
266   exit
267}
268
269if {! [file exists $kernelFile]} {
270   puts "-E- === Linux kernel file not found ==="
271   exit
272}
273
274if {! [file exists $dtbFile]} {
275   puts "-E- === Device Tree binary: $dtbFile file not found ==="
276   exit
277}
278
279if {! [file exists $rootfsFile]} {
280   puts "-E- === Rootfs file not found ==="
281   exit
282}
283
284## NandFlash Mapping
285set bootStrapAddr	0x00000000
286set ubootAddr		0x00040000
287set ubootEnvAddr	0x000c0000
288set dtbAddr		0x00180000
289set kernelAddr		0x00200000
290set rootfsAddr		0x00800000
291
292## u-boot variable
293set kernelLoadAddr [get_kernel_load_addr $boardFamily]
294set dtbLoadAddr	[get_dtb_load_addr $boardFamily]
295
296## NandFlash Mapping
297set kernelSize	[format "0x%08X" [file size $kernelFile]]
298set dtbSize	[format "0x%08X" [file size $dtbFile]]
299set bootCmd "bootcmd=nand read $dtbLoadAddr $dtbAddr $dtbSize; nand read $kernelLoadAddr $kernelAddr $kernelSize; bootz $kernelLoadAddr - $dtbLoadAddr"
300set rootfsSize	[format "0x%08X" [file size $rootfsFile]]
301
302lappend u_boot_variables \
303    "bootdelay=1" \
304    "baudrate=115200" \
305    "stdin=serial" \
306    "stdout=serial" \
307    "stderr=serial" \
308    "bootargs=console=ttyS0,115200 mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256k(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs rw $videoMode" \
309    "$bootCmd"
310
311## Additional files to load
312set ubootEnvFile	"ubootEnvtFileNandFlash.bin"
313
314
315##  Start flashing procedure  ##################################################
316puts "-I- === Initialize the NAND access ==="
317NANDFLASH::Init
318
319if {$pmeccConfig != "none"} {
320   puts "-I- === Enable PMECC OS Parameters ==="
321   NANDFLASH::NandHeaderValue HEADER $pmeccConfig
322}
323
324puts "-I- === Erase all the NAND flash blocs and test the erasing ==="
325NANDFLASH::EraseAllNandFlash
326
327puts "-I- === Load AT91Bootstrap in the first sector ==="
328if {$pmeccConfig != "none"} {
329   NANDFLASH::SendBootFilePmeccCmd $bootstrapFile
330} else {
331   NANDFLASH::sendBootFile $bootstrapFile
332}
333
334puts "-I- === Load u-boot in the next sectors ==="
335send_file {NandFlash} "$ubootFile" $ubootAddr 0
336
337if {$build_uboot_env == "yes"} {
338   puts "-I- === Load the u-boot environment variables ==="
339   set fh [open "$ubootEnvFile" w]
340   fconfigure $fh -translation binary
341   puts -nonewline $fh [set_uboot_env u_boot_variables]
342   close $fh
343   send_file {NandFlash} "$ubootEnvFile" $ubootEnvAddr 0
344}
345
346puts "-I- === Load the Kernel image and device tree database ==="
347send_file {NandFlash} "$dtbFile" $dtbAddr 0
348send_file {NandFlash} "$kernelFile" $kernelAddr 0
349
350if {$pmeccConfig != "none"} {
351   puts "-I- === Enable trimffs ==="
352   NANDFLASH::NandSetTrimffs 1
353}
354
355puts "-I- === Load the linux file system ==="
356send_file {NandFlash} "$rootfsFile" $rootfsAddr 0
357
358puts "-I- === DONE. ==="
359