mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	[ARM] S3C6410: Add helper for setting SDHCI device information
Add the necessary helper functions for setting up the SDHCI device information. Signed-off-by: Ben Dooks <ben-linux@fluff.org>
This commit is contained in:
		
							parent
							
								
									ea522c7a54
								
							
						
					
					
						commit
						5cc7fd88fc
					
				
					 6 changed files with 233 additions and 9 deletions
				
			
		|  | @ -14,9 +14,15 @@ config CPU_S3C6410 | |||
| 	help | ||||
| 	  Enable S3C6410 CPU support | ||||
| 
 | ||||
| config S3C6410_SETUP_SDHCI | ||||
| 	bool | ||||
| 	help | ||||
| 	  Internal helper functions for S3C6410 based SDHCI systems | ||||
| 
 | ||||
| config MACH_SMDK6410 | ||||
| 	bool "SMDK6410" | ||||
| 	select CPU_S3C6410 | ||||
| 	select S3C_DEV_HSMMC | ||||
| 	select S3C6410_SETUP_SDHCI | ||||
| 	help | ||||
| 	  Machine support for the Samsung SMDK6410 | ||||
|  |  | |||
|  | @ -14,6 +14,10 @@ obj-				:= | |||
| 
 | ||||
| obj-$(CONFIG_CPU_S3C6410)	+= cpu.o | ||||
| 
 | ||||
| # Helper and device support
 | ||||
| 
 | ||||
| obj-$(CONFIG_S3C6410_SETUP_SDHCI)	+= setup-sdhci.o | ||||
| 
 | ||||
| # machine support
 | ||||
| 
 | ||||
| obj-$(CONFIG_MACH_SMDK6410)	+= mach-smdk6410.o | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ | |||
| #include <plat/cpu.h> | ||||
| #include <plat/devs.h> | ||||
| #include <plat/clock.h> | ||||
| #include <plat/sdhci.h> | ||||
| #include <plat/s3c6400.h> | ||||
| #include <plat/s3c6410.h> | ||||
| 
 | ||||
|  | @ -51,6 +52,9 @@ static struct map_desc s3c6410_iodesc[] __initdata = { | |||
| void __init s3c6410_map_io(void) | ||||
| { | ||||
| 	iotable_init(s3c6410_iodesc, ARRAY_SIZE(s3c6410_iodesc)); | ||||
| 
 | ||||
| 	/* initialise device information early */ | ||||
| 	s3c6410_default_sdhci0(); | ||||
| } | ||||
| 
 | ||||
| void __init s3c6410_init_clocks(int xtal) | ||||
|  |  | |||
							
								
								
									
										102
									
								
								arch/arm/mach-s3c6410/setup-sdhci.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								arch/arm/mach-s3c6410/setup-sdhci.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,102 @@ | |||
| /* linux/arch/arm/mach-s3c6410/setup-sdhci.c
 | ||||
|  * | ||||
|  * Copyright 2008 Simtec Electronics | ||||
|  * Copyright 2008 Simtec Electronics | ||||
|  *	Ben Dooks <ben@simtec.co.uk> | ||||
|  *	http://armlinux.simtec.co.uk/
 | ||||
|  * | ||||
|  * S3C6410 - Helper functions for settign up SDHCI device(s) (HSMMC) | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
| */ | ||||
| 
 | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/types.h> | ||||
| #include <linux/interrupt.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/io.h> | ||||
| 
 | ||||
| #include <linux/mmc/card.h> | ||||
| #include <linux/mmc/host.h> | ||||
| 
 | ||||
| #include <mach/gpio.h> | ||||
| #include <plat/gpio-cfg.h> | ||||
| #include <plat/regs-sdhci.h> | ||||
| #include <plat/sdhci.h> | ||||
| 
 | ||||
| /* clock sources for the mmc bus clock, order as for the ctrl2[5..4] */ | ||||
| 
 | ||||
| char *s3c6410_hsmmc_clksrcs[4] = { | ||||
| 	[0] = "hsmmc", | ||||
| 	[1] = "hsmmc", | ||||
| 	[2] = "mmc_bus", | ||||
| 	/* [3] = "48m", - note not succesfully used yet */ | ||||
| }; | ||||
| 
 | ||||
| void s3c6410_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width) | ||||
| { | ||||
| 	unsigned int gpio; | ||||
| 	unsigned int end; | ||||
| 
 | ||||
| 	end = S3C64XX_GPG(2 + width); | ||||
| 
 | ||||
| 	/* Set all the necessary GPG pins to special-function 0 */ | ||||
| 	for (gpio = S3C64XX_GPG(0); gpio < end; gpio++) { | ||||
| 		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); | ||||
| 		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||||
| 	} | ||||
| 
 | ||||
| 	s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP); | ||||
| 	s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(2)); | ||||
| } | ||||
| 
 | ||||
