ARM: OMAP2+: PRCM: split and relocate the PRM/CM globals setup
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-omap2 / omap4-common.c
1 /*
2  * OMAP4 specific common source file.
3  *
4  * Copyright (C) 2010 Texas Instruments, Inc.
5  * Author:
6  *      Santosh Shilimkar <santosh.shilimkar@ti.com>
7  *
8  *
9  * This program is free software,you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/io.h>
17 #include <linux/platform_device.h>
18 #include <linux/memblock.h>
19 #include <linux/of_irq.h>
20 #include <linux/of_platform.h>
21 #include <linux/export.h>
22
23 #include <asm/hardware/gic.h>
24 #include <asm/hardware/cache-l2x0.h>
25 #include <asm/mach/map.h>
26 #include <asm/memblock.h>
27
28 #include "../plat-omap/sram.h"
29
30 #include "omap-wakeupgen.h"
31 #include "soc.h"
32 #include "iomap.h"
33 #include "common.h"
34 #include "mmc.h"
35 #include "hsmmc.h"
36 #include "prminst44xx.h"
37 #include "prcm_mpu44xx.h"
38 #include "omap4-sar-layout.h"
39 #include "omap-secure.h"
40
41 #ifdef CONFIG_CACHE_L2X0
42 static void __iomem *l2cache_base;
43 #endif
44
45 static void __iomem *sar_ram_base;
46
47 #ifdef CONFIG_OMAP4_ERRATA_I688
48 /* Used to implement memory barrier on DRAM path */
49 #define OMAP4_DRAM_BARRIER_VA                   0xfe600000
50
51 void __iomem *dram_sync, *sram_sync;
52
53 static phys_addr_t paddr;
54 static u32 size;
55
56 void omap_bus_sync(void)
57 {
58         if (dram_sync && sram_sync) {
59                 writel_relaxed(readl_relaxed(dram_sync), dram_sync);
60                 writel_relaxed(readl_relaxed(sram_sync), sram_sync);
61                 isb();
62         }
63 }
64 EXPORT_SYMBOL(omap_bus_sync);
65
66 /* Steal one page physical memory for barrier implementation */
67 int __init omap_barrier_reserve_memblock(void)
68 {
69
70         size = ALIGN(PAGE_SIZE, SZ_1M);
71         paddr = arm_memblock_steal(size, SZ_1M);
72
73         return 0;
74 }
75
76 void __init omap_barriers_init(void)
77 {
78         struct map_desc dram_io_desc[1];
79
80         dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA;
81         dram_io_desc[0].pfn = __phys_to_pfn(paddr);
82         dram_io_desc[0].length = size;
83         dram_io_desc[0].type = MT_MEMORY_SO;
84         iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc));
85         dram_sync = (void __iomem *) dram_io_desc[0].virtual;
86         sram_sync = (void __iomem *) OMAP4_SRAM_VA;
87
88         pr_info("OMAP4: Map 0x%08llx to 0x%08lx for dram barrier\n",
89                 (long long) paddr, dram_io_desc[0].virtual);
90
91 }
92 #else
93 void __init omap_barriers_init(void)
94 {}
95 #endif
96
97 void __init gic_init_irq(void)
98 {
99         void __iomem *omap_irq_base;
100         void __iomem *gic_dist_base_addr;
101
102         /* Static mapping, never released */
103         gic_dist_base_addr = ioremap(OMAP44XX_GIC_DIST_BASE, SZ_4K);
104         BUG_ON(!gic_dist_base_addr);
105
106         /* Static mapping, never released */
107         omap_irq_base = ioremap(OMAP44XX_GIC_CPU_BASE, SZ_512);
108         BUG_ON(!omap_irq_base);
109
110         omap_wakeupgen_init();
111
112         gic_init(0, 29, gic_dist_base_addr, omap_irq_base);
113 }
114
115 #ifdef CONFIG_CACHE_L2X0
116
117 void __iomem *omap4_get_l2cache_base(void)
118 {
119         return l2cache_base;
120 }
121
122 static void omap4_l2x0_disable(void)
123 {
124         /* Disable PL310 L2 Cache controller */
125         omap_smc1(0x102, 0x0);
126 }
127
128 static void omap4_l2x0_set_debug(unsigned long val)
129 {
130         /* Program PL310 L2 Cache controller debug register */
131         omap_smc1(0x100, val);
132 }
133
134 static int __init omap_l2_cache_init(void)
135 {
136         u32 aux_ctrl = 0;
137
138         /*
139          * To avoid code running on other OMAPs in
140          * multi-omap builds
141          */
142         if (!cpu_is_omap44xx())
143                 return -ENODEV;
144
145         /* Static mapping, never released */
146         l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
147         if (WARN_ON(!l2cache_base))
148                 return -ENOMEM;
149
150         /*
151          * 16-way associativity, parity disabled
152          * Way size - 32KB (es1.0)
153          * Way size - 64KB (es2.0 +)
154          */
155         aux_ctrl = ((1 << L2X0_AUX_CTRL_ASSOCIATIVITY_SHIFT) |
156                         (0x1 << 25) |
157                         (0x1 << L2X0_AUX_CTRL_NS_LOCKDOWN_SHIFT) |
158                         (0x1 << L2X0_AUX_CTRL_NS_INT_CTRL_SHIFT));
159
160         if (omap_rev() == OMAP4430_REV_ES1_0) {
161                 aux_ctrl |= 0x2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT;
162         } else {
163                 aux_ctrl |= ((0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT) |
164                         (1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT) |
165                         (1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
166                         (1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT) |
167                         (1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT));
168         }
169         if (omap_rev() != OMAP4430_REV_ES1_0)
170                 omap_smc1(0x109, aux_ctrl);
171
172         /* Enable PL310 L2 Cache controller */
173         omap_smc1(0x102, 0x1);
174
175         if (of_have_populated_dt())
176                 l2x0_of_init(aux_ctrl, L2X0_AUX_CTRL_MASK);
177         else
178                 l2x0_init(l2cache_base, aux_ctrl, L2X0_AUX_CTRL_MASK);
179
180         /*
181          * Override default outer_cache.disable with a OMAP4
182          * specific one
183         */
184         outer_cache.disable = omap4_l2x0_disable;
185         outer_cache.set_debug = omap4_l2x0_set_debug;
186
187         return 0;
188 }
189 early_initcall(omap_l2_cache_init);
190 #endif
191
192 void __iomem *omap4_get_sar_ram_base(void)
193 {
194         return sar_ram_base;
195 }
196
197 /*
198  * SAR RAM used to save and restore the HW
199  * context in low power modes
200  */
201 static int __init omap4_sar_ram_init(void)
202 {
203         /*
204          * To avoid code running on other OMAPs in
205          * multi-omap builds
206          */
207         if (!cpu_is_omap44xx())
208                 return -ENOMEM;
209
210         /* Static mapping, never released */
211         sar_ram_base = ioremap(OMAP44XX_SAR_RAM_BASE, SZ_16K);
212         if (WARN_ON(!sar_ram_base))
213                 return -ENOMEM;
214
215         return 0;
216 }
217 early_initcall(omap4_sar_ram_init);
218
219 static struct of_device_id irq_match[] __initdata = {
220         { .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
221         { .compatible = "arm,cortex-a15-gic", .data = gic_of_init, },
222         { }
223 };
224
225 void __init omap_gic_of_init(void)
226 {
227         omap_wakeupgen_init();
228         of_irq_init(irq_match);
229 }
230
231 #if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
232 static int omap4_twl6030_hsmmc_late_init(struct device *dev)
233 {
234         int irq = 0;
235         struct platform_device *pdev = container_of(dev,
236                                 struct platform_device, dev);
237         struct omap_mmc_platform_data *pdata = dev->platform_data;
238
239         /* Setting MMC1 Card detect Irq */
240         if (pdev->id == 0) {
241                 irq = twl6030_mmc_card_detect_config();
242                 if (irq < 0) {
243                         dev_err(dev, "%s: Error card detect config(%d)\n",
244                                 __func__, irq);
245                         return irq;
246                 }
247                 pdata->slots[0].card_detect_irq = irq;
248                 pdata->slots[0].card_detect = twl6030_mmc_card_detect;
249         }
250         return 0;
251 }
252
253 static __init void omap4_twl6030_hsmmc_set_late_init(struct device *dev)
254 {
255         struct omap_mmc_platform_data *pdata;
256
257         /* dev can be null if CONFIG_MMC_OMAP_HS is not set */
258         if (!dev) {
259                 pr_err("Failed %s\n", __func__);
260                 return;
261         }
262         pdata = dev->platform_data;
263         pdata->init =   omap4_twl6030_hsmmc_late_init;
264 }
265
266 int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
267 {
268         struct omap2_hsmmc_info *c;
269
270         omap_hsmmc_init(controllers);
271         for (c = controllers; c->mmc; c++) {
272                 /* pdev can be null if CONFIG_MMC_OMAP_HS is not set */
273                 if (!c->pdev)
274                         continue;
275                 omap4_twl6030_hsmmc_set_late_init(&c->pdev->dev);
276         }
277
278         return 0;
279 }
280 #else
281 int __init omap4_twl6030_hsmmc_init(struct omap2_hsmmc_info *controllers)
282 {
283         return 0;
284 }
285 #endif
286
287 /**
288  * omap44xx_restart - trigger a software restart of the SoC
289  * @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c
290  * @cmd: passed from the userspace program rebooting the system (if provided)
291  *
292  * Resets the SoC.  For @cmd, see the 'reboot' syscall in
293  * kernel/sys.c.  No return value.
294  */
295 void omap44xx_restart(char mode, const char *cmd)
296 {
297         /* XXX Should save 'cmd' into scratchpad for use after reboot */
298         omap4_prminst_global_warm_sw_reset(); /* never returns */
299         while (1);
300 }
301