@ -11,9 +11,13 @@
# include <watchdog.h>
# include <command.h>
# include <mmc.h>
# include <clk.h>
# include <dm.h>
# include <malloc.h>
# include <linux/errno.h>
# include <asm/io.h>
# include <linux/compat.h>
# include <linux/io.h>
# include <linux/sizes.h>
# include "sh_mmcif.h"
# define DRIVER_NAME "sh_mmcif"
@ -510,10 +514,9 @@ static int sh_mmcif_start_cmd(struct sh_mmcif_host *host,
return ret ;
}
static int sh_mmcif_request ( struct mmc * mmc , struct mmc_cmd * cmd ,
struct mmc_data * data )
static int sh_mmcif_send_cmd_common ( struct sh_mmcif_host * host ,
struct mmc_cmd * cmd , struct mmc_data * data )
{
struct sh_mmcif_host * host = mmc - > priv ;
int ret ;
WATCHDOG_RESET ( ) ;
@ -539,10 +542,8 @@ static int sh_mmcif_request(struct mmc *mmc, struct mmc_cmd *cmd,
return ret ;
}
static int sh_mmcif_set_ios ( struct mmc * mmc )
static int sh_mmcif_set_ios_common ( struct sh_mmcif_host * host , struct mmc * mmc )
{
struct sh_mmcif_host * host = mmc - > priv ;
if ( mmc - > clock )
sh_mmcif_clock_control ( host , mmc - > clock ) ;
@ -558,19 +559,45 @@ static int sh_mmcif_set_ios(struct mmc *mmc)
return 0 ;
}
static int sh_mmcif_init ( struct mmc * mmc )
static int sh_mmcif_initialize_common ( struct sh_mmcif_host * host )
{
struct sh_mmcif_host * host = mmc - > priv ;
sh_mmcif_sync_reset ( host ) ;
sh_mmcif_write ( MASK_ALL , & host - > regs - > ce_int_mask ) ;
return 0 ;
}
# ifndef CONFIG_DM_MMC
static void * mmc_priv ( struct mmc * mmc )
{
return ( void * ) mmc - > priv ;
}
static int sh_mmcif_send_cmd ( struct mmc * mmc , struct mmc_cmd * cmd ,
struct mmc_data * data )
{
struct sh_mmcif_host * host = mmc_priv ( mmc ) ;
return sh_mmcif_send_cmd_common ( host , cmd , data ) ;
}
static int sh_mmcif_set_ios ( struct mmc * mmc )
{
struct sh_mmcif_host * host = mmc_priv ( mmc ) ;
return sh_mmcif_set_ios_common ( host , mmc ) ;
}
static int sh_mmcif_initialize ( struct mmc * mmc )
{
struct sh_mmcif_host * host = mmc_priv ( mmc ) ;
return sh_mmcif_initialize_common ( host ) ;
}
static const struct mmc_ops sh_mmcif_ops = {
. send_cmd = sh_mmcif_request ,
. set_ios = sh_mmcif_set_ios ,
. init = sh_mmcif_init ,
. send_cmd = sh_mmcif_send_cmd ,
. set_ios = sh_mmcif_set_ios ,
. init = sh_mmcif_initialize ,
} ;
static struct mmc_config sh_mmcif_cfg = {
@ -606,3 +633,115 @@ int mmcif_mmc_init(void)
return 0 ;
}
# else
struct sh_mmcif_plat {
struct mmc_config cfg ;
struct mmc mmc ;
} ;
int sh_mmcif_dm_send_cmd ( struct udevice * dev , struct mmc_cmd * cmd ,
struct mmc_data * data )
{
struct sh_mmcif_host * host = dev_get_priv ( dev ) ;
return sh_mmcif_send_cmd_common ( host , cmd , data ) ;
}
int sh_mmcif_dm_set_ios ( struct udevice * dev )
{
struct sh_mmcif_host * host = dev_get_priv ( dev ) ;
struct mmc * mmc = mmc_get_mmc_dev ( dev ) ;
return sh_mmcif_set_ios_common ( host , mmc ) ;
}
static const struct dm_mmc_ops sh_mmcif_dm_ops = {
. send_cmd = sh_mmcif_dm_send_cmd ,
. set_ios = sh_mmcif_dm_set_ios ,
} ;
static int sh_mmcif_dm_bind ( struct udevice * dev )
{
struct sh_mmcif_plat * plat = dev_get_platdata ( dev ) ;
return mmc_bind ( dev , & plat - > mmc , & plat - > cfg ) ;
}
static int sh_mmcif_dm_probe ( struct udevice * dev )
{
struct sh_mmcif_plat * plat = dev_get_platdata ( dev ) ;
struct sh_mmcif_host * host = dev_get_priv ( dev ) ;
struct mmc_uclass_priv * upriv = dev_get_uclass_priv ( dev ) ;
struct clk sh_mmcif_clk ;
fdt_addr_t base ;
int ret ;
base = devfdt_get_addr ( dev ) ;
if ( base = = FDT_ADDR_T_NONE )
return - EINVAL ;
host - > regs = ( struct sh_mmcif_regs * ) devm_ioremap ( dev , base , SZ_2K ) ;
if ( ! host - > regs )
return - ENOMEM ;
ret = clk_get_by_index ( dev , 0 , & sh_mmcif_clk ) ;
if ( ret ) {
debug ( " failed to get clock, ret=%d \n " , ret ) ;
return ret ;
}
ret = clk_enable ( & sh_mmcif_clk ) ;
if ( ret ) {
debug ( " failed to enable clock, ret=%d \n " , ret ) ;
return ret ;
}
host - > clk = clk_get_rate ( & sh_mmcif_clk ) ;
plat - > cfg . name = dev - > name ;
plat - > cfg . host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS ;
switch ( fdtdec_get_int ( gd - > fdt_blob , dev_of_offset ( dev ) , " bus-width " ,
1 ) ) {
case 8 :
plat - > cfg . host_caps | = MMC_MODE_8BIT ;
break ;
case 4 :
plat - > cfg . host_caps | = MMC_MODE_4BIT ;
break ;
case 1 :
break ;
default :
dev_err ( dev , " Invalid \" bus-width \" value \n " ) ;
return - EINVAL ;
}
sh_mmcif_initialize_common ( host ) ;
plat - > cfg . voltages = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34 ;
plat - > cfg . f_min = MMC_CLK_DIV_MIN ( host - > clk ) ;
plat - > cfg . f_max = MMC_CLK_DIV_MAX ( host - > clk ) ;
plat - > cfg . b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT ;
upriv - > mmc = & plat - > mmc ;
return 0 ;
}
static const struct udevice_id sh_mmcif_sd_match [ ] = {
{ . compatible = " renesas,sh-mmcif " } ,
{ /* sentinel */ }
} ;
U_BOOT_DRIVER ( sh_mmcif_mmc ) = {
. name = " sh-mmcif " ,
. id = UCLASS_MMC ,
. of_match = sh_mmcif_sd_match ,
. bind = sh_mmcif_dm_bind ,
. probe = sh_mmcif_dm_probe ,
. priv_auto_alloc_size = sizeof ( struct sh_mmcif_host ) ,
. platdata_auto_alloc_size = sizeof ( struct sh_mmcif_plat ) ,
. ops = & sh_mmcif_dm_ops ,
} ;
# endif