mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	Topic branch for Samsung soc/drivers update for v4.7:
This moves Samsung SROM controller code from arm/mach-exynos into to separate driver under drivers/memory/samsung. In the future this driver will be re-used on ARM64 Exynos platform. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJXIHrcAAoJEME3ZuaGi4PXIfsP/0Fba9eiLkTobPb8B9KhBNzc sQqU3CfYNCQOHTz/1W//JHfFgyOQ67bQjKiMlU5NfXS34l33mafMRLqUhUxpnPZB 3FPkecv0eG/Ojj4XO/aY3GgDSDB0Dpi894D5y2OpbkcYTSADijf1VD4+0WvWsxn0 B9UnZFCbUg2nxbAEDxMuulaDnGi7WhUTaUFYUZVBMZjYaQxDVjVwhNFlixXey8cd 9X0SRnm0quPCnuL/j5UtLQCJQu6vnyM9MqauZQqC9J3Bkd+6LaCIVlObmmoV94O9 pOqllEpSbJ6YD6N3M6DYVMihmJUUj/MTFCuJQg9CJHeb4hWUHZXxDj9w+q0Ps1JI fKE7EhtloN1/31KpQJE7xysG8lyq1tE00v5d270QANyHUq6vYXIQgHU9DVpAorto xkytq/9QClVHm0c40BRVrxIgXyLeSekMtqA9ILpSnhdZepUpt0UIM21x1v5tez9Y S+CQJ3wU+iTA2HfSdFqaZ6bMYLlmqdHaylBtVorMdsLj/ZxKs2syEPgsJcDv1LWm 7pNG8S9d1zIeEB6YXfnUiaSkYvNWEkjn0GOiq+Hs+pPB+6HYoI9SaainAhzi9GAq G42gWyA8v/AupwS0A+V5d97agaMZXxuj/FhMH2xKGhvqdNB5QZVtkNOkO+twAO12 i8bFvqlBUO8vfmYj+J39 =6ukR -----END PGP SIGNATURE----- Merge tag 'samsung-drivers-exynos-srom-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux into next/drivers Merge "Samsung soc/drivers update for v4.7" from Krzysztof Kozłowski: This moves Samsung SROM controller code from arm/mach-exynos into to separate driver under drivers/memory/samsung. In the future this driver will be re-used on ARM64 Exynos platform. * tag 'samsung-drivers-exynos-srom-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux: memory: samsung: exynos-srom: Add support for bank configuration ARM: EXYNOS: Remove SROM related register settings from mach-exynos MAINTAINERS: Add maintainers entry for drivers/memory/samsung memory: Add support for Exynos SROM driver dt-bindings: EXYNOS: Add exynos-srom device tree binding ARM: dts: change SROM node compatible from generic to model specific
This commit is contained in:
		
						commit
						036dae83b9
					
				
					 18 changed files with 390 additions and 99 deletions
				
			
		|  | @ -0,0 +1,79 @@ | |||
| SAMSUNG Exynos SoCs SROM Controller driver. | ||||
| 
 | ||||
| Required properties: | ||||
| - compatible : Should contain "samsung,exynos4210-srom". | ||||
| 
 | ||||
| - reg: offset and length of the register set | ||||
| 
 | ||||
| Optional properties: | ||||
| The SROM controller can be used to attach external peripherals. In this case | ||||
| extra properties, describing the bus behind it, should be specified as below: | ||||
| 
 | ||||
