blob: cceafc8007c54708f8cca9e425b5f9e817510efc [file] [log] [blame]
/******************************************************************************
*
* (C)Copyright 2014 Marvell Hefei Branch. All Rights Reserved.
*
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF MARVELL.
* The copyright notice above does not evidence any actual or intended
* publication of such source code.
* This Module contains Proprietary Information of Marvell and should be
* treated as Confidential.
* The information in this file is provided for the exclusive use of the
* licensees of Marvell.
* Such users have the right to use, modify, and incorporate this code into
* products for purposes authorized by the license agreement provided they
* include this notice and the associated copyright notice with any such
* product.
* The information in this file is provided "AS IS" without warranty.
*
******************************************************************************/
#include "spi.h"
#include "PlatformConfig.h"
#include "xllp_dmac.h"
UINT gpio_cs_bit = 12; /* SPI_CS: NezhaS using GPIO76, 76%64=12 */
UINT gpio_base = GPIO2_BASE;
#define GPIO_CS_BIT gpio_cs_bit
#define pGPIO_LR (volatile int *)(gpio_base + GPIO_PLR) //Pin level. set 0
#define pGPIO_DR (volatile int *)(gpio_base + GPIO_PDR) //Direction. set 0
#define pGPIO_SR (volatile int *)(gpio_base + GPIO_PSR) //Set. set 0
#define pGPIO_CR (volatile int *)(gpio_base + GPIO_PCR) //Clear. set 0
#define pGPIO_SDR (volatile int *)(gpio_base + GPIO_SDR) //Bit set. set 0
#define GPIO_CS_SET (1<< GPIO_CS_BIT)
void SPI_ConfigCS(void)
{
#ifdef SSP_CS_USE_GPIO
gpio_cs_bit = (PlatformIsNezhac() || PlatformIsFalconA0())?12:13;
gpio_base = (PlatformIsNezhac() || PlatformIsFalconA0())?GPIO2_BASE:GPIO0_BASE;
obm_printf("SPI %d 0x%x\n\r", gpio_cs_bit, gpio_base);
*pGPIO_DR |= (0x1<<gpio_cs_bit);
#endif
}
void Assert_CS(void)
{
#ifdef SSP_CS_USE_GPIO
*pGPIO_CR |= GPIO_CS_SET;
while (*pGPIO_LR & GPIO_CS_SET);
#else
UINT_T top_ctrl = BU_REG_READ(SSP_TCR);
if(top_ctrl & SSP_TCR_SSE)
reg_bit_clr(SSP_TCR, SSP_TCR_SSE);
reg_bit_set(SSP_TCR, SSP_TCR_HFL);
if(top_ctrl & SSP_TCR_SSE)
reg_bit_set(SSP_TCR, SSP_TCR_SSE);
#endif
}
void Deassert_CS(void)
{
#ifdef SSP_CS_USE_GPIO
*pGPIO_SR |= GPIO_CS_SET;
while (!(*pGPIO_LR & GPIO_CS_SET));
#else
UINT_T top_ctrl = BU_REG_READ(SSP_TCR);
if(top_ctrl & SSP_TCR_SSE)
reg_bit_clr(SSP_TCR, SSP_TCR_SSE);
reg_bit_clr(SSP_TCR, SSP_TCR_HFL);
if(top_ctrl & SSP_TCR_SSE)
reg_bit_set(SSP_TCR, SSP_TCR_SSE);
#endif
}
void SPI_DisableSSP(void)
{
//make sure SSP is disabled
reg_bit_clr(SSP_TCR, SSP_TCR_SSE);
//reset SSP CR's
reg_write(SSP_TCR, SSP_TCR_INITIAL);
reg_write(SSP_FCR, SSP_FCR_INITIAL);
reg_write(SSP_IER, SSP_IER_INITIAL);
}
void SPI_WaitSSPComplete(void)
{
volatile int timeout = 0xFFFF;
while ((*SSP_SR & (SSP_SSSR_TFL | SSP_SSSR_TF_NF | SSP_SSSR_BSY)) != SSP_SSSR_TF_NF)
{
ROW_DELAY(DEFAULT_TIMEOUT);
if((timeout--) <= 0)
{
obm_printf("SPI_WaitSSPComplete timeout\n\r");
break;
}
}
}
void ROW_DELAY(UINT_T x)
{
while (x > 0)
{
x--;
}
}
/***********************************************************
* SPI_Write_Read
* PIO mode to write and then read out the data
* Returns:
* None
*************************************************************/
void SPI_Write_Read(unsigned char *cmd, unsigned char *data, unsigned char len)
{
unsigned char i;
for (i = 0; i < len; i++)
{
BU_REG_WRITE8(SSP_DR, cmd[i]);
SPI_WaitSSPComplete();
data[i] = BU_REG_READ8(SSP_DR);
}
}
void SPI_FireUp(void)
{
reg_bit_set(SSP_TCR, SSP_TCR_SSE);
}
void SPI_ConfigDSS(int dss)
{
UINT_T top_ctrl;
top_ctrl = BU_REG_READ(SSP_TCR);
if(top_ctrl & SSP_TCR_SSE)
reg_bit_clr(SSP_TCR, SSP_TCR_SSE);
reg_bit_clr(SSP_TCR, SSP_TCR_DSS_MASK);
reg_bit_set(SSP_TCR, SHIFT5(dss-1));
if(top_ctrl & SSP_TCR_SSE)
reg_bit_set(SSP_TCR, SSP_TCR_SSE);
}
UINT_T SPI_ReadData(void)
{
return BU_REG_READ(SSP_DR);
}
void SPI_WriteData(UINT_T data)
{
BU_REG_WRITE(SSP_DR, data);
}
void SPI_ConfigInt(int setting)
{
reg_bit_set(SSP_IER, SSP_IER_TIE | SSP_IER_RIE | SSP_IER_RTOIE);
}
void SPI_ConfigDMA(int rft, int tft, int rre, int twe, int rafc)
{
UINT_T fcr;
reg_write(SSP_TOR, SSP_TOR_TIMEOUT);
reg_bit_set(SSP_TCR, SSP_TCR_TRIAL);
fcr = SSP_FCR_TWE(twe) | SSP_FCR_RRE(rre) | SSP_FCR_RFT(rft) | SSP_FCR_TFT(tft);
fcr |= SSP_FCR_TSRE;
fcr |= SSP_FCR_RSRE;
if(rafc)
fcr |= SSP_FCR_RAFC;
reg_write(SSP_FCR, fcr);
return;
}