blackfin: bf60x: Port blackfin core architecture code to boot on bf60x.

Set up clocks, DDR controller, Nor flash controller, reboot,
serial port. Add new SPI boot modes.

Signed-off-by: Bob Liu <lliubbo@gmail.com>
Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Signed-off-by: Sonic Zhang <sonic.adi@gmail.com>
master
Sonic Zhang 12 years ago committed by sonic
parent 3ead92c571
commit a2979dcdbe
  1. 4
      arch/blackfin/cpu/cpu.c
  2. 325
      arch/blackfin/cpu/initcode.c
  3. 52
      arch/blackfin/cpu/initcode.h
  4. 6
      arch/blackfin/cpu/reset.c
  5. 4
      arch/blackfin/include/asm/config-pre.h
  6. 6
      arch/blackfin/lib/board.c
  7. 112
      arch/blackfin/lib/clocks.c
  8. 19
      common/cmd_reginfo.c

@ -68,7 +68,9 @@ void cpu_init_f(ulong bootflag, ulong loaded_from_ldr)
/* Reset upon a double exception rather than just hanging. /* Reset upon a double exception rather than just hanging.
* Do not do bfin_read on SWRST as that will reset status bits. * Do not do bfin_read on SWRST as that will reset status bits.
*/ */
# ifdef SWRST
bfin_write_SWRST(DOUBLE_FAULT); bfin_write_SWRST(DOUBLE_FAULT);
# endif
#endif #endif
serial_early_puts("Board init flash\n"); serial_early_puts("Board init flash\n");
@ -92,7 +94,7 @@ int irq_init(void)
#elif defined(SICA_IMASK0) #elif defined(SICA_IMASK0)
bfin_write_SICA_IMASK0(0); bfin_write_SICA_IMASK0(0);
bfin_write_SICA_IMASK1(0); bfin_write_SICA_IMASK1(0);
#else #elif defined(SIC_IMASK)
bfin_write_SIC_IMASK(0); bfin_write_SIC_IMASK(0);
#endif #endif
/* Set up a dummy NMI handler if needed. */ /* Set up a dummy NMI handler if needed. */