| - #address-cells: Must be set to 2 to allow device address translation. | ||||
| 		  Address is specified as (bank#, offset). | ||||
| 
 | ||||
| - #size-cells: Must be set to 1 to allow device size passing | ||||
| 
 | ||||
| - ranges: Must be set up to reflect the memory layout with four integer values | ||||
| 	  per bank: | ||||
| 		<bank-number> 0 <parent address of bank> <size> | ||||
| 
 | ||||
| Sub-nodes: | ||||
| The actual device nodes should be added as subnodes to the SROMc node. These | ||||
| subnodes, in addition to regular device specification, should contain the following | ||||
| properties, describing configuration of the relevant SROM bank: | ||||
| 
 | ||||
| Required properties: | ||||
| - reg: bank number, base address (relative to start of the bank) and size of | ||||
|        the memory mapped for the device. Note that base address will be | ||||
|        typically 0 as this is the start of the bank. | ||||
| 
 | ||||
| - samsung,srom-timing : array of 6 integers, specifying bank timings in the | ||||
|                         following order: Tacp, Tcah, Tcoh, Tacc, Tcos, Tacs. | ||||
|                         Each value is specified in cycles and has the following | ||||
|                         meaning and valid range: | ||||
|                         Tacp : Page mode access cycle at Page mode (0 - 15) | ||||
|                         Tcah : Address holding time after CSn (0 - 15) | ||||
|                         Tcoh : Chip selection hold on OEn (0 - 15) | ||||
|                         Tacc : Access cycle (0 - 31, the actual time is N + 1) | ||||
|                         Tcos : Chip selection set-up before OEn (0 - 15) | ||||
|                         Tacs : Address set-up before CSn (0 - 15) | ||||
| 
 | ||||
| Optional properties: | ||||
| - reg-io-width : data width in bytes (1 or 2). If omitted, default of 1 is used. | ||||
| 
 | ||||
| - samsung,srom-page-mode : if page mode is set, 4 data page mode will be configured, | ||||
| 			   else normal (1 data) page mode will be set. | ||||
| 
 | ||||
| Example: basic definition, no banks are configured | ||||
| 	memory-controller@12570000 { | ||||
| 		compatible = "samsung,exynos4210-srom"; | ||||
| 		reg = <0x12570000 0x14>; | ||||
| 	}; | ||||
| 
 | ||||
| Example: SROMc with SMSC911x ethernet chip on bank 3 | ||||
| 	memory-controller@12570000 { | ||||
| 		#address-cells = <2>; | ||||
| 		#size-cells = <1>; | ||||
| 		ranges = <0 0 0x04000000 0x20000   // Bank0 | ||||
| 			  1 0 0x05000000 0x20000   // Bank1 | ||||
| 			  2 0 0x06000000 0x20000   // Bank2 | ||||
| 			  3 0 0x07000000 0x20000>; // Bank3 | ||||
| 
 | ||||
| 		compatible = "samsung,exynos4210-srom"; | ||||
| 		reg = <0x12570000 0x14>; | ||||
| 
 | ||||
| 		ethernet@3,0 { | ||||
| 			compatible = "smsc,lan9115"; | ||||
| 			reg = <3 0 0x10000>;	   // Bank 3, offset = 0 | ||||
| 			phy-mode = "mii"; | ||||
| 			interrupt-parent = <&gpx0>; | ||||
| 			interrupts = <5 8>; | ||||
| 			reg-io-width = <2>; | ||||
| 			smsc,irq-push-pull; | ||||
| 			smsc,force-internal-phy; | ||||
| 
 | ||||
| 			samsung,srom-page-mode; | ||||
| 			samsung,srom-timing = <9 12 1 9 1 1>; | ||||
| 		}; | ||||
| 	}; | ||||
|  | @ -1545,6 +1545,7 @@ F:	arch/arm/mach-s5p*/ | |||
| F:	arch/arm/mach-exynos*/ | ||||
| F:	drivers/*/*s3c2410* | ||||
| F:	drivers/*/*/*s3c2410* | ||||
| F:	drivers/memory/samsung/* | ||||
| F:	drivers/soc/samsung/* | ||||
| F:	drivers/spi/spi-s3c* | ||||
| F:	sound/soc/samsung/* | ||||
|  |  | |||
|  | @ -77,8 +77,8 @@ | |||
| 		reg = <0x10000000 0x100>; | ||||
| 	}; | ||||
| 
 | ||||
| 	sromc@12570000 { | ||||
| 		compatible = "samsung,exynos-srom"; | ||||
| 	memory-controller@12570000 { | ||||
| 		compatible = "samsung,exynos4210-srom"; | ||||
| 		reg = <0x12570000 0x14>; | ||||
| 	}; | ||||
| 
 | ||||
|  |  | |||
|  | @ -31,8 +31,8 @@ | |||
| 		reg = <0x10000000 0x100>; | ||||
| 	}; | ||||
| 
 | ||||
| 	sromc@12250000 { | ||||
| 		compatible = "samsung,exynos-srom"; | ||||
| 	memory-controller@12250000 { | ||||
| 		compatible = "samsung,exynos4210-srom"; | ||||
| 		reg = <0x12250000 0x14>; | ||||
| 	}; | ||||
| 
 | ||||
|  |  | |||
|  | @ -97,7 +97,7 @@ | |||
| 		smsc,irq-push-pull; | ||||
| 		smsc,force-internal-phy; | ||||
| 
 | ||||
| 		samsung,srom-page-mode = <1>; | ||||
| 		samsung,srom-page-mode; | ||||
| 		samsung,srom-timing = <9 12 1 9 1 1>; | ||||
| 	}; | ||||
| }; | ||||
|  |  | |||
|  | @ -102,8 +102,8 @@ | |||
| 			reg = <0x10000000 0x100>; | ||||
| 		}; | ||||
| 
 | ||||
| 		sromc: sromc@12250000 { | ||||
| 			compatible = "samsung,exynos-srom"; | ||||
| 		sromc: memory-controller@12250000 { | ||||
| 			compatible = "samsung,exynos4210-srom"; | ||||
| 			reg = <0x12250000 0x14>; | ||||
| 			#address-cells = <2>; | ||||
| 			#size-cells = <1>; | ||||
|  |  | |||
|  | @ -18,6 +18,7 @@ menuconfig ARCH_EXYNOS | |||
| 	select COMMON_CLK_SAMSUNG | ||||
| 	select EXYNOS_THERMAL | ||||
| 	select EXYNOS_PMU | ||||
| 	select EXYNOS_SROM | ||||
| 	select HAVE_ARM_SCU if SMP | ||||
| 	select HAVE_S3C2410_I2C if I2C | ||||
| 	select HAVE_S3C2410_WATCHDOG if WATCHDOG | ||||
|  | @ -26,11 +27,13 @@ menuconfig ARCH_EXYNOS | |||
| 	select PINCTRL_EXYNOS | ||||
| 	select PM_GENERIC_DOMAINS if PM | ||||
| 	select S5P_DEV_MFC | ||||
| 	select SAMSUNG_MC | ||||
| 	select SOC_SAMSUNG | ||||
| 	select SRAM | ||||
| 	select THERMAL | ||||
| 	select THERMAL_OF | ||||
| 	select MFD_SYSCON | ||||
| 	select MEMORY | ||||
| 	select CLKSRC_EXYNOS_MCT | ||||
| 	select POWER_RESET | ||||
| 	select POWER_RESET_SYSCON | ||||
|  |  | |||
|  | @ -31,11 +31,6 @@ | |||
| 
 | ||||
| static struct map_desc exynos4_iodesc[] __initdata = { | ||||
| 	{ | ||||
| 		.virtual	= (unsigned long)S5P_VA_SROMC, | ||||
| 		.pfn		= __phys_to_pfn(EXYNOS4_PA_SROMC), | ||||
| 		.length		= SZ_4K, | ||||
| 		.type		= MT_DEVICE, | ||||
| 	}, { | ||||
| 		.virtual	= (unsigned long)S5P_VA_CMU, | ||||
| 		.pfn		= __phys_to_pfn(EXYNOS4_PA_CMU), | ||||
| 		.length		= SZ_128K, | ||||
|  | @ -58,15 +53,6 @@ static struct map_desc exynos4_iodesc[] __initdata = { | |||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static struct map_desc exynos5_iodesc[] __initdata = { | ||||
| 	{ | ||||
| 		.virtual	= (unsigned long)S5P_VA_SROMC, | ||||
| 		.pfn		= __phys_to_pfn(EXYNOS5_PA_SROMC), | ||||
| 		.length		= SZ_4K, | ||||
| 		.type		= MT_DEVICE, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| static struct platform_device exynos_cpuidle = { | ||||
| 	.name              = "exynos_cpuidle", | ||||
| #ifdef CONFIG_ARM_EXYNOS_CPUIDLE | ||||
|  | @ -138,9 +124,6 @@ static void __init exynos_map_io(void) | |||
| { | ||||
| 	if (soc_is_exynos4()) | ||||
| 		iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc)); | ||||
| 
 | ||||
| 	if (soc_is_exynos5()) | ||||
| 		iotable_init(exynos5_iodesc, ARRAY_SIZE(exynos5_iodesc)); | ||||
| } | ||||
| 
 | ||||
| static void __init exynos_init_io(void) | ||||
|  |  | |||
|  | @ -25,7 +25,4 @@ | |||
| 
 | ||||
| #define EXYNOS4_PA_COREPERI		0x10500000 | ||||
| 
 | ||||
| #define EXYNOS4_PA_SROMC		0x12570000 | ||||
| #define EXYNOS5_PA_SROMC		0x12250000 | ||||
| 
 | ||||
| #endif /* __ASM_ARCH_MAP_H */ | ||||
|  |  | |||
|  | @ -1,53 +0,0 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2010 Samsung Electronics Co., Ltd. | ||||
|  *		http://www.samsung.com
 | ||||
|  * | ||||
|  * S5P SROMC register 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_SAMSUNG_REGS_SROM_H | ||||
| #define __PLAT_SAMSUNG_REGS_SROM_H __FILE__ | ||||
| 
 | ||||
| #include <mach/map.h> | ||||
| 
 | ||||
| #define S5P_SROMREG(x)		(S5P_VA_SROMC + (x)) | ||||
| 
 | ||||
| #define S5P_SROM_BW		S5P_SROMREG(0x0) | ||||
| #define S5P_SROM_BC0		S5P_SROMREG(0x4) | ||||
| #define S5P_SROM_BC1		S5P_SROMREG(0x8) | ||||
| #define S5P_SROM_BC2		S5P_SROMREG(0xc) | ||||
| #define S5P_SROM_BC3		S5P_SROMREG(0x10) | ||||
| #define S5P_SROM_BC4		S5P_SROMREG(0x14) | ||||
| #define S5P_SROM_BC5		S5P_SROMREG(0x18) | ||||
| 
 | ||||
| /* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */ | ||||
| 
 | ||||
| #define S5P_SROM_BW__DATAWIDTH__SHIFT		0 | ||||
| #define S5P_SROM_BW__ADDRMODE__SHIFT		1 | ||||
| #define S5P_SROM_BW__WAITENABLE__SHIFT		2 | ||||
| #define S5P_SROM_BW__BYTEENABLE__SHIFT		3 | ||||
| 
 | ||||
| #define S5P_SROM_BW__CS_MASK			0xf | ||||
| 
 | ||||
| #define S5P_SROM_BW__NCS0__SHIFT		0 | ||||
| #define S5P_SROM_BW__NCS1__SHIFT		4 | ||||
| #define S5P_SROM_BW__NCS2__SHIFT		8 | ||||
| #define S5P_SROM_BW__NCS3__SHIFT		12 | ||||
| #define S5P_SROM_BW__NCS4__SHIFT		16 | ||||
| #define S5P_SROM_BW__NCS5__SHIFT		20 | ||||
| 
 | ||||
| /* applies to same to BCS0 - BCS3 */ | ||||
| 
 | ||||
| #define S5P_SROM_BCX__PMC__SHIFT		0 | ||||
| #define S5P_SROM_BCX__TACP__SHIFT		4 | ||||
| #define S5P_SROM_BCX__TCAH__SHIFT		8 | ||||
| #define S5P_SROM_BCX__TCOH__SHIFT		12 | ||||
| #define S5P_SROM_BCX__TACC__SHIFT		16 | ||||
| #define S5P_SROM_BCX__TCOS__SHIFT		24 | ||||
| #define S5P_SROM_BCX__TACS__SHIFT		28 | ||||
| 
 | ||||
| #endif /* __PLAT_SAMSUNG_REGS_SROM_H */ | ||||
|  | @ -34,10 +34,11 @@ | |||
| #include <asm/smp_scu.h> | ||||
| #include <asm/suspend.h> | ||||
| 
 | ||||
| #include <mach/map.h> | ||||
| 
 | ||||
| #include <plat/pm-common.h> | ||||
| 
 | ||||
| #include "common.h" | ||||
| #include "regs-srom.h" | ||||
| 
 | ||||
| #define REG_TABLE_END (-1U) | ||||
| 
 | ||||
|  | @ -53,15 +54,6 @@ struct exynos_wkup_irq { | |||
| 	u32 mask; | ||||
| }; | ||||
| 
 | ||||
| static struct sleep_save exynos_core_save[] = { | ||||
| 	/* SROM side */ | ||||
| 	SAVE_ITEM(S5P_SROM_BW), | ||||
| 	SAVE_ITEM(S5P_SROM_BC0), | ||||
| 	SAVE_ITEM(S5P_SROM_BC1), | ||||
| 	SAVE_ITEM(S5P_SROM_BC2), | ||||
| 	SAVE_ITEM(S5P_SROM_BC3), | ||||
| }; | ||||
| 
 | ||||
| struct exynos_pm_data { | ||||
| 	const struct exynos_wkup_irq *wkup_irq; | ||||
| 	unsigned int wake_disable_mask; | ||||
|  | @ -343,8 +335,6 @@ static void exynos_pm_prepare(void) | |||
| 	/* Set wake-up mask registers */ | ||||
| 	exynos_pm_set_wakeup_mask(); | ||||
| 
 | ||||
| 	s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save)); | ||||
| 
 | ||||
