blob: a039cbbbce12d4969b5d9a3f9b2b2452da37f721 [file] [log] [blame]
Mike Frysinger94bae5c2008-03-30 15:46:13 -04001/*
2 * initcode.c - Initialize the processor. This is usually entails things
3 * like external memory, voltage regulators, etc... Note that this file
4 * cannot make any function calls as it may be executed all by itself by
5 * the Blackfin's bootrom in LDR format.
6 *
7 * Copyright (c) 2004-2008 Analog Devices Inc.
8 *
9 * Licensed under the GPL-2 or later.
10 */
11
12#include <config.h>
13#include <asm/blackfin.h>
14#include <asm/mach-common/bits/bootrom.h>
Mike Frysinger268dbf52008-10-11 21:58:33 -040015#include <asm/mach-common/bits/core.h>
Mike Frysinger94bae5c2008-03-30 15:46:13 -040016#include <asm/mach-common/bits/ebiu.h>
17#include <asm/mach-common/bits/pll.h>
18#include <asm/mach-common/bits/uart.h>
19
20#define BFIN_IN_INITCODE
21#include "serial.h"
22
23__attribute__((always_inline))
Mike Frysinger84451302008-12-10 12:33:54 -050024static inline void serial_init(void)
Mike Frysinger94bae5c2008-03-30 15:46:13 -040025{
26#ifdef __ADSPBF54x__
27# ifdef BFIN_BOOT_UART_USE_RTS
28# define BFIN_UART_USE_RTS 1
29# else
30# define BFIN_UART_USE_RTS 0
31# endif
32 if (BFIN_UART_USE_RTS && CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) {
33 size_t i;
34
35 /* force RTS rather than relying on auto RTS */
36 bfin_write_UART1_MCR(bfin_read_UART1_MCR() | FCPOL);
37
38 /* Wait for the line to clear up. We cannot rely on UART
39 * registers as none of them reflect the status of the RSR.
40 * Instead, we'll sleep for ~10 bit times at 9600 baud.
41 * We can precalc things here by assuming boot values for
42 * PLL rather than loading registers and calculating.
43 * baud = SCLK / (16 ^ (1 - EDBO) * Divisor)
44 * EDB0 = 0
45 * Divisor = (SCLK / baud) / 16
46 * SCLK = baud * 16 * Divisor
47 * SCLK = (0x14 * CONFIG_CLKIN_HZ) / 5
48 * CCLK = (16 * Divisor * 5) * (9600 / 10)
49 * In reality, this will probably be just about 1 second delay,
50 * so assuming 9600 baud is OK (both as a very low and too high
51 * speed as this will buffer things enough).
52 */
53#define _NUMBITS (10) /* how many bits to delay */
54#define _LOWBAUD (9600) /* low baud rate */
55#define _SCLK ((0x14 * CONFIG_CLKIN_HZ) / 5) /* SCLK based on PLL */
56#define _DIVISOR ((_SCLK / _LOWBAUD) / 16) /* UART DLL/DLH */
57#define _NUMINS (3) /* how many instructions in loop */
58#define _CCLK (((16 * _DIVISOR * 5) * (_LOWBAUD / _NUMBITS)) / _NUMINS)
59 i = _CCLK;
60 while (i--)
61 asm volatile("" : : : "memory");
62 }
63#endif
64
Mike Frysinger94bae5c2008-03-30 15:46:13 -040065 if (BFIN_DEBUG_EARLY_SERIAL) {
Mike Frysinger84451302008-12-10 12:33:54 -050066 int ucen = *pUART_GCTL & UCEN;
Mike Frysinger94bae5c2008-03-30 15:46:13 -040067 serial_early_init();
68
69 /* If the UART is off, that means we need to program
70 * the baud rate ourselves initially.
71 */
Mike Frysinger84451302008-12-10 12:33:54 -050072 if (ucen != UCEN)
Mike Frysinger94bae5c2008-03-30 15:46:13 -040073 serial_early_set_baud(CONFIG_BAUDRATE);
Mike Frysinger94bae5c2008-03-30 15:46:13 -040074 }
Mike Frysinger94bae5c2008-03-30 15:46:13 -040075}
76
77__attribute__((always_inline))
78static inline void serial_deinit(void)
79{
80#ifdef __ADSPBF54x__
81 if (BFIN_UART_USE_RTS && CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) {
82 /* clear forced RTS rather than relying on auto RTS */
83 bfin_write_UART1_MCR(bfin_read_UART1_MCR() & ~FCPOL);
84 }
85#endif
Mike Frysinger94bae5c2008-03-30 15:46:13 -040086}
87
88__attribute__((always_inline))
89static inline void serial_putc(char c)
90{
91 if (!BFIN_DEBUG_EARLY_SERIAL)
92 return;
93
94 if (c == '\n')
Mike Frysingere7851d02009-04-24 23:22:48 -040095 serial_putc('\r');
Mike Frysinger94bae5c2008-03-30 15:46:13 -040096
97 *pUART_THR = c;
98
99 while (!(*pUART_LSR & TEMT))
100 continue;
101}
102
103
Mike Frysinger2c001972008-12-09 17:21:08 -0500104/* Max SCLK can be 133MHz ... dividing that by (2*4) gives
105 * us a freq of 16MHz for SPI which should generally be
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400106 * slow enough for the slow reads the bootrom uses.
107 */
Mike Frysinger2c001972008-12-09 17:21:08 -0500108#if !defined(CONFIG_SPI_FLASH_SLOW_READ) && \
109 ((defined(__ADSPBF52x__) && __SILICON_REVISION__ >= 2) || \
110 (defined(__ADSPBF54x__) && __SILICON_REVISION__ >= 1))
111# define BOOTROM_SUPPORTS_SPI_FAST_READ 1
112#else
113# define BOOTROM_SUPPORTS_SPI_FAST_READ 0
114#endif
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400115#ifndef CONFIG_SPI_BAUD_INITBLOCK
Mike Frysinger2c001972008-12-09 17:21:08 -0500116# define CONFIG_SPI_BAUD_INITBLOCK (BOOTROM_SUPPORTS_SPI_FAST_READ ? 2 : 4)
117#endif
118#ifdef SPI0_BAUD
119# define bfin_write_SPI_BAUD bfin_write_SPI0_BAUD
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400120#endif
121
122/* PLL_DIV defines */
123#ifndef CONFIG_PLL_DIV_VAL
124# if (CONFIG_CCLK_DIV == 1)
125# define CONFIG_CCLK_ACT_DIV CCLK_DIV1
126# elif (CONFIG_CCLK_DIV == 2)
127# define CONFIG_CCLK_ACT_DIV CCLK_DIV2
128# elif (CONFIG_CCLK_DIV == 4)
129# define CONFIG_CCLK_ACT_DIV CCLK_DIV4
130# elif (CONFIG_CCLK_DIV == 8)
131# define CONFIG_CCLK_ACT_DIV CCLK_DIV8
132# else
133# define CONFIG_CCLK_ACT_DIV CONFIG_CCLK_DIV_not_defined_properly
134# endif
135# define CONFIG_PLL_DIV_VAL (CONFIG_CCLK_ACT_DIV | CONFIG_SCLK_DIV)
136#endif
137
138#ifndef CONFIG_PLL_LOCKCNT_VAL
139# define CONFIG_PLL_LOCKCNT_VAL 0x0300
140#endif
141
142#ifndef CONFIG_PLL_CTL_VAL
Mike Frysingerc13fc442008-06-01 01:26:29 -0400143# define CONFIG_PLL_CTL_VAL (SPORT_HYST | (CONFIG_VCO_MULT << 9) | CONFIG_CLKIN_HALF)
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400144#endif
145
146#ifndef CONFIG_EBIU_RSTCTL_VAL
147# define CONFIG_EBIU_RSTCTL_VAL 0 /* only MDDRENABLE is useful */
148#endif
Mike Frysinger4f7fb332008-10-11 21:46:52 -0400149#if ((CONFIG_EBIU_RSTCTL_VAL & 0xFFFFFFC4) != 0)
150# error invalid EBIU_RSTCTL value: must not set reserved bits
151#endif
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400152
153#ifndef CONFIG_EBIU_MBSCTL_VAL
154# define CONFIG_EBIU_MBSCTL_VAL 0
155#endif
156
Mike Frysinger4f7fb332008-10-11 21:46:52 -0400157#if defined(CONFIG_EBIU_DDRQUE_VAL) && ((CONFIG_EBIU_DDRQUE_VAL & 0xFFFF8000) != 0)
158# error invalid EBIU_DDRQUE value: must not set reserved bits
159#endif
160
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400161/* Make sure our voltage value is sane so we don't blow up! */
162#ifndef CONFIG_VR_CTL_VAL
163# define BFIN_CCLK ((CONFIG_CLKIN_HZ * CONFIG_VCO_MULT) / CONFIG_CCLK_DIV)
164# if defined(__ADSPBF533__) || defined(__ADSPBF532__) || defined(__ADSPBF531__)
165# define CCLK_VLEV_120 400000000
166# define CCLK_VLEV_125 533000000
167# elif defined(__ADSPBF537__) || defined(__ADSPBF536__) || defined(__ADSPBF534__)
168# define CCLK_VLEV_120 401000000
169# define CCLK_VLEV_125 401000000
170# elif defined(__ADSPBF561__)
171# define CCLK_VLEV_120 300000000
172# define CCLK_VLEV_125 501000000
173# endif
174# if BFIN_CCLK < CCLK_VLEV_120
175# define CONFIG_VR_CTL_VLEV VLEV_120
176# elif BFIN_CCLK < CCLK_VLEV_125
177# define CONFIG_VR_CTL_VLEV VLEV_125
178# else
179# define CONFIG_VR_CTL_VLEV VLEV_130
180# endif
181# if defined(__ADSPBF52x__) /* TBD; use default */
182# undef CONFIG_VR_CTL_VLEV
183# define CONFIG_VR_CTL_VLEV VLEV_110
184# elif defined(__ADSPBF54x__) /* TBD; use default */
185# undef CONFIG_VR_CTL_VLEV
186# define CONFIG_VR_CTL_VLEV VLEV_120
Mike Frysingera7ab10a2008-10-11 21:54:00 -0400187# elif defined(__ADSPBF538__) || defined(__ADSPBF539__) /* TBD; use default */
188# undef CONFIG_VR_CTL_VLEV
189# define CONFIG_VR_CTL_VLEV VLEV_125
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400190# endif
191
192# ifdef CONFIG_BFIN_MAC
193# define CONFIG_VR_CTL_CLKBUF CLKBUFOE
194# else
195# define CONFIG_VR_CTL_CLKBUF 0
196# endif
197
198# if defined(__ADSPBF52x__)
199# define CONFIG_VR_CTL_FREQ FREQ_1000
200# else
201# define CONFIG_VR_CTL_FREQ (GAIN_20 | FREQ_1000)
202# endif
203
204# define CONFIG_VR_CTL_VAL (CONFIG_VR_CTL_CLKBUF | CONFIG_VR_CTL_VLEV | CONFIG_VR_CTL_FREQ)
205#endif
206
Mike Frysinger446d5702008-10-11 21:56:08 -0400207/* some parts do not have an on-chip voltage regulator */
208#if defined(__ADSPBF51x__)
209# define CONFIG_HAS_VR 0
210# undef CONFIG_VR_CTL_VAL
211# define CONFIG_VR_CTL_VAL 0
212#else
213# define CONFIG_HAS_VR 1
214#endif
215
Mike Frysingerb0f14682008-06-01 01:28:24 -0400216#ifndef EBIU_RSTCTL
217/* Blackfin with SDRAM */
218#ifndef CONFIG_EBIU_SDBCTL_VAL
219# if CONFIG_MEM_SIZE == 16
220# define CONFIG_EBSZ_VAL EBSZ_16
221# elif CONFIG_MEM_SIZE == 32
222# define CONFIG_EBSZ_VAL EBSZ_32
223# elif CONFIG_MEM_SIZE == 64
224# define CONFIG_EBSZ_VAL EBSZ_64
225# elif CONFIG_MEM_SIZE == 128
226# define CONFIG_EBSZ_VAL EBSZ_128
227# elif CONFIG_MEM_SIZE == 256
228# define CONFIG_EBSZ_VAL EBSZ_256
229# elif CONFIG_MEM_SIZE == 512
230# define CONFIG_EBSZ_VAL EBSZ_512
231# else
232# error You need to define CONFIG_EBIU_SDBCTL_VAL or CONFIG_MEM_SIZE
233# endif
234# if CONFIG_MEM_ADD_WDTH == 8
235# define CONFIG_EBCAW_VAL EBCAW_8
236# elif CONFIG_MEM_ADD_WDTH == 9
237# define CONFIG_EBCAW_VAL EBCAW_9
238# elif CONFIG_MEM_ADD_WDTH == 10
239# define CONFIG_EBCAW_VAL EBCAW_10
240# elif CONFIG_MEM_ADD_WDTH == 11
241# define CONFIG_EBCAW_VAL EBCAW_11
242# else
243# error You need to define CONFIG_EBIU_SDBCTL_VAL or CONFIG_MEM_ADD_WDTH
244# endif
245# define CONFIG_EBIU_SDBCTL_VAL (CONFIG_EBCAW_VAL | CONFIG_EBSZ_VAL | EBE)
246#endif
247#endif
248
Mike Frysinger8c10be42009-04-04 08:40:13 -0400249/* Conflicting Column Address Widths Causes SDRAM Errors:
250 * EB2CAW and EB3CAW must be the same
251 */
252#if ANOMALY_05000362
253# if ((CONFIG_EBIU_SDBCTL_VAL & 0x30000000) >> 8) != (CONFIG_EBIU_SDBCTL_VAL & 0x00300000)
254# error "Anomaly 05000362: EB2CAW and EB3CAW must be the same"
255# endif
256#endif
257
Mike Frysinger1114d0e2008-06-01 01:29:57 -0400258BOOTROM_CALLED_FUNC_ATTR
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400259void initcode(ADI_BOOT_DATA *bootstruct)
260{
Mike Frysinger01986762009-02-13 17:10:58 -0500261 ADI_BOOT_DATA bootstruct_scratch;
262
Mike Frysinger84451302008-12-10 12:33:54 -0500263 /* Save the clock pieces that are used in baud rate calculation */
264 unsigned int sdivB, divB, vcoB;
265 serial_init();
266 if (BFIN_DEBUG_EARLY_SERIAL || CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) {
267 sdivB = bfin_read_PLL_DIV() & 0xf;
268 vcoB = (bfin_read_PLL_CTL() >> 9) & 0x3f;
269 divB = serial_early_get_div();
270 }
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400271
Mike Frysinger268dbf52008-10-11 21:58:33 -0400272 serial_putc('A');
273
Mike Frysinger01986762009-02-13 17:10:58 -0500274 /* If the bootstruct is NULL, then it's because we're loading
275 * dynamically and not via LDR (bootrom). So set the struct to
276 * some scratch space.
277 */
278 if (!bootstruct)
279 bootstruct = &bootstruct_scratch;
280
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400281#ifdef CONFIG_HW_WATCHDOG
282# ifndef CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE
283# define CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE 20000
284# endif
285 /* Program the watchdog with an initial timeout of ~20 seconds.
286 * Hopefully that should be long enough to load the u-boot LDR
287 * (from wherever) and then the common u-boot code can take over.
288 * In bypass mode, the start.S would have already set a much lower
289 * timeout, so don't clobber that.
290 */
291 if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS) {
292 bfin_write_WDOG_CNT(MSEC_TO_SCLK(CONFIG_HW_WATCHDOG_TIMEOUT_INITCODE));
293 bfin_write_WDOG_CTL(0);
294 }
295#endif
296
Mike Frysinger268dbf52008-10-11 21:58:33 -0400297 serial_putc('B');
298
299 /* If external memory is enabled, put it into self refresh first. */
300 bool put_into_srfs = false;
301#ifdef EBIU_RSTCTL
302 if (bfin_read_EBIU_RSTCTL() & DDR_SRESET) {
303 bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() | SRREQ);
304 put_into_srfs = true;
305 }
306#else
307 if (bfin_read_EBIU_SDBCTL() & EBE) {
308 bfin_write_EBIU_SDGCTL(bfin_read_EBIU_SDGCTL() | SRFS);
309 put_into_srfs = true;
310 }
311#endif
312
313 serial_putc('C');
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400314
315 /* Blackfin bootroms use the SPI slow read opcode instead of the SPI
316 * fast read, so we need to slow down the SPI clock a lot more during
317 * boot. Once we switch over to u-boot's SPI flash driver, we'll
318 * increase the speed appropriately.
319 */
Mike Frysinger2c001972008-12-09 17:21:08 -0500320 if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_SPI_MASTER) {
321 if (BOOTROM_SUPPORTS_SPI_FAST_READ && CONFIG_SPI_BAUD_INITBLOCK < 4)
322 bootstruct->dFlags |= BFLAG_FASTREAD;
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400323 bfin_write_SPI_BAUD(CONFIG_SPI_BAUD_INITBLOCK);
Mike Frysinger2c001972008-12-09 17:21:08 -0500324 }
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400325
Mike Frysinger268dbf52008-10-11 21:58:33 -0400326 serial_putc('D');
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400327
Mike Frysinger268dbf52008-10-11 21:58:33 -0400328 /* If we're entering self refresh, make sure it has happened. */
329 if (put_into_srfs)
330#ifdef EBIU_RSTCTL
331 while (!(bfin_read_EBIU_RSTCTL() & SRACK))
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400332#else
Mike Frysinger268dbf52008-10-11 21:58:33 -0400333 while (!(bfin_read_EBIU_SDSTAT() & SDSRA))
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400334#endif
Mike Frysinger268dbf52008-10-11 21:58:33 -0400335 continue;
336
337 serial_putc('E');
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400338
Mike Frysinger1114d0e2008-06-01 01:29:57 -0400339 /* With newer bootroms, we use the helper function to set up
340 * the memory controller. Older bootroms lacks such helpers
341 * so we do it ourselves.
342 */
Mike Frysinger268dbf52008-10-11 21:58:33 -0400343 uint16_t vr_ctl = bfin_read_VR_CTL();
344 if (!ANOMALY_05000386) {
345 serial_putc('F');
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400346
Mike Frysingere8aea4a2009-04-04 08:29:55 -0400347 /* Always programming PLL_LOCKCNT avoids Anomaly 05000430 */
Mike Frysinger1114d0e2008-06-01 01:29:57 -0400348 ADI_SYSCTRL_VALUES memory_settings;
Mike Frysinger446d5702008-10-11 21:56:08 -0400349 uint32_t actions = SYSCTRL_WRITE | SYSCTRL_PLLCTL | SYSCTRL_PLLDIV | SYSCTRL_LOCKCNT;
350 if (CONFIG_HAS_VR) {
351 actions |= SYSCTRL_VRCTL;
352 if (CONFIG_VR_CTL_VAL & FREQ_MASK)
353 actions |= SYSCTRL_INTVOLTAGE;
354 else
355 actions |= SYSCTRL_EXTVOLTAGE;
356 memory_settings.uwVrCtl = CONFIG_VR_CTL_VAL;
357 } else
358 actions |= SYSCTRL_EXTVOLTAGE;
Mike Frysinger1114d0e2008-06-01 01:29:57 -0400359 memory_settings.uwPllCtl = CONFIG_PLL_CTL_VAL;
360 memory_settings.uwPllDiv = CONFIG_PLL_DIV_VAL;
361 memory_settings.uwPllLockCnt = CONFIG_PLL_LOCKCNT_VAL;
Mike Frysingerf9d004b2008-12-06 18:06:58 -0500362#if ANOMALY_05000432
363 bfin_write_SIC_IWR1(0);
364#endif
Mike Frysinger446d5702008-10-11 21:56:08 -0400365 bfrom_SysControl(actions, &memory_settings, NULL);
Mike Frysingerf9d004b2008-12-06 18:06:58 -0500366#if ANOMALY_05000432
367 bfin_write_SIC_IWR1(-1);
368#endif
Mike Frysinger1f1ac0a2009-04-04 08:09:24 -0400369#if ANOMALY_05000171
370 bfin_write_SICA_IWR0(-1);
371 bfin_write_SICA_IWR1(-1);
372#endif
Mike Frysinger1114d0e2008-06-01 01:29:57 -0400373 } else {
Mike Frysinger268dbf52008-10-11 21:58:33 -0400374 serial_putc('G');
375
376 /* Disable all peripheral wakeups except for the PLL event. */
377#ifdef SIC_IWR0
378 bfin_write_SIC_IWR0(1);
379 bfin_write_SIC_IWR1(0);
380# ifdef SIC_IWR2
381 bfin_write_SIC_IWR2(0);
382# endif
383#elif defined(SICA_IWR0)
384 bfin_write_SICA_IWR0(1);
385 bfin_write_SICA_IWR1(0);
386#else
387 bfin_write_SIC_IWR(1);
388#endif
389
390 serial_putc('H');
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400391
Mike Frysingere8aea4a2009-04-04 08:29:55 -0400392 /* Always programming PLL_LOCKCNT avoids Anomaly 05000430 */
Mike Frysinger1114d0e2008-06-01 01:29:57 -0400393 bfin_write_PLL_LOCKCNT(CONFIG_PLL_LOCKCNT_VAL);
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400394
Mike Frysinger268dbf52008-10-11 21:58:33 -0400395 serial_putc('I');
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400396
Mike Frysinger1114d0e2008-06-01 01:29:57 -0400397 /* Only reprogram when needed to avoid triggering unnecessary
398 * PLL relock sequences.
399 */
Mike Frysinger268dbf52008-10-11 21:58:33 -0400400 if (vr_ctl != CONFIG_VR_CTL_VAL) {
Mike Frysinger1114d0e2008-06-01 01:29:57 -0400401 serial_putc('!');
402 bfin_write_VR_CTL(CONFIG_VR_CTL_VAL);
403 asm("idle;");
404 }
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400405
Mike Frysinger268dbf52008-10-11 21:58:33 -0400406 serial_putc('J');
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400407
Mike Frysinger1114d0e2008-06-01 01:29:57 -0400408 bfin_write_PLL_DIV(CONFIG_PLL_DIV_VAL);
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400409
Mike Frysinger1114d0e2008-06-01 01:29:57 -0400410 serial_putc('K');
411
412 /* Only reprogram when needed to avoid triggering unnecessary
413 * PLL relock sequences.
414 */
Mike Frysinger43ed6962009-04-04 08:10:22 -0400415 if (ANOMALY_05000242 || bfin_read_PLL_CTL() != CONFIG_PLL_CTL_VAL) {
Mike Frysinger1114d0e2008-06-01 01:29:57 -0400416 serial_putc('!');
417 bfin_write_PLL_CTL(CONFIG_PLL_CTL_VAL);
418 asm("idle;");
419 }
Mike Frysinger268dbf52008-10-11 21:58:33 -0400420
421 serial_putc('L');
422
423 /* Restore all peripheral wakeups. */
424#ifdef SIC_IWR0
425 bfin_write_SIC_IWR0(-1);
426 bfin_write_SIC_IWR1(-1);
427# ifdef SIC_IWR2
428 bfin_write_SIC_IWR2(-1);
429# endif
430#elif defined(SICA_IWR0)
431 bfin_write_SICA_IWR0(-1);
432 bfin_write_SICA_IWR1(-1);
433#else
434 bfin_write_SIC_IWR(-1);
435#endif
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400436 }
437
Mike Frysinger268dbf52008-10-11 21:58:33 -0400438 serial_putc('M');
439
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400440 /* Since we've changed the SCLK above, we may need to update
441 * the UART divisors (UART baud rates are based on SCLK).
Mike Frysinger84451302008-12-10 12:33:54 -0500442 * Do the division by hand as there are no native instructions
443 * for dividing which means we'd generate a libgcc reference.
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400444 */
Mike Frysinger84451302008-12-10 12:33:54 -0500445 if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) {
446 unsigned int sdivR, vcoR;
447 sdivR = bfin_read_PLL_DIV() & 0xf;
448 vcoR = (bfin_read_PLL_CTL() >> 9) & 0x3f;
449 int dividend = sdivB * divB * vcoR;
450 int divisor = vcoB * sdivR;
451 unsigned int quotient;
452 for (quotient = 0; dividend > 0; ++quotient)
453 dividend -= divisor;
454 serial_early_put_div(quotient - ANOMALY_05000230);
455 }
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400456
Mike Frysinger268dbf52008-10-11 21:58:33 -0400457 serial_putc('N');
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400458
Mike Frysinger268dbf52008-10-11 21:58:33 -0400459 /* Program the external memory controller before we come out of
460 * self-refresh. This only works with our SDRAM controller.
461 */
462#ifndef EBIU_RSTCTL
463 bfin_write_EBIU_SDRRC(CONFIG_EBIU_SDRRC_VAL);
464 bfin_write_EBIU_SDBCTL(CONFIG_EBIU_SDBCTL_VAL);
465 bfin_write_EBIU_SDGCTL(CONFIG_EBIU_SDGCTL_VAL);
466#endif
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400467
Mike Frysinger268dbf52008-10-11 21:58:33 -0400468 serial_putc('O');
469
470 /* Now that we've reprogrammed, take things out of self refresh. */
471 if (put_into_srfs)
472#ifdef EBIU_RSTCTL
473 bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() & ~(SRREQ));
474#else
475 bfin_write_EBIU_SDGCTL(bfin_read_EBIU_SDGCTL() & ~(SRFS));
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400476#endif
477
Mike Frysinger268dbf52008-10-11 21:58:33 -0400478 serial_putc('P');
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400479
Mike Frysinger268dbf52008-10-11 21:58:33 -0400480 /* Our DDR controller sucks and cannot be programmed while in
481 * self-refresh. So we have to pull it out before programming.
482 */
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400483#ifdef EBIU_RSTCTL
484 bfin_write_EBIU_RSTCTL(bfin_read_EBIU_RSTCTL() | 0x1 /*DDRSRESET*/ | CONFIG_EBIU_RSTCTL_VAL);
485 bfin_write_EBIU_DDRCTL0(CONFIG_EBIU_DDRCTL0_VAL);
486 bfin_write_EBIU_DDRCTL1(CONFIG_EBIU_DDRCTL1_VAL);
487 bfin_write_EBIU_DDRCTL2(CONFIG_EBIU_DDRCTL2_VAL);
488# ifdef CONFIG_EBIU_DDRCTL3_VAL
489 /* default is disable, so don't need to force this */
490 bfin_write_EBIU_DDRCTL3(CONFIG_EBIU_DDRCTL3_VAL);
491# endif
Mike Frysinger268dbf52008-10-11 21:58:33 -0400492# ifdef CONFIG_EBIU_DDRQUE_VAL
493 bfin_write_EBIU_DDRQUE(bfin_read_EBIU_DDRQUE() | CONFIG_EBIU_DDRQUE_VAL);
494# endif
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400495#endif
496
Mike Frysinger268dbf52008-10-11 21:58:33 -0400497 serial_putc('Q');
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400498
Mike Frysinger268dbf52008-10-11 21:58:33 -0400499 /* Are we coming out of hibernate (suspend to memory) ?
500 * The memory layout is:
501 * 0x0: hibernate magic for anomaly 307 (0xDEADBEEF)
502 * 0x4: return address
503 * 0x8: stack pointer
504 *
505 * SCKELOW is unreliable on older parts (anomaly 307)
506 */
507 if (ANOMALY_05000307 || vr_ctl & 0x8000) {
508 uint32_t *hibernate_magic = 0;
509 __builtin_bfin_ssync(); /* make sure memory controller is done */
510 if (hibernate_magic[0] == 0xDEADBEEF) {
511 serial_putc('R');
512 bfin_write_EVT15(hibernate_magic[1]);
513 bfin_write_IMASK(EVT_IVG15);
514 __asm__ __volatile__ (
515 /* load reti early to avoid anomaly 281 */
516 "reti = %0;"
517 /* clear hibernate magic */
518 "[%0] = %1;"
519 /* load stack pointer */
520 "SP = [%0 + 8];"
521 /* lower ourselves from reset ivg to ivg15 */
522 "raise 15;"
523 "rti;"
524 :
525 : "p"(hibernate_magic), "d"(0x2000 /* jump.s 0 */)
526 );
527 }
528 }
529
530 serial_putc('S');
531
532 /* Program the async banks controller. */
533 bfin_write_EBIU_AMBCTL0(CONFIG_EBIU_AMBCTL0_VAL);
534 bfin_write_EBIU_AMBCTL1(CONFIG_EBIU_AMBCTL1_VAL);
535 bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL);
536
537#ifdef EBIU_MODE
538 /* Not all parts have these additional MMRs. */
539 bfin_write_EBIU_MBSCTL(CONFIG_EBIU_MBSCTL_VAL);
540 bfin_write_EBIU_MODE(CONFIG_EBIU_MODE_VAL);
541 bfin_write_EBIU_FCTL(CONFIG_EBIU_FCTL_VAL);
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400542#endif
543
Mike Frysinger268dbf52008-10-11 21:58:33 -0400544 serial_putc('T');
545
Mike Frysingera48e0ed2009-04-24 23:39:41 -0400546#ifdef CONFIG_BFIN_BOOTROM_USES_EVT1
Mike Frysinger99593682008-10-18 04:04:49 -0400547 /* tell the bootrom where our entry point is */
548 if (CONFIG_BFIN_BOOT_MODE != BFIN_BOOT_BYPASS)
549 bfin_write_EVT1(CONFIG_SYS_MONITOR_BASE);
Mike Frysingera48e0ed2009-04-24 23:39:41 -0400550#endif
Mike Frysinger99593682008-10-18 04:04:49 -0400551
Mike Frysinger94bae5c2008-03-30 15:46:13 -0400552 serial_putc('>');
553 serial_putc('\n');
554
555 serial_deinit();
556}