18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * arch/arm/mach-lpc32xx/common.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Author: Kevin Wells <kevin.wells@nxp.com> 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Copyright (C) 2010 NXP Semiconductors 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/init.h> 118c2ecf20Sopenharmony_ci#include <linux/soc/nxp/lpc32xx-misc.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <asm/mach/map.h> 148c2ecf20Sopenharmony_ci#include <asm/system_info.h> 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci#include "lpc32xx.h" 178c2ecf20Sopenharmony_ci#include "common.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci/* 208c2ecf20Sopenharmony_ci * Returns the unique ID for the device 218c2ecf20Sopenharmony_ci */ 228c2ecf20Sopenharmony_civoid lpc32xx_get_uid(u32 devid[4]) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci int i; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci for (i = 0; i < 4; i++) 278c2ecf20Sopenharmony_ci devid[i] = __raw_readl(LPC32XX_CLKPWR_DEVID(i << 2)); 288c2ecf20Sopenharmony_ci} 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/* 318c2ecf20Sopenharmony_ci * Detects and returns IRAM size for the device variation 328c2ecf20Sopenharmony_ci */ 338c2ecf20Sopenharmony_ci#define LPC32XX_IRAM_BANK_SIZE SZ_128K 348c2ecf20Sopenharmony_cistatic u32 iram_size; 358c2ecf20Sopenharmony_ciu32 lpc32xx_return_iram(void __iomem **mapbase, dma_addr_t *dmaaddr) 368c2ecf20Sopenharmony_ci{ 378c2ecf20Sopenharmony_ci if (iram_size == 0) { 388c2ecf20Sopenharmony_ci u32 savedval1, savedval2; 398c2ecf20Sopenharmony_ci void __iomem *iramptr1, *iramptr2; 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_ci iramptr1 = io_p2v(LPC32XX_IRAM_BASE); 428c2ecf20Sopenharmony_ci iramptr2 = io_p2v(LPC32XX_IRAM_BASE + LPC32XX_IRAM_BANK_SIZE); 438c2ecf20Sopenharmony_ci savedval1 = __raw_readl(iramptr1); 448c2ecf20Sopenharmony_ci savedval2 = __raw_readl(iramptr2); 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci if (savedval1 == savedval2) { 478c2ecf20Sopenharmony_ci __raw_writel(savedval2 + 1, iramptr2); 488c2ecf20Sopenharmony_ci if (__raw_readl(iramptr1) == savedval2 + 1) 498c2ecf20Sopenharmony_ci iram_size = LPC32XX_IRAM_BANK_SIZE; 508c2ecf20Sopenharmony_ci else 518c2ecf20Sopenharmony_ci iram_size = LPC32XX_IRAM_BANK_SIZE * 2; 528c2ecf20Sopenharmony_ci __raw_writel(savedval2, iramptr2); 538c2ecf20Sopenharmony_ci } else 548c2ecf20Sopenharmony_ci iram_size = LPC32XX_IRAM_BANK_SIZE * 2; 558c2ecf20Sopenharmony_ci } 568c2ecf20Sopenharmony_ci if (dmaaddr) 578c2ecf20Sopenharmony_ci *dmaaddr = LPC32XX_IRAM_BASE; 588c2ecf20Sopenharmony_ci if (mapbase) 598c2ecf20Sopenharmony_ci *mapbase = io_p2v(LPC32XX_IRAM_BASE); 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci return iram_size; 628c2ecf20Sopenharmony_ci} 638c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(lpc32xx_return_iram); 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_civoid lpc32xx_set_phy_interface_mode(phy_interface_t mode) 668c2ecf20Sopenharmony_ci{ 678c2ecf20Sopenharmony_ci u32 tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL); 688c2ecf20Sopenharmony_ci tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK; 698c2ecf20Sopenharmony_ci if (mode == PHY_INTERFACE_MODE_MII) 708c2ecf20Sopenharmony_ci tmp |= LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS; 718c2ecf20Sopenharmony_ci else 728c2ecf20Sopenharmony_ci tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS; 738c2ecf20Sopenharmony_ci __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL); 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(lpc32xx_set_phy_interface_mode); 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_cistatic struct map_desc lpc32xx_io_desc[] __initdata = { 788c2ecf20Sopenharmony_ci { 798c2ecf20Sopenharmony_ci .virtual = (unsigned long)IO_ADDRESS(LPC32XX_AHB0_START), 808c2ecf20Sopenharmony_ci .pfn = __phys_to_pfn(LPC32XX_AHB0_START), 818c2ecf20Sopenharmony_ci .length = LPC32XX_AHB0_SIZE, 828c2ecf20Sopenharmony_ci .type = MT_DEVICE 838c2ecf20Sopenharmony_ci }, 848c2ecf20Sopenharmony_ci { 858c2ecf20Sopenharmony_ci .virtual = (unsigned long)IO_ADDRESS(LPC32XX_AHB1_START), 868c2ecf20Sopenharmony_ci .pfn = __phys_to_pfn(LPC32XX_AHB1_START), 878c2ecf20Sopenharmony_ci .length = LPC32XX_AHB1_SIZE, 888c2ecf20Sopenharmony_ci .type = MT_DEVICE 898c2ecf20Sopenharmony_ci }, 908c2ecf20Sopenharmony_ci { 918c2ecf20Sopenharmony_ci .virtual = (unsigned long)IO_ADDRESS(LPC32XX_FABAPB_START), 928c2ecf20Sopenharmony_ci .pfn = __phys_to_pfn(LPC32XX_FABAPB_START), 938c2ecf20Sopenharmony_ci .length = LPC32XX_FABAPB_SIZE, 948c2ecf20Sopenharmony_ci .type = MT_DEVICE 958c2ecf20Sopenharmony_ci }, 968c2ecf20Sopenharmony_ci { 978c2ecf20Sopenharmony_ci .virtual = (unsigned long)IO_ADDRESS(LPC32XX_IRAM_BASE), 988c2ecf20Sopenharmony_ci .pfn = __phys_to_pfn(LPC32XX_IRAM_BASE), 998c2ecf20Sopenharmony_ci .length = (LPC32XX_IRAM_BANK_SIZE * 2), 1008c2ecf20Sopenharmony_ci .type = MT_DEVICE 1018c2ecf20Sopenharmony_ci }, 1028c2ecf20Sopenharmony_ci}; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_civoid __init lpc32xx_map_io(void) 1058c2ecf20Sopenharmony_ci{ 1068c2ecf20Sopenharmony_ci iotable_init(lpc32xx_io_desc, ARRAY_SIZE(lpc32xx_io_desc)); 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistatic int __init lpc32xx_check_uid(void) 1108c2ecf20Sopenharmony_ci{ 1118c2ecf20Sopenharmony_ci u32 uid[4]; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci lpc32xx_get_uid(uid); 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_ci printk(KERN_INFO "LPC32XX unique ID: %08x%08x%08x%08x\n", 1168c2ecf20Sopenharmony_ci uid[3], uid[2], uid[1], uid[0]); 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci if (!system_serial_low && !system_serial_high) { 1198c2ecf20Sopenharmony_ci system_serial_low = uid[0]; 1208c2ecf20Sopenharmony_ci system_serial_high = uid[1]; 1218c2ecf20Sopenharmony_ci } 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci return 1; 1248c2ecf20Sopenharmony_ci} 1258c2ecf20Sopenharmony_ciarch_initcall(lpc32xx_check_uid); 126