@ -19,8 +19,13 @@
# define DWMMC_MAX_CH_NUM 4
# define DWMMC_MAX_FREQ 52000000
# define DWMMC_MIN_FREQ 400000
# define DWMMC_MMC0_CLKSEL_VAL 0x03030001
# define DWMMC_MMC2_CLKSEL_VAL 0x03020001
# define DWMMC_MMC0_SDR_TIMING_VAL 0x03030001
# define DWMMC_MMC2_SDR_TIMING_VAL 0x03020001
/* Exynos implmentation specific drver private data */
struct dwmci_exynos_priv_data {
u32 sdr_timing ;
} ;
/*
* Function used as callback function to initialise the
@ -28,7 +33,9 @@
*/
static void exynos_dwmci_clksel ( struct dwmci_host * host )
{
dwmci_writel ( host , DWMCI_CLKSEL , host - > clksel_val ) ;
struct dwmci_exynos_priv_data * priv = host - > priv ;
dwmci_writel ( host , DWMCI_CLKSEL , priv - > sdr_timing ) ;
}
unsigned int exynos_dwmci_get_clk ( struct dwmci_host * host )
@ -55,6 +62,8 @@ unsigned int exynos_dwmci_get_clk(struct dwmci_host *host)
static void exynos_dwmci_board_init ( struct dwmci_host * host )
{
struct dwmci_exynos_priv_data * priv = host - > priv ;
if ( host - > quirks & DWMCI_QUIRK_DISABLE_SMU ) {
dwmci_writel ( host , EMMCP_MPSBEGIN0 , 0 ) ;
dwmci_writel ( host , EMMCP_SEND0 , 0 ) ;
@ -65,8 +74,8 @@ static void exynos_dwmci_board_init(struct dwmci_host *host)
MPSCTRL_NON_SECURE_WRITE_BIT | MPSCTRL_VALID ) ;
}
/* Set to clksel_val at initial time */
if ( host - > clksel_val )
/* Set to timing value at initial time */
if ( priv - > sdr_timing )
exynos_dwmci_clksel ( host ) ;
}
@ -74,6 +83,7 @@ static int exynos_dwmci_core_init(struct dwmci_host *host, int index)
{
unsigned int div ;
unsigned long freq , sclk ;
struct dwmci_exynos_priv_data * priv = host - > priv ;
if ( host - > bus_hz )
freq = host - > bus_hz ;
@ -92,11 +102,11 @@ static int exynos_dwmci_core_init(struct dwmci_host *host, int index)
# endif
host - > board_init = exynos_dwmci_board_init ;
if ( ! host - > clksel_val ) {
if ( ! priv - > sdr_timing ) {
if ( index = = 0 )
host - > clksel_val = DWMMC_MMC0_CLKSEL _VAL;
priv - > sdr_timing = DWMMC_MMC0_SDR_TIMING _VAL;
else if ( index = = 2 )
host - > clksel_val = DWMMC_MMC2_CLKSEL _VAL;
priv - > sdr_timing = DWMMC_MMC2_SDR_TIMING _VAL;
}
host - > caps = MMC_MODE_DDR_52MHz ;
@ -122,6 +132,7 @@ static int exynos_dwmci_core_init(struct dwmci_host *host, int index)
int exynos_dwmci_add_port ( int index , u32 regbase , int bus_width , u32 clksel )
{
struct dwmci_host * host = NULL ;
struct dwmci_exynos_priv_data * priv ;
host = malloc ( sizeof ( struct dwmci_host ) ) ;
if ( ! host ) {
@ -129,11 +140,19 @@ int exynos_dwmci_add_port(int index, u32 regbase, int bus_width, u32 clksel)
return - ENOMEM ;
}
priv = malloc ( sizeof ( struct dwmci_exynos_priv_data ) ) ;
if ( ! priv ) {
error ( " dwmci_exynos_priv_data malloc fail! \n " ) ;
return - ENOMEM ;
}
host - > ioaddr = ( void * ) regbase ;
host - > buswidth = bus_width ;
if ( clksel )
host - > clksel_val = clksel ;
priv - > sdr_timing = clksel ;
host - > priv = priv ;
return exynos_dwmci_core_init ( host , index ) ;
}
@ -161,7 +180,14 @@ static int exynos_dwmci_get_config(const void *blob, int node,
struct dwmci_host * host )
{
int err = 0 ;
u32 base , clksel_val , timing [ 3 ] ;
u32 base , timing [ 3 ] ;
struct dwmci_exynos_priv_data * priv ;
priv = malloc ( sizeof ( struct dwmci_exynos_priv_data ) ) ;
if ( ! priv ) {
error ( " dwmci_exynos_priv_data malloc fail! \n " ) ;
return - ENOMEM ;
}
/* Extract device id for each mmc channel */
host - > dev_id = pinmux_decode_periph_id ( blob , node ) ;
@ -194,16 +220,24 @@ static int exynos_dwmci_get_config(const void *blob, int node,
return - EINVAL ;
}
clksel_val = ( DWMCI_SET_SAMPLE_CLK ( timing [ 0 ] ) |
priv - > sdr_timing = ( DWMCI_SET_SAMPLE_CLK ( timing [ 0 ] ) |
DWMCI_SET_DRV_CLK ( timing [ 1 ] ) |
DWMCI_SET_DIV_RATIO ( timing [ 2 ] ) ) ;
if ( clksel_val )
host - > clksel_val = clksel_val ;
/* sdr_timing didn't assigned anything, use the default value */
if ( ! priv - > sdr_timing ) {
if ( host - > dev_index = = 0 )
priv - > sdr_timing = DWMMC_MMC0_SDR_TIMING_VAL ;
else if ( host - > dev_index = = 2 )
priv - > sdr_timing = DWMMC_MMC2_SDR_TIMING_VAL ;
}
host - > fifoth_val = fdtdec_get_int ( blob , node , " fifoth_val " , 0 ) ;
host - > bus_hz = fdtdec_get_int ( blob , node , " bus_hz " , 0 ) ;
host - > div = fdtdec_get_int ( blob , node , " div " , 0 ) ;
host - > priv = priv ;
return 0 ;
}