| 	exynos_pm_enter_sleep_mode(); | ||||
| 
 | ||||
| 	/* ensure at least INFORM0 has the resume address */ | ||||
|  | @ -375,8 +365,6 @@ static void exynos5420_pm_prepare(void) | |||
| 	/* Set wake-up mask registers */ | ||||
| 	exynos_pm_set_wakeup_mask(); | ||||
| 
 | ||||
| 	s3c_pm_do_save(exynos_core_save, ARRAY_SIZE(exynos_core_save)); | ||||
| 
 | ||||
| 	exynos_pmu_spare3 = pmu_raw_readl(S5P_PMU_SPARE3); | ||||
| 	/*
 | ||||
| 	 * The cpu state needs to be saved and restored so that the | ||||
|  | @ -467,8 +455,6 @@ static void exynos_pm_resume(void) | |||
| 	/* For release retention */ | ||||
| 	exynos_pm_release_retention(); | ||||
| 
 | ||||
| 	s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); | ||||
| 
 | ||||
| 	if (cpuid == ARM_CPU_PART_CORTEX_A9) | ||||
| 		scu_enable(S5P_VA_SCU); | ||||
| 
 | ||||
|  | @ -535,8 +521,6 @@ static void exynos5420_pm_resume(void) | |||
| 
 | ||||
