@ -7,9 +7,10 @@
# include <config.h>
# include <common.h>
# include <command .h>
# include <dm .h>
# include <errno.h>
# include <mmc.h>
# include <command.h>
# include <part.h>
# include <malloc.h>
# include <asm/io.h>
@ -23,10 +24,38 @@
# define set_bit(addr, val) set_val((addr), (get_val(addr) | (val)))
# define clear_bit(addr, val) set_val((addr), (get_val(addr) & ~(val)))
# ifdef CONFIG_DM_MMC
struct davinci_of_data {
const char * name ;
u8 version ;
} ;
/* Davinci MMC board definitions */
struct davinci_mmc_priv {
struct davinci_mmc_regs * reg_base ; /* Register base address */
uint input_clk ; /* Input clock to MMC controller */
uint version ; /* MMC Controller version */
} ;
struct davinci_mmc_plat
{
struct mmc_config cfg ;
struct mmc mmc ;
} ;
# endif
/* Set davinci clock prescalar value based on the required clock in HZ */
# if !CONFIG_IS_ENABLED(DM_MMC)
static void dmmc_set_clock ( struct mmc * mmc , uint clock )
{
struct davinci_mmc * host = mmc - > priv ;
# else
static void davinci_mmc_set_clock ( struct udevice * dev , uint clock )
{
struct davinci_mmc_priv * host = dev_get_priv ( dev ) ;
struct mmc * mmc = mmc_get_mmc_dev ( dev ) ;
# endif
struct davinci_mmc_regs * regs = host - > reg_base ;
uint clkrt , sysclk2 , act_clock ;
@ -120,13 +149,19 @@ static int dmmc_check_status(volatile struct davinci_mmc_regs *regs,
}
/*
* Sends a command out on the bus . Takes the mmc pointer ,
* Sends a command out on the bus . Takes the device pointer ,
* a command pointer , and an optional data pointer .
*/
static int
dmmc_send_cmd ( struct mmc * mmc , struct mmc_cmd * cmd , struct mmc_data * data )
# if !CONFIG_IS_ENABLED(DM_MMC)
static int dmmc_send_cmd ( struct mmc * mmc , struct mmc_cmd * cmd , struct mmc_data * data )
{
struct davinci_mmc * host = mmc - > priv ;
# else
static int
davinci_mmc_send_cmd ( struct udevice * dev , struct mmc_cmd * cmd , struct mmc_data * data )
{
struct davinci_mmc_priv * host = dev_get_priv ( dev ) ;
# endif
volatile struct davinci_mmc_regs * regs = host - > reg_base ;
uint mmcstatus , status_rdy , status_err ;
uint i , cmddata , bytes_left = 0 ;
@ -312,9 +347,15 @@ dmmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
}
/* Initialize Davinci MMC controller */
# if !CONFIG_IS_ENABLED(DM_MMC)
static int dmmc_init ( struct mmc * mmc )
{
struct davinci_mmc * host = mmc - > priv ;
# else
static int davinci_dm_mmc_init ( struct udevice * dev )
{
struct davinci_mmc_priv * host = dev_get_priv ( dev ) ;
# endif
struct davinci_mmc_regs * regs = host - > reg_base ;
/* Clear status registers explicitly - soft reset doesn't clear it
@ -347,11 +388,19 @@ static int dmmc_init(struct mmc *mmc)
}
/* Set buswidth or clock as indicated by the MMC framework */
# if !CONFIG_IS_ENABLED(DM_MMC)
static int dmmc_set_ios ( struct mmc * mmc )
{
struct davinci_mmc * host = mmc - > priv ;
struct davinci_mmc_regs * regs = host - > reg_base ;
# else
static int davinci_mmc_set_ios ( struct udevice * dev )
{
struct mmc * mmc = mmc_get_mmc_dev ( dev ) ;
struct davinci_mmc_priv * host = dev_get_priv ( dev ) ;
struct davinci_mmc_regs * regs = host - > reg_base ;
# endif
/* Set the bus width */
if ( mmc - > bus_width = = 4 )
set_bit ( & regs - > mmcctl , MMCCTL_WIDTH_4_BIT ) ;
@ -359,21 +408,33 @@ static int dmmc_set_ios(struct mmc *mmc)
clear_bit ( & regs - > mmcctl , MMCCTL_WIDTH_4_BIT ) ;
/* Set clock speed */
if ( mmc - > clock )
if ( mmc - > clock ) {
# if !CONFIG_IS_ENABLED(DM_MMC)
dmmc_set_clock ( mmc , mmc - > clock ) ;
# else
davinci_mmc_set_clock ( dev , mmc - > clock ) ;
# endif
}
return 0 ;
}
# if !CONFIG_IS_ENABLED(DM_MMC)
static const struct mmc_ops dmmc_ops = {
. send_cmd = dmmc_send_cmd ,
. set_ios = dmmc_set_ios ,
. init = dmmc_init ,
. send_cmd = dmmc_send_cmd ,
. set_ios = dmmc_set_ios ,
. init = dmmc_init ,
} ;
# else
static const struct dm_mmc_ops davinci_mmc_ops = {
. send_cmd = davinci_mmc_send_cmd ,
. set_ios = davinci_mmc_set_ios ,
} ;
# endif
# if !CONFIG_IS_ENABLED(DM_MMC)
/* Called from board_mmc_init during startup. Can be called multiple times
* depending on the number of slots available on board and controller
*/
* depending on the number of slots available on board and controller
*/
int davinci_mmc_init ( bd_t * bis , struct davinci_mmc * host )
{
host - > cfg . name = " davinci " ;
@ -389,3 +450,78 @@ int davinci_mmc_init(bd_t *bis, struct davinci_mmc *host)
return 0 ;
}
# else
static int davinci_mmc_probe ( struct udevice * dev )
{
struct mmc_uclass_priv * upriv = dev_get_uclass_priv ( dev ) ;
struct davinci_mmc_plat * plat = dev_get_platdata ( dev ) ;
struct davinci_mmc_priv * priv = dev_get_priv ( dev ) ;
struct mmc_config * cfg = & plat - > cfg ;
struct davinci_of_data * data =
( struct davinci_of_data * ) dev_get_driver_data ( dev ) ;
cfg - > f_min = 200000 ;
cfg - > f_max = 25000000 ;
cfg - > voltages = MMC_VDD_32_33 | MMC_VDD_33_34 ,
cfg - > host_caps = MMC_MODE_4BIT , /* DA850 supports only 4-bit SD/MMC */
cfg - > b_max = DAVINCI_MAX_BLOCKS ;
if ( data ) {
cfg - > name = data - > name ;
priv - > version = data - > version ;
}
priv - > reg_base = ( struct davinci_mmc_regs * ) dev_read_addr ( dev ) ;
priv - > input_clk = clk_get ( DAVINCI_MMCSD_CLKID ) ;
upriv - > mmc = & plat - > mmc ;
return davinci_dm_mmc_init ( dev ) ;
}
static int davinci_mmc_bind ( struct udevice * dev )
{
struct davinci_mmc_plat * plat = dev_get_platdata ( dev ) ;
return mmc_bind ( dev , & plat - > mmc , & plat - > cfg ) ;
}
const struct davinci_of_data davinci_mmc_host_info [ ] = {
{
. name = " dm6441-mmc " ,
. version = MMC_CTLR_VERSION_1 ,
} ,
{
. name = " da830-mmc " ,
. version = MMC_CTLR_VERSION_2 ,
} ,
{ } ,
} ;
static const struct udevice_id davinci_mmc_ids [ ] = {
{
. compatible = " ti,dm6441-mmc " ,
. data = ( ulong ) & davinci_mmc_host_info [ MMC_CTLR_VERSION_1 ]
} ,
{
. compatible = " ti,da830-mmc " ,
. data = ( ulong ) & davinci_mmc_host_info [ MMC_CTLR_VERSION_2 ]
} ,
{ } ,
} ;
U_BOOT_DRIVER ( davinci_mmc_drv ) = {
. name = " davinci_mmc " ,
. id = UCLASS_MMC ,
. of_match = davinci_mmc_ids ,
# if CONFIG_BLK
. bind = davinci_mmc_bind ,
# endif
. probe = davinci_mmc_probe ,
. ops = & davinci_mmc_ops ,
. platdata_auto_alloc_size = sizeof ( struct davinci_mmc_plat ) ,
. priv_auto_alloc_size = sizeof ( struct davinci_mmc_priv ) ,
} ;
# endif