Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *
0004  * OMAP SRAM detection and management
0005  *
0006  * Copyright (C) 2005 Nokia Corporation
0007  * Written by Tony Lindgren <tony@atomide.com>
0008  *
0009  * Copyright (C) 2009-2012 Texas Instruments
0010  * Added OMAP4/5 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
0011  */
0012 
0013 #include <linux/module.h>
0014 #include <linux/kernel.h>
0015 #include <linux/init.h>
0016 #include <linux/io.h>
0017 
0018 #include <asm/fncpy.h>
0019 #include <asm/tlb.h>
0020 #include <asm/cacheflush.h>
0021 #include <asm/set_memory.h>
0022 
0023 #include <asm/mach/map.h>
0024 
0025 #include "soc.h"
0026 #include "iomap.h"
0027 #include "prm2xxx_3xxx.h"
0028 #include "sdrc.h"
0029 #include "sram.h"
0030 
0031 #define OMAP2_SRAM_PUB_PA   (OMAP2_SRAM_PA + 0xf800)
0032 #define OMAP3_SRAM_PUB_PA       (OMAP3_SRAM_PA + 0x8000)
0033 
0034 #define SRAM_BOOTLOADER_SZ  0x00
0035 
0036 #define OMAP24XX_VA_REQINFOPERM0    OMAP2_L3_IO_ADDRESS(0x68005048)
0037 #define OMAP24XX_VA_READPERM0       OMAP2_L3_IO_ADDRESS(0x68005050)
0038 #define OMAP24XX_VA_WRITEPERM0      OMAP2_L3_IO_ADDRESS(0x68005058)
0039 
0040 #define OMAP34XX_VA_REQINFOPERM0    OMAP2_L3_IO_ADDRESS(0x68012848)
0041 #define OMAP34XX_VA_READPERM0       OMAP2_L3_IO_ADDRESS(0x68012850)
0042 #define OMAP34XX_VA_WRITEPERM0      OMAP2_L3_IO_ADDRESS(0x68012858)
0043 #define OMAP34XX_VA_ADDR_MATCH2     OMAP2_L3_IO_ADDRESS(0x68012880)
0044 #define OMAP34XX_VA_SMS_RG_ATT0     OMAP2_L3_IO_ADDRESS(0x6C000048)
0045 
0046 #define GP_DEVICE       0x300
0047 
0048 #define ROUND_DOWN(value,boundary)  ((value) & (~((boundary)-1)))
0049 
0050 static unsigned long omap_sram_start;
0051 static unsigned long omap_sram_size;
0052 static void __iomem *omap_sram_base;
0053 static unsigned long omap_sram_skip;
0054 static void __iomem *omap_sram_ceil;
0055 
0056 /*
0057  * Memory allocator for SRAM: calculates the new ceiling address
0058  * for pushing a function using the fncpy API.
0059  *
0060  * Note that fncpy requires the returned address to be aligned
0061  * to an 8-byte boundary.
0062  */
0063 static void *omap_sram_push_address(unsigned long size)
0064 {
0065     unsigned long available, new_ceil = (unsigned long)omap_sram_ceil;
0066 
0067     available = omap_sram_ceil - (omap_sram_base + omap_sram_skip);
0068 
0069     if (size > available) {
0070         pr_err("Not enough space in SRAM\n");
0071         return NULL;
0072     }
0073 
0074     new_ceil -= size;
0075     new_ceil = ROUND_DOWN(new_ceil, FNCPY_ALIGN);
0076     omap_sram_ceil = IOMEM(new_ceil);
0077 
0078     return (void __force *)omap_sram_ceil;
0079 }
0080 
0081 void *omap_sram_push(void *funcp, unsigned long size)
0082 {
0083     void *sram;
0084     unsigned long base;
0085     int pages;
0086     void *dst = NULL;
0087 
0088     sram = omap_sram_push_address(size);
0089     if (!sram)
0090         return NULL;
0091 
0092     base = (unsigned long)sram & PAGE_MASK;
0093     pages = PAGE_ALIGN(size) / PAGE_SIZE;
0094 
0095     set_memory_rw(base, pages);
0096 
0097     dst = fncpy(sram, funcp, size);
0098 
0099     set_memory_ro(base, pages);
0100     set_memory_x(base, pages);
0101 
0102     return dst;
0103 }
0104 
0105 /*
0106  * The SRAM context is lost during off-idle and stack
0107  * needs to be reset.
0108  */
0109 static void omap_sram_reset(void)
0110 {
0111     omap_sram_ceil = omap_sram_base + omap_sram_size;
0112 }
0113 
0114 /*
0115  * Depending on the target RAMFS firewall setup, the public usable amount of
0116  * SRAM varies.  The default accessible size for all device types is 2k. A GP
0117  * device allows ARM11 but not other initiators for full size. This
0118  * functionality seems ok until some nice security API happens.
0119  */
0120 static int is_sram_locked(void)
0121 {
0122     if (OMAP2_DEVICE_TYPE_GP == omap_type()) {
0123         /* RAMFW: R/W access to all initiators for all qualifier sets */
0124         if (cpu_is_omap242x()) {
0125             writel_relaxed(0xFF, OMAP24XX_VA_REQINFOPERM0); /* all q-vects */
0126             writel_relaxed(0xCFDE, OMAP24XX_VA_READPERM0);  /* all i-read */
0127             writel_relaxed(0xCFDE, OMAP24XX_VA_WRITEPERM0); /* all i-write */
0128         }
0129         if (cpu_is_omap34xx()) {
0130             writel_relaxed(0xFFFF, OMAP34XX_VA_REQINFOPERM0); /* all q-vects */
0131             writel_relaxed(0xFFFF, OMAP34XX_VA_READPERM0);  /* all i-read */
0132             writel_relaxed(0xFFFF, OMAP34XX_VA_WRITEPERM0); /* all i-write */
0133             writel_relaxed(0x0, OMAP34XX_VA_ADDR_MATCH2);
0134             writel_relaxed(0xFFFFFFFF, OMAP34XX_VA_SMS_RG_ATT0);
0135         }
0136         return 0;
0137     } else
0138         return 1; /* assume locked with no PPA or security driver */
0139 }
0140 
0141 /*
0142  * The amount of SRAM depends on the core type.
0143  * Note that we cannot try to test for SRAM here because writes
0144  * to secure SRAM will hang the system. Also the SRAM is not
0145  * yet mapped at this point.
0146  */
0147 static void __init omap_detect_sram(void)
0148 {
0149     omap_sram_skip = SRAM_BOOTLOADER_SZ;
0150     if (is_sram_locked()) {
0151         if (cpu_is_omap34xx()) {
0152             omap_sram_start = OMAP3_SRAM_PUB_PA;
0153             if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) ||
0154                 (omap_type() == OMAP2_DEVICE_TYPE_SEC)) {
0155                 omap_sram_size = 0x7000; /* 28K */
0156                 omap_sram_skip += SZ_16K;
0157             } else {
0158                 omap_sram_size = 0x8000; /* 32K */
0159             }
0160         } else {
0161             omap_sram_start = OMAP2_SRAM_PUB_PA;
0162             omap_sram_size = 0x800; /* 2K */
0163         }
0164     } else {
0165         if (cpu_is_omap34xx()) {
0166             omap_sram_start = OMAP3_SRAM_PA;
0167             omap_sram_size = 0x10000; /* 64K */
0168         } else {
0169             omap_sram_start = OMAP2_SRAM_PA;
0170             if (cpu_is_omap242x())
0171                 omap_sram_size = 0xa0000; /* 640K */
0172             else if (cpu_is_omap243x())
0173                 omap_sram_size = 0x10000; /* 64K */
0174         }
0175     }
0176 }
0177 
0178 /*
0179  * Note that we cannot use ioremap for SRAM, as clock init needs SRAM early.
0180  */
0181 static void __init omap2_map_sram(void)
0182 {
0183     unsigned long base;
0184     int pages;
0185     int cached = 1;
0186 
0187     if (cpu_is_omap34xx()) {
0188         /*
0189          * SRAM must be marked as non-cached on OMAP3 since the
0190          * CORE DPLL M2 divider change code (in SRAM) runs with the
0191          * SDRAM controller disabled, and if it is marked cached,
0192          * the ARM may attempt to write cache lines back to SDRAM
0193          * which will cause the system to hang.
0194          */
0195         cached = 0;
0196     }
0197 
0198     if (omap_sram_size == 0)
0199         return;
0200 
0201     omap_sram_start = ROUND_DOWN(omap_sram_start, PAGE_SIZE);
0202     omap_sram_base = __arm_ioremap_exec(omap_sram_start, omap_sram_size, cached);
0203     if (!omap_sram_base) {
0204         pr_err("SRAM: Could not map\n");
0205         return;
0206     }
0207 
0208     omap_sram_reset();
0209 
0210     /*
0211      * Looks like we need to preserve some bootloader code at the
0212      * beginning of SRAM for jumping to flash for reboot to work...
0213      */
0214     memset_io(omap_sram_base + omap_sram_skip, 0,
0215           omap_sram_size - omap_sram_skip);
0216 
0217     base = (unsigned long)omap_sram_base;
0218     pages = PAGE_ALIGN(omap_sram_size) / PAGE_SIZE;
0219 
0220     set_memory_ro(base, pages);
0221     set_memory_x(base, pages);
0222 }
0223 
0224 static void (*_omap2_sram_ddr_init)(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
0225                   u32 base_cs, u32 force_unlock);
0226 
0227 void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl,
0228            u32 base_cs, u32 force_unlock)
0229 {
0230     BUG_ON(!_omap2_sram_ddr_init);
0231     _omap2_sram_ddr_init(slow_dll_ctrl, fast_dll_ctrl,
0232                  base_cs, force_unlock);
0233 }
0234 
0235 static void (*_omap2_sram_reprogram_sdrc)(u32 perf_level, u32 dll_val,
0236                       u32 mem_type);
0237 
0238 void omap2_sram_reprogram_sdrc(u32 perf_level, u32 dll_val, u32 mem_type)
0239 {
0240     BUG_ON(!_omap2_sram_reprogram_sdrc);
0241     _omap2_sram_reprogram_sdrc(perf_level, dll_val, mem_type);
0242 }
0243 
0244 static u32 (*_omap2_set_prcm)(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass);
0245 
0246 u32 omap2_set_prcm(u32 dpll_ctrl_val, u32 sdrc_rfr_val, int bypass)
0247 {
0248     BUG_ON(!_omap2_set_prcm);
0249     return _omap2_set_prcm(dpll_ctrl_val, sdrc_rfr_val, bypass);
0250 }
0251 
0252 #ifdef CONFIG_SOC_OMAP2420
0253 static int __init omap242x_sram_init(void)
0254 {
0255     _omap2_sram_ddr_init = omap_sram_push(omap242x_sram_ddr_init,
0256                     omap242x_sram_ddr_init_sz);
0257 
0258     _omap2_sram_reprogram_sdrc = omap_sram_push(omap242x_sram_reprogram_sdrc,
0259                         omap242x_sram_reprogram_sdrc_sz);
0260 
0261     _omap2_set_prcm = omap_sram_push(omap242x_sram_set_prcm,
0262                      omap242x_sram_set_prcm_sz);
0263 
0264     return 0;
0265 }
0266 #else
0267 static inline int omap242x_sram_init(void)
0268 {
0269     return 0;
0270 }
0271 #endif
0272 
0273 #ifdef CONFIG_SOC_OMAP2430
0274 static int __init omap243x_sram_init(void)
0275 {
0276     _omap2_sram_ddr_init = omap_sram_push(omap243x_sram_ddr_init,
0277                     omap243x_sram_ddr_init_sz);
0278 
0279     _omap2_sram_reprogram_sdrc = omap_sram_push(omap243x_sram_reprogram_sdrc,
0280                         omap243x_sram_reprogram_sdrc_sz);
0281 
0282     _omap2_set_prcm = omap_sram_push(omap243x_sram_set_prcm,
0283                      omap243x_sram_set_prcm_sz);
0284 
0285     return 0;
0286 }
0287 #else
0288 static inline int omap243x_sram_init(void)
0289 {
0290     return 0;
0291 }
0292 #endif
0293 
0294 #ifdef CONFIG_ARCH_OMAP3
0295 
0296 void omap3_sram_restore_context(void)
0297 {
0298     omap_sram_reset();
0299 
0300     omap_push_sram_idle();
0301 }
0302 
0303 static inline int omap34xx_sram_init(void)
0304 {
0305     omap3_sram_restore_context();
0306     return 0;
0307 }
0308 #else
0309 static inline int omap34xx_sram_init(void)
0310 {
0311     return 0;
0312 }
0313 #endif /* CONFIG_ARCH_OMAP3 */
0314 
0315 int __init omap_sram_init(void)
0316 {
0317     omap_detect_sram();
0318     omap2_map_sram();
0319 
0320     if (cpu_is_omap242x())
0321         omap242x_sram_init();
0322     else if (cpu_is_omap2430())
0323         omap243x_sram_init();
0324     else if (cpu_is_omap34xx())
0325         omap34xx_sram_init();
0326 
0327     return 0;
0328 }