| void s3c6410_setup_sdhci0_cfg_card(struct platform_device *dev, | ||||
| 				    void __iomem *r, | ||||
| 				    struct mmc_ios *ios, | ||||
| 				    struct mmc_card *card) | ||||
| { | ||||
| 	u32 ctrl2, ctrl3; | ||||
| 
 | ||||
| 	/* don't need to alter anything acording to card-type */ | ||||
| 
 | ||||
| 	writel(S3C64XX_SDHCI_CONTROL4_DRIVE_9mA, r + S3C64XX_SDHCI_CONTROL4); | ||||
| 
 | ||||
| 	ctrl2 = readl(r + S3C_SDHCI_CONTROL2); | ||||
| 	ctrl2 &= S3C_SDHCI_CTRL2_SELBASECLK_MASK; | ||||
| 	ctrl2 |= (S3C64XX_SDHCI_CTRL2_ENSTAASYNCCLR | | ||||
| 		  S3C64XX_SDHCI_CTRL2_ENCMDCNFMSK | | ||||
| 		  S3C_SDHCI_CTRL2_ENFBCLKRX | | ||||
| 		  S3C_SDHCI_CTRL2_DFCNT_NONE | | ||||
| 		  S3C_SDHCI_CTRL2_ENCLKOUTHOLD); | ||||
| 
 | ||||
| 	if (ios->clock < 25 * 1000000) | ||||
| 		ctrl3 = (S3C_SDHCI_CTRL3_FCSEL3 | | ||||
| 			 S3C_SDHCI_CTRL3_FCSEL2 | | ||||
| 			 S3C_SDHCI_CTRL3_FCSEL1 | | ||||
| 			 S3C_SDHCI_CTRL3_FCSEL0); | ||||
| 	else | ||||
| 		ctrl3 = (S3C_SDHCI_CTRL3_FCSEL1 | S3C_SDHCI_CTRL3_FCSEL0); | ||||
| 
 | ||||
| 	printk(KERN_INFO "%s: CTRL 2=%08x, 3=%08x\n", __func__, ctrl2, ctrl3); | ||||
| 	writel(ctrl2, r + S3C_SDHCI_CONTROL2); | ||||
| 	writel(ctrl3, r + S3C_SDHCI_CONTROL3); | ||||
| } | ||||
| 
 | ||||
| void s3c6410_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width) | ||||
| { | ||||
| 	unsigned int gpio; | ||||
| 	unsigned int end; | ||||
| 
 | ||||
| 	end = S3C64XX_GPH(2 + width); | ||||
| 
 | ||||
| 	/* Set all the necessary GPG pins to special-function 0 */ | ||||
| 	for (gpio = S3C64XX_GPH(0); gpio < end; gpio++) { | ||||
| 		s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2)); | ||||
| 		s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE); | ||||
| 	} | ||||
| 
 | ||||
| 	s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP); | ||||
| 	s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(3)); | ||||
| } | ||||
|  | @ -13,8 +13,10 @@ | |||
| 
 | ||||
| #include <linux/kernel.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/mmc/host.h> | ||||
| 
 | ||||
| #include <mach/map.h> | ||||
| #include <plat/sdhci.h> | ||||
| #include <plat/devs.h> | ||||
| #include <plat/cpu.h> | ||||
| 
 | ||||