| 	pmu_raw_writel(exynos_pmu_spare3, S5P_PMU_SPARE3); | ||||
| 
 | ||||
| 	s3c_pm_do_restore_core(exynos_core_save, ARRAY_SIZE(exynos_core_save)); | ||||
| 
 | ||||
| early_wakeup: | ||||
| 
 | ||||
| 	tmp = pmu_raw_readl(EXYNOS5420_SFR_AXI_CGDIS1); | ||||
|  |  | |||
|  | @ -18,7 +18,6 @@ | |||
| 
 | ||||
| #define S5P_VA_DMC0		S3C_ADDR(0x02440000) | ||||
| #define S5P_VA_DMC1		S3C_ADDR(0x02480000) | ||||
| #define S5P_VA_SROMC		S3C_ADDR(0x024C0000) | ||||
| 
 | ||||
| #define S5P_VA_COREPERI_BASE	S3C_ADDR(0x02800000) | ||||
| #define S5P_VA_COREPERI(x)	(S5P_VA_COREPERI_BASE + (x)) | ||||
|  |  | |||
|  | @ -122,6 +122,7 @@ config MTK_SMI | |||
| 	  mainly help enable/disable iommu and control the power domain and | ||||
| 	  clocks for each local arbiter. | ||||
| 
 | ||||
