tcl/target/imx6: add yet another SJC tapid
[openocd.git] / tcl / target / davinci.cfg
1 #
2 # Utility code for DaVinci-family chips
3 #
4
5 # davinci_pinmux: assigns PINMUX$reg <== $value
6 proc davinci_pinmux {soc reg value} {
7 mww [expr [dict get $soc sysbase] + 4 * $reg] $value
8 }
9
10 source [find mem_helper.tcl]
11
12 #
13 # pll_setup: initialize PLL
14 # - pll_addr ... physical addr of controller
15 # - mult ... pll multiplier
16 # - config ... dict mapping { prediv, postdiv, div[1-9] } to dividers
17 #
18 # For PLLs that don't have a given register (e.g. plldiv8), or where a
19 # given divider is non-programmable, caller provides *NO* config mapping.
20 #
21
22 # PLL version 0x02: tested on dm355
23 # REVISIT: On dm6446/dm357 the PLLRST polarity is different.
24 proc pll_v02_setup {pll_addr mult config} {
25 set pll_ctrl_addr [expr $pll_addr + 0x100]
26 set pll_ctrl [mrw $pll_ctrl_addr]
27
28 # 1 - clear CLKMODE (bit 8) iff using on-chip oscillator
29 # NOTE: this assumes we should clear that bit
30 set pll_ctrl [expr $pll_ctrl & ~0x0100]
31 mww $pll_ctrl_addr $pll_ctrl
32
33 # 2 - clear PLLENSRC (bit 5)
34 set pll_ctrl [expr $pll_ctrl & ~0x0020]
35 mww $pll_ctrl_addr $pll_ctrl
36
37 # 3 - clear PLLEN (bit 0) ... enter bypass mode
38 set pll_ctrl [expr $pll_ctrl & ~0x0001]
39 mww $pll_ctrl_addr $pll_ctrl
40
41 # 4 - wait at least 4 refclk cycles
42 sleep 1
43
44 # 5 - set PLLRST (bit 3)
45 set pll_ctrl [expr $pll_ctrl | 0x0008]
46 mww $pll_ctrl_addr $pll_ctrl
47
48 # 6 - set PLLDIS (bit 4)
49 set pll_ctrl [expr $pll_ctrl | 0x0010]
50 mww $pll_ctrl_addr $pll_ctrl
51
52 # 7 - clear PLLPWRDN (bit 1)
53 set pll_ctrl [expr $pll_ctrl & ~0x0002]
54 mww $pll_ctrl_addr $pll_ctrl
55
56 # 8 - clear PLLDIS (bit 4)
57 set pll_ctrl [expr $pll_ctrl & ~0x0010]
58 mww $pll_ctrl_addr $pll_ctrl
59
60 # 9 - optional: write prediv, postdiv, and pllm
61 # NOTE: for dm355 PLL1, postdiv is controlled via MISC register
62 mww [expr $pll_addr + 0x0110] [expr ($mult - 1) & 0xff]
63 if { [dict exists $config prediv] } {
64 set div [dict get $config prediv]
65 set div [expr 0x8000 | ($div - 1)]
66 mww [expr $pll_addr + 0x0114] $div
67 }
68 if { [dict exists $config postdiv] } {
69 set div [dict get $config postdiv]
70 set div [expr 0x8000 | ($div - 1)]
71 mww [expr $pll_addr + 0x0128] $div
72 }
73
74 # 10 - optional: set plldiv1, plldiv2, ...
75 # NOTE: this assumes some registers have their just-reset values:
76 # - PLLSTAT.GOSTAT is clear when we enter
77 # - ALNCTL has everything set
78 set go 0
79 if { [dict exists $config div1] } {
80 set div [dict get $config div1]
81 set div [expr 0x8000 | ($div - 1)]
82 mww [expr $pll_addr + 0x0118] $div
83 set go 1
84 }
85 if { [dict exists $config div2] } {
86 set div [dict get $config div2]
87 set div [expr 0x8000 | ($div - 1)]
88 mww [expr $pll_addr + 0x011c] $div
89 set go 1
90 }
91 if { [dict exists $config div3] } {
92 set div [dict get $config div3]
93 set div [expr 0x8000 | ($div - 1)]
94 mww [expr $pll_addr + 0x0120] $div
95 set go 1
96 }
97 if { [dict exists $config div4] } {
98 set div [dict get $config div4]
99 set div [expr 0x8000 | ($div - 1)]
100 mww [expr $pll_addr + 0x0160] $div
101 set go 1
102 }
103 if { [dict exists $config div5] } {
104 set div [dict get $config div5]
105 set div [expr 0x8000 | ($div - 1)]
106 mww [expr $pll_addr + 0x0164] $div
107 set go 1
108 }
109 if {$go != 0} {
110 # write pllcmd.GO; poll pllstat.GO
111 mww [expr $pll_addr + 0x0138] 0x01
112 set pllstat [expr $pll_addr + 0x013c]
113 while {[expr [mrw $pllstat] & 0x01] != 0} { sleep 1 }
114 }
115 mww [expr $pll_addr + 0x0138] 0x00
116
117 # 11 - wait at least 5 usec for reset to finish
118 # (assume covered by overheads including JTAG messaging)
119
120 # 12 - clear PLLRST (bit 3)
121 set pll_ctrl [expr $pll_ctrl & ~0x0008]
122 mww $pll_ctrl_addr $pll_ctrl
123
124 # 13 - wait at least 8000 refclk cycles for PLL to lock
125 # if we assume 24 MHz (slowest osc), that's 1/3 msec
126 sleep 3
127
128 # 14 - set PLLEN (bit 0) ... leave bypass mode
129 set pll_ctrl [expr $pll_ctrl | 0x0001]
130 mww $pll_ctrl_addr $pll_ctrl
131 }
132
133 # PLL version 0x03: tested on dm365
134 proc pll_v03_setup {pll_addr mult config} {
135 set pll_ctrl_addr [expr $pll_addr + 0x100]
136 set pll_secctrl_addr [expr $pll_addr + 0x108]
137 set pll_ctrl [mrw $pll_ctrl_addr]
138
139 # 1 - power up the PLL
140 set pll_ctrl [expr $pll_ctrl & ~0x0002]
141 mww $pll_ctrl_addr $pll_ctrl
142
143 # 2 - clear PLLENSRC (bit 5)
144 set pll_ctrl [expr $pll_ctrl & ~0x0020]
145 mww $pll_ctrl_addr $pll_ctrl
146
147 # 2 - clear PLLEN (bit 0) ... enter bypass mode
148 set pll_ctrl [expr $pll_ctrl & ~0x0001]
149 mww $pll_ctrl_addr $pll_ctrl
150
151 # 3 - wait at least 4 refclk cycles
152 sleep 1
153
154 # 4 - set PLLRST (bit 3)
155 set pll_ctrl [expr $pll_ctrl | 0x0008]
156 mww $pll_ctrl_addr $pll_ctrl
157
158 # 5 - wait at least 5 usec
159 sleep 1
160
161 # 6 - clear PLLRST (bit 3)
162 set pll_ctrl [expr $pll_ctrl & ~0x0008]
163 mww $pll_ctrl_addr $pll_ctrl
164
165 # 9 - optional: write prediv, postdiv, and pllm
166 mww [expr $pll_addr + 0x0110] [expr ($mult / 2) & 0x1ff]
167 if { [dict exists $config prediv] } {
168 set div [dict get $config prediv]
169 set div [expr 0x8000 | ($div - 1)]
170 mww [expr $pll_addr + 0x0114] $div
171 }
172 if { [dict exists $config postdiv] } {
173 set div [dict get $config postdiv]
174 set div [expr 0x8000 | ($div - 1)]
175 mww [expr $pll_addr + 0x0128] $div
176 }
177
178 # 10 - write start sequence to PLLSECCTL
179 mww $pll_secctrl_addr 0x00470000
180 mww $pll_secctrl_addr 0x00460000
181 mww $pll_secctrl_addr 0x00400000
182 mww $pll_secctrl_addr 0x00410000
183
184 # 11 - optional: set plldiv1, plldiv2, ...
185 # NOTE: this assumes some registers have their just-reset values:
186 # - PLLSTAT.GOSTAT is clear when we enter
187 set aln 0
188 if { [dict exists $config div1] } {
189 set div [dict get $config div1]
190 set div [expr 0x8000 | ($div - 1)]
191 mww [expr $pll_addr + 0x0118] $div
192 set aln [expr $aln | 0x1]
193 } else {
194 mww [expr $pll_addr + 0x0118] 0
195 }
196 if { [dict exists $config div2] } {
197 set div [dict get $config div2]
198 set div [expr 0x8000 | ($div - 1)]
199 mww [expr $pll_addr + 0x011c] $div
200 set aln [expr $aln | 0x2]
201 } else {
202 mww [expr $pll_addr + 0x011c] 0
203 }
204 if { [dict exists $config div3] } {
205 set div [dict get $config div3]
206 set div [expr 0x8000 | ($div - 1)]
207 mww [expr $pll_addr + 0x0120] $div
208 set aln [expr $aln | 0x4]
209 } else {
210 mww [expr $pll_addr + 0x0120] 0
211 }
212 if { [dict exists $config oscdiv] } {
213 set div [dict get $config oscdiv]
214 set div [expr 0x8000 | ($div - 1)]
215 mww [expr $pll_addr + 0x0124] $div
216 } else {
217 mww [expr $pll_addr + 0x0124] 0
218 }
219 if { [dict exists $config div4] } {
220 set div [dict get $config div4]
221 set div [expr 0x8000 | ($div - 1)]
222 mww [expr $pll_addr + 0x0160] $div
223 set aln [expr $aln | 0x8]
224 } else {
225 mww [expr $pll_addr + 0x0160] 0
226 }
227 if { [dict exists $config div5] } {
228 set div [dict get $config div5]
229 set div [expr 0x8000 | ($div - 1)]
230 mww [expr $pll_addr + 0x0164] $div
231 set aln [expr $aln | 0x10]
232 } else {
233 mww [expr $pll_addr + 0x0164] 0
234 }
235 if { [dict exists $config div6] } {
236 set div [dict get $config div6]
237 set div [expr 0x8000 | ($div - 1)]
238 mww [expr $pll_addr + 0x0168] $div
239 set aln [expr $aln | 0x20]
240 } else {
241 mww [expr $pll_addr + 0x0168] 0
242 }
243 if { [dict exists $config div7] } {
244 set div [dict get $config div7]
245 set div [expr 0x8000 | ($div - 1)]
246 mww [expr $pll_addr + 0x016c] $div
247 set aln [expr $aln | 0x40]
248 } else {
249 mww [expr $pll_addr + 0x016c] 0
250 }
251 if { [dict exists $config div8] } {
252 set div [dict get $config div8]
253 set div [expr 0x8000 | ($div - 1)]
254 mww [expr $pll_addr + 0x0170] $div
255 set aln [expr $aln | 0x80]
256 } else {
257 mww [expr $pll_addr + 0x0170] 0
258 }
259 if { [dict exists $config div9] } {
260 set div [dict get $config div9]
261 set div [expr 0x8000 | ($div - 1)]
262 mww [expr $pll_addr + 0x0174] $div
263 set aln [expr $aln | 0x100]
264 } else {
265 mww [expr $pll_addr + 0x0174] 0
266 }
267 if {$aln != 0} {
268 # clear pllcmd.GO
269 mww [expr $pll_addr + 0x0138] 0x00
270 # write alingment flags
271 mww [expr $pll_addr + 0x0140] $aln
272 # write pllcmd.GO; poll pllstat.GO
273 mww [expr $pll_addr + 0x0138] 0x01
274 set pllstat [expr $pll_addr + 0x013c]
275 while {[expr [mrw $pllstat] & 0x01] != 0} { sleep 1 }
276 }
277 mww [expr $pll_addr + 0x0138] 0x00
278 set addr [dict get $config ctladdr]
279 while {[expr [mrw $addr] & 0x0e000000] != 0x0e000000} { sleep 1 }
280
281 # 12 - set PLLEN (bit 0) ... leave bypass mode
282 set pll_ctrl [expr $pll_ctrl | 0x0001]
283 mww $pll_ctrl_addr $pll_ctrl
284 }
285
286 # NOTE: dm6446 requires EMURSTIE set in MDCTL before certain
287 # modules can be enabled.
288
289 # prepare a non-DSP module to be enabled; finish with psc_go
290 proc psc_enable {module} {
291 set psc_addr 0x01c41000
292 # write MDCTL
293 mmw [expr $psc_addr + 0x0a00 + (4 * $module)] 0x03 0x1f
294 }
295
296 # prepare a non-DSP module to be reset; finish with psc_go
297 proc psc_reset {module} {
298 set psc_addr 0x01c41000
299 # write MDCTL
300 mmw [expr $psc_addr + 0x0a00 + (4 * $module)] 0x01 0x1f
301 }
302
303 # execute non-DSP PSC transition(s) set up by psc_enable, psc_reset, etc
304 proc psc_go {} {
305 set psc_addr 0x01c41000
306 set ptstat_addr [expr $psc_addr + 0x0128]
307
308 # just in case PTSTAT.go isn't clear
309 while { [expr [mrw $ptstat_addr] & 0x01] != 0 } { sleep 1 }
310
311 # write PTCMD.go ... ignoring any DSP power domain
312 mww [expr $psc_addr + 0x0120] 1
313
314 # wait for PTSTAT.go to clear (again ignoring DSP power domain)
315 while { [expr [mrw $ptstat_addr] & 0x01] != 0 } { sleep 1 }
316 }
317
318 #
319 # A reset using only SRST is a "Warm Reset", resetting everything in the
320 # chip except ARM emulation (and everything _outside_ the chip that hooks
321 # up to SRST). But many boards don't expose SRST via their JTAG connectors
322 # (it's not present on TI-14 headers).
323 #
324 # From the chip-only perspective, a "Max Reset" is a "Warm" reset ... except
325 # without any board-wide side effects, since it's triggered using JTAG using
326 # either (a) ARM watchdog timer, or (b) ICEpick.
327 #
328 proc davinci_wdog_reset {} {
329 set timer2_phys 0x01c21c00
330
331 # NOTE -- on entry
332 # - JTAG communication with the ARM *must* be working OK; this
333 # may imply using adaptive clocking or disabling WFI-in-idle
334 # - current target must be the DaVinci ARM
335 # - that ARM core must be halted
336 # - timer2 clock is still enabled (PSC 29 on most chips)
337
338 #
339 # Part I -- run regardless of being halted via JTAG
340 #
341 # NOTE: for now, we assume there's no DSP that could control the
342 # watchdog; or, equivalently, SUSPSRC.TMR2SRC says the watchdog
343 # suspend signal is controlled via ARM emulation suspend.
344 #
345
346 # EMUMGT_CLKSPEED: write FREE bit to run despite emulation halt
347 mww phys [expr $timer2_phys + 0x28] 0x00004000
348
349 #
350 # Part II -- in case watchdog hasn't been set up
351 #
352
353 # TCR: disable, force internal clock source
354 mww phys [expr $timer2_phys + 0x20] 0
355
356 # TGCR: reset, force to 64-bit wdog mode, un-reset ("initial" state)
357 mww phys [expr $timer2_phys + 0x24] 0
358 mww phys [expr $timer2_phys + 0x24] 0x110b
359
360 # clear counter (TIM12, TIM34) and period (PRD12, PRD34) registers
361 # so watchdog triggers ASAP
362 mww phys [expr $timer2_phys + 0x10] 0
363 mww phys [expr $timer2_phys + 0x14] 0
364 mww phys [expr $timer2_phys + 0x18] 0
365 mww phys [expr $timer2_phys + 0x1c] 0
366
367 # WDTCR: put into pre-active state, then active
368 mww phys [expr $timer2_phys + 0x28] 0xa5c64000
369 mww phys [expr $timer2_phys + 0x28] 0xda7e4000
370
371 #
372 # Part III -- it's ready to rumble
373 #
374
375 # WDTCR: write invalid WDKEY to trigger reset
376 mww phys [expr $timer2_phys + 0x28] 0x00004000
377 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)