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.
* Do not do bfin_read on SWRST as that will reset status bits.
*/
# ifdef SWRST
bfin_write_SWRST(DOUBLE_FAULT);
# endif
#endif
serial_early_puts("Board init flash\n");
@ -92,7 +94,7 @@ int irq_init(void)
#elif defined(SICA_IMASK0)
bfin_write_SICA_IMASK0(0);
bfin_write_SICA_IMASK1(0);
#else
#elif defined(SIC_IMASK)
bfin_write_SIC_IMASK(0);
#endif
/* Set up a dummy NMI handler if needed. */

@ -15,20 +15,141 @@
#include <asm/blackfin.h>
#include <asm/mach-common/bits/bootrom.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;"); }
#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))
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
# define BFIN_UART_USE_RTS 1
# else
@ -38,7 +159,12 @@ static inline void serial_init(void)
size_t i;
/* force RTS rather than relying on auto RTS */
#if BFIN_UART_HW_VER < 4
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
* registers as none of them reflect the status of the RSR.
@ -68,13 +194,14 @@ static inline void serial_init(void)
#endif
if (BFIN_DEBUG_EARLY_SERIAL) {
int ucen = bfin_read16(&pUART->gctl) & UCEN;
int enabled = serial_early_enabled(uart_base);
serial_early_init(uart_base);
/* If the UART is off, that means we need to program
* the baud rate ourselves initially.
*/
if (ucen != UCEN)
if (!enabled)
serial_early_set_baud(uart_base, CONFIG_BAUDRATE);
}
}
@ -82,12 +209,17 @@ static inline void serial_init(void)
__attribute__((always_inline))
static inline void serial_deinit(void)
{
#ifdef __ADSPBF54x__
uint32_t uart_base = UART_DLL;
#if defined(__ADSPBF54x__) || defined(__ADSPBF60x__)
uint32_t uart_base = UART_BASE;
if (BFIN_UART_USE_RTS && CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) {
/* clear forced RTS rather than relying on auto RTS */
#if BFIN_UART_HW_VER < 4
bfin_write16(&pUART->mcr, bfin_read16(&pUART->mcr) & ~FCPOL);
#else
bfin_write32(&pUART->control, bfin_read32(&pUART->control) &
~FCPOL);
#endif
}
#endif
}
@ -95,7 +227,7 @@ static inline void serial_deinit(void)
__attribute__((always_inline))
static inline void serial_putc(char c)
{
uint32_t uart_base = UART_DLL;
uint32_t uart_base = UART_BASE;
if (!BFIN_DEBUG_EARLY_SERIAL)
return;
@ -103,9 +235,9 @@ static inline void serial_putc(char c)
if (c == '\n')
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;
}
@ -152,6 +284,24 @@ program_nmi_handler(void)
# define bfin_write_SPI_BAUD bfin_write_SPI0_BAUD
#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 */
#ifndef CONFIG_PLL_DIV_VAL
# if (CONFIG_CCLK_DIV == 1)
@ -275,6 +425,8 @@ program_nmi_handler(void)
# endif
#endif
#endif /* __ADSPBF60x__ */
__attribute__((always_inline)) static inline void
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 */
if (BFIN_DEBUG_EARLY_SERIAL || CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) {
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;
*vcoB = (bfin_read_PLL_CTL() >> 9) & 0x3f;
#endif
*divB = serial_early_get_div();
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
* increase the speed appropriately.
*/
#ifdef SPI_BAUD
if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_SPI_MASTER) {
serial_putc('h');
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);
serial_putc('i');
}
#endif
serial_putc('j');
}
@ -335,6 +495,10 @@ maybe_self_refresh(ADI_BOOT_DATA *bs)
if (!CONFIG_MEM_SIZE)
return false;
#ifdef __ADSPBF60x__
#else /* __ADSPBF60x__ */
/* If external memory is enabled, put it into self refresh first. */
#if defined(EBIU_RSTCTL)
if (bfin_read_EBIU_RSTCTL() & DDR_SRESET) {
@ -350,6 +514,7 @@ maybe_self_refresh(ADI_BOOT_DATA *bs)
}
#endif
#endif /* __ADSPBF60x__ */
serial_putc('c');
return false;
@ -362,6 +527,37 @@ program_clocks(ADI_BOOT_DATA *bs, bool put_into_srfs)
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();
serial_putc('b');
@ -433,7 +629,7 @@ program_clocks(ADI_BOOT_DATA *bs, bool put_into_srfs)
#elif defined(SICA_IWR0)
bfin_write_SICA_IWR0(1);
bfin_write_SICA_IWR1(0);
#else
#elif defined(SIC_IWR)
bfin_write_SIC_IWR(1);
#endif
@ -482,13 +678,15 @@ program_clocks(ADI_BOOT_DATA *bs, bool put_into_srfs)
#elif defined(SICA_IWR0)
bfin_write_SICA_IWR0(-1);
bfin_write_SICA_IWR1(-1);
#else
#elif defined(SIC_IWR)
bfin_write_SIC_IWR(-1);
#endif
serial_putc('n');
}
#endif /* __ADSPBF60x__ */
serial_putc('o');
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.
*/
if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_UART) {
serial_putc('b');
unsigned int sdivR, vcoR;
sdivR = bfin_read_PLL_DIV() & 0xf;
vcoR = (bfin_read_PLL_CTL() >> 9) & 0x3f;
int dividend = sdivB * divB * vcoR;
int divisor = vcoB * sdivR;
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)
dividend -= divisor;
serial_early_put_div(UART_DLL, quotient - ANOMALY_05000230);
serial_early_put_div(quotient - ANOMALY_05000230);
serial_putc('c');
}
@ -531,6 +738,84 @@ program_memory_controller(ADI_BOOT_DATA *bs, bool put_into_srfs)
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
* 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 /* __ADSPBF60x__ */
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) {
uint32_t *hibernate_magic = 0;
__builtin_bfin_ssync(); /* make sure memory controller is done */
SSYNC();
if (hibernate_magic[0] == 0xDEADBEEF) {
serial_putc('c');
bfin_write_EVT15(hibernate_magic[1]);

@ -15,6 +15,8 @@
# define serial_putc(c)
#endif
#ifndef __ADSPBF60x__
#ifndef CONFIG_EBIU_RSTCTL_VAL
# define CONFIG_EBIU_RSTCTL_VAL 0 /* only MDDRENABLE is useful */
#endif
@ -30,6 +32,8 @@
# error invalid EBIU_DDRQUE value: must not set reserved bits
#endif
#endif /* __ADSPBF60x__ */
__attribute__((always_inline)) static inline void
program_async_controller(ADI_BOOT_DATA *bs)
{
@ -45,10 +49,13 @@ program_async_controller(ADI_BOOT_DATA *bs)
serial_putc('a');
#ifdef __ADSPBF60x__
/* Program the async banks controller. */
#ifdef EBIU_AMGCTL
bfin_write_EBIU_AMBCTL0(CONFIG_EBIU_AMBCTL0_VAL);
bfin_write_EBIU_AMBCTL1(CONFIG_EBIU_AMBCTL1_VAL);
bfin_write_EBIU_AMGCTL(CONFIG_EBIU_AMGCTL_VAL);
#endif
serial_putc('b');
@ -66,6 +73,51 @@ program_async_controller(ADI_BOOT_DATA *bs)
#endif
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

@ -23,6 +23,7 @@
__attribute__ ((__l1_text__, __noreturn__))
static void bfin_reset(void)
{
#ifdef SWRST
/* Wait for completion of "system" events such as cache line
* line fills so that we avoid infinite stalls later on as
* 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)
: "LC1", "LB1", "LT1"
);
#endif
while (1)
#if defined(__ADSPBF60x__)
bfin_write_RCU0_CTL(0x1);
#else
/* Issue core reset */
asm("raise 1");
#endif
}
/* 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_8HOST_DMA 12 /* boot ldr from 8-bit host dma */
#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__
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_8HOST_DMA: return "8bit dma";
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";
}
}

@ -295,7 +295,13 @@ void board_init_f(ulong bootflag)
printf("Clock: VCO: %s MHz, ", strmhz(buf, get_vco()));
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()));
#endif
if (CONFIG_MEM_SIZE) {
printf("RAM: ");

@ -9,69 +9,139 @@
#include <common.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 */
static u_long cached_vco_pll_ctl, cached_vco;
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)
return cached_vco;
else
cached_vco_pll_ctl = pll_ctl;
msel = (pll_ctl >> 9) & 0x3F;
msel = (pll_ctl & MSEL) >> MSEL_P;
if (0 == msel)
msel = 64;
msel = (MSEL >> MSEL_P) + 1;
cached_vco = CONFIG_CLKIN_HZ;
cached_vco >>= (1 & pll_ctl); /* DF bit */
cached_vco >>= (pll_ctl & DF);
cached_vco *= msel;
return cached_vco;
}
/* Get the Core clock */
static u_long cached_cclk_pll_div, cached_cclk;
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;
ssel = bfin_read_PLL_DIV();
if (ssel == cached_cclk_pll_div)
div = bfin_read_PLL_DIV();
if (div == cached_cclk_pll_div)
return cached_cclk;
else
cached_cclk_pll_div = ssel;
cached_cclk_pll_div = div;
csel = ((ssel >> 4) & 0x03);
ssel &= 0xf;
csel = (div & CSEL) >> CSEL_P;
#ifndef CGU_DIV
ssel = (div & SSEL) >> SSEL_P;
if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */
cached_cclk = get_vco() / ssel;
else
cached_cclk = get_vco() >> csel;
#else
cached_cclk = get_vco() / csel;
#endif
return cached_cclk;
}
/* Get the System clock */
#ifdef CGU_DIV
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 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;
ssel = bfin_read_PLL_DIV();
if (ssel == cached_sclk_pll_div)
div = bfin_read_PLL_DIV();
if (div == cached_sclk_pll_div)
return cached_sclk;
else
cached_sclk_pll_div = ssel;
ssel &= 0xf;
cached_sclk_pll_div = div;
ssel = (div & SSEL) >> SSEL_P;
cached_sclk = get_vco() / ssel;
return cached_sclk;
}
#endif

@ -191,7 +191,7 @@ static int do_reginfo(cmd_tbl_t *cmdtp, int flag, int argc,
#elif defined(CONFIG_BLACKFIN)
puts("\nSystem Configuration registers\n");
#ifndef __ADSPBF60x__
puts("\nPLL Registers\n");
printf("\tPLL_DIV: 0x%04x PLL_CTL: 0x%04x\n",
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",
bfin_read_EBIU_SDSTAT(), bfin_read_EBIU_SDGCTL());
# 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 */
return 0;

Loading…
Cancel
Save