@ -15,20 +15,141 @@
#include <asm/blackfin.h> #include <asm/blackfin.h>
#include <asm/mach-common/bits/bootrom.h> #include <asm/mach-common/bits/bootrom.h>
#include <asm/mach-common/bits/core.h> #include <asm/mach-common/bits/core.h>
#include <asm/mach-common/bits/ebiu.h>
#include <asm/mach-common/bits/pll.h>
#include <asm/mach-common/bits/uart.h>
#define BUG() while (1) { asm volatile("emuexcpt;"); } #define BUG() while (1) { asm volatile("emuexcpt;"); }
#include "serial.h" #include "serial.h"
#ifndef __ADSPBF60x__
#include <asm/mach-common/bits/ebiu.h>
#include <asm/mach-common/bits/pll.h>
#else /* __ADSPBF60x__ */
#include <asm/mach-common/bits/cgu.h>
#define CONFIG_BFIN_GET_DCLK_M \
((CONFIG_CLKIN_HZ*CONFIG_VCO_MULT)/(CONFIG_DCLK_DIV*1000000))
#ifndef CONFIG_DMC_DDRCFG
#if ((CONFIG_BFIN_GET_DCLK_M != 125) && \
(CONFIG_BFIN_GET_DCLK_M != 133) && \
(CONFIG_BFIN_GET_DCLK_M != 150) && \
(CONFIG_BFIN_GET_DCLK_M != 166) && \
(CONFIG_BFIN_GET_DCLK_M != 200) && \
(CONFIG_BFIN_GET_DCLK_M != 225) && \
(CONFIG_BFIN_GET_DCLK_M != 250))
#error "DDR2 CLK must be in (125, 133, 150, 166, 200, 225, 250)MHz"
#endif
#endif
/* DMC control bits */
#define SRREQ 0x8
/* DMC status bits */
#define IDLE 0x1
#define MEMINITDONE 0x4
#define SRACK 0x8
#define PDACK 0x10
#define DPDACK 0x20
#define DLLCALDONE 0x2000
#define PENDREF 0xF0000
#define PHYRDPHASE 0xF00000
#define PHYRDPHASE_OFFSET 20
/* DMC DLL control bits */
#define DLLCALRDCNT 0xFF
#define DATACYC_OFFSET 8
struct ddr_config {
u32 ddr_clk;
u32 dmc_ddrctl;
u32 dmc_ddrcfg;
u32 dmc_ddrtr0;
u32 dmc_ddrtr1;
u32 dmc_ddrtr2;
u32 dmc_ddrmr;
u32 dmc_ddrmr1;
};
static struct ddr_config ddr_config_table[] = {
[0] = {
.ddr_clk = 125, /* 125MHz */
.dmc_ddrctl = 0x00000904,
.dmc_ddrcfg = 0x00000422,
.dmc_ddrtr0 = 0x20705212,
.dmc_ddrtr1 = 0x201003CF,
.dmc_ddrtr2 = 0x00320107,
.dmc_ddrmr = 0x00000422,
.dmc_ddrmr1 = 0x4,
},
[1] = {
.ddr_clk = 133, /* 133MHz */
.dmc_ddrctl = 0x00000904,
.dmc_ddrcfg = 0x00000422,
.dmc_ddrtr0 = 0x20806313,
.dmc_ddrtr1 = 0x2013040D,
.dmc_ddrtr2 = 0x00320108,
.dmc_ddrmr = 0x00000632,
.dmc_ddrmr1 = 0x4,
},
[2] = {
.ddr_clk = 150, /* 150MHz */
.dmc_ddrctl = 0x00000904,
.dmc_ddrcfg = 0x00000422,
.dmc_ddrtr0 = 0x20A07323,
.dmc_ddrtr1 = 0x20160492,
.dmc_ddrtr2 = 0x00320209,
.dmc_ddrmr = 0x00000632,
.dmc_ddrmr1 = 0x4,
},
[3] = {
.ddr_clk = 166, /* 166MHz */
.dmc_ddrctl = 0x00000904,
.dmc_ddrcfg = 0x00000422,
.dmc_ddrtr0 = 0x20A07323,
.dmc_ddrtr1 = 0x2016050E,
.dmc_ddrtr2 = 0x00320209,
.dmc_ddrmr = 0x00000632,
.dmc_ddrmr1 = 0x4,
},
[4] = {
.ddr_clk = 200, /* 200MHz */
.dmc_ddrctl = 0x00000904,
.dmc_ddrcfg = 0x00000422,
.dmc_ddrtr0 = 0x20a07323,
.dmc_ddrtr1 = 0x2016050f,
.dmc_ddrtr2 = 0x00320509,
.dmc_ddrmr = 0x00000632,
.dmc_ddrmr1 = 0x4,
},
[5] = {
.ddr_clk = 225, /* 225MHz */
.dmc_ddrctl = 0x00000904,
.dmc_ddrcfg = 0x00000422,
.dmc_ddrtr0 = 0x20E0A424,
.dmc_ddrtr1 = 0x302006DB,
.dmc_ddrtr2 = 0x0032020D,
.dmc_ddrmr = 0x00000842,
.dmc_ddrmr1 = 0x4,
},
[6] = {
.ddr_clk = 250, /* 250MHz */
.dmc_ddrctl = 0x00000904,
.dmc_ddrcfg = 0x00000422,
.dmc_ddrtr0 = 0x20E0A424,
.dmc_ddrtr1 = 0x3020079E,
.dmc_ddrtr2 = 0x0032050D,
.dmc_ddrmr = 0x00000842,
.dmc_ddrmr1 = 0x4,
},
};
#endif /* __ADSPBF60x__ */
__attribute__((always_inline)) __attribute__((always_inline))
static inline void serial_init(void) static inline void serial_init(void)
{ {
uint32_t uart_base = UART_DLL; uint32_t uart_base = UART_BASE;
#ifdef __ADSPBF54x__ #if defined(__ADSPBF54x__) || defined(__ADSPBF60x__)
# ifdef BFIN_BOOT_UART_USE_RTS # ifdef BFIN_BOOT_UART_USE_RTS
# define BFIN_UART_USE_RTS 1 # define BFIN_UART_USE_RTS 1
# else # else
@ -38,7 +159,12 @@ static inline void serial_init(void)
size_t i; size_t i;
/* force RTS rather than relying on auto RTS */ /* force RTS rather than relying on auto RTS */
#if BFIN_UART_HW_VER < 4
bfin_write16(&pUART->mcr, bfin_read16(&pUART->mcr) | FCPOL); bfin_write16(&pUART->mcr, bfin_read16(&pUART->mcr) | FCPOL);
#else
bfin_write32(&pUART->control, bfin_read32(&pUART->control) |
FCPOL);
#endif
/* Wait for the line to clear up. We cannot rely on UART /* Wait for the line to clear up. We cannot rely on UART
* registers as none of them reflect the status of the RSR. * registers as none of them reflect the status of the RSR.
@ -68,13 +194,14 @@ static inline void serial_init(void)
#endif #endif
if (BFIN_DEBUG_EARLY_SERIAL) { if (BFIN_DEBUG_EARLY_SERIAL) {
int ucen = bfin_read16(&pUART->gctl) & UCEN; int enabled = serial_early_enabled(uart_base);
serial_early_init(uart_base); serial_early_init(uart_base);
/* If the UART is off, that means we need to program /* If the UART is off, that means we need to program
* the baud rate ourselves initially. * the baud rate ourselves initially.
*/ */
if (ucen != UCEN) if (!enabled)
serial_early_set_baud(uart_base, CONFIG_BAUDRATE); serial_early_set_baud(uart_base, CONFIG_BAUDRATE);
} }
} }
@ -82,12 +209,17 @@ static inline void serial_init(void)
__attribute__((always_inline)) __attribute__((always_inline))
static inline void serial_deinit(void) static inline void serial_deinit(void)
{ {
#ifdef __ADSPBF54x__ #if defined(__ADSPBF54x__) || defined(__ADSPBF60x__)
uint32_t uart_base = UART_DLL; uint32_t uart_base = UART_BASE;
if (BFIN_UART_USE_RTS && CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) { if (BFIN_UART_USE_RTS && CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) {
/* clear forced RTS rather than relying on auto RTS */ /* clear forced RTS rather than relying on auto RTS */
#if BFIN_UART_HW_VER < 4
bfin_write16(&pUART->mcr, bfin_read16(&pUART->mcr) & ~FCPOL); bfin_write16(&pUART->mcr, bfin_read16(&pUART->mcr) & ~FCPOL);
#else
bfin_write32(&pUART->control, bfin_read32(&pUART->control) &
~FCPOL);
#endif
} }
#endif #endif
} }
@ -95,7 +227,7 @@ static inline void serial_deinit(void)
__attribute__((always_inline)) __attribute__((always_inline))
static inline void serial_putc(char c) static inline void serial_putc(char c)
{ {
uint32_t uart_base = UART_DLL; uint32_t uart_base = UART_BASE;
if (!BFIN_DEBUG_EARLY_SERIAL) if (!BFIN_DEBUG_EARLY_SERIAL)
return; return;
@ -103,9 +235,9 @@ static inline void serial_putc(char c)
if (c == '\n') if (c == '\n')
serial_putc('\r'); serial_putc('\r');
bfin_write16(&pUART->thr, c); bfin_write(&pUART->thr, c);
while (!(bfin_read16(&pUART->lsr) & TEMT)) while (!(_lsr_read(pUART) & TEMT))
continue; continue;
} }
@ -152,6 +284,24 @@ program_nmi_handler(void)
# define bfin_write_SPI_BAUD bfin_write_SPI0_BAUD # define bfin_write_SPI_BAUD bfin_write_SPI0_BAUD
#endif #endif
#ifdef __ADSPBF60x__
#ifndef CONFIG_CGU_CTL_VAL
# define CONFIG_CGU_CTL_VAL ((CONFIG_VCO_MULT << 8) | CONFIG_CLKIN_HALF)
#endif
#ifndef CONFIG_CGU_DIV_VAL
# define CONFIG_CGU_DIV_VAL \
((CONFIG_CCLK_DIV << CSEL_P) | \
(CONFIG_SCLK0_DIV << S0SEL_P) | \
(CONFIG_SCLK_DIV << SYSSEL_P) | \
(CONFIG_SCLK1_DIV << S1SEL_P) | \
(CONFIG_DCLK_DIV << DSEL_P) | \
(CONFIG_OCLK_DIV << OSEL_P))
#endif
#else /* __ADSPBF60x__ */
/* PLL_DIV defines */ /* PLL_DIV defines */
#ifndef CONFIG_PLL_DIV_VAL #ifndef CONFIG_PLL_DIV_VAL
# if (CONFIG_CCLK_DIV == 1) # if (CONFIG_CCLK_DIV == 1)
@ -275,6 +425,8 @@ program_nmi_handler(void)
# endif # endif
#endif #endif
#endif /* __ADSPBF60x__ */
__attribute__((always_inline)) static inline void __attribute__((always_inline)) static inline void
program_early_devices(ADI_BOOT_DATA *bs, uint *sdivB, uint *divB, uint *vcoB) program_early_devices(ADI_BOOT_DATA *bs, uint *sdivB, uint *divB, uint *vcoB)
{ {
@ -283,8 +435,14 @@ program_early_devices(ADI_BOOT_DATA *bs, uint *sdivB, uint *divB, uint *vcoB)
/* Save the clock pieces that are used in baud rate calculation */ /* Save the clock pieces that are used in baud rate calculation */
if (BFIN_DEBUG_EARLY_SERIAL || CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) { if (BFIN_DEBUG_EARLY_SERIAL || CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) {
serial_putc('b'); serial_putc('b');
#ifdef __ADSPBF60x__
*sdivB = bfin_read_CGU_DIV();
*sdivB = ((*sdivB >> 8) & 0x1f) * ((*sdivB >> 5) & 0x7);
*vcoB = (bfin_read_CGU_CTL() >> 8) & 0x7f;
#else
*sdivB = bfin_read_PLL_DIV() & 0xf; *sdivB = bfin_read_PLL_DIV() & 0xf;
*vcoB = (bfin_read_PLL_CTL() >> 9) & 0x3f; *vcoB = (bfin_read_PLL_CTL() >> 9) & 0x3f;
#endif
*divB = serial_early_get_div(); *divB = serial_early_get_div();
serial_putc('c'); serial_putc('c');
} }
@ -316,6 +474,7 @@ program_early_devices(ADI_BOOT_DATA *bs, uint *sdivB, uint *divB, uint *vcoB)
* boot. Once we switch over to u-boot's SPI flash driver, we'll * boot. Once we switch over to u-boot's SPI flash driver, we'll
* increase the speed appropriately. * increase the speed appropriately.
*/ */
#ifdef SPI_BAUD
if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_SPI_MASTER) { if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_SPI_MASTER) {
serial_putc('h'); serial_putc('h');
if (BOOTROM_SUPPORTS_SPI_FAST_READ && CONFIG_SPI_BAUD_INITBLOCK < 4) if (BOOTROM_SUPPORTS_SPI_FAST_READ && CONFIG_SPI_BAUD_INITBLOCK < 4)
@ -323,6 +482,7 @@ program_early_devices(ADI_BOOT_DATA *bs, uint *sdivB, uint *divB, uint *vcoB)
bfin_write_SPI_BAUD(CONFIG_SPI_BAUD_INITBLOCK); bfin_write_SPI_BAUD(CONFIG_SPI_BAUD_INITBLOCK);
serial_putc('i'); serial_putc('i');
} }
#endif
serial_putc('j'); serial_putc('j');
} }
@ -335,6 +495,10 @@ maybe_self_refresh(ADI_BOOT_DATA *bs)
if (!CONFIG_MEM_SIZE) if (!CONFIG_MEM_SIZE)
return false; return false;
#ifdef __ADSPBF60x__
#else /* __ADSPBF60x__ */
/* If external memory is enabled, put it into self refresh first. */ /* If external memory is enabled, put it into self refresh first. */
#if defined(EBIU_RSTCTL) #if defined(EBIU_RSTCTL)
if (bfin_read_EBIU_RSTCTL() & DDR_SRESET) { if (bfin_read_EBIU_RSTCTL() & DDR_SRESET) {
@ -350,6 +514,7 @@ maybe_self_refresh(ADI_BOOT_DATA *bs)
} }
#endif #endif
#endif /* __ADSPBF60x__ */
serial_putc('c'); serial_putc('c');
return false; return false;
@ -362,6 +527,37 @@ program_clocks(ADI_BOOT_DATA *bs, bool put_into_srfs)
serial_putc('a'); serial_putc('a');
#ifdef __ADSPBF60x__
if (bfin_read_DMC0_STAT() & MEMINITDONE) {
bfin_write_DMC0_CTL(bfin_read_DMC0_CTL() | SRREQ);
SSYNC();
while (!(bfin_read_DMC0_STAT() & SRACK))
continue;
}
/* Don't set the same value of MSEL and DF to CGU_CTL */
if ((bfin_read_CGU_CTL() & (MSEL_MASK | DF_MASK))
!= CONFIG_CGU_CTL_VAL) {
bfin_write_CGU_DIV(CONFIG_CGU_DIV_VAL);
bfin_write_CGU_CTL(CONFIG_CGU_CTL_VAL);
while ((bfin_read_CGU_STAT() & (CLKSALGN | PLLBP)) ||
!(bfin_read_CGU_STAT() & PLLLK))
continue;
}
bfin_write_CGU_DIV(CONFIG_CGU_DIV_VAL | UPDT);
while (bfin_read_CGU_STAT() & CLKSALGN)
continue;
if (bfin_read_DMC0_STAT() & MEMINITDONE) {
bfin_write_DMC0_CTL(bfin_read_DMC0_CTL() & ~SRREQ);
SSYNC();
while (bfin_read_DMC0_STAT() & SRACK)
continue;
}
#else /* __ADSPBF60x__ */
vr_ctl = bfin_read_VR_CTL(); vr_ctl = bfin_read_VR_CTL();
serial_putc('b'); serial_putc('b');
@ -433,7 +629,7 @@ program_clocks(ADI_BOOT_DATA *bs, bool put_into_srfs)
#elif defined(SICA_IWR0) #elif defined(SICA_IWR0)
bfin_write_SICA_IWR0(1); bfin_write_SICA_IWR0(1);
bfin_write_SICA_IWR1(0); bfin_write_SICA_IWR1(0);
#else #elif defined(SIC_IWR)
bfin_write_SIC_IWR(1); bfin_write_SIC_IWR(1);
#endif #endif
@ -482,13 +678,15 @@ program_clocks(ADI_BOOT_DATA *bs, bool put_into_srfs)
#elif defined(SICA_IWR0) #elif defined(SICA_IWR0)
bfin_write_SICA_IWR0(-1); bfin_write_SICA_IWR0(-1);
bfin_write_SICA_IWR1(-1); bfin_write_SICA_IWR1(-1);
#else #elif defined(SIC_IWR)
bfin_write_SIC_IWR(-1); bfin_write_SIC_IWR(-1);
#endif #endif
serial_putc('n'); serial_putc('n');
} }
#endif /* __ADSPBF60x__ */
serial_putc('o'); serial_putc('o');
return vr_ctl; return vr_ctl;
@ -505,16 +703,25 @@ update_serial_clocks(ADI_BOOT_DATA *bs, uint sdivB, uint divB, uint vcoB)
* for dividing which means we'd generate a libgcc reference. * for dividing which means we'd generate a libgcc reference.
*/ */
if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) { if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) {
serial_putc('b');
unsigned int sdivR, vcoR; unsigned int sdivR, vcoR;
sdivR = bfin_read_PLL_DIV() & 0xf;
vcoR = (bfin_read_PLL_CTL() >> 9) & 0x3f;
int dividend = sdivB * divB * vcoR; int dividend = sdivB * divB * vcoR;
int divisor = vcoB * sdivR; int divisor = vcoB * sdivR;
unsigned int quotient; unsigned int quotient;
serial_putc('b');
#ifdef __ADSPBF60x__
sdivR = bfin_read_CGU_DIV();
sdivR = ((sdivR >> 8) & 0x1f) * ((sdivR >> 5) & 0x7);
vcoR = (bfin_read_CGU_CTL() >> 8) & 0x7f;
#else
sdivR = bfin_read_PLL_DIV() & 0xf;
vcoR = (bfin_read_PLL_CTL() >> 9) & 0x3f;
#endif
for (quotient = 0; dividend > 0; ++quotient) for (quotient = 0; dividend > 0; ++quotient)
dividend -= divisor; dividend -= divisor;
serial_early_put_div(UART_DLL, quotient - ANOMALY_05000230); serial_early_put_div(quotient - ANOMALY_05000230);
serial_putc('c'); serial_putc('c');
} }
@ -531,6 +738,84 @@ program_memory_controller(ADI_BOOT_DATA *bs, bool put_into_srfs)
serial_putc('b'); serial_putc('b');
#ifdef __ADSPBF60x__
int dlldatacycle;
int dll_ctl;
int i = 0;
if (CONFIG_BFIN_GET_DCLK_M == 125)
i = 0;
else if (CONFIG_BFIN_GET_DCLK_M == 133)
i = 1;
else if (CONFIG_BFIN_GET_DCLK_M == 150)
i = 2;
else if (CONFIG_BFIN_GET_DCLK_M == 166)
i = 3;
else if (CONFIG_BFIN_GET_DCLK_M == 200)
i = 4;
else if (CONFIG_BFIN_GET_DCLK_M == 225)
i = 5;
else if (CONFIG_BFIN_GET_DCLK_M == 250)
i = 6;
#if 0
for (i = 0; i < ARRAY_SIZE(ddr_config_table); i++)
if (CONFIG_BFIN_GET_DCLK_M == ddr_config_table[i].ddr_clk)
break;
#endif
#ifndef CONFIG_DMC_DDRCFG
bfin_write_DMC0_CFG(ddr_config_table[i].dmc_ddrcfg);
#else
bfin_write_DMC0_CFG(CONFIG_DMC_DDRCFG);
#endif
#ifndef CONFIG_DMC_DDRTR0
bfin_write_DMC0_TR0(ddr_config_table[i].dmc_ddrtr0);
#else
bfin_write_DMC0_TR0(CONFIG_DMC_DDRTR0);
#endif
#ifndef CONFIG_DMC_DDRTR1
bfin_write_DMC0_TR1(ddr_config_table[i].dmc_ddrtr1);
#else
bfin_write_DMC0_TR1(CONFIG_DMC_DDRTR1);
#endif
#ifndef CONFIG_DMC_DDRTR2
bfin_write_DMC0_TR2(ddr_config_table[i].dmc_ddrtr2);
#else
bfin_write_DMC0_TR2(CONFIG_DMC_DDRTR2);
#endif
#ifndef CONFIG_DMC_DDRMR
bfin_write_DMC0_MR(ddr_config_table[i].dmc_ddrmr);
#else
bfin_write_DMC0_MR(CONFIG_DMC_DDRMR);
#endif
#ifndef CONFIG_DMC_DDREMR1
bfin_write_DMC0_EMR1(ddr_config_table[i].dmc_ddrmr1);
#else
bfin_write_DMC0_EMR1(CONFIG_DMC_DDREMR1);
#endif
#ifndef CONFIG_DMC_DDRCTL
bfin_write_DMC0_CTL(ddr_config_table[i].dmc_ddrctl);
#else
bfin_write_DMC0_CTL(CONFIG_DMC_DDRCTL);
#endif
SSYNC();
while (!(bfin_read_DMC0_STAT() & MEMINITDONE))
continue;
dlldatacycle = (bfin_read_DMC0_STAT() & PHYRDPHASE) >>
PHYRDPHASE_OFFSET;
dll_ctl = bfin_read_DMC0_DLLCTL();
dll_ctl &= 0x0ff;
bfin_write_DMC0_DLLCTL(dll_ctl | (dlldatacycle << DATACYC_OFFSET));
SSYNC();
while (!(bfin_read_DMC0_STAT() & DLLCALDONE))
continue;
serial_putc('!');
#else /* __ADSPBF60x__ */
/* Program the external memory controller before we come out of /* Program the external memory controller before we come out of
* self-refresh. This only works with our SDRAM controller. * self-refresh. This only works with our SDRAM controller.
*/ */
@ -583,6 +868,7 @@ program_memory_controller(ADI_BOOT_DATA *bs, bool put_into_srfs)
# endif # endif
#endif #endif
#endif /* __ADSPBF60x__ */
serial_putc('e'); serial_putc('e');
} }
@ -606,7 +892,8 @@ check_hibernation(ADI_BOOT_DATA *bs, u16 vr_ctl, bool put_into_srfs)
*/ */
if (ANOMALY_05000307 || vr_ctl & 0x8000) { if (ANOMALY_05000307 || vr_ctl & 0x8000) {
uint32_t *hibernate_magic = 0; uint32_t *hibernate_magic = 0;
__builtin_bfin_ssync(); /* make sure memory controller is done */
SSYNC();
if (hibernate_magic[0] == 0xDEADBEEF) { if (hibernate_magic[0] == 0xDEADBEEF) {
serial_putc('c'); serial_putc('c');
bfin_write_EVT15(hibernate_magic[1]); bfin_write_EVT15(hibernate_magic[1]);

@ -15,6 +15,8 @@
# define serial_putc(c) # define serial_putc(c)
#endif #endif
#ifndef __ADSPBF60x__
#ifndef CONFIG_EBIU_RSTCTL_VAL #ifndef CONFIG_EBIU_RSTCTL_VAL
# define CONFIG_EBIU_RSTCTL_VAL 0 /* only MDDRENABLE is useful */ # define CONFIG_EBIU_RSTCTL_VAL 0 /* only MDDRENABLE is useful */
#endif #endif
@ -30,6 +32,8 @@
# error invalid EBIU_DDRQUE value: must not set reserved bits # error invalid EBIU_DDRQUE value: must not set reserved bits
#endif #endif
#endif /* __ADSPBF60x__ */
__attribute__((always_inline)) static inline void __attribute__((always_inline)) static inline void
program_async_controller(ADI_BOOT_DATA *bs) program_async_controller(ADI_BOOT_DATA *bs)
{ {
@ -45,10 +49,13 @@ program_async_controller(ADI_BOOT_DATA *bs)
serial_putc('a'); serial_putc('a');
#ifdef __ADSPBF60x__
/* Program the async banks controller. */ /* Program the async banks controller. */
#ifdef EBIU_AMGCTL
bfin_write_EBIU_AMBCTL0(CONFIG_EBIU_AMBCTL0_VAL); bfin_write_EBIU_AMBCTL0(CONFIG_EBIU_AMBCTL0_VAL);
bfin_write_EBIU_AMBCTL1(CONFIG_EBIU_AMBCTL1_VAL); bfin_write_EBIU_AMBCTL1(CONFIG_EBIU_AMBCTL1_VAL);
bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL); bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL);
#endif
serial_putc('b'); serial_putc('b');
@ -66,6 +73,51 @@ program_async_controller(ADI_BOOT_DATA *bs)
#endif #endif
serial_putc('c'); serial_putc('c');
#else /* __ADSPBF60x__ */
/* Program the static memory controller. */
# ifdef CONFIG_SMC_GCTL_VAL
bfin_write_SMC_GCTL(CONFIG_SMC_GCTL_VAL);
# endif
# ifdef CONFIG_SMC_B0CTL_VAL
bfin_write_SMC_B0CTL(CONFIG_SMC_B0CTL_VAL);
# endif
# ifdef CONFIG_SMC_B0TIM_VAL
bfin_write_SMC_B0TIM(CONFIG_SMC_B0TIM_VAL);
# endif
# ifdef CONFIG_SMC_B0ETIM_VAL
bfin_write_SMC_B0ETIM(CONFIG_SMC_B0ETIM_VAL);
# endif
# ifdef CONFIG_SMC_B1CTL_VAL
bfin_write_SMC_B1CTL(CONFIG_SMC_B1CTL_VAL);
# endif
# ifdef CONFIG_SMC_B1TIM_VAL
bfin_write_SMC_B1TIM(CONFIG_SMC_B1TIM_VAL);
# endif
# ifdef CONFIG_SMC_B1ETIM_VAL
bfin_write_SMC_B1ETIM(CONFIG_SMC_B1ETIM_VAL);
# endif
# ifdef CONFIG_SMC_B2CTL_VAL
bfin_write_SMC_B2CTL(CONFIG_SMC_B2CTL_VAL);
# endif
# ifdef CONFIG_SMC_B2TIM_VAL
bfin_write_SMC_B2TIM(CONFIG_SMC_B2TIM_VAL);
# endif
# ifdef CONFIG_SMC_B2ETIM_VAL
bfin_write_SMC_B2ETIM(CONFIG_SMC_B2ETIM_VAL);
# endif
# ifdef CONFIG_SMC_B3CTL_VAL
bfin_write_SMC_B3CTL(CONFIG_SMC_B3CTL_VAL);
# endif
# ifdef CONFIG_SMC_B3TIM_VAL
bfin_write_SMC_B3TIM(CONFIG_SMC_B3TIM_VAL);
# endif
# ifdef CONFIG_SMC_B3ETIM_VAL
bfin_write_SMC_B3ETIM(CONFIG_SMC_B3ETIM_VAL);
# endif
#endif
serial_putc('d');
} }
#endif #endif

@ -23,6 +23,7 @@
__attribute__ ((__l1_text__, __noreturn__)) __attribute__ ((__l1_text__, __noreturn__))
static void bfin_reset(void) static void bfin_reset(void)
{ {
#ifdef SWRST
/* Wait for completion of "system" events such as cache line /* Wait for completion of "system" events such as cache line
* line fills so that we avoid infinite stalls later on as * line fills so that we avoid infinite stalls later on as
* much as possible. This code is in L1, so it won't trigger * much as possible. This code is in L1, so it won't trigger
@ -66,10 +67,15 @@ static void bfin_reset(void)
: "a" (15 * 1) : "a" (15 * 1)
: "LC1", "LB1", "LT1" : "LC1", "LB1", "LT1"
); );
#endif
while (1) while (1)
#if defined(__ADSPBF60x__)
bfin_write_RCU0_CTL(0x1);
#else
/* Issue core reset */ /* Issue core reset */
asm("raise 1"); asm("raise 1");
#endif
} }
/* We need to trampoline ourselves up into L1 since our linker /* We need to trampoline ourselves up into L1 since our linker

@ -29,6 +29,8 @@
#define BFIN_BOOT_16HOST_DMA 11 /* boot ldr from 16-bit host dma */ #define BFIN_BOOT_16HOST_DMA 11 /* boot ldr from 16-bit host dma */
#define BFIN_BOOT_8HOST_DMA 12 /* boot ldr from 8-bit host dma */ #define BFIN_BOOT_8HOST_DMA 12 /* boot ldr from 8-bit host dma */
#define BFIN_BOOT_NAND 13 /* boot ldr from nand flash */ #define BFIN_BOOT_NAND 13 /* boot ldr from nand flash */
#define BFIN_BOOT_RSI_MASTER 14 /* boot ldr from rsi */
#define BFIN_BOOT_LP_SLAVE 15 /* boot ldr from link port */
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
static inline const char *get_bfin_boot_mode(int bfin_boot) static inline const char *get_bfin_boot_mode(int bfin_boot)
@ -47,6 +49,8 @@ static inline const char *get_bfin_boot_mode(int bfin_boot)
case BFIN_BOOT_16HOST_DMA: return "16bit dma"; case BFIN_BOOT_16HOST_DMA: return "16bit dma";
case BFIN_BOOT_8HOST_DMA: return "8bit dma"; case BFIN_BOOT_8HOST_DMA: return "8bit dma";
case BFIN_BOOT_NAND: return "nand flash"; case BFIN_BOOT_NAND: return "nand flash";
case BFIN_BOOT_RSI_MASTER: return "rsi master";
case BFIN_BOOT_LP_SLAVE: return "link port slave";
default: return "INVALID"; default: return "INVALID";
} }
} }

