blob: c8b44988d3c1aa0d90bd90b0e7127fd40e5582aa [file] [log] [blame]
Heiko Schocher75b27132011-11-01 20:00:32 +00001/*
2 * SoC-specific lowlevel code for tms320dm365 and similar chips
3 * Actually used for booting from NAND with nand_spl.
4 *
5 * Copyright (C) 2011
6 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
7 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +02008 * SPDX-License-Identifier: GPL-2.0+
Heiko Schocher75b27132011-11-01 20:00:32 +00009 */
10#include <common.h>
11#include <nand.h>
12#include <ns16550.h>
13#include <post.h>
Khoronzhuk, Ivan753a00a2014-06-07 04:22:52 +030014#include <asm/ti-common/davinci_nand.h>
Heiko Schocher75b27132011-11-01 20:00:32 +000015#include <asm/arch/dm365_lowlevel.h>
16#include <asm/arch/hardware.h>
17
18void dm365_waitloop(unsigned long loopcnt)
19{
20 unsigned long i;
21
22 for (i = 0; i < loopcnt; i++)
23 asm(" NOP");
24}
25
26int dm365_pll1_init(unsigned long pllmult, unsigned long prediv)
27{
28 unsigned int clksrc = 0x0;
29
30 /* Power up the PLL */
31 clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLPWRDN);
32
33 clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_RES_9);
Heiko Schocher34061e82011-11-15 10:00:02 -050034 setbits_le32(&dv_pll0_regs->pllctl,
35 clksrc << PLLCTL_CLOCK_MODE_SHIFT);
Heiko Schocher75b27132011-11-01 20:00:32 +000036
37 /*
38 * Set PLLENSRC '0', PLL Enable(PLLEN) selection is controlled
39 * through MMR
40 */
41 clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLENSRC);
42
43 /* Set PLLEN=0 => PLL BYPASS MODE */
44 clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLEN);
45
46 dm365_waitloop(150);
47
48 /* PLLRST=1(reset assert) */
49 setbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLRST);
50
51 dm365_waitloop(300);
52
53 /*Bring PLL out of Reset*/
54 clrbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLRST);
55
56 /* Program the Multiper and Pre-Divider for PLL1 */
57 writel(pllmult, &dv_pll0_regs->pllm);
58 writel(prediv, &dv_pll0_regs->prediv);
59
60 /* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 1 */
61 writel(PLLSECCTL_STOPMODE | PLLSECCTL_TENABLEDIV | PLLSECCTL_TENABLE |
62 PLLSECCTL_TINITZ, &dv_pll0_regs->secctl);
63 /* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 0 */
64 writel(PLLSECCTL_STOPMODE | PLLSECCTL_TENABLEDIV | PLLSECCTL_TENABLE,
65 &dv_pll0_regs->secctl);
66 /* Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 0 */
67 writel(PLLSECCTL_STOPMODE, &dv_pll0_regs->secctl);
68 /* Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 1 */
69 writel(PLLSECCTL_STOPMODE | PLLSECCTL_TINITZ, &dv_pll0_regs->secctl);
70
71 /* Program the PostDiv for PLL1 */
Heiko Schocher34061e82011-11-15 10:00:02 -050072 writel(PLL_POSTDEN, &dv_pll0_regs->postdiv);
Heiko Schocher75b27132011-11-01 20:00:32 +000073
74 /* Post divider setting for PLL1 */
75 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV1, &dv_pll0_regs->plldiv1);
76 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV2, &dv_pll0_regs->plldiv2);
77 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV3, &dv_pll0_regs->plldiv3);
78 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV4, &dv_pll0_regs->plldiv4);
79 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV5, &dv_pll0_regs->plldiv5);
80 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV6, &dv_pll0_regs->plldiv6);
81 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV7, &dv_pll0_regs->plldiv7);
82 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV8, &dv_pll0_regs->plldiv8);
83 writel(CONFIG_SYS_DM36x_PLL1_PLLDIV9, &dv_pll0_regs->plldiv9);
84
85 dm365_waitloop(300);
86
87 /* Set the GOSET bit */
88 writel(PLLCMD_GOSET, &dv_pll0_regs->pllcmd); /* Go */
89
90 dm365_waitloop(300);
91
92 /* Wait for PLL to LOCK */
93 while (!((readl(&dv_sys_module_regs->pll0_config) & PLL0_LOCK)
94 == PLL0_LOCK))
95 ;
96
97 /* Enable the PLL Bit of PLLCTL*/
98 setbits_le32(&dv_pll0_regs->pllctl, PLLCTL_PLLEN);
99
100 return 0;
101}
102
103int dm365_pll2_init(unsigned long pllm, unsigned long prediv)
104{
105 unsigned int clksrc = 0x0;
106
107 /* Power up the PLL*/
108 clrbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLPWRDN);
109
110 /*
111 * Select the Clock Mode as Onchip Oscilator or External Clock on
112 * MXI pin
113 * VDB has input on MXI pin
114 */
115 clrbits_le32(&dv_pll1_regs->pllctl, PLLCTL_RES_9);
Heiko Schocher34061e82011-11-15 10:00:02 -0500116 setbits_le32(&dv_pll1_regs->pllctl,
117 clksrc << PLLCTL_CLOCK_MODE_SHIFT);
Heiko Schocher75b27132011-11-01 20:00:32 +0000118
119 /*
120 * Set PLLENSRC '0', PLL Enable(PLLEN) selection is controlled
121 * through MMR
122 */
123 clrbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLENSRC);
124
125 /* Set PLLEN=0 => PLL BYPASS MODE */
126 clrbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLEN);
127
128 dm365_waitloop(50);
129
130 /* PLLRST=1(reset assert) */
131 setbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLRST);
132
133 dm365_waitloop(300);
134
135 /* Bring PLL out of Reset */
136 clrbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLRST);
137
138 /* Program the Multiper and Pre-Divider for PLL2 */
139 writel(pllm, &dv_pll1_regs->pllm);
140 writel(prediv, &dv_pll1_regs->prediv);
141
Heiko Schocher34061e82011-11-15 10:00:02 -0500142 writel(PLL_POSTDEN, &dv_pll1_regs->postdiv);
Heiko Schocher75b27132011-11-01 20:00:32 +0000143
144 /* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 1 */
145 writel(PLLSECCTL_STOPMODE | PLLSECCTL_TENABLEDIV | PLLSECCTL_TENABLE |
146 PLLSECCTL_TINITZ, &dv_pll1_regs->secctl);
147 /* Assert TENABLE = 1, TENABLEDIV = 1, TINITZ = 0 */
148 writel(PLLSECCTL_STOPMODE | PLLSECCTL_TENABLEDIV | PLLSECCTL_TENABLE,
149 &dv_pll1_regs->secctl);
150 /* Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 0 */
151 writel(PLLSECCTL_STOPMODE, &dv_pll1_regs->secctl);
152 /* Assert TENABLE = 0, TENABLEDIV = 0, TINITZ = 1 */
153 writel(PLLSECCTL_STOPMODE | PLLSECCTL_TINITZ, &dv_pll1_regs->secctl);
154
155 /* Post divider setting for PLL2 */
156 writel(CONFIG_SYS_DM36x_PLL2_PLLDIV1, &dv_pll1_regs->plldiv1);
157 writel(CONFIG_SYS_DM36x_PLL2_PLLDIV2, &dv_pll1_regs->plldiv2);
158 writel(CONFIG_SYS_DM36x_PLL2_PLLDIV3, &dv_pll1_regs->plldiv3);
159 writel(CONFIG_SYS_DM36x_PLL2_PLLDIV4, &dv_pll1_regs->plldiv4);
160 writel(CONFIG_SYS_DM36x_PLL2_PLLDIV5, &dv_pll1_regs->plldiv5);
161
162 /* GoCmd for PostDivider to take effect */
163 writel(PLLCMD_GOSET, &dv_pll1_regs->pllcmd);
164
165 dm365_waitloop(150);
166
167 /* Wait for PLL to LOCK */
168 while (!((readl(&dv_sys_module_regs->pll1_config) & PLL1_LOCK)
169 == PLL1_LOCK))
170 ;
171
172 dm365_waitloop(4100);
173
174 /* Enable the PLL2 */
175 setbits_le32(&dv_pll1_regs->pllctl, PLLCTL_PLLEN);
176
177 /* do this after PLL's have been set up */
178 writel(CONFIG_SYS_DM36x_PERI_CLK_CTRL,
179 &dv_sys_module_regs->peri_clkctl);
180
181 return 0;
182}
183
184int dm365_ddr_setup(void)
185{
186 lpsc_on(DAVINCI_LPSC_DDR_EMIF);
187 clrbits_le32(&dv_sys_module_regs->vtpiocr,
188 VPTIO_IOPWRDN | VPTIO_CLRZ | VPTIO_LOCK | VPTIO_PWRDN);
189
190 /* Set bit CLRZ (bit 13) */
191 setbits_le32(&dv_sys_module_regs->vtpiocr, VPTIO_CLRZ);
192
193 /* Check VTP READY Status */
194 while (!(readl(&dv_sys_module_regs->vtpiocr) & VPTIO_RDY))
195 ;
196
197 /* Set bit VTP_IOPWRDWN bit 14 for DDR input buffers) */
198 setbits_le32(&dv_sys_module_regs->vtpiocr, VPTIO_IOPWRDN);
199
200 /* Set bit LOCK(bit7) */
201 setbits_le32(&dv_sys_module_regs->vtpiocr, VPTIO_LOCK);
202
203 /*
204 * Powerdown VTP as it is locked (bit 6)
205 * Set bit VTP_IOPWRDWN bit 14 for DDR input buffers)
206 */
207 setbits_le32(&dv_sys_module_regs->vtpiocr,
208 VPTIO_IOPWRDN | VPTIO_PWRDN);
209
210 /* Wait for calibration to complete */
211 dm365_waitloop(150);
212
213 /* Set the DDR2 to synreset, then enable it again */
214 lpsc_syncreset(DAVINCI_LPSC_DDR_EMIF);
215 lpsc_on(DAVINCI_LPSC_DDR_EMIF);
216
217 writel(CONFIG_SYS_DM36x_DDR2_DDRPHYCR, &dv_ddr2_regs_ctrl->ddrphycr);
218
219 /* Program SDRAM Bank Config Register */
220 writel((CONFIG_SYS_DM36x_DDR2_SDBCR | DV_DDR_BOOTUNLOCK),
221 &dv_ddr2_regs_ctrl->sdbcr);
222 writel((CONFIG_SYS_DM36x_DDR2_SDBCR | DV_DDR_TIMUNLOCK),
223 &dv_ddr2_regs_ctrl->sdbcr);
224
225 /* Program SDRAM Timing Control Register1 */
226 writel(CONFIG_SYS_DM36x_DDR2_SDTIMR, &dv_ddr2_regs_ctrl->sdtimr);
227 /* Program SDRAM Timing Control Register2 */
228 writel(CONFIG_SYS_DM36x_DDR2_SDTIMR2, &dv_ddr2_regs_ctrl->sdtimr2);
229
230 writel(CONFIG_SYS_DM36x_DDR2_PBBPR, &dv_ddr2_regs_ctrl->pbbpr);
231
232 writel(CONFIG_SYS_DM36x_DDR2_SDBCR, &dv_ddr2_regs_ctrl->sdbcr);
233
234 /* Program SDRAM Refresh Control Register */
235 writel(CONFIG_SYS_DM36x_DDR2_SDRCR, &dv_ddr2_regs_ctrl->sdrcr);
236
237 lpsc_syncreset(DAVINCI_LPSC_DDR_EMIF);
238 lpsc_on(DAVINCI_LPSC_DDR_EMIF);
239
240 return 0;
241}
242
Heiko Schocherf15223f2012-01-14 21:42:46 +0000243static void dm365_vpss_sync_reset(void)
Heiko Schocher75b27132011-11-01 20:00:32 +0000244{
245 unsigned int PdNum = 0;
246
247 /* VPSS_CLKMD 1:1 */
248 setbits_le32(&dv_sys_module_regs->vpss_clkctl,
249 VPSS_CLK_CTL_VPSS_CLKMD);
250
251 /* LPSC SyncReset DDR Clock Enable */
Heiko Schocher34061e82011-11-15 10:00:02 -0500252 writel(((readl(&dv_psc_regs->mdctl[DAVINCI_LPSC_VPSSMASTER]) &
253 ~PSC_MD_STATE_MSK) | PSC_SYNCRESET),
254 &dv_psc_regs->mdctl[DAVINCI_LPSC_VPSSMASTER]);
Heiko Schocher75b27132011-11-01 20:00:32 +0000255
256 writel((1 << PdNum), &dv_psc_regs->ptcmd);
257
258 while (!(((readl(&dv_psc_regs->ptstat) >> PdNum) & PSC_GOSTAT) == 0))
259 ;
Heiko Schocher34061e82011-11-15 10:00:02 -0500260 while (!((readl(&dv_psc_regs->mdstat[DAVINCI_LPSC_VPSSMASTER]) &
261 PSC_MD_STATE_MSK) == PSC_SYNCRESET))
Heiko Schocher75b27132011-11-01 20:00:32 +0000262 ;
263}
264
Heiko Schocherf15223f2012-01-14 21:42:46 +0000265static void dm365_por_reset(void)
Heiko Schocher75b27132011-11-01 20:00:32 +0000266{
Heiko Schocherf15223f2012-01-14 21:42:46 +0000267 struct davinci_timer *wdog =
268 (struct davinci_timer *)DAVINCI_WDOG_BASE;
269
Heiko Schocher34061e82011-11-15 10:00:02 -0500270 if (readl(&dv_pll0_regs->rstype) &
Heiko Schocherf15223f2012-01-14 21:42:46 +0000271 (PLL_RSTYPE_POR | PLL_RSTYPE_XWRST)) {
272 dm365_vpss_sync_reset();
273
274 writel(DV_TMPBUF_VAL, TMPBUF);
275 setbits_le32(TMPSTATUS, FLAG_PORRST);
276 writel(DV_WDT_ENABLE_SYS_RESET, &wdog->na1);
277 writel(DV_WDT_TRIGGER_SYS_RESET, &wdog->na2);
278
279 while (1);
280 }
281}
282
283static void dm365_wdt_reset(void)
284{
285 struct davinci_timer *wdog =
286 (struct davinci_timer *)DAVINCI_WDOG_BASE;
287
288 if (readl(TMPBUF) != DV_TMPBUF_VAL) {
289 writel(DV_TMPBUF_VAL, TMPBUF);
290 setbits_le32(TMPSTATUS, FLAG_PORRST);
291 setbits_le32(TMPSTATUS, FLAG_FLGOFF);
292
293 dm365_waitloop(100);
294
Heiko Schocher75b27132011-11-01 20:00:32 +0000295 dm365_vpss_sync_reset();
Heiko Schocherf15223f2012-01-14 21:42:46 +0000296
297 writel(DV_WDT_ENABLE_SYS_RESET, &wdog->na1);
298 writel(DV_WDT_TRIGGER_SYS_RESET, &wdog->na2);
299
300 while (1);
301 }
302}
303
304static void dm365_wdt_flag_on(void)
305{
306 /* VPSS_CLKMD 1:2 */
307 clrbits_le32(&dv_sys_module_regs->vpss_clkctl,
308 VPSS_CLK_CTL_VPSS_CLKMD);
309 writel(0, TMPBUF);
310 setbits_le32(TMPSTATUS, FLAG_FLGON);
Heiko Schocher75b27132011-11-01 20:00:32 +0000311}
312
313void dm365_psc_init(void)
314{
315 unsigned char i = 0;
316 unsigned char lpsc_start;
317 unsigned char lpsc_end, lpscgroup, lpscmin, lpscmax;
318 unsigned int PdNum = 0;
319
320 lpscmin = 0;
321 lpscmax = 2;
322
323 for (lpscgroup = lpscmin; lpscgroup <= lpscmax; lpscgroup++) {
324 if (lpscgroup == 0) {
Heiko Schocher34061e82011-11-15 10:00:02 -0500325 /* Enabling LPSC 3 to 28 SCR first */
326 lpsc_start = DAVINCI_LPSC_VPSSMSTR;
327 lpsc_end = DAVINCI_LPSC_TIMER1;
Heiko Schocher75b27132011-11-01 20:00:32 +0000328 } else if (lpscgroup == 1) { /* Skip locked LPSCs [29-37] */
Heiko Schocher34061e82011-11-15 10:00:02 -0500329 lpsc_start = DAVINCI_LPSC_CFG5;
330 lpsc_end = DAVINCI_LPSC_VPSSMASTER;
Heiko Schocher75b27132011-11-01 20:00:32 +0000331 } else {
Heiko Schocher34061e82011-11-15 10:00:02 -0500332 lpsc_start = DAVINCI_LPSC_MJCP;
333 lpsc_end = DAVINCI_LPSC_HDVICP;
Heiko Schocher75b27132011-11-01 20:00:32 +0000334 }
335
336 /* NEXT=0x3, Enable LPSC's */
337 for (i = lpsc_start; i <= lpsc_end; i++)
Heiko Schocher34061e82011-11-15 10:00:02 -0500338 setbits_le32(&dv_psc_regs->mdctl[i], PSC_ENABLE);
Heiko Schocher75b27132011-11-01 20:00:32 +0000339
340 /*
341 * Program goctl to start transition sequence for LPSCs
342 * CSL_PSC_0_REGS->PTCMD = (1<<PdNum); Kick off Power
343 * Domain 0 Modules
344 */
345 writel((1 << PdNum), &dv_psc_regs->ptcmd);
346
347 /*
348 * Wait for GOSTAT = NO TRANSITION from PSC for Powerdomain 0
349 */
350 while (!(((readl(&dv_psc_regs->ptstat) >> PdNum) & PSC_GOSTAT)
351 == 0))
352 ;
353
354 /* Wait for MODSTAT = ENABLE from LPSC's */
355 for (i = lpsc_start; i <= lpsc_end; i++)
356 while (!((readl(&dv_psc_regs->mdstat[i]) &
Heiko Schocher34061e82011-11-15 10:00:02 -0500357 PSC_MD_STATE_MSK) == PSC_ENABLE))
Heiko Schocher75b27132011-11-01 20:00:32 +0000358 ;
359 }
360}
361
362static void dm365_emif_init(void)
363{
364 writel(CONFIG_SYS_DM36x_AWCCR, &davinci_emif_regs->awccr);
365 writel(CONFIG_SYS_DM36x_AB1CR, &davinci_emif_regs->ab1cr);
366
Heiko Schocher34061e82011-11-15 10:00:02 -0500367 setbits_le32(&davinci_emif_regs->nandfcr, DAVINCI_NANDFCR_CS2NAND);
Heiko Schocher75b27132011-11-01 20:00:32 +0000368
369 writel(CONFIG_SYS_DM36x_AB2CR, &davinci_emif_regs->ab2cr);
370
371 return;
372}
373
374void dm365_pinmux_ctl(unsigned long offset, unsigned long mask,
375 unsigned long value)
376{
377 clrbits_le32(&dv_sys_module_regs->pinmux[offset], mask);
378 setbits_le32(&dv_sys_module_regs->pinmux[offset], (mask & value));
379}
380
381__attribute__((weak))
382void board_gpio_init(void)
383{
384 return;
385}
386
387#if defined(CONFIG_POST)
388int post_log(char *format, ...)
389{
390 return 0;
391}
392#endif
393
394void dm36x_lowlevel_init(ulong bootflag)
395{
Heiko Schocher34061e82011-11-15 10:00:02 -0500396 struct davinci_uart_ctrl_regs *davinci_uart_ctrl_regs =
397 (struct davinci_uart_ctrl_regs *)(CONFIG_SYS_NS16550_COM1 +
398 DAVINCI_UART_CTRL_BASE);
Heiko Schocher75b27132011-11-01 20:00:32 +0000399
400 /* Mask all interrupts */
Heiko Schocher34061e82011-11-15 10:00:02 -0500401 writel(DV_AINTC_INTCTL_IDMODE, &dv_aintc_regs->intctl);
Heiko Schocher75b27132011-11-01 20:00:32 +0000402 writel(0x0, &dv_aintc_regs->eabase);
403 writel(0x0, &dv_aintc_regs->eint0);
404 writel(0x0, &dv_aintc_regs->eint1);
405
406 /* Clear all interrupts */
407 writel(0xffffffff, &dv_aintc_regs->fiq0);
408 writel(0xffffffff, &dv_aintc_regs->fiq1);
409 writel(0xffffffff, &dv_aintc_regs->irq0);
410 writel(0xffffffff, &dv_aintc_regs->irq1);
411
Heiko Schocherf15223f2012-01-14 21:42:46 +0000412 dm365_por_reset();
413 dm365_wdt_reset();
414
Heiko Schocher75b27132011-11-01 20:00:32 +0000415 /* System PSC setup - enable all */
416 dm365_psc_init();
417
418 /* Setup Pinmux */
419 dm365_pinmux_ctl(0, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX0);
420 dm365_pinmux_ctl(1, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX1);
421 dm365_pinmux_ctl(2, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX2);
422 dm365_pinmux_ctl(3, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX3);
423 dm365_pinmux_ctl(4, 0xFFFFFFFF, CONFIG_SYS_DM36x_PINMUX4);
424
425 /* PLL setup */
426 dm365_pll1_init(CONFIG_SYS_DM36x_PLL1_PLLM,
427 CONFIG_SYS_DM36x_PLL1_PREDIV);
428 dm365_pll2_init(CONFIG_SYS_DM36x_PLL2_PLLM,
429 CONFIG_SYS_DM36x_PLL2_PREDIV);
430
431 /* GPIO setup */
432 board_gpio_init();
433
434 NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM1),
435 CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE);
436
437 /*
438 * Fix Power and Emulation Management Register
439 * see sprufh2.pdf page 38 Table 22
440 */
Heiko Schocher34061e82011-11-15 10:00:02 -0500441 writel((DAVINCI_UART_PWREMU_MGMT_FREE | DAVINCI_UART_PWREMU_MGMT_URRST |
442 DAVINCI_UART_PWREMU_MGMT_UTRST),
443 &davinci_uart_ctrl_regs->pwremu_mgmt);
444
Heiko Schocher75b27132011-11-01 20:00:32 +0000445 puts("ddr init\n");
446 dm365_ddr_setup();
447
448 puts("emif init\n");
449 dm365_emif_init();
450
Heiko Schocherf15223f2012-01-14 21:42:46 +0000451 dm365_wdt_flag_on();
452
Heiko Schocher75b27132011-11-01 20:00:32 +0000453#if defined(CONFIG_POST)
454 /*
455 * Do memory tests, calls arch_memory_failure_handle()
456 * if error detected.
457 */
458 memory_post_test(0);
459#endif
460}