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

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)