DM36x: Disable unused SYSCLKs
[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 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 0x8000 | ($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 set aln 0
201 if { [dict exists $config div1] } {
202 set div [dict get $config div1]
203 set div [expr 0x8000 | ($div - 1)]
204 mww [expr $pll_addr + 0x0118] $div
205 set aln [expr $aln | 0x1]
206 } else {
207 mww [expr $pll_addr + 0x0118] 0
208 }
209 if { [dict exists $config div2] } {
210 set div [dict get $config div2]
211 set div [expr 0x8000 | ($div - 1)]
212 mww [expr $pll_addr + 0x011c] $div
213 set aln [expr $aln | 0x2]
214 } else {
215 mww [expr $pll_addr + 0x011c] 0
216 }
217 if { [dict exists $config div3] } {
218 set div [dict get $config div3]
219 set div [expr 0x8000 | ($div - 1)]
220 mww [expr $pll_addr + 0x0120] $div
221 set aln [expr $aln | 0x4]
222 } else {
223 mww [expr $pll_addr + 0x0120] 0
224 }
225 if { [dict exists $config div4] } {
226 set div [dict get $config div4]
227 set div [expr 0x8000 | ($div - 1)]
228 mww [expr $pll_addr + 0x0160] $div
229 set aln [expr $aln | 0x8]
230 } else {
231 mww [expr $pll_addr + 0x0160] 0
232 }
233 if { [dict exists $config div5] } {
234 set div [dict get $config div5]
235 set div [expr 0x8000 | ($div - 1)]
236 mww [expr $pll_addr + 0x0164] $div
237 set aln [expr $aln | 0x10]
238 } else {
239 mww [expr $pll_addr + 0x0164] 0
240 }
241 if { [dict exists $config div6] } {
242 set div [dict get $config div6]
243 set div [expr 0x8000 | ($div - 1)]
244 mww [expr $pll_addr + 0x0168] $div
245 set aln [expr $aln | 0x20]
246 } else {
247 mww [expr $pll_addr + 0x0168] 0
248 }
249 if { [dict exists $config div7] } {
250 set div [dict get $config div7]
251 set div [expr 0x8000 | ($div - 1)]
252 mww [expr $pll_addr + 0x016c] $div
253 set aln [expr $aln | 0x40]
254 } else {
255 mww [expr $pll_addr + 0x016c] 0
256 }
257 if { [dict exists $config div8] } {
258 set div [dict get $config div8]
259 set div [expr 0x8000 | ($div - 1)]
260 mww [expr $pll_addr + 0x0170] $div
261 set aln [expr $aln | 0x80]
262 } else {
263 mww [expr $pll_addr + 0x0170] 0
264 }
265 if { [dict exists $config div9] } {
266 set div [dict get $config div9]
267 set div [expr 0x8000 | ($div - 1)]
268 mww [expr $pll_addr + 0x0174] $div
269 set aln [expr $aln | 0x100]
270 } else {
271 mww [expr $pll_addr + 0x0174] 0
272 }
273 if {$aln != 0} {
274 # clear pllcmd.GO
275 mww [expr $pll_addr + 0x0138] 0x00
276 # write alingment flags
277 mww [expr $pll_addr + 0x0140] $aln
278 # write pllcmd.GO; poll pllstat.GO
279 mww [expr $pll_addr + 0x0138] 0x01
280 set pllstat [expr $pll_addr + 0x013c]
281 while {[expr [mrw $pllstat] & 0x01] != 0} { sleep 1 }
282 }
283 mww [expr $pll_addr + 0x0138] 0x00
284 set addr [dict get $config ctladdr]
285 while {[expr [mrw $addr] & 0x0e000000] != 0x0e000000} { sleep 1 }
286
287 # 12 - set PLLEN (bit 0) ... leave bypass mode
288 set pll_ctrl [expr $pll_ctrl | 0x0001]
289 mww $pll_ctrl_addr $pll_ctrl
290 }
291
292 # NOTE: dm6446 requires EMURSTIE set in MDCTL before certain
293 # modules can be enabled.
294
295 # prepare a non-DSP module to be enabled; finish with psc_go
296 proc psc_enable {module} {
297 set psc_addr 0x01c41000
298 # write MDCTL
299 mmw [expr $psc_addr + 0x0a00 + (4 * $module)] 0x03 0x1f
300 }
301
302 # prepare a non-DSP module to be reset; finish with psc_go
303 proc psc_reset {module} {
304 set psc_addr 0x01c41000
305 # write MDCTL
306 mmw [expr $psc_addr + 0x0a00 + (4 * $module)] 0x01 0x1f
307 }
308
309 # execute non-DSP PSC transition(s) set up by psc_enable, psc_reset, etc
310 proc psc_go {} {
311 set psc_addr 0x01c41000
312 set ptstat_addr [expr $psc_addr + 0x0128]
313
314 # just in case PTSTAT.go isn't clear
315 while { [expr [mrw $ptstat_addr] & 0x01] != 0 } { sleep 1 }
316
317 # write PTCMD.go ... ignoring any DSP power domain
318 mww [expr $psc_addr + 0x0120] 1
319
320 # wait for PTSTAT.go to clear (again ignoring DSP power domain)
321 while { [expr [mrw $ptstat_addr] & 0x01] != 0 } { sleep 1 }
322 }
323
324 #
325 # A reset using only SRST is a "Warm Reset", resetting everything in the
326 # chip except ARM emulation (and everything _outside_ the chip that hooks
327 # up to SRST). But many boards don't expose SRST via their JTAG connectors
328 # (it's not present on TI-14 headers).
329 #
330 # From the chip-only perspective, a "Max Reset" is a "Warm" reset ... except
331 # without any board-wide side effects, since it's triggered using JTAG using
332 # either (a) ARM watchdog timer, or (b) ICEpick.
333 #
334 proc davinci_wdog_reset {} {
335 set timer2_phys 0x01c21c00
336
337 # NOTE -- on entry
338 # - JTAG communication with the ARM *must* be working OK; this
339 # may imply using adaptive clocking or disabling WFI-in-idle
340 # - current target must be the DaVinci ARM
341 # - that ARM core must be halted
342 # - timer2 clock is still enabled (PSC 29 on most chips)
343
344 #
345 # Part I -- run regardless of being halted via JTAG
346 #
347 # NOTE: for now, we assume there's no DSP that could control the
348 # watchdog; or, equivalently, SUSPSRC.TMR2SRC says the watchdog
349 # suspend signal is controlled via ARM emulation suspend.
350 #
351
352 # EMUMGT_CLKSPEED: write FREE bit to run despite emulation halt
353 mww phys [expr $timer2_phys + 0x28] 0x00004000
354
355 #
356 # Part II -- in case watchdog hasn't been set up
357 #
358
359 # TCR: disable, force internal clock source
360 mww phys [expr $timer2_phys + 0x20] 0
361
362 # TGCR: reset, force to 64-bit wdog mode, un-reset ("initial" state)
363 mww phys [expr $timer2_phys + 0x24] 0
364 mww phys [expr $timer2_phys + 0x24] 0x110b
365
366 # clear counter (TIM12, TIM34) and period (PRD12, PRD34) registers
367 # so watchdog triggers ASAP
368 mww phys [expr $timer2_phys + 0x10] 0
369 mww phys [expr $timer2_phys + 0x14] 0
370 mww phys [expr $timer2_phys + 0x18] 0
371 mww phys [expr $timer2_phys + 0x1c] 0
372
373 # WDTCR: put into pre-active state, then active
374 mww phys [expr $timer2_phys + 0x28] 0xa5c64000
375 mww phys [expr $timer2_phys + 0x28] 0xda7e4000
376
377 #
378 # Part III -- it's ready to rumble
379 #
380
381 # WDTCR: write invalid WDKEY to trigger reset
382 mww phys [expr $timer2_phys + 0x28] 0x00004000
383 }

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)