aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Fedin <p.fedin@samsung.com>2016-04-11 03:42:27 -0400
committerKrzysztof Kozlowski <k.kozlowski@samsung.com>2016-04-18 08:25:29 -0400
commit8ac2266d88318d348fa5f1dad5b525e0d2c665ef (patch)
treea5654998e07d42976f3943a5cb24ffdbbdded1b8
parent5901f4c279f7ddbd32041ce1166387ffa05b902d (diff)
memory: samsung: exynos-srom: Add support for bank configuration
Implement handling properties in subnodes and adding child devices to the system. Child devices will not be added if configuration fails. Since the driver now does more than suspend-resume support, dependency on CONFIG_PM is removed. Signed-off-by: Pavel Fedin <p.fedin@samsung.com> Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com> Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
-rw-r--r--arch/arm/mach-exynos/Kconfig2
-rw-r--r--drivers/memory/samsung/Kconfig2
-rw-r--r--drivers/memory/samsung/exynos-srom.c60
3 files changed, 60 insertions, 4 deletions
diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig
index 28f992886d67..e65aa7d11b20 100644
--- a/arch/arm/mach-exynos/Kconfig
+++ b/arch/arm/mach-exynos/Kconfig
@@ -18,7 +18,7 @@ menuconfig ARCH_EXYNOS
18 select COMMON_CLK_SAMSUNG 18 select COMMON_CLK_SAMSUNG
19 select EXYNOS_THERMAL 19 select EXYNOS_THERMAL
20 select EXYNOS_PMU 20 select EXYNOS_PMU
21 select EXYNOS_SROM if PM 21 select EXYNOS_SROM
22 select HAVE_ARM_SCU if SMP 22 select HAVE_ARM_SCU if SMP
23 select HAVE_S3C2410_I2C if I2C 23 select HAVE_S3C2410_I2C if I2C
24 select HAVE_S3C2410_WATCHDOG if WATCHDOG 24 select HAVE_S3C2410_WATCHDOG if WATCHDOG
diff --git a/drivers/memory/samsung/Kconfig b/drivers/memory/samsung/Kconfig
index 64ab5dd9f626..9de12222061c 100644
--- a/drivers/memory/samsung/Kconfig
+++ b/drivers/memory/samsung/Kconfig
@@ -8,6 +8,6 @@ if SAMSUNG_MC
8 8
9config EXYNOS_SROM 9config EXYNOS_SROM
10 bool "Exynos SROM controller driver" if COMPILE_TEST 10 bool "Exynos SROM controller driver" if COMPILE_TEST
11 depends on (ARM && ARCH_EXYNOS && PM) || (COMPILE_TEST && HAS_IOMEM) 11 depends on (ARM && ARCH_EXYNOS) || (COMPILE_TEST && HAS_IOMEM)
12 12
13endif 13endif
diff --git a/drivers/memory/samsung/exynos-srom.c b/drivers/memory/samsung/exynos-srom.c
index 68e073c1651c..96756fb4d6bd 100644
--- a/drivers/memory/samsung/exynos-srom.c
+++ b/drivers/memory/samsung/exynos-srom.c
@@ -14,6 +14,7 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/of.h> 15#include <linux/of.h>
16#include <linux/of_address.h> 16#include <linux/of_address.h>
17#include <linux/of_platform.h>
17#include <linux/platform_device.h> 18#include <linux/platform_device.h>
18#include <linux/slab.h> 19#include <linux/slab.h>
19 20
@@ -67,11 +68,50 @@ static struct exynos_srom_reg_dump *exynos_srom_alloc_reg_dump(
67 return rd; 68 return rd;
68} 69}
69 70
71static int exynos_srom_configure_bank(struct exynos_srom *srom,
72 struct device_node *np)
73{
74 u32 bank, width, pmc = 0;
75 u32 timing[6];
76 u32 cs, bw;
77
78 if (of_property_read_u32(np, "reg", &bank))
79 return -EINVAL;
80 if (of_property_read_u32(np, "reg-io-width", &width))
81 width = 1;
82 if (of_property_read_bool(np, "samsung,srom-page-mode"))
83 pmc = 1 << EXYNOS_SROM_BCX__PMC__SHIFT;
84 if (of_property_read_u32_array(np, "samsung,srom-timing", timing,
85 ARRAY_SIZE(timing)))
86 return -EINVAL;
87
88 bank *= 4; /* Convert bank into shift/offset */
89
90 cs = 1 << EXYNOS_SROM_BW__BYTEENABLE__SHIFT;
91 if (width == 2)
92 cs |= 1 << EXYNOS_SROM_BW__DATAWIDTH__SHIFT;
93
94 bw = __raw_readl(srom->reg_base + EXYNOS_SROM_BW);
95 bw = (bw & ~(EXYNOS_SROM_BW__CS_MASK << bank)) | (cs << bank);
96 __raw_writel(bw, srom->reg_base + EXYNOS_SROM_BW);
97
98 __raw_writel(pmc | (timing[0] << EXYNOS_SROM_BCX__TACP__SHIFT) |
99 (timing[1] << EXYNOS_SROM_BCX__TCAH__SHIFT) |
100 (timing[2] << EXYNOS_SROM_BCX__TCOH__SHIFT) |
101 (timing[3] << EXYNOS_SROM_BCX__TACC__SHIFT) |
102 (timing[4] << EXYNOS_SROM_BCX__TCOS__SHIFT) |
103 (timing[5] << EXYNOS_SROM_BCX__TACS__SHIFT),
104 srom->reg_base + EXYNOS_SROM_BC0 + bank);
105
106 return 0;
107}
108
70static int exynos_srom_probe(struct platform_device *pdev) 109static int exynos_srom_probe(struct platform_device *pdev)
71{ 110{
72 struct device_node *np; 111 struct device_node *np, *child;
73 struct exynos_srom *srom; 112 struct exynos_srom *srom;
74 struct device *dev = &pdev->dev; 113 struct device *dev = &pdev->dev;
114 bool bad_bank_config = false;
75 115
76 np = dev->of_node; 116 np = dev->of_node;
77 if (!np) { 117 if (!np) {
@@ -100,7 +140,23 @@ static int exynos_srom_probe(struct platform_device *pdev)
100 return -ENOMEM; 140 return -ENOMEM;
101 } 141 }
102 142
103 return 0; 143 for_each_child_of_node(np, child) {
144 if (exynos_srom_configure_bank(srom, child)) {
145 dev_err(dev,
146 "Could not decode bank configuration for %s\n",
147 child->name);
148 bad_bank_config = true;
149 }
150 }
151
152 /*
153 * If any bank failed to configure, we still provide suspend/resume,
154 * but do not probe child devices
155 */
156 if (bad_bank_config)
157 return 0;
158
159 return of_platform_populate(np, NULL, NULL, dev);
104} 160}
105 161
106static int exynos_srom_remove(struct platform_device *pdev) 162static int exynos_srom_remove(struct platform_device *pdev)