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

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)