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>
This commit is contained in:
parent
3ead92c571
commit
a2979dcdbe
8 changed files with 489 additions and 45 deletions
|
@ -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 pll_ctl = bfin_read_PLL_CTL();
|
||||
u_long msel, 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 */
|
||||
static u_long cached_sclk_pll_div, cached_sclk;
|
||||
u_long get_sclk(void)
|
||||
{
|
||||
u_long ssel;
|
||||
#ifdef CGU_DIV
|
||||
|
||||
if (bfin_read_PLL_STAT() & 0x1)
|
||||
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;
|
||||
|
||||
ssel = bfin_read_PLL_DIV();
|
||||
if (ssel == cached_sclk_pll_div)
|
||||
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)
|
||||
{
|
||||
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 (pll_is_bypassed())
|
||||
return CONFIG_CLKIN_HZ;
|
||||
|
||||
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…
Reference in a new issue