@ -6,6 +6,8 @@
# include <common.h>
# include <malloc.h>
# include <fdtdec.h>
# include <libfdt.h>
# include <dwmmc.h>
# include <errno.h>
# include <asm/arch/dwmmc.h>
@ -42,34 +44,87 @@ static void socfpga_dwmci_clksel(struct dwmci_host *host)
CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK ) ;
}
int socfpga_dwmmc_init ( u32 regbase , int bus_width , int inde x)
static int socfpga_dwmci_of_probe ( const void * blob , int node , const int id x)
{
/* FIXME: probe from DT eventually too/ */
const unsigned long clk = cm_get_mmc_controller_clk_hz ( ) ;
struct dwmci_host * host ;
unsigned long clk = cm_get_mmc_controller_clk_hz ( ) ;
fdt_addr_t reg_base ;
int bus_width , fifo_depth ;
if ( clk = = 0 ) {
printf ( " %s: MMC clock is zero! " , __func__ ) ;
printf ( " DWMMC%d: MMC clock is zero! " , idx ) ;
return - EINVAL ;
}
/* calloc for zero init */
host = calloc ( 1 , sizeof ( struct dwmci_host ) ) ;
if ( ! host ) {
printf ( " %s: calloc() failed! \n " , __func__ ) ;
return - ENOMEM ;
/* Get the register address from the device node */
reg_base = fdtdec_get_addr ( blob , node , " reg " ) ;
if ( ! reg_base ) {
printf ( " DWMMC%d: Can't get base address \n " , idx ) ;
return - EINVAL ;
}
/* Get the bus width from the device node */
bus_width = fdtdec_get_int ( blob , node , " bus-width " , 0 ) ;
if ( bus_width < = 0 ) {
printf ( " DWMMC%d: Can't get bus-width \n " , idx ) ;
return - EINVAL ;
}
fifo_depth = fdtdec_get_int ( blob , node , " fifo-depth " , 0 ) ;
if ( fifo_depth < 0 ) {
printf ( " DWMMC%d: Can't get FIFO depth \n " , idx ) ;
return - EINVAL ;
}
/* Allocate the host */
host = calloc ( 1 , sizeof ( * host ) ) ;
if ( ! host )
return - ENOMEM ;
host - > name = " SOCFPGA DWMMC " ;
host - > ioaddr = ( void * ) regbase ;
host - > ioaddr = ( void * ) reg_ base ;
host - > buswidth = bus_width ;
host - > clksel = socfpga_dwmci_clksel ;
host - > dev_index = index ;
/* fixed clock divide by 4 which due to the SDMMC wrapper */
host - > dev_index = idx ;
/* F ixed clock divide by 4 which due to the SDMMC wrapper */
host - > bus_hz = clk ;
host - > fifoth_val = MSIZE ( 0x2 ) |
RX_WMARK ( CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2 - 1 ) |
TX_WMARK ( CONFIG_SOCFPGA_DWMMC_FIFO_DEPTH / 2 ) ;
RX_WMARK ( fifo_depth / 2 - 1 ) | TX_WMARK ( fifo_depth / 2 ) ;
return add_dwmci ( host , host - > bus_hz , 400000 ) ;
}
static int socfpga_dwmci_process_node ( const void * blob , int nodes [ ] ,
int count )
{
int i , node , ret ;
for ( i = 0 ; i < count ; i + + ) {
node = nodes [ i ] ;
if ( node < = 0 )
continue ;
ret = socfpga_dwmci_of_probe ( blob , node , i ) ;
if ( ret ) {
printf ( " %s: failed to decode dev %d \n " , __func__ , i ) ;
return ret ;
}
}
return 0 ;
}
int socfpga_dwmmc_init ( const void * blob )
{
int nodes [ 2 ] ; /* Max. two controllers. */
int ret , count ;
count = fdtdec_find_aliases_for_id ( blob , " mmc " ,
COMPAT_ALTERA_SOCFPGA_DWMMC ,
nodes , ARRAY_SIZE ( nodes ) ) ;
ret = socfpga_dwmci_process_node ( blob , nodes , count ) ;
return ret ;
}