@ -8,14 +8,12 @@
*/
# include <common.h>
# include <spi.h>
# include <asm/io.h>
# include <asm/gpio.h>
# define SCLK (192 + 8) /* GPIO6 8 */
# define SSTBZ (64 + 3) /* GPIO2 3 */
# define MOSI (192 + 7) /* GPIO6 8 */
# define MISO (192 + 10) /* GPIO6 10 */
# include <asm/io.h>
# include <dm.h>
# include <errno.h>
# include <linux/err.h>
# include <sysreset.h>
# define CPLD_ADDR_MODE 0x00 /* RW */
# define CPLD_ADDR_MUX 0x02 /* RW */
@ -23,111 +21,89 @@
# define CPLD_ADDR_RESET 0x80 /* RW */
# define CPLD_ADDR_VERSION 0xFF /* R */
static int cpld_initialized ;
int spi_cs_is_valid ( unsigned int bus , unsigned int cs )
{
/* Always valid */
return 1 ;
}
void spi_cs_activate ( struct spi_slave * slave )
{
/* Always active */
}
void spi_cs_deactivate ( struct spi_slave * slave )
{
/* Always active */
}
void ulcb_softspi_sda ( int set )
{
gpio_set_value ( MOSI , set ) ;
}
struct renesas_ulcb_sysreset_priv {
struct gpio_desc miso ;
struct gpio_desc mosi ;
struct gpio_desc sck ;
struct gpio_desc sstbz ;
} ;
void ulcb_softspi_scl ( int set )
{
gpio_set_value ( SCLK , set ) ;
}
unsigned char ulcb_softspi_read ( void )
{
return ! ! gpio_get_value ( MISO ) ;
}
static void cpld_rw ( u8 write )
{
gpio_set_value ( MOSI , write ) ;
gpio_set_value ( SSTBZ , 0 ) ;
gpio_set_value ( SCLK , 1 ) ;
gpio_set_value ( SCLK , 0 ) ;
gpio_set_value ( SSTBZ , 1 ) ;
}
static u32 cpld_read ( u8 addr )
static u32 cpld_read ( struct udevice * dev , u8 addr )
{
struct renesas_ulcb_sysreset_priv * priv = dev_get_priv ( dev ) ;
u32 data = 0 ;
int i ;
spi_xfer ( NULL , 8 , & addr , NULL , SPI_XFER_BEGIN | SPI_XFER_END ) ;
cpld_rw ( 0 ) ;
spi_xfer ( NULL , 32 , NULL , & data , SPI_XFER_BEGIN | SPI_XFER_END ) ;
return swab32 ( data ) ;
}
static void cpld_write ( u8 addr , u32 data )
{
data = swab32 ( data ) ;
spi_xfer ( NULL , 32 , & data , NULL , SPI_XFER_BEGIN | SPI_XFER_END ) ;
for ( i = 0 ; i < 8 ; i + + ) {
dm_gpio_set_value ( & priv - > mosi , ! ! ( addr & 0x80 ) ) ; /* MSB first */
dm_gpio_set_value ( & priv - > sck , 1 ) ;
addr < < = 1 ;
dm_gpio_set_value ( & priv - > sck , 0 ) ;
}
spi_xfer ( NULL , 8 , NULL , & addr , SPI_XFER_BEGIN | SPI_XFER_END ) ;
dm_gpio_set_value ( & priv - > mosi , 0 ) ; /* READ */
dm_gpio_set_value ( & priv - > sstbz , 0 ) ;
dm_gpio_set_value ( & priv - > sck , 1 ) ;
dm_gpio_set_value ( & priv - > sck , 0 ) ;
dm_gpio_set_value ( & priv - > sstbz , 1 ) ;
for ( i = 0 ; i < 32 ; i + + ) {
dm_gpio_set_value ( & priv - > sck , 1 ) ;
data < < = 1 ;
data | = dm_gpio_get_value ( & priv - > miso ) ; /* MSB first */
dm_gpio_set_value ( & priv - > sck , 0 ) ;
}
cpld_rw ( 1 ) ;
return data ;
}
static void cpld_init ( void )
static void cpld_write ( struct udevice * dev , u8 addr , u32 data )
{
if ( cpld_initialized )
return ;
/* PULL-UP on MISO line */
setbits_le32 ( PFC_PUEN5 , PUEN_SSI_SDATA4 ) ;
gpio_request ( SCLK , NULL ) ;
gpio_request ( SSTBZ , NULL ) ;
gpio_request ( MOSI , NULL ) ;
gpio_request ( MISO , NULL ) ;
gpio_direction_output ( SCLK , 0 ) ;
gpio_direction_output ( SSTBZ , 1 ) ;
gpio_direction_output ( MOSI , 0 ) ;
gpio_direction_input ( MISO ) ;
struct renesas_ulcb_sysreset_priv * priv = dev_get_priv ( dev ) ;
int i ;
for ( i = 0 ; i < 32 ; i + + ) {
dm_gpio_set_value ( & priv - > mosi , data & ( 1 < < 31 ) ) ; /* MSB first */
dm_gpio_set_value ( & priv - > sck , 1 ) ;
data < < = 1 ;
dm_gpio_set_value ( & priv - > sck , 0 ) ;
}
/* Dummy read */
cpld_read ( CPLD_ADDR_VERSION ) ;
for ( i = 0 ; i < 8 ; i + + ) {
dm_gpio_set_value ( & priv - > mosi , addr & 0x80 ) ; /* MSB first */
dm_gpio_set_value ( & priv - > sck , 1 ) ;
addr < < = 1 ;
dm_gpio_set_value ( & priv - > sck , 0 ) ;
}
cpld_initialized = 1 ;
dm_gpio_set_value ( & priv - > mosi , 1 ) ; /* WRITE */
dm_gpio_set_value ( & priv - > sstbz , 0 ) ;
dm_gpio_set_value ( & priv - > sck , 1 ) ;
dm_gpio_set_value ( & priv - > sck , 0 ) ;
dm_gpio_set_value ( & priv - > sstbz , 1 ) ;
}
static int do_cpld ( cmd_tbl_t * cmdtp , int flag , int argc , char * const argv [ ] )
{
struct udevice * dev ;
u32 addr , val ;
int ret ;
cpld_init ( ) ;
ret = uclass_get_device_by_driver ( UCLASS_SYSRESET ,
DM_GET_DRIVER ( sysreset_renesas_ulcb ) ,
& dev ) ;
if ( ret )
return ret ;
if ( argc = = 2 & & strcmp ( argv [ 1 ] , " info " ) = = 0 ) {
printf ( " CPLD version: \t \t \t 0x%08x \n " ,
cpld_read ( CPLD_ADDR_VERSION ) ) ;
cpld_read ( dev , CPLD_ADDR_VERSION ) ) ;
printf ( " H3 Mode setting (MD0..28): \t 0x%08x \n " ,
cpld_read ( CPLD_ADDR_MODE ) ) ;
cpld_read ( dev , CPLD_ADDR_MODE ) ) ;
printf ( " Multiplexer settings: \t \t 0x%08x \n " ,
cpld_read ( CPLD_ADDR_MUX ) ) ;
cpld_read ( dev , CPLD_ADDR_MUX ) ) ;
printf ( " DIPSW (SW6): \t \t \t 0x%08x \n " ,
cpld_read ( CPLD_ADDR_DIPSW6 ) ) ;
cpld_read ( dev , CPLD_ADDR_DIPSW6 ) ) ;
return 0 ;
}
@ -143,10 +119,10 @@ static int do_cpld(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
if ( argc = = 3 & & strcmp ( argv [ 1 ] , " read " ) = = 0 ) {
printf ( " 0x%x \n " , cpld_read ( addr ) ) ;
printf ( " 0x%x \n " , cpld_read ( dev , addr ) ) ;
} else if ( argc = = 4 & & strcmp ( argv [ 1 ] , " write " ) = = 0 ) {
val = simple_strtoul ( argv [ 3 ] , NULL , 16 ) ;
cpld_write ( addr , val ) ;
cpld_write ( dev , addr , val ) ;
}
return 0 ;
@ -160,8 +136,56 @@ U_BOOT_CMD(
" cpld write addr val \n "
) ;
void reset_cpu ( ulong addr )
static int renesas_ulcb_sysreset_request ( struct udevice * dev , enum sysreset_t type )
{
cpld_write ( dev , CPLD_ADDR_RESET , 1 ) ;
return - EINPROGRESS ;
}
static int renesas_ulcb_sysreset_probe ( struct udevice * dev )
{
cpld_init ( ) ;
cpld_write ( CPLD_ADDR_RESET , 1 ) ;
struct renesas_ulcb_sysreset_priv * priv = dev_get_priv ( dev ) ;
if ( gpio_request_by_name ( dev , " gpio-miso " , 0 , & priv - > miso ,
GPIOD_IS_IN ) )
return - EINVAL ;
if ( gpio_request_by_name ( dev , " gpio-sck " , 0 , & priv - > sck ,
GPIOD_IS_OUT ) )
return - EINVAL ;
if ( gpio_request_by_name ( dev , " gpio-sstbz " , 0 , & priv - > sstbz ,
GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE ) )
return - EINVAL ;
if ( gpio_request_by_name ( dev , " gpio-mosi " , 0 , & priv - > mosi ,
GPIOD_IS_OUT ) )
return - EINVAL ;
/* PULL-UP on MISO line */
setbits_le32 ( PFC_PUEN5 , PUEN_SSI_SDATA4 ) ;
/* Dummy read */
cpld_read ( dev , CPLD_ADDR_VERSION ) ;
return 0 ;
}
static struct sysreset_ops renesas_ulcb_sysreset = {
. request = renesas_ulcb_sysreset_request ,
} ;
static const struct udevice_id renesas_ulcb_sysreset_ids [ ] = {
{ . compatible = " renesas,ulcb-cpld " } ,
{ }
} ;
U_BOOT_DRIVER ( sysreset_renesas_ulcb ) = {
. name = " renesas_ulcb_sysreset " ,
. id = UCLASS_SYSRESET ,
. ops = & renesas_ulcb_sysreset ,
. probe = renesas_ulcb_sysreset_probe ,
. of_match = renesas_ulcb_sysreset_ids ,
. priv_auto_alloc_size = sizeof ( struct renesas_ulcb_sysreset_priv ) ,
} ;