aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPankaj Dubey <pankaj.dubey@samsung.com>2016-04-11 03:42:24 -0400
committerKrzysztof Kozlowski <k.kozlowski@samsung.com>2016-04-18 08:25:27 -0400
commita8aabb91dc5bef0875d93d6a86d01779947604e1 (patch)
tree21cccc4bd15e66e7de670d68362ea9877e9c3e2c
parent92537d65d58ede86d752d1390cf3b51480ab0179 (diff)
memory: Add support for Exynos SROM driver
This patch adds Exynos SROM controller driver which will handle save restore of SROM registers during S2R. Signed-off-by: Pankaj Dubey <pankaj.dubey@samsung.com> Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> [p.fedin@samsung.com: tested on SMDK5410] Tested-by: Pavel Fedin <p.fedin@samsung.com> Signed-off-by: Kukjin Kim <kgene@kernel.org> [k.kozlowski: Minor COMPILE_TEST adjustments in Kconfig entries] Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
-rw-r--r--drivers/memory/Kconfig1
-rw-r--r--drivers/memory/Makefile1
-rw-r--r--drivers/memory/samsung/Kconfig13
-rw-r--r--drivers/memory/samsung/Makefile1
-rw-r--r--drivers/memory/samsung/exynos-srom.c175
-rw-r--r--drivers/memory/samsung/exynos-srom.h51
6 files changed, 242 insertions, 0 deletions
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index 51d5cd20c26a..c61a284133e0 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -122,6 +122,7 @@ config MTK_SMI
122 mainly help enable/disable iommu and control the power domain and 122 mainly help enable/disable iommu and control the power domain and
123 clocks for each local arbiter. 123 clocks for each local arbiter.
124 124
125source "drivers/memory/samsung/Kconfig"
125source "drivers/memory/tegra/Kconfig" 126source "drivers/memory/tegra/Kconfig"
126 127
127endif 128endif
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index 890bdf402449..cb0b7a1df11a 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -17,4 +17,5 @@ obj-$(CONFIG_TEGRA20_MC) += tegra20-mc.o
17obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o 17obj-$(CONFIG_JZ4780_NEMC) += jz4780-nemc.o
18obj-$(CONFIG_MTK_SMI) += mtk-smi.o 18obj-$(CONFIG_MTK_SMI) += mtk-smi.o
19 19
20obj-$(CONFIG_SAMSUNG_MC) += samsung/
20obj-$(CONFIG_TEGRA_MC) += tegra/ 21obj-$(CONFIG_TEGRA_MC) += tegra/
diff --git a/drivers/memory/samsung/Kconfig b/drivers/memory/samsung/Kconfig
new file mode 100644
index 000000000000..64ab5dd9f626
--- /dev/null
+++ b/drivers/memory/samsung/Kconfig
@@ -0,0 +1,13 @@
1config SAMSUNG_MC
2 bool "Samsung Exynos Memory Controller support" if COMPILE_TEST
3 help
4 Support for the Memory Controller (MC) devices found on
5 Samsung Exynos SoCs.
6
7if SAMSUNG_MC
8
9config EXYNOS_SROM
10 bool "Exynos SROM controller driver" if COMPILE_TEST
11 depends on (ARM && ARCH_EXYNOS && PM) || (COMPILE_TEST && HAS_IOMEM)
12
13endif
diff --git a/drivers/memory/samsung/Makefile b/drivers/memory/samsung/Makefile
new file mode 100644
index 000000000000..9c554d5522ad
--- /dev/null
+++ b/drivers/memory/samsung/Makefile
@@ -0,0 +1 @@
obj-$(CONFIG_EXYNOS_SROM) += exynos-srom.o
diff --git a/drivers/memory/samsung/exynos-srom.c b/drivers/memory/samsung/exynos-srom.c
new file mode 100644
index 000000000000..68e073c1651c
--- /dev/null
+++ b/drivers/memory/samsung/exynos-srom.c
@@ -0,0 +1,175 @@
1/*
2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com/
4 *
5 * EXYNOS - SROM Controller support
6 * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/io.h>
14#include <linux/module.h>
15#include <linux/of.h>
16#include <linux/of_address.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19
20#include "exynos-srom.h"
21
22static const unsigned long exynos_srom_offsets[] = {
23 /* SROM side */
24 EXYNOS_SROM_BW,
25 EXYNOS_SROM_BC0,
26 EXYNOS_SROM_BC1,
27 EXYNOS_SROM_BC2,
28 EXYNOS_SROM_BC3,
29};
30
31/**
32 * struct exynos_srom_reg_dump: register dump of SROM Controller registers.
33 * @offset: srom register offset from the controller base address.
34 * @value: the value of register under the offset.
35 */
36struct exynos_srom_reg_dump {
37 u32 offset;
38 u32 value;
39};
40
41/**
42 * struct exynos_srom: platform data for exynos srom controller driver.
43 * @dev: platform device pointer
44 * @reg_base: srom base address
45 * @reg_offset: exynos_srom_reg_dump pointer to hold offset and its value.
46 */
47struct exynos_srom {
48 struct device *dev;
49 void __iomem *reg_base;
50 struct exynos_srom_reg_dump *reg_offset;
51};
52
53static struct exynos_srom_reg_dump *exynos_srom_alloc_reg_dump(
54 const unsigned long *rdump,
55 unsigned long nr_rdump)
56{
57 struct exynos_srom_reg_dump *rd;
58 unsigned int i;
59
60 rd = kcalloc(nr_rdump, sizeof(*rd), GFP_KERNEL);
61 if (!rd)
62 return NULL;
63
64 for (i = 0; i < nr_rdump; ++i)
65 rd[i].offset = rdump[i];
66
67 return rd;
68}
69
70static int exynos_srom_probe(struct platform_device *pdev)
71{
72 struct device_node *np;
73 struct exynos_srom *srom;
74 struct device *dev = &pdev->dev;
75
76 np = dev->of_node;
77 if (!np) {
78 dev_err(&pdev->dev, "could not find device info\n");
79 return -EINVAL;
80 }
81
82 srom = devm_kzalloc(&pdev->dev,
83 sizeof(struct exynos_srom), GFP_KERNEL);
84 if (!srom)
85 return -ENOMEM;
86
87 srom->dev = dev;
88 srom->reg_base = of_iomap(np, 0);
89 if (!srom->reg_base) {
90 dev_err(&pdev->dev, "iomap of exynos srom controller failed\n");
91 return -ENOMEM;
92 }
93
94 platform_set_drvdata(pdev, srom);
95
96 srom->reg_offset = exynos_srom_alloc_reg_dump(exynos_srom_offsets,
97 sizeof(exynos_srom_offsets));
98 if (!srom->reg_offset) {
99 iounmap(srom->reg_base);
100 return -ENOMEM;
101 }
102
103 return 0;
104}
105
106static int exynos_srom_remove(struct platform_device *pdev)
107{
108 struct exynos_srom *srom = platform_get_drvdata(pdev);
109
110 kfree(srom->reg_offset);
111 iounmap(srom->reg_base);
112
113 return 0;
114}
115
116#ifdef CONFIG_PM_SLEEP
117static void exynos_srom_save(void __iomem *base,
118 struct exynos_srom_reg_dump *rd,
119 unsigned int num_regs)
120{
121 for (; num_regs > 0; --num_regs, ++rd)
122 rd->value = readl(base + rd->offset);
123}
124
125static void exynos_srom_restore(void __iomem *base,
126 const struct exynos_srom_reg_dump *rd,
127 unsigned int num_regs)
128{
129 for (; num_regs > 0; --num_regs, ++rd)
130 writel(rd->value, base + rd->offset);
131}
132
133static int exynos_srom_suspend(struct device *dev)
134{
135 struct exynos_srom *srom = dev_get_drvdata(dev);
136
137 exynos_srom_save(srom->reg_base, srom->reg_offset,
138 ARRAY_SIZE(exynos_srom_offsets));
139 return 0;
140}
141
142static int exynos_srom_resume(struct device *dev)
143{
144 struct exynos_srom *srom = dev_get_drvdata(dev);
145
146 exynos_srom_restore(srom->reg_base, srom->reg_offset,
147 ARRAY_SIZE(exynos_srom_offsets));
148 return 0;
149}
150#endif
151
152static const struct of_device_id of_exynos_srom_ids[] = {
153 {
154 .compatible = "samsung,exynos4210-srom",
155 },
156 {},
157};
158MODULE_DEVICE_TABLE(of, of_exynos_srom_ids);
159
160static SIMPLE_DEV_PM_OPS(exynos_srom_pm_ops, exynos_srom_suspend, exynos_srom_resume);
161
162static struct platform_driver exynos_srom_driver = {
163 .probe = exynos_srom_probe,
164 .remove = exynos_srom_remove,
165 .driver = {
166 .name = "exynos-srom",
167 .of_match_table = of_exynos_srom_ids,
168 .pm = &exynos_srom_pm_ops,
169 },
170};
171module_platform_driver(exynos_srom_driver);
172
173MODULE_AUTHOR("Pankaj Dubey <pankaj.dubey@samsung.com>");
174MODULE_DESCRIPTION("Exynos SROM Controller Driver");
175MODULE_LICENSE("GPL");
diff --git a/drivers/memory/samsung/exynos-srom.h b/drivers/memory/samsung/exynos-srom.h
new file mode 100644
index 000000000000..34660c6a57a9
--- /dev/null
+++ b/drivers/memory/samsung/exynos-srom.h
@@ -0,0 +1,51 @@
1/*
2 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
3 * http://www.samsung.com
4 *
5 * Exynos SROMC register definitions
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10*/
11
12#ifndef __EXYNOS_SROM_H
13#define __EXYNOS_SROM_H __FILE__
14
15#define EXYNOS_SROMREG(x) (x)
16
17#define EXYNOS_SROM_BW EXYNOS_SROMREG(0x0)
18#define EXYNOS_SROM_BC0 EXYNOS_SROMREG(0x4)
19#define EXYNOS_SROM_BC1 EXYNOS_SROMREG(0x8)
20#define EXYNOS_SROM_BC2 EXYNOS_SROMREG(0xc)
21#define EXYNOS_SROM_BC3 EXYNOS_SROMREG(0x10)
22#define EXYNOS_SROM_BC4 EXYNOS_SROMREG(0x14)
23#define EXYNOS_SROM_BC5 EXYNOS_SROMREG(0x18)
24
25/* one register BW holds 4 x 4-bit packed settings for NCS0 - NCS3 */
26
27#define EXYNOS_SROM_BW__DATAWIDTH__SHIFT 0
28#define EXYNOS_SROM_BW__ADDRMODE__SHIFT 1
29#define EXYNOS_SROM_BW__WAITENABLE__SHIFT 2
30#define EXYNOS_SROM_BW__BYTEENABLE__SHIFT 3
31
32#define EXYNOS_SROM_BW__CS_MASK 0xf
33
34#define EXYNOS_SROM_BW__NCS0__SHIFT 0
35#define EXYNOS_SROM_BW__NCS1__SHIFT 4
36#define EXYNOS_SROM_BW__NCS2__SHIFT 8
37#define EXYNOS_SROM_BW__NCS3__SHIFT 12
38#define EXYNOS_SROM_BW__NCS4__SHIFT 16
39#define EXYNOS_SROM_BW__NCS5__SHIFT 20
40
41/* applies to same to BCS0 - BCS3 */
42
43#define EXYNOS_SROM_BCX__PMC__SHIFT 0
44#define EXYNOS_SROM_BCX__TACP__SHIFT 4
45#define EXYNOS_SROM_BCX__TCAH__SHIFT 8
46#define EXYNOS_SROM_BCX__TCOH__SHIFT 12
47#define EXYNOS_SROM_BCX__TACC__SHIFT 16
48#define EXYNOS_SROM_BCX__TCOS__SHIFT 24
49#define EXYNOS_SROM_BCX__TACS__SHIFT 28
50
51#endif /* __EXYNOS_SROM_H */