162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * arch/arm/mach-lpc32xx/common.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Author: Kevin Wells <kevin.wells@nxp.com> 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (C) 2010 NXP Semiconductors 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <linux/init.h> 1162306a36Sopenharmony_ci#include <linux/soc/nxp/lpc32xx-misc.h> 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#include <asm/mach/map.h> 1462306a36Sopenharmony_ci#include <asm/system_info.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include "lpc32xx.h" 1762306a36Sopenharmony_ci#include "common.h" 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci/* 2062306a36Sopenharmony_ci * Returns the unique ID for the device 2162306a36Sopenharmony_ci */ 2262306a36Sopenharmony_civoid lpc32xx_get_uid(u32 devid[4]) 2362306a36Sopenharmony_ci{ 2462306a36Sopenharmony_ci int i; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci for (i = 0; i < 4; i++) 2762306a36Sopenharmony_ci devid[i] = __raw_readl(LPC32XX_CLKPWR_DEVID(i << 2)); 2862306a36Sopenharmony_ci} 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/* 3162306a36Sopenharmony_ci * Detects and returns IRAM size for the device variation 3262306a36Sopenharmony_ci */ 3362306a36Sopenharmony_ci#define LPC32XX_IRAM_BANK_SIZE SZ_128K 3462306a36Sopenharmony_cistatic u32 iram_size; 3562306a36Sopenharmony_ciu32 lpc32xx_return_iram(void __iomem **mapbase, dma_addr_t *dmaaddr) 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci if (iram_size == 0) { 3862306a36Sopenharmony_ci u32 savedval1, savedval2; 3962306a36Sopenharmony_ci void __iomem *iramptr1, *iramptr2; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci iramptr1 = io_p2v(LPC32XX_IRAM_BASE); 4262306a36Sopenharmony_ci iramptr2 = io_p2v(LPC32XX_IRAM_BASE + LPC32XX_IRAM_BANK_SIZE); 4362306a36Sopenharmony_ci savedval1 = __raw_readl(iramptr1); 4462306a36Sopenharmony_ci savedval2 = __raw_readl(iramptr2); 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci if (savedval1 == savedval2) { 4762306a36Sopenharmony_ci __raw_writel(savedval2 + 1, iramptr2); 4862306a36Sopenharmony_ci if (__raw_readl(iramptr1) == savedval2 + 1) 4962306a36Sopenharmony_ci iram_size = LPC32XX_IRAM_BANK_SIZE; 5062306a36Sopenharmony_ci else 5162306a36Sopenharmony_ci iram_size = LPC32XX_IRAM_BANK_SIZE * 2; 5262306a36Sopenharmony_ci __raw_writel(savedval2, iramptr2); 5362306a36Sopenharmony_ci } else 5462306a36Sopenharmony_ci iram_size = LPC32XX_IRAM_BANK_SIZE * 2; 5562306a36Sopenharmony_ci } 5662306a36Sopenharmony_ci if (dmaaddr) 5762306a36Sopenharmony_ci *dmaaddr = LPC32XX_IRAM_BASE; 5862306a36Sopenharmony_ci if (mapbase) 5962306a36Sopenharmony_ci *mapbase = io_p2v(LPC32XX_IRAM_BASE); 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci return iram_size; 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(lpc32xx_return_iram); 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_civoid lpc32xx_set_phy_interface_mode(phy_interface_t mode) 6662306a36Sopenharmony_ci{ 6762306a36Sopenharmony_ci u32 tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL); 6862306a36Sopenharmony_ci tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK; 6962306a36Sopenharmony_ci if (mode == PHY_INTERFACE_MODE_MII) 7062306a36Sopenharmony_ci tmp |= LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS; 7162306a36Sopenharmony_ci else 7262306a36Sopenharmony_ci tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS; 7362306a36Sopenharmony_ci __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL); 7462306a36Sopenharmony_ci} 7562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(lpc32xx_set_phy_interface_mode); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_cistatic struct map_desc lpc32xx_io_desc[] __initdata = { 7862306a36Sopenharmony_ci { 7962306a36Sopenharmony_ci .virtual = (unsigned long)IO_ADDRESS(LPC32XX_AHB0_START), 8062306a36Sopenharmony_ci .pfn = __phys_to_pfn(LPC32XX_AHB0_START), 8162306a36Sopenharmony_ci .length = LPC32XX_AHB0_SIZE, 8262306a36Sopenharmony_ci .type = MT_DEVICE 8362306a36Sopenharmony_ci }, 8462306a36Sopenharmony_ci { 8562306a36Sopenharmony_ci .virtual = (unsigned long)IO_ADDRESS(LPC32XX_AHB1_START), 8662306a36Sopenharmony_ci .pfn = __phys_to_pfn(LPC32XX_AHB1_START), 8762306a36Sopenharmony_ci .length = LPC32XX_AHB1_SIZE, 8862306a36Sopenharmony_ci .type = MT_DEVICE 8962306a36Sopenharmony_ci }, 9062306a36Sopenharmony_ci { 9162306a36Sopenharmony_ci .virtual = (unsigned long)IO_ADDRESS(LPC32XX_FABAPB_START), 9262306a36Sopenharmony_ci .pfn = __phys_to_pfn(LPC32XX_FABAPB_START), 9362306a36Sopenharmony_ci .length = LPC32XX_FABAPB_SIZE, 9462306a36Sopenharmony_ci .type = MT_DEVICE 9562306a36Sopenharmony_ci }, 9662306a36Sopenharmony_ci { 9762306a36Sopenharmony_ci .virtual = (unsigned long)IO_ADDRESS(LPC32XX_IRAM_BASE), 9862306a36Sopenharmony_ci .pfn = __phys_to_pfn(LPC32XX_IRAM_BASE), 9962306a36Sopenharmony_ci .length = (LPC32XX_IRAM_BANK_SIZE * 2), 10062306a36Sopenharmony_ci .type = MT_DEVICE 10162306a36Sopenharmony_ci }, 10262306a36Sopenharmony_ci}; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_civoid __init lpc32xx_map_io(void) 10562306a36Sopenharmony_ci{ 10662306a36Sopenharmony_ci iotable_init(lpc32xx_io_desc, ARRAY_SIZE(lpc32xx_io_desc)); 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistatic int __init lpc32xx_check_uid(void) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci u32 uid[4]; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci lpc32xx_get_uid(uid); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci printk(KERN_INFO "LPC32XX unique ID: %08x%08x%08x%08x\n", 11662306a36Sopenharmony_ci uid[3], uid[2], uid[1], uid[0]); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci if (!system_serial_low && !system_serial_high) { 11962306a36Sopenharmony_ci system_serial_low = uid[0]; 12062306a36Sopenharmony_ci system_serial_high = uid[1]; 12162306a36Sopenharmony_ci } 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci return 1; 12462306a36Sopenharmony_ci} 12562306a36Sopenharmony_ciarch_initcall(lpc32xx_check_uid); 126