summaryrefslogtreecommitdiffstats
path: root/drivers/memory
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2018-01-05 02:12:57 -0500
committerOlof Johansson <olof@lixom.net>2018-01-05 02:12:57 -0500
commit11077e9bf7fef8b1081221b482260a6bfa2b6d5f (patch)
tree9867459628434bb88338cdade7fb58ee2ec3a378 /drivers/memory
parent8102324d862f50360646da6391019b8d0ccaf76c (diff)
parentaefc5818553680c50c9f6840e47c01b80edd9b3a (diff)
Merge tag 'keystone_driver_soc_for_4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone into next/drivers
SOC: Keystone Soc driver updates for 4.16 - TI EMIF-SRAM driver - TI SCI print format fix - Navigator strndup lenth fix * tag 'keystone_driver_soc_for_4.16' of git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone: soc: ti: fix max dup length for kstrndup firmware: ti_sci: Use %zu for size_t print format memory: ti-emif-sram: remove unused variable memory: ti-emif-sram: introduce relocatable suspend/resume handlers Documentation: dt: Update ti,emif bindings Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/memory')
-rw-r--r--drivers/memory/Kconfig10
-rw-r--r--drivers/memory/Makefile8
-rw-r--r--drivers/memory/Makefile.asm-offsets5
-rw-r--r--drivers/memory/emif-asm-offsets.c92
-rw-r--r--drivers/memory/emif.h17
-rw-r--r--drivers/memory/ti-emif-pm.c324
-rw-r--r--drivers/memory/ti-emif-sram-pm.S334
7 files changed, 790 insertions, 0 deletions
diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig
index ffc350258041..19a0e83f260d 100644
--- a/drivers/memory/Kconfig
+++ b/drivers/memory/Kconfig
@@ -84,6 +84,16 @@ config OMAP_GPMC_DEBUG
84 bootloader or else the GPMC timings won't be identical with the 84 bootloader or else the GPMC timings won't be identical with the
85 bootloader timings. 85 bootloader timings.
86 86
87config TI_EMIF_SRAM
88 tristate "Texas Instruments EMIF SRAM driver"
89 depends on (SOC_AM33XX || SOC_AM43XX) && SRAM
90 help
91 This driver is for the EMIF module available on Texas Instruments
92 AM33XX and AM43XX SoCs and is required for PM. Certain parts of
93 the EMIF PM code must run from on-chip SRAM late in the suspend
94 sequence so this driver provides several relocatable PM functions
95 for the SoC PM code to use.
96
87config MVEBU_DEVBUS 97config MVEBU_DEVBUS
88 bool "Marvell EBU Device Bus Controller" 98 bool "Marvell EBU Device Bus Controller"
89 default y 99 default y
diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile
index 929a601d4cd1..66f55240830e 100644
--- a/drivers/memory/Makefile
+++ b/drivers/memory/Makefile
@@ -23,3 +23,11 @@ obj-$(CONFIG_DA8XX_DDRCTL) += da8xx-ddrctl.o
23 23
24obj-$(CONFIG_SAMSUNG_MC) += samsung/ 24obj-$(CONFIG_SAMSUNG_MC) += samsung/
25obj-$(CONFIG_TEGRA_MC) += tegra/ 25obj-$(CONFIG_TEGRA_MC) += tegra/
26obj-$(CONFIG_TI_EMIF_SRAM) += ti-emif-sram.o
27ti-emif-sram-objs := ti-emif-pm.o ti-emif-sram-pm.o
28
29AFLAGS_ti-emif-sram-pm.o :=-Wa,-march=armv7-a
30
31include drivers/memory/Makefile.asm-offsets
32
33drivers/memory/ti-emif-sram-pm.o: include/generated/ti-emif-asm-offsets.h
diff --git a/drivers/memory/Makefile.asm-offsets b/drivers/memory/Makefile.asm-offsets
new file mode 100644
index 000000000000..843ff60ccb5a
--- /dev/null
+++ b/drivers/memory/Makefile.asm-offsets
@@ -0,0 +1,5 @@
1drivers/memory/emif-asm-offsets.s: drivers/memory/emif-asm-offsets.c
2 $(call if_changed_dep,cc_s_c)
3
4include/generated/ti-emif-asm-offsets.h: drivers/memory/emif-asm-offsets.s FORCE
5 $(call filechk,offsets,__TI_EMIF_ASM_OFFSETS_H__)
diff --git a/drivers/memory/emif-asm-offsets.c b/drivers/memory/emif-asm-offsets.c
new file mode 100644
index 000000000000..71a89d5d3efd
--- /dev/null
+++ b/drivers/memory/emif-asm-offsets.c
@@ -0,0 +1,92 @@
1/*
2 * TI AM33XX EMIF PM Assembly Offsets
3 *
4 * Copyright (C) 2016-2017 Texas Instruments Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
9 *
10 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
11 * kind, whether express or implied; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15#include <linux/ti-emif-sram.h>
16
17int main(void)
18{
19 DEFINE(EMIF_SDCFG_VAL_OFFSET,
20 offsetof(struct emif_regs_amx3, emif_sdcfg_val));
21 DEFINE(EMIF_TIMING1_VAL_OFFSET,
22 offsetof(struct emif_regs_amx3, emif_timing1_val));
23 DEFINE(EMIF_TIMING2_VAL_OFFSET,
24 offsetof(struct emif_regs_amx3, emif_timing2_val));
25 DEFINE(EMIF_TIMING3_VAL_OFFSET,
26 offsetof(struct emif_regs_amx3, emif_timing3_val));
27 DEFINE(EMIF_REF_CTRL_VAL_OFFSET,
28 offsetof(struct emif_regs_amx3, emif_ref_ctrl_val));
29 DEFINE(EMIF_ZQCFG_VAL_OFFSET,
30 offsetof(struct emif_regs_amx3, emif_zqcfg_val));
31 DEFINE(EMIF_PMCR_VAL_OFFSET,
32 offsetof(struct emif_regs_amx3, emif_pmcr_val));
33 DEFINE(EMIF_PMCR_SHDW_VAL_OFFSET,
34 offsetof(struct emif_regs_amx3, emif_pmcr_shdw_val));
35 DEFINE(EMIF_RD_WR_LEVEL_RAMP_CTRL_OFFSET,
36 offsetof(struct emif_regs_amx3, emif_rd_wr_level_ramp_ctrl));
37 DEFINE(EMIF_RD_WR_EXEC_THRESH_OFFSET,
38 offsetof(struct emif_regs_amx3, emif_rd_wr_exec_thresh));
39 DEFINE(EMIF_COS_CONFIG_OFFSET,
40 offsetof(struct emif_regs_amx3, emif_cos_config));
41 DEFINE(EMIF_PRIORITY_TO_COS_MAPPING_OFFSET,
42 offsetof(struct emif_regs_amx3, emif_priority_to_cos_mapping));
43 DEFINE(EMIF_CONNECT_ID_SERV_1_MAP_OFFSET,
44 offsetof(struct emif_regs_amx3, emif_connect_id_serv_1_map));
45 DEFINE(EMIF_CONNECT_ID_SERV_2_MAP_OFFSET,
46 offsetof(struct emif_regs_amx3, emif_connect_id_serv_2_map));
47 DEFINE(EMIF_OCP_CONFIG_VAL_OFFSET,
48 offsetof(struct emif_regs_amx3, emif_ocp_config_val));
49 DEFINE(EMIF_LPDDR2_NVM_TIM_OFFSET,
50 offsetof(struct emif_regs_amx3, emif_lpddr2_nvm_tim));
51 DEFINE(EMIF_LPDDR2_NVM_TIM_SHDW_OFFSET,
52 offsetof(struct emif_regs_amx3, emif_lpddr2_nvm_tim_shdw));
53 DEFINE(EMIF_DLL_CALIB_CTRL_VAL_OFFSET,
54 offsetof(struct emif_regs_amx3, emif_dll_calib_ctrl_val));
55 DEFINE(EMIF_DLL_CALIB_CTRL_VAL_SHDW_OFFSET,
56 offsetof(struct emif_regs_amx3, emif_dll_calib_ctrl_val_shdw));
57 DEFINE(EMIF_DDR_PHY_CTLR_1_OFFSET,
58 offsetof(struct emif_regs_amx3, emif_ddr_phy_ctlr_1));
59 DEFINE(EMIF_EXT_PHY_CTRL_VALS_OFFSET,
60 offsetof(struct emif_regs_amx3, emif_ext_phy_ctrl_vals));
61 DEFINE(EMIF_REGS_AMX3_SIZE, sizeof(struct emif_regs_amx3));
62
63 BLANK();
64
65 DEFINE(EMIF_PM_BASE_ADDR_VIRT_OFFSET,
66 offsetof(struct ti_emif_pm_data, ti_emif_base_addr_virt));
67 DEFINE(EMIF_PM_BASE_ADDR_PHYS_OFFSET,
68 offsetof(struct ti_emif_pm_data, ti_emif_base_addr_phys));
69 DEFINE(EMIF_PM_CONFIG_OFFSET,
70 offsetof(struct ti_emif_pm_data, ti_emif_sram_config));
71 DEFINE(EMIF_PM_REGS_VIRT_OFFSET,
72 offsetof(struct ti_emif_pm_data, regs_virt));
73 DEFINE(EMIF_PM_REGS_PHYS_OFFSET,
74 offsetof(struct ti_emif_pm_data, regs_phys));
75 DEFINE(EMIF_PM_DATA_SIZE, sizeof(struct ti_emif_pm_data));
76
77 BLANK();
78
79 DEFINE(EMIF_PM_SAVE_CONTEXT_OFFSET,
80 offsetof(struct ti_emif_pm_functions, save_context));
81 DEFINE(EMIF_PM_RESTORE_CONTEXT_OFFSET,
82 offsetof(struct ti_emif_pm_functions, restore_context));
83 DEFINE(EMIF_PM_ENTER_SR_OFFSET,
84 offsetof(struct ti_emif_pm_functions, enter_sr));
85 DEFINE(EMIF_PM_EXIT_SR_OFFSET,
86 offsetof(struct ti_emif_pm_functions, exit_sr));
87 DEFINE(EMIF_PM_ABORT_SR_OFFSET,
88 offsetof(struct ti_emif_pm_functions, abort_sr));
89 DEFINE(EMIF_PM_FUNCTIONS_SIZE, sizeof(struct ti_emif_pm_functions));
90
91 return 0;
92}
diff --git a/drivers/memory/emif.h b/drivers/memory/emif.h
index bfe08bae961a..9e9f8037955d 100644
--- a/drivers/memory/emif.h
+++ b/drivers/memory/emif.h
@@ -555,6 +555,9 @@
555#define READ_LATENCY_SHDW_SHIFT 0 555#define READ_LATENCY_SHDW_SHIFT 0
556#define READ_LATENCY_SHDW_MASK (0x1f << 0) 556#define READ_LATENCY_SHDW_MASK (0x1f << 0)
557 557
558#define EMIF_SRAM_AM33_REG_LAYOUT 0x00000000
559#define EMIF_SRAM_AM43_REG_LAYOUT 0x00000001
560
558#ifndef __ASSEMBLY__ 561#ifndef __ASSEMBLY__
559/* 562/*
560 * Structure containing shadow of important registers in EMIF 563 * Structure containing shadow of important registers in EMIF
@@ -585,5 +588,19 @@ struct emif_regs {
585 u32 ext_phy_ctrl_3_shdw; 588 u32 ext_phy_ctrl_3_shdw;
586 u32 ext_phy_ctrl_4_shdw; 589 u32 ext_phy_ctrl_4_shdw;
587}; 590};
591
592struct ti_emif_pm_functions;
593
594extern unsigned int ti_emif_sram;
595extern unsigned int ti_emif_sram_sz;
596extern struct ti_emif_pm_data ti_emif_pm_sram_data;
597extern struct emif_regs_amx3 ti_emif_regs_amx3;
598
599void ti_emif_save_context(void);
600void ti_emif_restore_context(void);
601void ti_emif_enter_sr(void);
602void ti_emif_exit_sr(void);
603void ti_emif_abort_sr(void);
604
588#endif /* __ASSEMBLY__ */ 605#endif /* __ASSEMBLY__ */
589#endif /* __EMIF_H */ 606#endif /* __EMIF_H */
diff --git a/drivers/memory/ti-emif-pm.c b/drivers/memory/ti-emif-pm.c
new file mode 100644
index 000000000000..62a86c4bcd0b
--- /dev/null
+++ b/drivers/memory/ti-emif-pm.c
@@ -0,0 +1,324 @@
1/*
2 * TI AM33XX SRAM EMIF Driver
3 *
4 * Copyright (C) 2016-2017 Texas Instruments Inc.
5 * Dave Gerlach
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/err.h>
18#include <linux/genalloc.h>
19#include <linux/io.h>
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/of.h>
23#include <linux/of_platform.h>
24#include <linux/platform_device.h>
25#include <linux/sram.h>
26#include <linux/ti-emif-sram.h>
27
28#include "emif.h"
29
30#define TI_EMIF_SRAM_SYMBOL_OFFSET(sym) ((unsigned long)(sym) - \
31 (unsigned long)&ti_emif_sram)
32
33#define EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES 0x00a0
34
35struct ti_emif_data {
36 phys_addr_t ti_emif_sram_phys;
37 phys_addr_t ti_emif_sram_data_phys;
38 unsigned long ti_emif_sram_virt;
39 unsigned long ti_emif_sram_data_virt;
40 struct gen_pool *sram_pool_code;
41 struct gen_pool *sram_pool_data;
42 struct ti_emif_pm_data pm_data;
43 struct ti_emif_pm_functions pm_functions;
44};
45
46static struct ti_emif_data *emif_instance;
47
48static u32 sram_suspend_address(struct ti_emif_data *emif_data,
49 unsigned long addr)
50{
51 return (emif_data->ti_emif_sram_virt +
52 TI_EMIF_SRAM_SYMBOL_OFFSET(addr));
53}
54
55static phys_addr_t sram_resume_address(struct ti_emif_data *emif_data,
56 unsigned long addr)
57{
58 return ((unsigned long)emif_data->ti_emif_sram_phys +
59 TI_EMIF_SRAM_SYMBOL_OFFSET(addr));
60}
61
62static void ti_emif_free_sram(struct ti_emif_data *emif_data)
63{
64 gen_pool_free(emif_data->sram_pool_code, emif_data->ti_emif_sram_virt,
65 ti_emif_sram_sz);
66 gen_pool_free(emif_data->sram_pool_data,
67 emif_data->ti_emif_sram_data_virt,
68 sizeof(struct emif_regs_amx3));
69}
70
71static int ti_emif_alloc_sram(struct device *dev,
72 struct ti_emif_data *emif_data)
73{
74 struct device_node *np = dev->of_node;
75 int ret;
76
77 emif_data->sram_pool_code = of_gen_pool_get(np, "sram", 0);
78 if (!emif_data->sram_pool_code) {
79 dev_err(dev, "Unable to get sram pool for ocmcram code\n");
80 return -ENODEV;
81 }
82
83 emif_data->ti_emif_sram_virt =
84 gen_pool_alloc(emif_data->sram_pool_code,
85 ti_emif_sram_sz);
86 if (!emif_data->ti_emif_sram_virt) {
87 dev_err(dev, "Unable to allocate code memory from ocmcram\n");
88 return -ENOMEM;
89 }
90
91 /* Save physical address to calculate resume offset during pm init */
92 emif_data->ti_emif_sram_phys =
93 gen_pool_virt_to_phys(emif_data->sram_pool_code,
94 emif_data->ti_emif_sram_virt);
95
96 /* Get sram pool for data section and allocate space */
97 emif_data->sram_pool_data = of_gen_pool_get(np, "sram", 1);
98 if (!emif_data->sram_pool_data) {
99 dev_err(dev, "Unable to get sram pool for ocmcram data\n");
100 ret = -ENODEV;
101 goto err_free_sram_code;
102 }
103
104 emif_data->ti_emif_sram_data_virt =
105 gen_pool_alloc(emif_data->sram_pool_data,
106 sizeof(struct emif_regs_amx3));
107 if (!emif_data->ti_emif_sram_data_virt) {
108 dev_err(dev, "Unable to allocate data memory from ocmcram\n");
109 ret = -ENOMEM;
110 goto err_free_sram_code;
111 }
112
113 /* Save physical address to calculate resume offset during pm init */
114 emif_data->ti_emif_sram_data_phys =
115 gen_pool_virt_to_phys(emif_data->sram_pool_data,
116 emif_data->ti_emif_sram_data_virt);
117 /*
118 * These functions are called during suspend path while MMU is
119 * still on so add virtual base to offset for absolute address
120 */
121 emif_data->pm_functions.save_context =
122 sram_suspend_address(emif_data,
123 (unsigned long)ti_emif_save_context);
124 emif_data->pm_functions.enter_sr =
125 sram_suspend_address(emif_data,
126 (unsigned long)ti_emif_enter_sr);
127 emif_data->pm_functions.abort_sr =
128 sram_suspend_address(emif_data,
129 (unsigned long)ti_emif_abort_sr);
130
131 /*
132 * These are called during resume path when MMU is not enabled
133 * so physical address is used instead
134 */
135 emif_data->pm_functions.restore_context =
136 sram_resume_address(emif_data,
137 (unsigned long)ti_emif_restore_context);
138 emif_data->pm_functions.exit_sr =
139 sram_resume_address(emif_data,
140 (unsigned long)ti_emif_exit_sr);
141
142 emif_data->pm_data.regs_virt =
143 (struct emif_regs_amx3 *)emif_data->ti_emif_sram_data_virt;
144 emif_data->pm_data.regs_phys = emif_data->ti_emif_sram_data_phys;
145
146 return 0;
147
148err_free_sram_code:
149 gen_pool_free(emif_data->sram_pool_code, emif_data->ti_emif_sram_virt,
150 ti_emif_sram_sz);
151 return ret;
152}
153
154static int ti_emif_push_sram(struct device *dev, struct ti_emif_data *emif_data)
155{
156 void *copy_addr;
157 u32 data_addr;
158
159 copy_addr = sram_exec_copy(emif_data->sram_pool_code,
160 (void *)emif_data->ti_emif_sram_virt,
161 &ti_emif_sram, ti_emif_sram_sz);
162 if (!copy_addr) {
163 dev_err(dev, "Cannot copy emif code to sram\n");
164 return -ENODEV;
165 }
166
167 data_addr = sram_suspend_address(emif_data,
168 (unsigned long)&ti_emif_pm_sram_data);
169 copy_addr = sram_exec_copy(emif_data->sram_pool_code,
170 (void *)data_addr,
171 &emif_data->pm_data,
172 sizeof(emif_data->pm_data));
173 if (!copy_addr) {
174 dev_err(dev, "Cannot copy emif data to code sram\n");
175 return -ENODEV;
176 }
177
178 return 0;
179}
180
181/*
182 * Due to Usage Note 3.1.2 "DDR3: JEDEC Compliance for Maximum
183 * Self-Refresh Command Limit" found in AM335x Silicon Errata
184 * (Document SPRZ360F Revised November 2013) we must configure
185 * the self refresh delay timer to 0xA (8192 cycles) to avoid
186 * generating too many refresh command from the EMIF.
187 */
188static void ti_emif_configure_sr_delay(struct ti_emif_data *emif_data)
189{
190 writel(EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES,
191 (emif_data->pm_data.ti_emif_base_addr_virt +
192 EMIF_POWER_MANAGEMENT_CONTROL));
193
194 writel(EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES,
195 (emif_data->pm_data.ti_emif_base_addr_virt +
196 EMIF_POWER_MANAGEMENT_CTRL_SHDW));
197}
198
199/**
200 * ti_emif_copy_pm_function_table - copy mapping of pm funcs in sram
201 * @sram_pool: pointer to struct gen_pool where dst resides
202 * @dst: void * to address that table should be copied
203 *
204 * Returns 0 if success other error code if table is not available
205 */
206int ti_emif_copy_pm_function_table(struct gen_pool *sram_pool, void *dst)
207{
208 void *copy_addr;
209
210 if (!emif_instance)
211 return -ENODEV;
212
213 copy_addr = sram_exec_copy(sram_pool, dst,
214 &emif_instance->pm_functions,
215 sizeof(emif_instance->pm_functions));
216 if (!copy_addr)
217 return -ENODEV;
218
219 return 0;
220}
221EXPORT_SYMBOL_GPL(ti_emif_copy_pm_function_table);
222
223/**
224 * ti_emif_get_mem_type - return type for memory type in use
225 *
226 * Returns memory type value read from EMIF or error code if fails
227 */
228int ti_emif_get_mem_type(void)
229{
230 unsigned long temp;
231
232 if (!emif_instance)
233 return -ENODEV;
234
235 temp = readl(emif_instance->pm_data.ti_emif_base_addr_virt +
236 EMIF_SDRAM_CONFIG);
237
238 temp = (temp & SDRAM_TYPE_MASK) >> SDRAM_TYPE_SHIFT;
239 return temp;
240}
241EXPORT_SYMBOL_GPL(ti_emif_get_mem_type);
242
243static const struct of_device_id ti_emif_of_match[] = {
244 { .compatible = "ti,emif-am3352", .data =
245 (void *)EMIF_SRAM_AM33_REG_LAYOUT, },
246 { .compatible = "ti,emif-am4372", .data =
247 (void *)EMIF_SRAM_AM43_REG_LAYOUT, },
248 {},
249};
250MODULE_DEVICE_TABLE(of, ti_emif_of_match);
251
252static int ti_emif_probe(struct platform_device *pdev)
253{
254 int ret;
255 struct resource *res;
256 struct device *dev = &pdev->dev;
257 const struct of_device_id *match;
258 struct ti_emif_data *emif_data;
259
260 emif_data = devm_kzalloc(dev, sizeof(*emif_data), GFP_KERNEL);
261 if (!emif_data)
262 return -ENOMEM;
263
264 match = of_match_device(ti_emif_of_match, &pdev->dev);
265 if (!match)
266 return -ENODEV;
267
268 emif_data->pm_data.ti_emif_sram_config = (unsigned long)match->data;
269
270 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
271 emif_data->pm_data.ti_emif_base_addr_virt = devm_ioremap_resource(dev,
272 res);
273 if (IS_ERR(emif_data->pm_data.ti_emif_base_addr_virt)) {
274 dev_err(dev, "could not ioremap emif mem\n");
275 ret = PTR_ERR(emif_data->pm_data.ti_emif_base_addr_virt);
276 return ret;
277 }
278
279 emif_data->pm_data.ti_emif_base_addr_phys = res->start;
280
281 ti_emif_configure_sr_delay(emif_data);
282
283 ret = ti_emif_alloc_sram(dev, emif_data);
284 if (ret)
285 return ret;
286
287 ret = ti_emif_push_sram(dev, emif_data);
288 if (ret)
289 goto fail_free_sram;
290
291 emif_instance = emif_data;
292
293 return 0;
294
295fail_free_sram:
296 ti_emif_free_sram(emif_data);
297
298 return ret;
299}
300
301static int ti_emif_remove(struct platform_device *pdev)
302{
303 struct ti_emif_data *emif_data = emif_instance;
304
305 emif_instance = NULL;
306
307 ti_emif_free_sram(emif_data);
308
309 return 0;
310}
311
312static struct platform_driver ti_emif_driver = {
313 .probe = ti_emif_probe,
314 .remove = ti_emif_remove,
315 .driver = {
316 .name = KBUILD_MODNAME,
317 .of_match_table = of_match_ptr(ti_emif_of_match),
318 },
319};
320module_platform_driver(ti_emif_driver);
321
322MODULE_AUTHOR("Dave Gerlach <d-gerlach@ti.com>");
323MODULE_DESCRIPTION("Texas Instruments SRAM EMIF driver");
324MODULE_LICENSE("GPL v2");
diff --git a/drivers/memory/ti-emif-sram-pm.S b/drivers/memory/ti-emif-sram-pm.S
new file mode 100644
index 000000000000..a5369181e5c2
--- /dev/null
+++ b/drivers/memory/ti-emif-sram-pm.S
@@ -0,0 +1,334 @@
1/*
2 * Low level PM code for TI EMIF
3 *
4 * Copyright (C) 2016-2017 Texas Instruments Incorporated - http://www.ti.com/
5 * Dave Gerlach
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation version 2.
10 *
11 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
12 * kind, whether express or implied; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <generated/ti-emif-asm-offsets.h>
18#include <linux/linkage.h>
19#include <asm/assembler.h>
20#include <asm/memory.h>
21
22#include "emif.h"
23
24#define EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES 0x00a0
25#define EMIF_POWER_MGMT_SR_TIMER_MASK 0x00f0
26#define EMIF_POWER_MGMT_SELF_REFRESH_MODE 0x0200
27#define EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK 0x0700
28
29#define EMIF_SDCFG_TYPE_DDR2 0x2 << SDRAM_TYPE_SHIFT
30#define EMIF_STATUS_READY 0x4
31
32#define AM43XX_EMIF_PHY_CTRL_REG_COUNT 0x120
33
34#define EMIF_AM437X_REGISTERS 0x1
35
36 .arm
37 .align 3
38
39ENTRY(ti_emif_sram)
40
41/*
42 * void ti_emif_save_context(void)
43 *
44 * Used during suspend to save the context of all required EMIF registers
45 * to local memory if the EMIF is going to lose context during the sleep
46 * transition. Operates on the VIRTUAL address of the EMIF.
47 */
48ENTRY(ti_emif_save_context)
49 stmfd sp!, {r4 - r11, lr} @ save registers on stack
50
51 adr r4, ti_emif_pm_sram_data
52 ldr r0, [r4, #EMIF_PM_BASE_ADDR_VIRT_OFFSET]
53 ldr r2, [r4, #EMIF_PM_REGS_VIRT_OFFSET]
54
55 /* Save EMIF configuration */
56 ldr r1, [r0, #EMIF_SDRAM_CONFIG]
57 str r1, [r2, #EMIF_SDCFG_VAL_OFFSET]
58
59 ldr r1, [r0, #EMIF_SDRAM_REFRESH_CONTROL]
60 str r1, [r2, #EMIF_REF_CTRL_VAL_OFFSET]
61
62 ldr r1, [r0, #EMIF_SDRAM_TIMING_1]
63 str r1, [r2, #EMIF_TIMING1_VAL_OFFSET]
64
65 ldr r1, [r0, #EMIF_SDRAM_TIMING_2]
66 str r1, [r2, #EMIF_TIMING2_VAL_OFFSET]
67
68 ldr r1, [r0, #EMIF_SDRAM_TIMING_3]
69 str r1, [r2, #EMIF_TIMING3_VAL_OFFSET]
70
71 ldr r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
72 str r1, [r2, #EMIF_PMCR_VAL_OFFSET]
73
74 ldr r1, [r0, #EMIF_POWER_MANAGEMENT_CTRL_SHDW]
75 str r1, [r2, #EMIF_PMCR_SHDW_VAL_OFFSET]
76
77 ldr r1, [r0, #EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG]
78 str r1, [r2, #EMIF_ZQCFG_VAL_OFFSET]
79
80 ldr r1, [r0, #EMIF_DDR_PHY_CTRL_1]
81 str r1, [r2, #EMIF_DDR_PHY_CTLR_1_OFFSET]
82
83 ldr r1, [r0, #EMIF_COS_CONFIG]
84 str r1, [r2, #EMIF_COS_CONFIG_OFFSET]
85
86 ldr r1, [r0, #EMIF_PRIORITY_TO_CLASS_OF_SERVICE_MAPPING]
87 str r1, [r2, #EMIF_PRIORITY_TO_COS_MAPPING_OFFSET]
88
89 ldr r1, [r0, #EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_1_MAPPING]
90 str r1, [r2, #EMIF_CONNECT_ID_SERV_1_MAP_OFFSET]
91
92 ldr r1, [r0, #EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_2_MAPPING]
93 str r1, [r2, #EMIF_CONNECT_ID_SERV_2_MAP_OFFSET]
94
95 ldr r1, [r0, #EMIF_OCP_CONFIG]
96 str r1, [r2, #EMIF_OCP_CONFIG_VAL_OFFSET]
97
98 ldr r5, [r4, #EMIF_PM_CONFIG_OFFSET]
99 cmp r5, #EMIF_SRAM_AM43_REG_LAYOUT
100 bne emif_skip_save_extra_regs
101
102 ldr r1, [r0, #EMIF_READ_WRITE_LEVELING_RAMP_CONTROL]
103 str r1, [r2, #EMIF_RD_WR_LEVEL_RAMP_CTRL_OFFSET]
104
105 ldr r1, [r0, #EMIF_READ_WRITE_EXECUTION_THRESHOLD]
106 str r1, [r2, #EMIF_RD_WR_EXEC_THRESH_OFFSET]
107
108 ldr r1, [r0, #EMIF_LPDDR2_NVM_TIMING]
109 str r1, [r2, #EMIF_LPDDR2_NVM_TIM_OFFSET]
110
111 ldr r1, [r0, #EMIF_LPDDR2_NVM_TIMING_SHDW]
112 str r1, [r2, #EMIF_LPDDR2_NVM_TIM_SHDW_OFFSET]
113
114 ldr r1, [r0, #EMIF_DLL_CALIB_CTRL]
115 str r1, [r2, #EMIF_DLL_CALIB_CTRL_VAL_OFFSET]
116
117 ldr r1, [r0, #EMIF_DLL_CALIB_CTRL_SHDW]
118 str r1, [r2, #EMIF_DLL_CALIB_CTRL_VAL_SHDW_OFFSET]
119
120 /* Loop and save entire block of emif phy regs */
121 mov r5, #0x0
122 add r4, r2, #EMIF_EXT_PHY_CTRL_VALS_OFFSET
123 add r3, r0, #EMIF_EXT_PHY_CTRL_1
124ddr_phy_ctrl_save:
125 ldr r1, [r3, r5]
126 str r1, [r4, r5]
127 add r5, r5, #0x4
128 cmp r5, #AM43XX_EMIF_PHY_CTRL_REG_COUNT
129 bne ddr_phy_ctrl_save
130
131emif_skip_save_extra_regs:
132 ldmfd sp!, {r4 - r11, pc} @ restore regs and return
133ENDPROC(ti_emif_save_context)
134
135/*
136 * void ti_emif_restore_context(void)
137 *
138 * Used during resume to restore the context of all required EMIF registers
139 * from local memory after the EMIF has lost context during a sleep transition.
140 * Operates on the PHYSICAL address of the EMIF.
141 */
142ENTRY(ti_emif_restore_context)
143 adr r4, ti_emif_pm_sram_data
144 ldr r0, [r4, #EMIF_PM_BASE_ADDR_PHYS_OFFSET]
145 ldr r2, [r4, #EMIF_PM_REGS_PHYS_OFFSET]
146
147 /* Config EMIF Timings */
148 ldr r1, [r2, #EMIF_DDR_PHY_CTLR_1_OFFSET]
149 str r1, [r0, #EMIF_DDR_PHY_CTRL_1]
150 str r1, [r0, #EMIF_DDR_PHY_CTRL_1_SHDW]
151
152 ldr r1, [r2, #EMIF_TIMING1_VAL_OFFSET]
153 str r1, [r0, #EMIF_SDRAM_TIMING_1]
154 str r1, [r0, #EMIF_SDRAM_TIMING_1_SHDW]
155
156 ldr r1, [r2, #EMIF_TIMING2_VAL_OFFSET]
157 str r1, [r0, #EMIF_SDRAM_TIMING_2]
158 str r1, [r0, #EMIF_SDRAM_TIMING_2_SHDW]
159
160 ldr r1, [r2, #EMIF_TIMING3_VAL_OFFSET]
161 str r1, [r0, #EMIF_SDRAM_TIMING_3]
162 str r1, [r0, #EMIF_SDRAM_TIMING_3_SHDW]
163
164 ldr r1, [r2, #EMIF_REF_CTRL_VAL_OFFSET]
165 str r1, [r0, #EMIF_SDRAM_REFRESH_CONTROL]
166 str r1, [r0, #EMIF_SDRAM_REFRESH_CTRL_SHDW]
167
168 ldr r1, [r2, #EMIF_PMCR_VAL_OFFSET]
169 str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
170
171 ldr r1, [r2, #EMIF_PMCR_SHDW_VAL_OFFSET]
172 str r1, [r0, #EMIF_POWER_MANAGEMENT_CTRL_SHDW]
173
174 ldr r1, [r2, #EMIF_COS_CONFIG_OFFSET]
175 str r1, [r0, #EMIF_COS_CONFIG]
176
177 ldr r1, [r2, #EMIF_PRIORITY_TO_COS_MAPPING_OFFSET]
178 str r1, [r0, #EMIF_PRIORITY_TO_CLASS_OF_SERVICE_MAPPING]
179
180 ldr r1, [r2, #EMIF_CONNECT_ID_SERV_1_MAP_OFFSET]
181 str r1, [r0, #EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_1_MAPPING]
182
183 ldr r1, [r2, #EMIF_CONNECT_ID_SERV_2_MAP_OFFSET]
184 str r1, [r0, #EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_2_MAPPING]
185
186 ldr r1, [r2, #EMIF_OCP_CONFIG_VAL_OFFSET]
187 str r1, [r0, #EMIF_OCP_CONFIG]
188
189 ldr r5, [r4, #EMIF_PM_CONFIG_OFFSET]
190 cmp r5, #EMIF_SRAM_AM43_REG_LAYOUT
191 bne emif_skip_restore_extra_regs
192
193 ldr r1, [r2, #EMIF_RD_WR_LEVEL_RAMP_CTRL_OFFSET]
194 str r1, [r0, #EMIF_READ_WRITE_LEVELING_RAMP_CONTROL]
195
196 ldr r1, [r2, #EMIF_RD_WR_EXEC_THRESH_OFFSET]
197 str r1, [r0, #EMIF_READ_WRITE_EXECUTION_THRESHOLD]
198
199 ldr r1, [r2, #EMIF_LPDDR2_NVM_TIM_OFFSET]
200 str r1, [r0, #EMIF_LPDDR2_NVM_TIMING]
201
202 ldr r1, [r2, #EMIF_LPDDR2_NVM_TIM_SHDW_OFFSET]
203 str r1, [r0, #EMIF_LPDDR2_NVM_TIMING_SHDW]
204
205 ldr r1, [r2, #EMIF_DLL_CALIB_CTRL_VAL_OFFSET]
206 str r1, [r0, #EMIF_DLL_CALIB_CTRL]
207
208 ldr r1, [r2, #EMIF_DLL_CALIB_CTRL_VAL_SHDW_OFFSET]
209 str r1, [r0, #EMIF_DLL_CALIB_CTRL_SHDW]
210
211 ldr r1, [r2, #EMIF_ZQCFG_VAL_OFFSET]
212 str r1, [r0, #EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG]
213
214 /* Loop and restore entire block of emif phy regs */
215 mov r5, #0x0
216 /* Load ti_emif_regs_amx3 + EMIF_EXT_PHY_CTRL_VALS_OFFSET for address
217 * to phy register save space
218 */
219 add r3, r2, #EMIF_EXT_PHY_CTRL_VALS_OFFSET
220 add r4, r0, #EMIF_EXT_PHY_CTRL_1
221ddr_phy_ctrl_restore:
222 ldr r1, [r3, r5]
223 str r1, [r4, r5]
224 add r5, r5, #0x4
225 cmp r5, #AM43XX_EMIF_PHY_CTRL_REG_COUNT
226 bne ddr_phy_ctrl_restore
227
228emif_skip_restore_extra_regs:
229 /*
230 * Output impedence calib needed only for DDR3
231 * but since the initial state of this will be
232 * disabled for DDR2 no harm in restoring the
233 * old configuration
234 */
235 ldr r1, [r2, #EMIF_ZQCFG_VAL_OFFSET]
236 str r1, [r0, #EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG]
237
238 /* Write to sdcfg last for DDR2 only */
239 ldr r1, [r2, #EMIF_SDCFG_VAL_OFFSET]
240 and r2, r1, #SDRAM_TYPE_MASK
241 cmp r2, #EMIF_SDCFG_TYPE_DDR2
242 streq r1, [r0, #EMIF_SDRAM_CONFIG]
243
244 mov pc, lr
245ENDPROC(ti_emif_restore_context)
246
247/*
248 * void ti_emif_enter_sr(void)
249 *
250 * Programs the EMIF to tell the SDRAM to enter into self-refresh
251 * mode during a sleep transition. Operates on the VIRTUAL address
252 * of the EMIF.
253 */
254ENTRY(ti_emif_enter_sr)
255 stmfd sp!, {r4 - r11, lr} @ save registers on stack
256
257 adr r4, ti_emif_pm_sram_data
258 ldr r0, [r4, #EMIF_PM_BASE_ADDR_VIRT_OFFSET]
259 ldr r2, [r4, #EMIF_PM_REGS_VIRT_OFFSET]
260
261 ldr r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
262 bic r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK
263 orr r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE
264 str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
265
266 ldmfd sp!, {r4 - r11, pc} @ restore regs and return
267ENDPROC(ti_emif_enter_sr)
268
269/*
270 * void ti_emif_exit_sr(void)
271 *
272 * Programs the EMIF to tell the SDRAM to exit self-refresh mode
273 * after a sleep transition. Operates on the PHYSICAL address of
274 * the EMIF.
275 */
276ENTRY(ti_emif_exit_sr)
277 adr r4, ti_emif_pm_sram_data
278 ldr r0, [r4, #EMIF_PM_BASE_ADDR_PHYS_OFFSET]
279 ldr r2, [r4, #EMIF_PM_REGS_PHYS_OFFSET]
280
281 /*
282 * Toggle EMIF to exit refresh mode:
283 * if EMIF lost context, PWR_MGT_CTRL is currently 0, writing disable
284 * (0x0), wont do diddly squat! so do a toggle from SR(0x2) to disable
285 * (0x0) here.
286 * *If* EMIF did not lose context, nothing broken as we write the same
287 * value(0x2) to reg before we write a disable (0x0).
288 */
289 ldr r1, [r2, #EMIF_PMCR_VAL_OFFSET]
290 bic r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK
291 orr r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE
292 str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
293 bic r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK
294 str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
295
296 /* Wait for EMIF to become ready */
2971: ldr r1, [r0, #EMIF_STATUS]
298 tst r1, #EMIF_STATUS_READY
299 beq 1b
300
301 mov pc, lr
302ENDPROC(ti_emif_exit_sr)
303
304/*
305 * void ti_emif_abort_sr(void)
306 *
307 * Disables self-refresh after a failed transition to a low-power
308 * state so the kernel can jump back to DDR and follow abort path.
309 * Operates on the VIRTUAL address of the EMIF.
310 */
311ENTRY(ti_emif_abort_sr)
312 stmfd sp!, {r4 - r11, lr} @ save registers on stack
313
314 adr r4, ti_emif_pm_sram_data
315 ldr r0, [r4, #EMIF_PM_BASE_ADDR_VIRT_OFFSET]
316 ldr r2, [r4, #EMIF_PM_REGS_VIRT_OFFSET]
317
318 ldr r1, [r2, #EMIF_PMCR_VAL_OFFSET]
319 bic r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK
320 str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
321
322 /* Wait for EMIF to become ready */
3231: ldr r1, [r0, #EMIF_STATUS]
324 tst r1, #EMIF_STATUS_READY
325 beq 1b
326
327 ldmfd sp!, {r4 - r11, pc} @ restore regs and return
328ENDPROC(ti_emif_abort_sr)
329
330 .align 3
331ENTRY(ti_emif_pm_sram_data)
332 .space EMIF_PM_DATA_SIZE
333ENTRY(ti_emif_sram_sz)
334 .word . - ti_emif_save_context