162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * SDK7786 FPGA SRAM Support. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2010 Paul Mundt 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <linux/init.h> 1062306a36Sopenharmony_ci#include <linux/kernel.h> 1162306a36Sopenharmony_ci#include <linux/types.h> 1262306a36Sopenharmony_ci#include <linux/io.h> 1362306a36Sopenharmony_ci#include <linux/string.h> 1462306a36Sopenharmony_ci#include <mach/fpga.h> 1562306a36Sopenharmony_ci#include <asm/sram.h> 1662306a36Sopenharmony_ci#include <linux/sizes.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_cistatic int __init fpga_sram_init(void) 1962306a36Sopenharmony_ci{ 2062306a36Sopenharmony_ci unsigned long phys; 2162306a36Sopenharmony_ci unsigned int area; 2262306a36Sopenharmony_ci void __iomem *vaddr; 2362306a36Sopenharmony_ci int ret; 2462306a36Sopenharmony_ci u16 data; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci /* Enable FPGA SRAM */ 2762306a36Sopenharmony_ci data = fpga_read_reg(LCLASR); 2862306a36Sopenharmony_ci data |= LCLASR_FRAMEN; 2962306a36Sopenharmony_ci fpga_write_reg(data, LCLASR); 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci /* 3262306a36Sopenharmony_ci * FPGA_SEL determines the area mapping 3362306a36Sopenharmony_ci */ 3462306a36Sopenharmony_ci area = (data & LCLASR_FPGA_SEL_MASK) >> LCLASR_FPGA_SEL_SHIFT; 3562306a36Sopenharmony_ci if (unlikely(area == LCLASR_AREA_MASK)) { 3662306a36Sopenharmony_ci pr_err("FPGA memory unmapped.\n"); 3762306a36Sopenharmony_ci return -ENXIO; 3862306a36Sopenharmony_ci } 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci /* 4162306a36Sopenharmony_ci * The memory itself occupies a 2KiB range at the top of the area 4262306a36Sopenharmony_ci * immediately below the system registers. 4362306a36Sopenharmony_ci */ 4462306a36Sopenharmony_ci phys = (area << 26) + SZ_64M - SZ_4K; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci /* 4762306a36Sopenharmony_ci * The FPGA SRAM resides in translatable physical space, so set 4862306a36Sopenharmony_ci * up a mapping prior to inserting it in to the pool. 4962306a36Sopenharmony_ci */ 5062306a36Sopenharmony_ci vaddr = ioremap(phys, SZ_2K); 5162306a36Sopenharmony_ci if (unlikely(!vaddr)) { 5262306a36Sopenharmony_ci pr_err("Failed remapping FPGA memory.\n"); 5362306a36Sopenharmony_ci return -ENXIO; 5462306a36Sopenharmony_ci } 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci pr_info("Adding %dKiB of FPGA memory at 0x%08lx-0x%08lx " 5762306a36Sopenharmony_ci "(area %d) to pool.\n", 5862306a36Sopenharmony_ci SZ_2K >> 10, phys, phys + SZ_2K - 1, area); 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci ret = gen_pool_add(sram_pool, (unsigned long)vaddr, SZ_2K, -1); 6162306a36Sopenharmony_ci if (unlikely(ret < 0)) { 6262306a36Sopenharmony_ci pr_err("Failed adding memory\n"); 6362306a36Sopenharmony_ci iounmap(vaddr); 6462306a36Sopenharmony_ci return ret; 6562306a36Sopenharmony_ci } 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci return 0; 6862306a36Sopenharmony_ci} 6962306a36Sopenharmony_cipostcore_initcall(fpga_sram_init); 70