2010-10-15 12:21:03 +02:00
/*
* Freescale eSDHC controller driver generics for OF and pltfm .
*
* Copyright ( c ) 2007 Freescale Semiconductor , Inc .
* Copyright ( c ) 2009 MontaVista Software , Inc .
* Copyright ( c ) 2010 Pengutronix e . K .
* Author : Wolfram Sang < w . sang @ pengutronix . de >
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation ; either version 2 of the License .
*/
# ifndef _DRIVERS_MMC_SDHCI_ESDHC_H
# define _DRIVERS_MMC_SDHCI_ESDHC_H
/*
* Ops and quirks for the Freescale eSDHC controller .
*/
# define ESDHC_DEFAULT_QUIRKS (SDHCI_QUIRK_FORCE_BLK_SZ_2048 | \
SDHCI_QUIRK_NO_BUSY_IRQ | \
SDHCI_QUIRK_NONSTANDARD_CLOCK | \
SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
SDHCI_QUIRK_PIO_NEEDS_DELAY | \
2011-03-21 13:22:13 +08:00
SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET )
2010-10-15 12:21:03 +02:00
# define ESDHC_SYSTEM_CONTROL 0x2c
# define ESDHC_CLOCK_MASK 0x0000fff0
# define ESDHC_PREDIV_SHIFT 8
# define ESDHC_DIVIDER_SHIFT 4
# define ESDHC_CLOCK_PEREN 0x00000004
# define ESDHC_CLOCK_HCKEN 0x00000002
# define ESDHC_CLOCK_IPGEN 0x00000001
/* pltfm-specific */
# define ESDHC_HOST_CONTROL_LE 0x20
/* OF-specific */
# define ESDHC_DMA_SYSCTL 0x40c
# define ESDHC_DMA_SNOOP 0x00000040
# define ESDHC_HOST_CONTROL_RES 0x05
static inline void esdhc_set_clock ( struct sdhci_host * host , unsigned int clock )
{
int pre_div = 2 ;
int div = 1 ;
u32 temp ;
2012-08-22 23:10:01 +08:00
if ( clock = = 0 )
goto out ;
2010-10-15 12:21:03 +02:00
temp = sdhci_readl ( host , ESDHC_SYSTEM_CONTROL ) ;
temp & = ~ ( ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
| ESDHC_CLOCK_MASK ) ;
sdhci_writel ( host , temp , ESDHC_SYSTEM_CONTROL ) ;
while ( host - > max_clk / pre_div / 16 > clock & & pre_div < 256 )
pre_div * = 2 ;
while ( host - > max_clk / pre_div / div > clock & & div < 16 )
div + + ;
dev_dbg ( mmc_dev ( host - > mmc ) , " desired SD clock: %d, actual: %d \n " ,
clock , host - > max_clk / pre_div / div ) ;
pre_div > > = 1 ;
div - - ;
temp = sdhci_readl ( host , ESDHC_SYSTEM_CONTROL ) ;
temp | = ( ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
| ( div < < ESDHC_DIVIDER_SHIFT )
| ( pre_div < < ESDHC_PREDIV_SHIFT ) ) ;
sdhci_writel ( host , temp , ESDHC_SYSTEM_CONTROL ) ;
2011-11-22 14:42:30 +08:00
mdelay ( 1 ) ;
2010-10-15 12:21:03 +02:00
out :
host - > clock = clock ;
}
# endif /* _DRIVERS_MMC_SDHCI_ESDHC_H */