0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/init.h>
0012 #include <linux/io.h>
0013 #include <linux/irq.h>
0014 #include <linux/irqchip.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/memblock.h>
0017 #include <linux/of_irq.h>
0018 #include <linux/of_platform.h>
0019 #include <linux/export.h>
0020 #include <linux/irqchip/arm-gic.h>
0021 #include <linux/of_address.h>
0022 #include <linux/reboot.h>
0023 #include <linux/genalloc.h>
0024
0025 #include <asm/hardware/cache-l2x0.h>
0026 #include <asm/mach/map.h>
0027 #include <asm/memblock.h>
0028 #include <asm/smp_twd.h>
0029
0030 #include "omap-wakeupgen.h"
0031 #include "soc.h"
0032 #include "iomap.h"
0033 #include "common.h"
0034 #include "prminst44xx.h"
0035 #include "prcm_mpu44xx.h"
0036 #include "omap4-sar-layout.h"
0037 #include "omap-secure.h"
0038 #include "sram.h"
0039
0040 #ifdef CONFIG_CACHE_L2X0
0041 static void __iomem *l2cache_base;
0042 #endif
0043
0044 static void __iomem *sar_ram_base;
0045 static void __iomem *gic_dist_base_addr;
0046 static void __iomem *twd_base;
0047
0048 #define IRQ_LOCALTIMER 29
0049
0050 #ifdef CONFIG_OMAP_INTERCONNECT_BARRIER
0051
0052
0053 #define OMAP4_DRAM_BARRIER_VA 0xfe600000
0054
0055 static void __iomem *dram_sync, *sram_sync;
0056 static phys_addr_t dram_sync_paddr;
0057 static u32 dram_sync_size;
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081 static void omap4_mb(void)
0082 {
0083 if (dram_sync)
0084 writel_relaxed(0, dram_sync);
0085 }
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116 void omap_interconnect_sync(void)
0117 {
0118 if (dram_sync && sram_sync) {
0119 writel_relaxed(readl_relaxed(dram_sync), dram_sync);
0120 writel_relaxed(readl_relaxed(sram_sync), sram_sync);
0121 isb();
0122 }
0123 }
0124
0125 static int __init omap4_sram_init(void)
0126 {
0127 struct device_node *np;
0128 struct gen_pool *sram_pool;
0129
0130 if (!soc_is_omap44xx() && !soc_is_omap54xx())
0131 return 0;
0132
0133 np = of_find_compatible_node(NULL, NULL, "ti,omap4-mpu");
0134 if (!np)
0135 pr_warn("%s:Unable to allocate sram needed to handle errata I688\n",
0136 __func__);
0137 sram_pool = of_gen_pool_get(np, "sram", 0);
0138 if (!sram_pool)
0139 pr_warn("%s:Unable to get sram pool needed to handle errata I688\n",
0140 __func__);
0141 else
0142 sram_sync = (void __iomem *)gen_pool_alloc(sram_pool, PAGE_SIZE);
0143
0144 return 0;
0145 }
0146 omap_arch_initcall(omap4_sram_init);
0147
0148
0149 void __init omap_barrier_reserve_memblock(void)
0150 {
0151 dram_sync_size = ALIGN(PAGE_SIZE, SZ_1M);
0152 dram_sync_paddr = arm_memblock_steal(dram_sync_size, SZ_1M);
0153 }
0154
0155 void __init omap_barriers_init(void)
0156 {
0157 struct map_desc dram_io_desc[1];
0158
0159 dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA;
0160 dram_io_desc[0].pfn = __phys_to_pfn(dram_sync_paddr);
0161 dram_io_desc[0].length = dram_sync_size;
0162 dram_io_desc[0].type = MT_MEMORY_RW_SO;
0163 iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc));
0164 dram_sync = (void __iomem *) dram_io_desc[0].virtual;
0165
0166 pr_info("OMAP4: Map %pa to %p for dram barrier\n",
0167 &dram_sync_paddr, dram_sync);
0168
0169 soc_mb = omap4_mb;
0170 }
0171
0172 #endif
0173
0174 void gic_dist_disable(void)
0175 {
0176 if (gic_dist_base_addr)
0177 writel_relaxed(0x0, gic_dist_base_addr + GIC_DIST_CTRL);
0178 }
0179
0180 void gic_dist_enable(void)
0181 {
0182 if (gic_dist_base_addr)
0183 writel_relaxed(0x1, gic_dist_base_addr + GIC_DIST_CTRL);
0184 }
0185
0186 bool gic_dist_disabled(void)
0187 {
0188 return !(readl_relaxed(gic_dist_base_addr + GIC_DIST_CTRL) & 0x1);
0189 }
0190
0191 void gic_timer_retrigger(void)
0192 {
0193 u32 twd_int = readl_relaxed(twd_base + TWD_TIMER_INTSTAT);
0194 u32 gic_int = readl_relaxed(gic_dist_base_addr + GIC_DIST_PENDING_SET);
0195 u32 twd_ctrl = readl_relaxed(twd_base + TWD_TIMER_CONTROL);
0196
0197 if (twd_int && !(gic_int & BIT(IRQ_LOCALTIMER))) {
0198
0199
0200
0201
0202 pr_warn("%s: lost localtimer interrupt\n", __func__);
0203 writel_relaxed(1, twd_base + TWD_TIMER_INTSTAT);
0204 if (!(twd_ctrl & TWD_TIMER_CONTROL_PERIODIC)) {
0205 writel_relaxed(1, twd_base + TWD_TIMER_COUNTER);
0206 twd_ctrl |= TWD_TIMER_CONTROL_ENABLE;
0207 writel_relaxed(twd_ctrl, twd_base + TWD_TIMER_CONTROL);
0208 }
0209 }
0210 }
0211
0212 #ifdef CONFIG_CACHE_L2X0
0213
0214 void __iomem *omap4_get_l2cache_base(void)
0215 {
0216 return l2cache_base;
0217 }
0218
0219 void omap4_l2c310_write_sec(unsigned long val, unsigned reg)
0220 {
0221 unsigned smc_op;
0222
0223 switch (reg) {
0224 case L2X0_CTRL:
0225 smc_op = OMAP4_MON_L2X0_CTRL_INDEX;
0226 break;
0227
0228 case L2X0_AUX_CTRL:
0229 smc_op = OMAP4_MON_L2X0_AUXCTRL_INDEX;
0230 break;
0231
0232 case L2X0_DEBUG_CTRL:
0233 smc_op = OMAP4_MON_L2X0_DBG_CTRL_INDEX;
0234 break;
0235
0236 case L310_PREFETCH_CTRL:
0237 smc_op = OMAP4_MON_L2X0_PREFETCH_INDEX;
0238 break;
0239
0240 case L310_POWER_CTRL:
0241 pr_info_once("OMAP L2C310: ROM does not support power control setting\n");
0242 return;
0243
0244 default:
0245 WARN_ONCE(1, "OMAP L2C310: ignoring write to reg 0x%x\n", reg);
0246 return;
0247 }
0248
0249 omap_smc1(smc_op, val);
0250 }
0251
0252 int __init omap_l2_cache_init(void)
0253 {
0254
0255 l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
0256 if (WARN_ON(!l2cache_base))
0257 return -ENOMEM;
0258 return 0;
0259 }
0260 #endif
0261
0262 void __iomem *omap4_get_sar_ram_base(void)
0263 {
0264 return sar_ram_base;
0265 }
0266
0267
0268
0269
0270
0271
0272 void __init omap4_sar_ram_init(void)
0273 {
0274 unsigned long sar_base;
0275
0276
0277
0278
0279
0280 if (cpu_is_omap44xx())
0281 sar_base = OMAP44XX_SAR_RAM_BASE;
0282 else if (soc_is_omap54xx())
0283 sar_base = OMAP54XX_SAR_RAM_BASE;
0284 else
0285 return;
0286
0287
0288 sar_ram_base = ioremap(sar_base, SZ_16K);
0289 if (WARN_ON(!sar_ram_base))
0290 return;
0291 }
0292
0293 static const struct of_device_id intc_match[] = {
0294 { .compatible = "ti,omap4-wugen-mpu", },
0295 { .compatible = "ti,omap5-wugen-mpu", },
0296 { },
0297 };
0298
0299 static struct device_node *intc_node;
0300
0301 void __init omap_gic_of_init(void)
0302 {
0303 struct device_node *np;
0304
0305 intc_node = of_find_matching_node(NULL, intc_match);
0306 if (WARN_ON(!intc_node)) {
0307 pr_err("No WUGEN found in DT, system will misbehave.\n");
0308 pr_err("UPDATE YOUR DEVICE TREE!\n");
0309 }
0310
0311
0312 if (!cpu_is_omap446x())
0313 goto skip_errata_init;
0314
0315 np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-gic");
0316 gic_dist_base_addr = of_iomap(np, 0);
0317 of_node_put(np);
0318 WARN_ON(!gic_dist_base_addr);
0319
0320 np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-twd-timer");
0321 twd_base = of_iomap(np, 0);
0322 of_node_put(np);
0323 WARN_ON(!twd_base);
0324
0325 skip_errata_init:
0326 irqchip_init();
0327 }