@ -702,16 +702,49 @@ static int mmc_change_freq(struct mmc *mmc)
return 0 ;
}
static int mmc_set_capacity ( struct mmc * mmc , int part_num )
{
switch ( part_num ) {
case 0 :
mmc - > capacity = mmc - > capacity_user ;
break ;
case 1 :
case 2 :
mmc - > capacity = mmc - > capacity_boot ;
break ;
case 3 :
mmc - > capacity = mmc - > capacity_rpmb ;
break ;
case 4 :
case 5 :
case 6 :
case 7 :
mmc - > capacity = mmc - > capacity_gp [ part_num - 4 ] ;
break ;
default :
return - 1 ;
}
mmc - > block_dev . lba = lldiv ( mmc - > capacity , mmc - > read_bl_len ) ;
return 0 ;
}
int mmc_switch_part ( int dev_num , unsigned int part_num )
{
struct mmc * mmc = find_mmc_device ( dev_num ) ;
int ret ;
if ( ! mmc )
return - 1 ;
return mmc_switch ( mmc , EXT_CSD_CMD_SET_NORMAL , EXT_CSD_PART_CONF ,
( mmc - > part_config & ~ PART_ACCESS_MASK )
| ( part_num & PART_ACCESS_MASK ) ) ;
ret = mmc_switch ( mmc , EXT_CSD_CMD_SET_NORMAL , EXT_CSD_PART_CONF ,
( mmc - > part_config & ~ PART_ACCESS_MASK )
| ( part_num & PART_ACCESS_MASK ) ) ;
if ( ret )
return ret ;
return mmc_set_capacity ( mmc , part_num ) ;
}
int mmc_getcd ( struct mmc * mmc )
@ -919,7 +952,7 @@ static void mmc_set_bus_width(struct mmc *mmc, uint width)
static int mmc_startup ( struct mmc * mmc )
{
int err ;
int err , i ;
uint mult , freq ;
u64 cmult , csize , capacity ;
struct mmc_cmd cmd ;
@ -1037,8 +1070,12 @@ static int mmc_startup(struct mmc *mmc)
cmult = ( mmc - > csd [ 2 ] & 0x00038000 ) > > 15 ;
}
mmc - > capacity = ( csize + 1 ) < < ( cmult + 2 ) ;
mmc - > capacity * = mmc - > read_bl_len ;
mmc - > capacity_user = ( csize + 1 ) < < ( cmult + 2 ) ;
mmc - > capacity_user * = mmc - > read_bl_len ;
mmc - > capacity_boot = 0 ;
mmc - > capacity_rpmb = 0 ;
for ( i = 0 ; i < 4 ; i + + )
mmc - > capacity_gp [ i ] = 0 ;
if ( mmc - > read_bl_len > MMC_MAX_BLOCK_LEN )
mmc - > read_bl_len = MMC_MAX_BLOCK_LEN ;
@ -1077,7 +1114,7 @@ static int mmc_startup(struct mmc *mmc)
| ext_csd [ EXT_CSD_SEC_CNT + 3 ] < < 24 ;
capacity * = MMC_MAX_BLOCK_LEN ;
if ( ( capacity > > 20 ) > 2 * 1024 )
mmc - > capacity = capacity ;
mmc - > capacity_user = capacity ;
}
switch ( ext_csd [ EXT_CSD_REV ] ) {
@ -1119,8 +1156,25 @@ static int mmc_startup(struct mmc *mmc)
if ( ( ext_csd [ EXT_CSD_PARTITIONING_SUPPORT ] & PART_SUPPORT ) | |
ext_csd [ EXT_CSD_BOOT_MULT ] )
mmc - > part_config = ext_csd [ EXT_CSD_PART_CONF ] ;
mmc - > capacity_boot = ext_csd [ EXT_CSD_BOOT_MULT ] < < 17 ;
mmc - > capacity_rpmb = ext_csd [ EXT_CSD_RPMB_MULT ] < < 17 ;
for ( i = 0 ; i < 4 ; i + + ) {
int idx = EXT_CSD_GP_SIZE_MULT + i * 3 ;
mmc - > capacity_gp [ i ] = ( ext_csd [ idx + 2 ] < < 16 ) +
( ext_csd [ idx + 1 ] < < 8 ) + ext_csd [ idx ] ;
mmc - > capacity_gp [ i ] * =
ext_csd [ EXT_CSD_HC_ERASE_GRP_SIZE ] ;
mmc - > capacity_gp [ i ] * = ext_csd [ EXT_CSD_HC_WP_GRP_SIZE ] ;
}
}
err = mmc_set_capacity ( mmc , mmc - > part_num ) ;
if ( err )
return err ;
if ( IS_SD ( mmc ) )
err = sd_change_freq ( mmc ) ;
else