@ -10,8 +10,11 @@
# include <asm/arch/clock.h>
# include <asm/arch/clk.h>
# include <asm/arch/dmc.h>
# include <asm/arch/periph.h>
# include <asm/arch/pinmux.h>
# include <asm/arch/power.h>
# include <asm/arch/spl.h>
# include <asm/arch/spi.h>
# include "common_setup.h"
# include "clock_init.h"
@ -59,6 +62,119 @@ static int config_branch_prediction(int set_cr_z)
}
# endif
static void spi_rx_tx ( struct exynos_spi * regs , int todo ,
void * dinp , void const * doutp , int i )
{
uint * rxp = ( uint * ) ( dinp + ( i * ( 32 * 1024 ) ) ) ;
int rx_lvl , tx_lvl ;
uint out_bytes , in_bytes ;
out_bytes = todo ;
in_bytes = todo ;
setbits_le32 ( & regs - > ch_cfg , SPI_CH_RST ) ;
clrbits_le32 ( & regs - > ch_cfg , SPI_CH_RST ) ;
writel ( ( ( todo * 8 ) / 32 ) | SPI_PACKET_CNT_EN , & regs - > pkt_cnt ) ;
while ( in_bytes ) {
uint32_t spi_sts ;
int temp ;
spi_sts = readl ( & regs - > spi_sts ) ;
rx_lvl = ( ( spi_sts > > 15 ) & 0x7f ) ;
tx_lvl = ( ( spi_sts > > 6 ) & 0x7f ) ;
while ( tx_lvl < 32 & & out_bytes ) {
temp = 0xffffffff ;
writel ( temp , & regs - > tx_data ) ;
out_bytes - = 4 ;
tx_lvl + = 4 ;
}
while ( rx_lvl > = 4 & & in_bytes ) {
temp = readl ( & regs - > rx_data ) ;
if ( rxp )
* rxp + + = temp ;
in_bytes - = 4 ;
rx_lvl - = 4 ;
}
}
}
/*
* Copy uboot from spi flash to RAM
*
* @ parma uboot_size size of u - boot to copy
* @ param uboot_addr address in u - boot to copy
*/
static void exynos_spi_copy ( unsigned int uboot_size , unsigned int uboot_addr )
{
int upto , todo ;
int i , timeout = 100 ;
struct exynos_spi * regs = ( struct exynos_spi * ) CONFIG_ENV_SPI_BASE ;
set_spi_clk ( PERIPH_ID_SPI1 , 50000000 ) ; /* set spi clock to 50Mhz */
/* set the spi1 GPIO */
exynos_pinmux_config ( PERIPH_ID_SPI1 , PINMUX_FLAG_NONE ) ;
/* set pktcnt and enable it */
writel ( 4 | SPI_PACKET_CNT_EN , & regs - > pkt_cnt ) ;
/* set FB_CLK_SEL */
writel ( SPI_FB_DELAY_180 , & regs - > fb_clk ) ;
/* set CH_WIDTH and BUS_WIDTH as word */
setbits_le32 ( & regs - > mode_cfg , SPI_MODE_CH_WIDTH_WORD |
SPI_MODE_BUS_WIDTH_WORD ) ;
clrbits_le32 ( & regs - > ch_cfg , SPI_CH_CPOL_L ) ; /* CPOL: active high */
/* clear rx and tx channel if set priveously */
clrbits_le32 ( & regs - > ch_cfg , SPI_RX_CH_ON | SPI_TX_CH_ON ) ;
setbits_le32 ( & regs - > swap_cfg , SPI_RX_SWAP_EN |
SPI_RX_BYTE_SWAP |
SPI_RX_HWORD_SWAP ) ;
/* do a soft reset */
setbits_le32 ( & regs - > ch_cfg , SPI_CH_RST ) ;
clrbits_le32 ( & regs - > ch_cfg , SPI_CH_RST ) ;
/* now set rx and tx channel ON */
setbits_le32 ( & regs - > ch_cfg , SPI_RX_CH_ON | SPI_TX_CH_ON | SPI_CH_HS_EN ) ;
clrbits_le32 ( & regs - > cs_reg , SPI_SLAVE_SIG_INACT ) ; /* CS low */
/* Send read instruction (0x3h) followed by a 24 bit addr */
writel ( ( SF_READ_DATA_CMD < < 24 ) | SPI_FLASH_UBOOT_POS , & regs - > tx_data ) ;
/* waiting for TX done */
while ( ! ( readl ( & regs - > spi_sts ) & SPI_ST_TX_DONE ) ) {
if ( ! timeout ) {
debug ( " SPI TIMEOUT \n " ) ;
break ;
}
timeout - - ;
}
for ( upto = 0 , i = 0 ; upto < uboot_size ; upto + = todo , i + + ) {
todo = min ( uboot_size - upto , ( 1 < < 15 ) ) ;
spi_rx_tx ( regs , todo , ( void * ) ( uboot_addr ) ,
( void * ) ( SPI_FLASH_UBOOT_POS ) , i ) ;
}
setbits_le32 ( & regs - > cs_reg , SPI_SLAVE_SIG_INACT ) ; /* make the CS high */
/*
* Let put controller mode to BYTE as
* SPI driver does not support WORD mode yet
*/
clrbits_le32 ( & regs - > mode_cfg , SPI_MODE_CH_WIDTH_WORD |
SPI_MODE_BUS_WIDTH_WORD ) ;
writel ( 0 , & regs - > swap_cfg ) ;
/*
* Flush spi tx , rx fifos and reset the SPI controller
* and clear rx / tx channel
*/
clrsetbits_le32 ( & regs - > ch_cfg , SPI_CH_HS_EN , SPI_CH_RST ) ;
clrbits_le32 ( & regs - > ch_cfg , SPI_CH_RST ) ;
clrbits_le32 ( & regs - > ch_cfg , SPI_TX_CH_ON | SPI_RX_CH_ON ) ;
}
/*
* Copy U - boot from mmc to RAM :
* COPY_BL2_FNPTR_ADDR : Address in iRAM , which Contains
@ -70,6 +186,7 @@ void copy_uboot_to_ram(void)
u32 ( * copy_bl2 ) ( u32 offset , u32 nblock , u32 dst ) = NULL ;
u32 offset = 0 , size = 0 ;
struct spl_machine_param * param = spl_get_machine_params ( ) ;
# ifdef CONFIG_SUPPORT_EMMC_BOOT
u32 ( * copy_bl2_from_emmc ) ( u32 nblock , u32 dst ) ;
void ( * end_bootop_from_emmc ) ( void ) ;
@ -91,9 +208,8 @@ void copy_uboot_to_ram(void)
switch ( bootmode ) {
# ifdef CONFIG_SPI_BOOTING
case BOOT_MODE_SERIAL :
offset = SPI_FLASH_UBOOT_POS ;
size = CONFIG_BL2_SIZE ;
copy_bl2 = get_irom_func ( SPI_INDEX ) ;
/* Customised function to copy u-boot from SF */
exynos_spi_copy ( param - > uboot_size , CONFIG_SYS_TEXT_BASE ) ;
break ;
# endif
case BOOT_MODE_MMC :