aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/memory
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 /drivers/memory
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>
Diffstat (limited to 'drivers/memory')
-rw-r--r--drivers/memory/samsung/Kconfig2
-rw-r--r--drivers/memory/samsung/exynos-srom.c60
2 files changed, 59 insertions, 3 deletions
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)