@ -295,7 +295,13 @@ void board_init_f(ulong bootflag)
printf("Clock: VCO: %s MHz, ", strmhz(buf, get_vco())); printf("Clock: VCO: %s MHz, ", strmhz(buf, get_vco()));
printf("Core: %s MHz, ", strmhz(buf, get_cclk())); printf("Core: %s MHz, ", strmhz(buf, get_cclk()));
#if defined(__ADSPBF60x__)
printf("System0: %s MHz, ", strmhz(buf, get_sclk0()));
printf("System1: %s MHz, ", strmhz(buf, get_sclk1()));
printf("Dclk: %s MHz\n", strmhz(buf, get_dclk()));
#else
printf("System: %s MHz\n", strmhz(buf, get_sclk())); printf("System: %s MHz\n", strmhz(buf, get_sclk()));
#endif
if (CONFIG_MEM_SIZE) { if (CONFIG_MEM_SIZE) {
printf("RAM: "); printf("RAM: ");

@ -9,69 +9,139 @@
#include <common.h> #include <common.h>
#include <asm/blackfin.h> #include <asm/blackfin.h>
#ifdef PLL_CTL
# include <asm/mach-common/bits/pll.h>
# define pll_is_bypassed() (bfin_read_PLL_STAT() & DF)
#else
# include <asm/mach-common/bits/cgu.h>
# define pll_is_bypassed() (bfin_read_CGU_STAT() & PLLBP)
# define bfin_read_PLL_CTL() bfin_read_CGU_CTL()
# define bfin_read_PLL_DIV() bfin_read_CGU_DIV()
#endif
/* Get the voltage input multiplier */ /* Get the voltage input multiplier */
static u_long cached_vco_pll_ctl, cached_vco;
u_long get_vco(void) u_long get_vco(void)
{ {
u_long msel; static u_long cached_vco_pll_ctl, cached_vco;
u_long msel, pll_ctl;
u_long pll_ctl = bfin_read_PLL_CTL(); pll_ctl = bfin_read_PLL_CTL();
if (pll_ctl == cached_vco_pll_ctl) if (pll_ctl == cached_vco_pll_ctl)
return cached_vco; return cached_vco;
else else
cached_vco_pll_ctl = pll_ctl; cached_vco_pll_ctl = pll_ctl;
msel = (pll_ctl >> 9) & 0x3F; msel = (pll_ctl & MSEL) >> MSEL_P;
if (0 == msel) if (0 == msel)
msel = 64; msel = (MSEL >> MSEL_P) + 1;
cached_vco = CONFIG_CLKIN_HZ; cached_vco = CONFIG_CLKIN_HZ;
cached_vco >>= (1 & pll_ctl); /* DF bit */ cached_vco >>= (pll_ctl & DF);
cached_vco *= msel; cached_vco *= msel;
return cached_vco; return cached_vco;
} }
/* Get the Core clock */ /* Get the Core clock */
static u_long cached_cclk_pll_div, cached_cclk;
u_long get_cclk(void) u_long get_cclk(void)
{ {
u_long csel, ssel; static u_long cached_cclk_pll_div, cached_cclk;
u_long div, csel, ssel;
if (bfin_read_PLL_STAT() & 0x1) if (pll_is_bypassed())
return CONFIG_CLKIN_HZ; return CONFIG_CLKIN_HZ;
ssel = bfin_read_PLL_DIV(); div = bfin_read_PLL_DIV();
if (ssel == cached_cclk_pll_div) if (div == cached_cclk_pll_div)
return cached_cclk; return cached_cclk;
else else
cached_cclk_pll_div = ssel; cached_cclk_pll_div = div;
csel = ((ssel >> 4) & 0x03); csel = (div & CSEL) >> CSEL_P;
ssel &= 0xf; #ifndef CGU_DIV
ssel = (div & SSEL) >> SSEL_P;
if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */ if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */
cached_cclk = get_vco() / ssel; cached_cclk = get_vco() / ssel;
else else
cached_cclk = get_vco() >> csel; cached_cclk = get_vco() >> csel;
#else
cached_cclk = get_vco() / csel;
#endif
return cached_cclk; return cached_cclk;
} }
/* Get the System clock */ /* Get the System clock */
#ifdef CGU_DIV
static u_long cached_sclk_pll_div, cached_sclk; static u_long cached_sclk_pll_div, cached_sclk;
static u_long cached_sclk0, cached_sclk1, cached_dclk;
static u_long _get_sclk(u_long *cache)
{
u_long div, ssel;
if (pll_is_bypassed())
return CONFIG_CLKIN_HZ;
div = bfin_read_PLL_DIV();
if (div == cached_sclk_pll_div)
return *cache;
else
cached_sclk_pll_div = div;
ssel = (div & SYSSEL) >> SYSSEL_P;
cached_sclk = get_vco() / ssel;
ssel = (div & S0SEL) >> S0SEL_P;
cached_sclk0 = cached_sclk / ssel;
ssel = (div & S1SEL) >> S1SEL_P;
cached_sclk1 = cached_sclk / ssel;
ssel = (div & DSEL) >> DSEL_P;
cached_dclk = get_vco() / ssel;
return *cache;
}
u_long get_sclk(void) u_long get_sclk(void)
{ {
u_long ssel; return _get_sclk(&cached_sclk);
}
u_long get_sclk0(void)
{
return _get_sclk(&cached_sclk0);
}
u_long get_sclk1(void)
{
return _get_sclk(&cached_sclk1);
}
u_long get_dclk(void)
{
return _get_sclk(&cached_dclk);
}
#else
u_long get_sclk(void)
{
static u_long cached_sclk_pll_div, cached_sclk;
u_long div, ssel;
if (bfin_read_PLL_STAT() & 0x1) if (pll_is_bypassed())
return CONFIG_CLKIN_HZ; return CONFIG_CLKIN_HZ;
ssel = bfin_read_PLL_DIV(); div = bfin_read_PLL_DIV();
if (ssel == cached_sclk_pll_div) if (div == cached_sclk_pll_div)
return cached_sclk; return cached_sclk;
else else
cached_sclk_pll_div = ssel; cached_sclk_pll_div = div;
ssel &= 0xf;
ssel = (div & SSEL) >> SSEL_P;
cached_sclk = get_vco() / ssel; cached_sclk = get_vco() / ssel;
return cached_sclk; return cached_sclk;
} }
#endif

@ -191,7 +191,7 @@ static int do_reginfo(cmd_tbl_t *cmdtp, int flag, int argc,
#elif defined(CONFIG_BLACKFIN) #elif defined(CONFIG_BLACKFIN)
puts("\nSystem Configuration registers\n"); puts("\nSystem Configuration registers\n");
#ifndef __ADSPBF60x__
puts("\nPLL Registers\n"); puts("\nPLL Registers\n");
printf("\tPLL_DIV: 0x%04x PLL_CTL: 0x%04x\n", printf("\tPLL_DIV: 0x%04x PLL_CTL: 0x%04x\n",
bfin_read_PLL_DIV(), bfin_read_PLL_CTL()); bfin_read_PLL_DIV(), bfin_read_PLL_CTL());
@ -227,7 +227,24 @@ static int do_reginfo(cmd_tbl_t *cmdtp, int flag, int argc,
printf("\tEBIU_SDSTAT: 0x%04x EBIU_SDGCTL: 0x%08x\n", printf("\tEBIU_SDSTAT: 0x%04x EBIU_SDGCTL: 0x%08x\n",
bfin_read_EBIU_SDSTAT(), bfin_read_EBIU_SDGCTL()); bfin_read_EBIU_SDSTAT(), bfin_read_EBIU_SDGCTL());
# endif # endif
#else
puts("\nCGU Registers\n");
printf("\tCGU_DIV: 0x%08x CGU_CTL: 0x%08x\n",
bfin_read_CGU_DIV(), bfin_read_CGU_CTL());
printf("\tCGU_STAT: 0x%08x CGU_LOCKCNT: 0x%08x\n",
bfin_read_CGU_STAT(), bfin_read_CGU_CLKOUTSEL());
puts("\nSMC DDR Registers\n");
printf("\tDDR_CFG: 0x%08x DDR_TR0: 0x%08x\n",
bfin_read_DMC0_CFG(), bfin_read_DMC0_TR0());
printf("\tDDR_TR1: 0x%08x DDR_TR2: 0x%08x\n",
bfin_read_DMC0_TR1(), bfin_read_DMC0_TR2());
printf("\tDDR_MR: 0x%08x DDR_EMR1: 0x%08x\n",
bfin_read_DMC0_MR(), bfin_read_DMC0_EMR1());
printf("\tDDR_CTL: 0x%08x DDR_STAT: 0x%08x\n",
bfin_read_DMC0_CTL(), bfin_read_DMC0_STAT());
printf("\tDDR_DLLCTL:0x%08x\n", bfin_read_DMC0_DLLCTL());
#endif
#endif /* CONFIG_BLACKFIN */ #endif /* CONFIG_BLACKFIN */
return 0; return 0;

Loading…
Cancel
Save