|  | @ -35,13 +37,32 @@ static struct resource s3c_hsmmc_resource[] = { | |||
| 
 | ||||
| static u64 s3c_device_hsmmc_dmamask = 0xffffffffUL; | ||||
| 
 | ||||
| struct platform_device s3c_device_hsmmc0 = { | ||||
| 	.name		  = "s3c-sdhci", | ||||
| 	.id		  = 0, | ||||
| 	.num_resources	  = ARRAY_SIZE(s3c_hsmmc_resource), | ||||
| 	.resource	  = s3c_hsmmc_resource, | ||||
| 	.dev              = { | ||||
| 		.dma_mask = &s3c_device_hsmmc_dmamask, | ||||
| 		.coherent_dma_mask = 0xffffffffUL | ||||
| 	} | ||||
| struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata = { | ||||
| 	.max_width	= 4, | ||||
| 	.host_caps	= (MMC_CAP_4_BIT_DATA | | ||||
| 			   MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED), | ||||
| }; | ||||
| 
 | ||||
| struct platform_device s3c_device_hsmmc0 = { | ||||
| 	.name		= "s3c-sdhci", | ||||
| 	.id		= 0, | ||||
| 	.num_resources	= ARRAY_SIZE(s3c_hsmmc_resource), | ||||
| 	.resource	= s3c_hsmmc_resource, | ||||
| 	.dev		= { | ||||
| 		.dma_mask		= &s3c_device_hsmmc_dmamask, | ||||
| 		.coherent_dma_mask	= 0xffffffffUL, | ||||
| 		.platform_data		= &s3c_hsmmc0_def_platdata, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd) | ||||
| { | ||||
| 	struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata; | ||||
| 
 | ||||
| 	set->max_width = pd->max_width; | ||||
| 
 | ||||
| 	if (pd->cfg_gpio) | ||||
| 		set->cfg_gpio = pd->cfg_gpio; | ||||
| 	if (pd->cfg_card) | ||||
| 		set->cfg_card = pd->cfg_card; | ||||
| } | ||||
|  |  | |||
							
								
								
									
										87
									
								
								arch/arm/plat-s3c/include/plat/sdhci.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								arch/arm/plat-s3c/include/plat/sdhci.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,87 @@ | |||
| /* linux/arch/arm/plat-s3c/include/plat/sdhci.h
 | ||||
|  * | ||||
|  * Copyright 2008 Openmoko, Inc. | ||||
|  * Copyright 2008 Simtec Electronics | ||||
|  *	http://armlinux.simtec.co.uk/
 | ||||
|  *	Ben Dooks <ben@simtec.co.uk> | ||||
|  * | ||||
|  * S3C Platform - SDHCI (HSMMC) platform data definitions | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify | ||||
|  * it under the terms of the GNU General Public License version 2 as | ||||
|  * published by the Free Software Foundation. | ||||
| */ | ||||
| 
 | ||||
| #ifndef __PLAT_S3C_SDHCI_H | ||||
| #define __PLAT_S3C_SDHCI_H __FILE__ | ||||
| 
 | ||||
| struct platform_device; | ||||
| struct mmc_host; | ||||
| struct mmc_card; | ||||
| struct mmc_ios; | ||||
| 
 | ||||
| /**
 | ||||
|  * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI | ||||
|  * @max_width: The maximum number of data bits supported. | ||||
|  * @host_caps: Standard MMC host capabilities bit field. | ||||
|  * @cfg_gpio: Configure the GPIO for a specific card bit-width | ||||
|  * @cfg_card: Configure the interface for a specific card and speed. This | ||||
|  *            is necessary the controllers and/or GPIO blocks require the | ||||
|  *	      changing of driver-strength and other controls dependant on | ||||
|  *	      the card and speed of operation. | ||||
|  * | ||||
|  * Initialisation data specific to either the machine or the platform | ||||
|  * for the device driver to use or call-back when configuring gpio or | ||||
|  * card speed information. | ||||
| */ | ||||
| struct s3c_sdhci_platdata { | ||||
| 	unsigned int	max_width; | ||||
| 	unsigned int	host_caps; | ||||
| 
 | ||||
| 	char		**clocks;	/* set of clock sources */ | ||||
| 
 | ||||
| 	void	(*cfg_gpio)(struct platform_device *dev, int width); | ||||
| 	void	(*cfg_card)(struct platform_device *dev, | ||||
| 			    void __iomem *regbase, | ||||
| 			    struct mmc_ios *ios, | ||||
| 			    struct mmc_card *card); | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * s3c_sdhci0_set_platdata - Set platform data for S3C SDHCI device. | ||||
|  * @pd: Platform data to register to device. | ||||
|  * | ||||
|  * Register the given platform data for use withe S3C SDHCI device. | ||||
|  * The call will copy the platform data, so the board definitions can | ||||
|  * make the structure itself __initdata. | ||||
|  */ | ||||
| extern void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd); | ||||
| 
 | ||||
| /* Default platform data, exported so that per-cpu initialisation can
 | ||||
|  * set the correct one when there are more than one cpu type selected. | ||||
| */ | ||||
| 
 | ||||
| extern struct s3c_sdhci_platdata s3c_hsmmc0_def_platata; | ||||
| 
 | ||||
| /* Helper function availablity */ | ||||
| 
 | ||||
| #ifdef CONFIG_S3C6410_SETUP_SDHCI | ||||
| extern char *s3c6410_hsmmc_clksrcs[4]; | ||||
| 
 | ||||
| extern void s3c6410_setup_sdhci0_cfg_gpio(struct platform_device *, int w); | ||||
| extern void s3c6410_setup_sdhci0_cfg_card(struct platform_device *dev, | ||||
| 					   void __iomem *r, | ||||
| 					   struct mmc_ios *ios, | ||||
| 					   struct mmc_card *card); | ||||
| 
 | ||||
| static inline void s3c6410_default_sdhci0(void) | ||||
| { | ||||
| 	s3c_hsmmc0_def_platdata.clocks = s3c6410_hsmmc_clksrcs; | ||||
| 	s3c_hsmmc0_def_platdata.cfg_gpio = s3c6410_setup_sdhci0_cfg_gpio; | ||||
| 	s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci0_cfg_card; | ||||
| } | ||||
| #else | ||||
| static inline void s3c6410_default_sdhci0(void) { } | ||||
| #endif /* CONFIG_S3C6410_SETUP_SDHCI */ | ||||
| 
 | ||||
| #endif /* __PLAT_S3C_SDHCI_H */ | ||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Ben Dooks
						Ben Dooks