| source "drivers/memory/samsung/Kconfig" | ||||
| source "drivers/memory/tegra/Kconfig" | ||||
| 
 | ||||
| endif | ||||
|  |  | |||
|  | @ -17,4 +17,5 @@ obj-$(CONFIG_TEGRA20_MC)	+= tegra20-mc.o | |||
| obj-$(CONFIG_JZ4780_NEMC)	+= jz4780-nemc.o | ||||
| obj-$(CONFIG_MTK_SMI)		+= mtk-smi.o | ||||
| 
 | ||||
| obj-$(CONFIG_SAMSUNG_MC)	+= samsung/ | ||||
| obj-$(CONFIG_TEGRA_MC)		+= tegra/ | ||||
|  |  | |||
							
								
								
									
										13
									
								
								drivers/memory/samsung/Kconfig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								drivers/memory/samsung/Kconfig
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| config SAMSUNG_MC | ||||
| 	bool "Samsung Exynos Memory Controller support" if COMPILE_TEST | ||||
| 	help | ||||
| 	  Support for the Memory Controller (MC) devices found on | ||||
| 	  Samsung Exynos SoCs. | ||||
| 
 | ||||
| if SAMSUNG_MC | ||||
| 
 | ||||
| config EXYNOS_SROM | ||||
| 	bool "Exynos SROM controller driver" if COMPILE_TEST | ||||
| 	depends on (ARM && ARCH_EXYNOS) || (COMPILE_TEST && HAS_IOMEM) | ||||
| 
 | ||||
| endif | ||||
							
								
								
									
										1
									
								
								drivers/memory/samsung/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								drivers/memory/samsung/Makefile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | |||
