@ -1,6 +1,6 @@
/*
* Copyright ( C ) 2014 Panasonic Corporation
* Copyright ( C ) 2015 - 2016 Socionext Inc .
* Copyright ( C ) 2015 - 2017 Socionext Inc .
* Author : Masahiro Yamada < yamada . masahiro @ socionext . com >
*
* SPDX - License - Identifier : GPL - 2.0 +
@ -24,35 +24,53 @@
# define ptr_to_uint(p) ((unsigned int)(unsigned long)(p))
struct phy_param {
resource_size_t base ;
unsigned int nr_dx ;
} ;
static const struct phy_param uniphier_ld4_phy_param [ ] = {
{ . base = 0x5bc01000 , . nr_dx = 2 , } ,
{ . base = 0x5be01000 , . nr_dx = 2 , } ,
{ /* sentinel */ }
} ;
# define UNIPHIER_MAX_NR_DDRPHY 4
static const struct phy_param uniphier_pro4_phy_param [ ] = {
{ . base = 0x5bc01000 , . nr_dx = 2 , } ,
{ . base = 0x5bc02000 , . nr_dx = 2 , } ,
{ . base = 0x5be01000 , . nr_dx = 2 , } ,
{ . base = 0x5be02000 , . nr_dx = 2 , } ,
{ /* sentinel */ }
struct uniphier_ddrphy_param {
unsigned int soc_id ;
unsigned int nr_phy ;
struct {
resource_size_t base ;
unsigned int nr_dx ;
} phy [ UNIPHIER_MAX_NR_DDRPHY ] ;
} ;
static const struct phy_param uniphier_sld8_phy_param [ ] = {
{ . base = 0x5bc01000 , . nr_dx = 2 , } ,
{ . base = 0x5be01000 , . nr_dx = 2 , } ,
{ /* sentinel */ }
} ;
static const struct phy_param uniphier_ld11_phy_param [ ] = {
{ . base = 0x5bc01000 , . nr_dx = 4 , } ,
{ /* sentinel */ }
static const struct uniphier_ddrphy_param uniphier_ddrphy_param [ ] = {
{
. soc_id = UNIPHIER_LD4_ID ,
. nr_phy = 2 ,
. phy = {
{ . base = 0x5bc01000 , . nr_dx = 2 , } ,
{ . base = 0x5be01000 , . nr_dx = 2 , } ,
} ,
} ,
{
. soc_id = UNIPHIER_PRO4_ID ,
. nr_phy = 4 ,
. phy = {
{ . base = 0x5bc01000 , . nr_dx = 2 , } ,
{ . base = 0x5bc02000 , . nr_dx = 2 , } ,
{ . base = 0x5be01000 , . nr_dx = 2 , } ,
{ . base = 0x5be02000 , . nr_dx = 2 , } ,
} ,
} ,
{
. soc_id = UNIPHIER_SLD8_ID ,
. nr_phy = 2 ,
. phy = {
{ . base = 0x5bc01000 , . nr_dx = 2 , } ,
{ . base = 0x5be01000 , . nr_dx = 2 , } ,
} ,
} ,
{
. soc_id = UNIPHIER_LD11_ID ,
. nr_phy = 1 ,
. phy = {
{ . base = 0x5bc01000 , . nr_dx = 4 , } ,
} ,
} ,
} ;
UNIPHIER_DEFINE_SOCDATA_FUNC ( uniphier_get_ddrphy_param , uniphier_ddrphy_param )
static void print_bdl ( void __iomem * reg , int n )
{
@ -63,18 +81,18 @@ static void print_bdl(void __iomem *reg, int n)
printf ( FS PRINTF_FORMAT , ( val > > i * 6 ) & 0x3f ) ;
}
static void dump_loop ( const struct phy_param * phy_ param,
static void dump_loop ( const struct uniphier_ddr phy_param * param ,
void ( * callback ) ( void __iomem * ) )
{
void __iomem * phy_base , * dx_base ;
int p , dx ;
int phy , dx ;
for ( p = 0 ; phy_param - > base ; phy_param + + , p + + ) {
phy_base = ioremap ( phy_p aram - > base , SZ_4K ) ;
for ( phy = 0 ; phy < param - > nr_phy ; phy + + ) {
phy_base = ioremap ( param - > phy [ phy ] . base , SZ_4K ) ;
dx_base = phy_base + PHY_DX_BASE ;
for ( dx = 0 ; dx < phy_p aram - > nr_dx ; dx + + ) {
printf ( " PHY%dDX%d: " , p , dx ) ;
for ( dx = 0 ; dx < param - > phy [ phy ] . nr_dx ; dx + + ) {
printf ( " PHY%dDX%d: " , phy , dx ) ;
( * callback ) ( dx_base ) ;
dx_base + = PHY_DX_STRIDE ;
printf ( " \n " ) ;
@ -93,12 +111,12 @@ static void __wbdl_dump(void __iomem *dx_base)
readl ( dx_base + PHY_DX_LCDLR1 ) & 0xff ) ;
}
static void wbdl_dump ( const struct phy_param * phy_ param)
static void wbdl_dump ( const struct uniphier_ddr phy_param * param )
{
printf ( " \n --- Write Bit Delay Line --- \n " ) ;
printf ( " DQ0 DQ1 DQ2 DQ3 DQ4 DQ5 DQ6 DQ7 DM DQS (WDQD) \n " ) ;
dump_loop ( phy_p aram , & __wbdl_dump ) ;
dump_loop ( param , & __wbdl_dump ) ;
}
static void __rbdl_dump ( void __iomem * dx_base )
@ -110,12 +128,12 @@ static void __rbdl_dump(void __iomem *dx_base)
( readl ( dx_base + PHY_DX_LCDLR1 ) > > 8 ) & 0xff ) ;
}
static void rbdl_dump ( const struct phy_param * phy_ param)
static void rbdl_dump ( const struct uniphier_ddr phy_param * param )
{
printf ( " \n --- Read Bit Delay Line --- \n " ) ;
printf ( " DQ0 DQ1 DQ2 DQ3 DQ4 DQ5 DQ6 DQ7 DM (RDQSD) \n " ) ;
dump_loop ( phy_p aram , & __rbdl_dump ) ;
dump_loop ( param , & __rbdl_dump ) ;
}
static void __wld_dump ( void __iomem * dx_base )
@ -133,12 +151,12 @@ static void __wld_dump(void __iomem *dx_base)
}
}
static void wld_dump ( const struct phy_param * phy_ param)
static void wld_dump ( const struct uniphier_ddr phy_param * param )
{
printf ( " \n --- Write Leveling Delay --- \n " ) ;
printf ( " Rank0 Rank1 Rank2 Rank3 \n " ) ;
printf ( " Rank0 Rank1 Rank2 Rank3 \n " ) ;
dump_loop ( phy_p aram , & __wld_dump ) ;
dump_loop ( param , & __wld_dump ) ;
}
static void __dqsgd_dump ( void __iomem * dx_base )
@ -155,28 +173,29 @@ static void __dqsgd_dump(void __iomem *dx_base)
}
}
static void dqsgd_dump ( const struct phy_param * phy_ param)
static void dqsgd_dump ( const struct uniphier_ddr phy_param * param )
{
printf ( " \n --- DQS Gating Delay --- \n " ) ;
printf ( " Rank0 Rank1 Rank2 Rank3 \n " ) ;
printf ( " Rank0 Rank1 Rank2 Rank3 \n " ) ;
dump_loop ( phy_p aram , & __dqsgd_dump ) ;
dump_loop ( param , & __dqsgd_dump ) ;
}
static void __mdl_dump ( void __iomem * dx_base )
{
int i ;
u32 mdl = readl ( dx_base + PHY_DX_MDLR ) ;
for ( i = 0 ; i < 3 ; i + + )
printf ( FS PRINTF_FORMAT , ( mdl > > ( 8 * i ) ) & 0xff ) ;
}
static void mdl_dump ( const struct phy_param * phy_ param)
static void mdl_dump ( const struct uniphier_ddr phy_param * param )
{
printf ( " \n --- Master Delay Line --- \n " ) ;
printf ( " IPRD TPRD MDLD \n " ) ;
dump_loop ( phy_p aram , & __mdl_dump ) ;
dump_loop ( param , & __mdl_dump ) ;
}
# define REG_DUMP(x) \
@ -193,17 +212,18 @@ static void mdl_dump(const struct phy_param *phy_param)
ofst > > PHY_REG_SHIFT , ( dx ) , # x , \
ptr_to_uint ( reg ) , readl ( reg ) ) ; }
static void reg_dump ( const struct phy_param * phy_ param)
static void reg_dump ( const struct uniphier_ddr phy_param * param )
{
void __iomem * phy_base ;
int p , dx ;
int phy , dx ;
printf ( " \n --- DDR PHY registers --- \n " ) ;
for ( p = 0 ; phy_param - > base ; phy_param + + , p + + ) {
phy_base = ioremap ( phy_p aram - > base , SZ_4K ) ;
for ( phy = 0 ; phy < param - > nr_phy ; phy + + ) {
phy_base = ioremap ( param - > phy [ phy ] . base , SZ_4K ) ;
printf ( " == PHY%d (base: %08x) == \n " , p , ptr_to_uint ( phy_base ) ) ;
printf ( " == PHY%d (base: %08x) == \n " ,
phy , ptr_to_uint ( phy_base ) ) ;
printf ( " No: Name : Address : Data \n " ) ;
REG_DUMP ( RIDR ) ;
@ -231,7 +251,7 @@ static void reg_dump(const struct phy_param *phy_param)
REG_DUMP ( MR2 ) ;
REG_DUMP ( MR3 ) ;
for ( dx = 0 ; dx < phy_p aram - > nr_dx ; dx + + ) {
for ( dx = 0 ; dx < param - > phy [ phy ] . nr_dx ; dx + + ) {
DX_REG_DUMP ( dx , GCR ) ;
DX_REG_DUMP ( dx , GTR ) ;
}
@ -242,47 +262,37 @@ static void reg_dump(const struct phy_param *phy_param)
static int do_ddr ( cmd_tbl_t * cmdtp , int flag , int argc , char * const argv [ ] )
{
char * cmd = argv [ 1 ] ;
const struct phy_param * phy_param ;
switch ( uniphier_get_soc_id ( ) ) {
case UNIPHIER_LD4_ID :
phy_param = uniphier_ld4_phy_param ;
break ;
case UNIPHIER_PRO4_ID :
phy_param = uniphier_pro4_phy_param ;
break ;
case UNIPHIER_SLD8_ID :
phy_param = uniphier_sld8_phy_param ;
break ;
case UNIPHIER_LD11_ID :
phy_param = uniphier_ld11_phy_param ;
break ;
default :
const struct uniphier_ddrphy_param * param ;
char * cmd ;
param = uniphier_get_ddrphy_param ( ) ;
if ( ! param ) {
printf ( " unsupported SoC \n " ) ;
return CMD_RET_FAILURE ;
}
if ( argc = = 1 )
cmd = " all " ;
else
cmd = argv [ 1 ] ;
if ( ! strcmp ( cmd , " wbdl " ) | | ! strcmp ( cmd , " all " ) )
wbdl_dump ( phy_p aram ) ;
wbdl_dump ( param ) ;
if ( ! strcmp ( cmd , " rbdl " ) | | ! strcmp ( cmd , " all " ) )
rbdl_dump ( phy_p aram ) ;
rbdl_dump ( param ) ;
if ( ! strcmp ( cmd , " wld " ) | | ! strcmp ( cmd , " all " ) )
wld_dump ( phy_p aram ) ;
wld_dump ( param ) ;
if ( ! strcmp ( cmd , " dqsgd " ) | | ! strcmp ( cmd , " all " ) )
dqsgd_dump ( phy_p aram ) ;
dqsgd_dump ( param ) ;
if ( ! strcmp ( cmd , " mdl " ) | | ! strcmp ( cmd , " all " ) )
mdl_dump ( phy_p aram ) ;
mdl_dump ( param ) ;
if ( ! strcmp ( cmd , " reg " ) | | ! strcmp ( cmd , " all " ) )
reg_dump ( phy_p aram ) ;
reg_dump ( param ) ;
return CMD_RET_SUCCESS ;
}