2 * OMAP4 specific common source file.
4 * Copyright (C) 2010 Texas Instruments, Inc.
6 * Santosh Shilimkar <santosh.shilimkar@ti.com>
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.
14 #include <linux/kernel.h>
15 #include <linux/init.h>
17 #include <linux/irq.h>
18 #include <linux/platform_device.h>
19 #include <linux/dma-mapping.h>
21 #include <asm/hardware/gic.h>
22 #include <asm/hardware/cache-l2x0.h>
23 #include <asm/cacheflush.h>
24 #include <asm/smp_twd.h>
26 #include <mach/hardware.h>
27 #include <mach/omap4-common.h>
28 #include <mach/omap-wakeupgen.h>
30 #include "omap4-sar-layout.h"
31 #include "clockdomain.h"
33 #ifdef CONFIG_CACHE_L2X0
34 #define L2X0_POR_OFFSET_VALUE 0x7
35 static void __iomem
*l2cache_base
;
38 static void __iomem
*gic_dist_base_addr
;
39 static void __iomem
*gic_cpu_base
;
40 static struct clockdomain
*l4_secure_clkdm
;
41 static void *dram_barrier_base
;
43 static void omap_bus_sync_noop(void)
46 struct omap_bus_post_fns omap_bus_post
= {
47 .sync
= omap_bus_sync_noop
,
49 EXPORT_SYMBOL(omap_bus_post
);
51 void __iomem
*omap4_get_gic_dist_base(void)
53 return gic_dist_base_addr
;
56 void __iomem
*omap4_get_gic_cpu_base(void)
61 void *omap_get_dram_barrier_base(void)
63 return dram_barrier_base
;
66 void __init
gic_init_irq(void)
69 /* Static mapping, never released */
70 gic_dist_base_addr
= ioremap(OMAP44XX_GIC_DIST_BASE
, SZ_4K
);
71 if (WARN_ON(!gic_dist_base_addr
))
74 /* Static mapping, never released */
75 gic_cpu_base
= ioremap(OMAP44XX_GIC_CPU_BASE
, SZ_512
);
76 if (WARN_ON(!gic_cpu_base
))
79 omap_wakeupgen_init();
81 gic_init(0, 29, gic_dist_base_addr
, gic_cpu_base
);
85 * FIXME: Remove this GIC APIs once common GIG library starts
88 void gic_cpu_enable(void)
90 __raw_writel(0xf0, gic_cpu_base
+ GIC_CPU_PRIMASK
);
91 __raw_writel(1, gic_cpu_base
+ GIC_CPU_CTRL
);
94 void gic_cpu_disable(void)
96 __raw_writel(0, gic_cpu_base
+ GIC_CPU_CTRL
);
100 bool gic_dist_disabled(void)
102 return !(__raw_readl(gic_dist_base_addr
+ GIC_DIST_CTRL
) & 0x1);
105 void gic_dist_enable(void)
107 if (cpu_is_omap443x() || gic_dist_disabled())
108 __raw_writel(0x1, gic_dist_base_addr
+ GIC_DIST_CTRL
);
110 void gic_dist_disable(void)
112 __raw_writel(0, gic_dist_base_addr
+ GIC_CPU_CTRL
);
115 void gic_timer_retrigger(void)
117 u32 twd_int
= __raw_readl(twd_base
+ TWD_TIMER_INTSTAT
);
118 u32 gic_int
= __raw_readl(gic_dist_base_addr
+ GIC_DIST_PENDING_SET
);
119 u32 twd_ctrl
= __raw_readl(twd_base
+ TWD_TIMER_CONTROL
);
121 if (twd_int
&& !(gic_int
& BIT(OMAP44XX_IRQ_LOCALTIMER
))) {
123 * The local timer interrupt got lost while the distributor was
124 * disabled. Ack the pending interrupt, and retrigger it.
126 pr_warn("%s: lost localtimer interrupt\n", __func__
);
127 __raw_writel(1, twd_base
+ TWD_TIMER_INTSTAT
);
128 if (!(twd_ctrl
& TWD_TIMER_CONTROL_PERIODIC
)) {
129 __raw_writel(1, twd_base
+ TWD_TIMER_COUNTER
);
130 twd_ctrl
|= TWD_TIMER_CONTROL_ENABLE
;
131 __raw_writel(twd_ctrl
, twd_base
+ TWD_TIMER_CONTROL
);
136 #ifdef CONFIG_CACHE_L2X0
138 void __iomem
*omap4_get_l2cache_base(void)
143 static void omap4_l2x0_disable(void)
145 /* Disable PL310 L2 Cache controller */
146 omap_smc1(0x102, 0x0);
149 static void omap4_l2x0_set_debug(unsigned long val
)
151 /* Program PL310 L2 Cache controller debug register */
152 omap_smc1(0x100, val
);
155 static int __init
omap_l2_cache_init(void)
160 bool mpu_prefetch_disable_errata
= false;
163 * To avoid code running on other OMAPs in
166 if (!cpu_is_omap44xx())
169 #ifdef CONFIG_OMAP_ALLOW_OSWR
170 if (omap_rev() == OMAP4460_REV_ES1_0
)
171 mpu_prefetch_disable_errata
= true;
174 /* Static mapping, never released */
175 l2cache_base
= ioremap(OMAP44XX_L2CACHE_BASE
, SZ_4K
);
176 if (WARN_ON(!l2cache_base
))
180 * 16-way associativity, parity disabled
181 * Way size - 32KB (es1.0)
182 * Way size - 64KB (es2.0 +)
184 aux_ctrl
= readl_relaxed(l2cache_base
+ L2X0_AUX_CTRL
);
186 if (omap_rev() == OMAP4430_REV_ES1_0
) {
187 aux_ctrl
|= 0x2 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT
;
188 goto skip_aux_por_api
;
192 * Drop instruction prefetch hint since it degrades the
195 aux_ctrl
|= ((0x3 << L2X0_AUX_CTRL_WAY_SIZE_SHIFT
) |
196 (1 << L2X0_AUX_CTRL_SHARE_OVERRIDE_SHIFT
) |
197 (1 << L2X0_AUX_CTRL_EARLY_BRESP_SHIFT
));
199 if (!mpu_prefetch_disable_errata
)
200 aux_ctrl
|= (1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT
);
202 omap_smc1(0x109, aux_ctrl
);
204 /* Setup POR Control register */
205 por_ctrl
= readl_relaxed(l2cache_base
+ L2X0_PREFETCH_CTRL
);
208 * Double linefill is available only on OMAP4460 L2X0.
209 * It may cause single cache line memory corruption, leave it disabled
212 por_ctrl
&= ~(1 << L2X0_PREFETCH_DOUBLE_LINEFILL_SHIFT
);
213 if (!mpu_prefetch_disable_errata
) {
214 por_ctrl
|= 1 << L2X0_PREFETCH_DATA_PREFETCH_SHIFT
;
215 por_ctrl
|= L2X0_POR_OFFSET_VALUE
;
218 /* Set POR through PPA service only in EMU/HS devices */
219 if (omap_type() != OMAP2_DEVICE_TYPE_GP
)
220 omap4_secure_dispatcher(PPA_SERVICE_PL310_POR
, 0x7, 1,
222 else if (omap_rev() >= OMAP4430_REV_ES2_1
)
223 omap_smc1(0x113, por_ctrl
);
227 * FIXME: Temporary WA for OMAP4460 stability issue.
228 * Lock-down specific L2 cache ways which makes effective
229 * L2 size as 512 KB instead of 1 MB
231 if (omap_rev() == OMAP4460_REV_ES1_0
) {
233 writel_relaxed(lockdown
, l2cache_base
+ L2X0_LOCKDOWN_WAY_D0
);
234 writel_relaxed(lockdown
, l2cache_base
+ L2X0_LOCKDOWN_WAY_D1
);
235 writel_relaxed(lockdown
, l2cache_base
+ L2X0_LOCKDOWN_WAY_I0
);
236 writel_relaxed(lockdown
, l2cache_base
+ L2X0_LOCKDOWN_WAY_I1
);
240 /* Enable PL310 L2 Cache controller */
241 omap_smc1(0x102, 0x1);
243 l2x0_init(l2cache_base
, aux_ctrl
, L2X0_AUX_CTRL_MASK
);
246 * Override default outer_cache.disable with a OMAP4
249 outer_cache
.disable
= omap4_l2x0_disable
;
250 outer_cache
.set_debug
= omap4_l2x0_set_debug
;
254 early_initcall(omap_l2_cache_init
);
257 static int __init
omap_barriers_init(void)
259 dma_addr_t dram_phys
;
261 if (!cpu_is_omap44xx())
264 dram_barrier_base
= dma_alloc_stronglyordered(NULL
, SZ_4K
,
265 (dma_addr_t
*)&dram_phys
, GFP_KERNEL
);
266 if (!dram_barrier_base
) {
267 pr_err("%s: failed to allocate memory.\n", __func__
);
271 omap_bus_post
.sync
= omap_bus_sync
;
275 core_initcall(omap_barriers_init
);
277 #ifndef CONFIG_SECURITY_MIDDLEWARE_COMPONENT
279 * omap4_sec_dispatcher: Routine to dispatch low power secure
282 * @idx: The HAL API index
283 * @flag: The flag indicating criticality of operation
284 * @nargs: Number of valid arguments out of four.
285 * @arg1, arg2, arg3 args4: Parameters passed to secure API
287 * Return the error value on success/failure
289 u32
omap4_secure_dispatcher(u32 idx
, u32 flag
, u32 nargs
, u32 arg1
, u32 arg2
,
301 /* Look-up Only once */
302 if (!l4_secure_clkdm
)
303 l4_secure_clkdm
= clkdm_lookup("l4_secure_clkdm");
306 * Put l4 secure to software wakeup so that secure
307 * modules are accessible
309 clkdm_wakeup(l4_secure_clkdm
);
312 * Secure API needs physical address
313 * pointer for the parameters
316 outer_clean_range(__pa(param
), __pa(param
+ 5));
318 ret
= omap_smc2(idx
, flag
, __pa(param
));
321 * Restore l4 secure to hardware superwised to allow
322 * secure modules idle
324 clkdm_allow_idle(l4_secure_clkdm
);