| obj-$(CONFIG_EXYNOS_SROM)	+= exynos-srom.o | ||||
							
								
								
									
										231
									
								
								drivers/memory/samsung/exynos-srom.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										231
									
								
								drivers/memory/samsung/exynos-srom.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,231 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2015 Samsung Electronics Co., Ltd. | ||||
|  *	      http://www.samsung.com/
 | ||||
|  * | ||||
|  * EXYNOS - SROM Controller support | ||||
|  * Author: Pankaj Dubey <pankaj.dubey@samsung.com> | ||||
|  * | ||||
|  * 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/io.h> | ||||
| #include <linux/module.h> | ||||
| #include <linux/of.h> | ||||
| #include <linux/of_address.h> | ||||
| #include <linux/of_platform.h> | ||||
| #include <linux/platform_device.h> | ||||
| #include <linux/slab.h> | ||||
| 
 | ||||
| #include "exynos-srom.h" | ||||
| 
 | ||||
| static const unsigned long exynos_srom_offsets[] = { | ||||
| 	/* SROM side */ | ||||
| 	EXYNOS_SROM_BW, | ||||
| 	EXYNOS_SROM_BC0, | ||||
| 	EXYNOS_SROM_BC1, | ||||
| 	EXYNOS_SROM_BC2, | ||||
| 	EXYNOS_SROM_BC3, | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * struct exynos_srom_reg_dump: register dump of SROM Controller registers. | ||||
|  * @offset: srom register offset from the controller base address. | ||||
|  * @value: the value of register under the offset. | ||||
|  */ | ||||
| struct exynos_srom_reg_dump { | ||||
| 	u32     offset; | ||||
| 	u32     value; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * struct exynos_srom: platform data for exynos srom controller driver. | ||||
|  * @dev: platform device pointer | ||||
|  * @reg_base: srom base address | ||||
|  * @reg_offset: exynos_srom_reg_dump pointer to hold offset and its value. | ||||
|  */ | ||||
| struct exynos_srom { | ||||
| 	struct device *dev; | ||||
| 	void __iomem *reg_base; | ||||
| 	struct exynos_srom_reg_dump *reg_offset; | ||||
| }; | ||||
| 
 | ||||
| static struct exynos_srom_reg_dump *exynos_srom_alloc_reg_dump( | ||||
| 		const unsigned long *rdump, | ||||
| 		unsigned long nr_rdump) | ||||
| { | ||||
| 	struct exynos_srom_reg_dump *rd; | ||||
| 	unsigned int i; | ||||
| 
 | ||||
| 	rd = kcalloc(nr_rdump, sizeof(*rd), GFP_KERNEL); | ||||
| 	if (!rd) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	for (i = 0; i < nr_rdump; ++i) | ||||
| 		rd[i].offset = rdump[i]; | ||||
| 
 | ||||
| 	return rd; | ||||
| } | ||||
| 
 | ||||
| static int exynos_srom_configure_bank(struct exynos_srom *srom, | ||||
| 				      struct device_node *np) | ||||
| { | ||||
| 	u32 bank, width, pmc = 0; | ||||
| 	u32 timing[6]; | ||||
| 	u32 cs, bw; | ||||
| 
 | ||||
| 	if (of_property_read_u32(np, "reg", &bank)) | ||||
| 		return -EINVAL; | ||||
| 	if (of_property_read_u32(np, "reg-io-width", &width)) | ||||
| 		width = 1; | ||||
| 	if (of_property_read_bool(np, "samsung,srom-page-mode")) | ||||
| 		pmc = 1 << EXYNOS_SROM_BCX__PMC__SHIFT; | ||||
| 	if (of_property_read_u32_array(np, "samsung,srom-timing", timing, | ||||
| 				       ARRAY_SIZE(timing))) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	bank *= 4; /* Convert bank into shift/offset */ | ||||
| 
 | ||||
| 	cs = 1 << EXYNOS_SROM_BW__BYTEENABLE__SHIFT; | ||||
| 	if (width == 2) | ||||
| 		cs |= 1 << EXYNOS_SROM_BW__DATAWIDTH__SHIFT; | ||||
| 
 | ||||
| 	bw = __raw_readl(srom->reg_base + EXYNOS_SROM_BW); | ||||
| 	bw = (bw & ~(EXYNOS_SROM_BW__CS_MASK << bank)) | (cs << bank); | ||||
| 	__raw_writel(bw, srom->reg_base + EXYNOS_SROM_BW); | ||||
| 
 | ||||
| 	__raw_writel(pmc | (timing[0] << EXYNOS_SROM_BCX__TACP__SHIFT) | | ||||
| 		    (timing[1] << EXYNOS_SROM_BCX__TCAH__SHIFT) | | ||||
| 		    (timing[2] << EXYNOS_SROM_BCX__TCOH__SHIFT) | | ||||
| 		    (timing[3] << EXYNOS_SROM_BCX__TACC__SHIFT) | | ||||
| 		    (timing[4] << EXYNOS_SROM_BCX__TCOS__SHIFT) | | ||||
| 		    (timing[5] << EXYNOS_SROM_BCX__TACS__SHIFT), | ||||
| 		    srom->reg_base + EXYNOS_SROM_BC0 + bank); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int exynos_srom_probe(struct platform_device *pdev) | ||||
| { | ||||
| 	struct device_node *np, *child; | ||||
| 	struct exynos_srom *srom; | ||||
| 	struct device *dev = &pdev->dev; | ||||
| 	bool bad_bank_config = false; | ||||
| 
 | ||||
| 	np = dev->of_node; | ||||
| 	if (!np) { | ||||
| 		dev_err(&pdev->dev, "could not find device info\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
| 
 | ||||
| 	srom = devm_kzalloc(&pdev->dev, | ||||
| 			sizeof(struct exynos_srom), GFP_KERNEL); | ||||
| 	if (!srom) | ||||
| 		return -ENOMEM; | ||||
| 
 | ||||
| 	srom->dev = dev; | ||||
| 	srom->reg_base = of_iomap(np, 0); | ||||
| 	if (!srom->reg_base) { | ||||
| 		dev_err(&pdev->dev, "iomap of exynos srom controller failed\n"); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 
 | ||||
| 	platform_set_drvdata(pdev, srom); | ||||
| 
 | ||||
| 	srom->reg_offset = exynos_srom_alloc_reg_dump(exynos_srom_offsets, | ||||
| 			sizeof(exynos_srom_offsets)); | ||||
| 	if (!srom->reg_offset) { | ||||
| 		iounmap(srom->reg_base); | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 
 | ||||
| 	for_each_child_of_node(np, child) { | ||||
| 		if (exynos_srom_configure_bank(srom, child)) { | ||||
| 			dev_err(dev, | ||||
| 				"Could not decode bank configuration for %s\n", | ||||
| 				child->name); | ||||
| 			bad_bank_config = true; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * If any bank failed to configure, we still provide suspend/resume, | ||||
| 	 * but do not probe child devices | ||||
| 	 */ | ||||
| 	if (bad_bank_config) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	return of_platform_populate(np, NULL, NULL, dev); | ||||
| } | ||||
| 
 | ||||
| static int exynos_srom_remove(struct platform_device *pdev) | ||||
| { | ||||
| 	struct exynos_srom *srom = platform_get_drvdata(pdev); | ||||
| 
 | ||||
| 	kfree(srom->reg_offset); | ||||
| 	iounmap(srom->reg_base); | ||||
| 
 | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_PM_SLEEP | ||||
| static void exynos_srom_save(void __iomem *base, | ||||
| 				    struct exynos_srom_reg_dump *rd, | ||||
| 				    unsigned int num_regs) | ||||
| { | ||||
| 	for (; num_regs > 0; --num_regs, ++rd) | ||||
| 		rd->value = readl(base + rd->offset); | ||||
| } | ||||
| 
 | ||||
| static void exynos_srom_restore(void __iomem *base, | ||||
| 				      const struct exynos_srom_reg_dump *rd, | ||||
| 				      unsigned int num_regs) | ||||
| { | ||||
| 	for (; num_regs > 0; --num_regs, ++rd) | ||||
| 		writel(rd->value, base + rd->offset); | ||||
| } | ||||
| 
 | ||||
| static int exynos_srom_suspend(struct device *dev) | ||||
| { | ||||
| 	struct exynos_srom *srom = dev_get_drvdata(dev); | ||||
| 
 | ||||
| 	exynos_srom_save(srom->reg_base, srom->reg_offset, | ||||
| 				ARRAY_SIZE(exynos_srom_offsets)); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static int exynos_srom_resume(struct device *dev) | ||||
| { | ||||
| 	struct exynos_srom *srom = dev_get_drvdata(dev); | ||||
| 
 | ||||
| 	exynos_srom_restore(srom->reg_base, srom->reg_offset, | ||||
| 				ARRAY_SIZE(exynos_srom_offsets)); | ||||
| 	return 0; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| static const struct of_device_id of_exynos_srom_ids[] = { | ||||
| 	{ | ||||
| 		.compatible	= "samsung,exynos4210-srom", | ||||
| 	}, | ||||
| 	{}, | ||||
| }; | ||||
| MODULE_DEVICE_TABLE(of, of_exynos_srom_ids); | ||||
| 
 | ||||
| static SIMPLE_DEV_PM_OPS(exynos_srom_pm_ops, exynos_srom_suspend, exynos_srom_resume); | ||||
| 
 | ||||
| static struct platform_driver exynos_srom_driver = { | ||||
| 	.probe = exynos_srom_probe, | ||||
| 	.remove = exynos_srom_remove, | ||||
| 	.driver = { | ||||
| 		.name = "exynos-srom", | ||||
| 		.of_match_table = of_exynos_srom_ids, | ||||
| 		.pm = &exynos_srom_pm_ops, | ||||
| 	}, | ||||
| }; | ||||
| module_platform_driver(exynos_srom_driver); | ||||
| 
 | ||||
| MODULE_AUTHOR("Pankaj Dubey <pankaj.dubey@samsung.com>"); | ||||
| MODULE_DESCRIPTION("Exynos SROM Controller Driver"); | ||||
| MODULE_LICENSE("GPL"); | ||||
							
								
								
									
										51
									
								
								drivers/memory/samsung/exynos-srom.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								drivers/memory/samsung/exynos-srom.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2015 Samsung Electronics Co., Ltd. | ||||
|  *		http://www.samsung.com
 | ||||
|  * | ||||
|  * Exynos SROMC register 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 __EXYNOS_SROM_H | ||||
| #define __EXYNOS_SROM_H __FILE__ | ||||
| 
 | ||||
| #define EXYNOS_SROMREG(x)		(x) | ||||
| 
 | ||||
| #define EXYNOS_SROM_BW		EXYNOS_SROMREG(0x0) | ||||
| #define EXYNOS_SROM_BC0		EXYNOS_SROMREG(0x4) | ||||
| #define EXYNOS_SROM_BC1		EXYNOS_SROMREG(0x8) | ||||
| #define EXYNOS_SROM_BC2		EXYNOS_SROMREG(0xc) | ||||
| #define EXYNOS_SROM_BC3		EXYNOS_SROMREG(0x10) | ||||
| #define EXYNOS_SROM_BC4		EXYNOS_SROMREG(0x14) | ||||
| #define EXYNOS_SROM_BC5		EXYNOS_SROMREG(0x18) | ||||
| 
 | ||||
| /* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */ | ||||
| 
 | ||||
| #define EXYNOS_SROM_BW__DATAWIDTH__SHIFT	0 | ||||
| #define EXYNOS_SROM_BW__ADDRMODE__SHIFT		1 | ||||
| #define EXYNOS_SROM_BW__WAITENABLE__SHIFT	2 | ||||
| #define EXYNOS_SROM_BW__BYTEENABLE__SHIFT	3 | ||||
| 
 | ||||
| #define EXYNOS_SROM_BW__CS_MASK			0xf | ||||
| 
 | ||||
| #define EXYNOS_SROM_BW__NCS0__SHIFT		0 | ||||
| #define EXYNOS_SROM_BW__NCS1__SHIFT		4 | ||||
| #define EXYNOS_SROM_BW__NCS2__SHIFT		8 | ||||
| #define EXYNOS_SROM_BW__NCS3__SHIFT		12 | ||||
| #define EXYNOS_SROM_BW__NCS4__SHIFT		16 | ||||
| #define EXYNOS_SROM_BW__NCS5__SHIFT		20 | ||||
| 
 | ||||
| /* applies to same to BCS0 - BCS3 */ | ||||
| 
 | ||||
| #define EXYNOS_SROM_BCX__PMC__SHIFT		0 | ||||
| #define EXYNOS_SROM_BCX__TACP__SHIFT		4 | ||||
| #define EXYNOS_SROM_BCX__TCAH__SHIFT		8 | ||||
| #define EXYNOS_SROM_BCX__TCOH__SHIFT		12 | ||||
| #define EXYNOS_SROM_BCX__TACC__SHIFT		16 | ||||
| #define EXYNOS_SROM_BCX__TCOS__SHIFT		24 | ||||
| #define EXYNOS_SROM_BCX__TACS__SHIFT		28 | ||||
| 
 | ||||
| #endif /* __EXYNOS_SROM_H */ | ||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Arnd Bergmann
						Arnd Bergmann