Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * OMAP SRAM detection and management
0004  *
0005  * Copyright (C) 2005 Nokia Corporation
0006  * Written by Tony Lindgren <tony@atomide.com>
0007  */
0008 
0009 #include <linux/module.h>
0010 #include <linux/kernel.h>
0011 #include <linux/init.h>
0012 #include <linux/io.h>
0013 
0014 #include <asm/fncpy.h>
0015 #include <asm/tlb.h>
0016 #include <asm/cacheflush.h>
0017 #include <asm/set_memory.h>
0018 
0019 #include <asm/mach/map.h>
0020 
0021 #include "soc.h"
0022 #include "sram.h"
0023 
0024 #define OMAP1_SRAM_PA       0x20000000
0025 #define SRAM_BOOTLOADER_SZ  0x80
0026 #define ROUND_DOWN(value,boundary)  ((value) & (~((boundary)-1)))
0027 
0028 static void __iomem *omap_sram_base;
0029 static unsigned long omap_sram_start;
0030 static unsigned long omap_sram_skip;
0031 static unsigned long omap_sram_size;
0032 static void __iomem *omap_sram_ceil;
0033 
0034 /*
0035  * Memory allocator for SRAM: calculates the new ceiling address
0036  * for pushing a function using the fncpy API.
0037  *
0038  * Note that fncpy requires the returned address to be aligned
0039  * to an 8-byte boundary.
0040  */
0041 static void *omap_sram_push_address(unsigned long size)
0042 {
0043     unsigned long available, new_ceil = (unsigned long)omap_sram_ceil;
0044 
0045     available = omap_sram_ceil - (omap_sram_base + omap_sram_skip);
0046 
0047     if (size > available) {
0048         pr_err("Not enough space in SRAM\n");
0049         return NULL;
0050     }
0051 
0052     new_ceil -= size;
0053     new_ceil = ROUND_DOWN(new_ceil, FNCPY_ALIGN);
0054     omap_sram_ceil = IOMEM(new_ceil);
0055 
0056     return (void __force *)omap_sram_ceil;
0057 }
0058 
0059 void *omap_sram_push(void *funcp, unsigned long size)
0060 {
0061     void *sram;
0062     unsigned long base;
0063     int pages;
0064     void *dst = NULL;
0065 
0066     sram = omap_sram_push_address(size);
0067     if (!sram)
0068         return NULL;
0069 
0070     base = (unsigned long)sram & PAGE_MASK;
0071     pages = PAGE_ALIGN(size) / PAGE_SIZE;
0072 
0073     set_memory_rw(base, pages);
0074 
0075     dst = fncpy(sram, funcp, size);
0076 
0077     set_memory_ro(base, pages);
0078     set_memory_x(base, pages);
0079 
0080     return dst;
0081 }
0082 
0083 /*
0084  * The amount of SRAM depends on the core type.
0085  * Note that we cannot try to test for SRAM here because writes
0086  * to secure SRAM will hang the system. Also the SRAM is not
0087  * yet mapped at this point.
0088  * Note that we cannot use ioremap for SRAM, as clock init needs SRAM early.
0089  */
0090 static void __init omap_detect_and_map_sram(void)
0091 {
0092     unsigned long base;
0093     int pages;
0094 
0095     omap_sram_skip = SRAM_BOOTLOADER_SZ;
0096     omap_sram_start = OMAP1_SRAM_PA;
0097 
0098     if (cpu_is_omap7xx())
0099         omap_sram_size = 0x32000;   /* 200K */
0100     else if (cpu_is_omap15xx())
0101         omap_sram_size = 0x30000;   /* 192K */
0102     else if (cpu_is_omap1610() || cpu_is_omap1611() ||
0103             cpu_is_omap1621() || cpu_is_omap1710())
0104         omap_sram_size = 0x4000;    /* 16K */
0105     else {
0106         pr_err("Could not detect SRAM size\n");
0107         omap_sram_size = 0x4000;
0108     }
0109 
0110     omap_sram_start = ROUND_DOWN(omap_sram_start, PAGE_SIZE);
0111     omap_sram_base = __arm_ioremap_exec(omap_sram_start, omap_sram_size, 1);
0112     if (!omap_sram_base) {
0113         pr_err("SRAM: Could not map\n");
0114         return;
0115     }
0116 
0117     omap_sram_ceil = omap_sram_base + omap_sram_size;
0118 
0119     /*
0120      * Looks like we need to preserve some bootloader code at the
0121      * beginning of SRAM for jumping to flash for reboot to work...
0122      */
0123     memset_io(omap_sram_base + omap_sram_skip, 0,
0124           omap_sram_size - omap_sram_skip);
0125 
0126     base = (unsigned long)omap_sram_base;
0127     pages = PAGE_ALIGN(omap_sram_size) / PAGE_SIZE;
0128 
0129     set_memory_ro(base, pages);
0130     set_memory_x(base, pages);
0131 }
0132 
0133 static void (*_omap_sram_reprogram_clock)(u32 dpllctl, u32 ckctl);
0134 
0135 void omap_sram_reprogram_clock(u32 dpllctl, u32 ckctl)
0136 {
0137     BUG_ON(!_omap_sram_reprogram_clock);
0138     /* On 730, bit 13 must always be 1 */
0139     if (cpu_is_omap7xx())
0140         ckctl |= 0x2000;
0141     _omap_sram_reprogram_clock(dpllctl, ckctl);
0142 }
0143 
0144 int __init omap1_sram_init(void)
0145 {
0146     omap_detect_and_map_sram();
0147     _omap_sram_reprogram_clock =
0148             omap_sram_push(omap1_sram_reprogram_clock,
0149                     omap1_sram_reprogram_clock_sz);
0150 
0151     return 0;
0152 }