1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * arch/arm/mach-lpc32xx/common.c 4 * 5 * Author: Kevin Wells <kevin.wells@nxp.com> 6 * 7 * Copyright (C) 2010 NXP Semiconductors 8 */ 9 10 #include <linux/init.h> 11 #include <linux/soc/nxp/lpc32xx-misc.h> 12 13 #include <asm/mach/map.h> 14 #include <asm/system_info.h> 15 16 #include "lpc32xx.h" 17 #include "common.h" 18 19 /* 20 * Returns the unique ID for the device 21 */ 22 void lpc32xx_get_uid(u32 devid[4]) 23 { 24 int i; 25 26 for (i = 0; i < 4; i++) 27 devid[i] = __raw_readl(LPC32XX_CLKPWR_DEVID(i << 2)); 28 } 29 30 /* 31 * Detects and returns IRAM size for the device variation 32 */ 33 #define LPC32XX_IRAM_BANK_SIZE SZ_128K 34 static u32 iram_size; 35 u32 lpc32xx_return_iram(void __iomem **mapbase, dma_addr_t *dmaaddr) 36 { 37 if (iram_size == 0) { 38 u32 savedval1, savedval2; 39 void __iomem *iramptr1, *iramptr2; 40 41 iramptr1 = io_p2v(LPC32XX_IRAM_BASE); 42 iramptr2 = io_p2v(LPC32XX_IRAM_BASE + LPC32XX_IRAM_BANK_SIZE); 43 savedval1 = __raw_readl(iramptr1); 44 savedval2 = __raw_readl(iramptr2); 45 46 if (savedval1 == savedval2) { 47 __raw_writel(savedval2 + 1, iramptr2); 48 if (__raw_readl(iramptr1) == savedval2 + 1) 49 iram_size = LPC32XX_IRAM_BANK_SIZE; 50 else 51 iram_size = LPC32XX_IRAM_BANK_SIZE * 2; 52 __raw_writel(savedval2, iramptr2); 53 } else 54 iram_size = LPC32XX_IRAM_BANK_SIZE * 2; 55 } 56 if (dmaaddr) 57 *dmaaddr = LPC32XX_IRAM_BASE; 58 if (mapbase) 59 *mapbase = io_p2v(LPC32XX_IRAM_BASE); 60 61 return iram_size; 62 } 63 EXPORT_SYMBOL_GPL(lpc32xx_return_iram); 64 65 void lpc32xx_set_phy_interface_mode(phy_interface_t mode) 66 { 67 u32 tmp = __raw_readl(LPC32XX_CLKPWR_MACCLK_CTRL); 68 tmp &= ~LPC32XX_CLKPWR_MACCTRL_PINS_MSK; 69 if (mode == PHY_INTERFACE_MODE_MII) 70 tmp |= LPC32XX_CLKPWR_MACCTRL_USE_MII_PINS; 71 else 72 tmp |= LPC32XX_CLKPWR_MACCTRL_USE_RMII_PINS; 73 __raw_writel(tmp, LPC32XX_CLKPWR_MACCLK_CTRL); 74 } 75 EXPORT_SYMBOL_GPL(lpc32xx_set_phy_interface_mode); 76 77 static struct map_desc lpc32xx_io_desc[] __initdata = { 78 { 79 .virtual = (unsigned long)IO_ADDRESS(LPC32XX_AHB0_START), 80 .pfn = __phys_to_pfn(LPC32XX_AHB0_START), 81 .length = LPC32XX_AHB0_SIZE, 82 .type = MT_DEVICE 83 }, 84 { 85 .virtual = (unsigned long)IO_ADDRESS(LPC32XX_AHB1_START), 86 .pfn = __phys_to_pfn(LPC32XX_AHB1_START), 87 .length = LPC32XX_AHB1_SIZE, 88 .type = MT_DEVICE 89 }, 90 { 91 .virtual = (unsigned long)IO_ADDRESS(LPC32XX_FABAPB_START), 92 .pfn = __phys_to_pfn(LPC32XX_FABAPB_START), 93 .length = LPC32XX_FABAPB_SIZE, 94 .type = MT_DEVICE 95 }, 96 { 97 .virtual = (unsigned long)IO_ADDRESS(LPC32XX_IRAM_BASE), 98 .pfn = __phys_to_pfn(LPC32XX_IRAM_BASE), 99 .length = (LPC32XX_IRAM_BANK_SIZE * 2), 100 .type = MT_DEVICE 101 }, 102 }; 103 104 void __init lpc32xx_map_io(void) 105 { 106 iotable_init(lpc32xx_io_desc, ARRAY_SIZE(lpc32xx_io_desc)); 107 } 108 109 static int __init lpc32xx_check_uid(void) 110 { 111 u32 uid[4]; 112 113 lpc32xx_get_uid(uid); 114 115 printk(KERN_INFO "LPC32XX unique ID: %08x%08x%08x%08x\n", 116 uid[3], uid[2], uid[1], uid[0]); 117 118 if (!system_serial_low && !system_serial_high) { 119 system_serial_low = uid[0]; 120 system_serial_high = uid[1]; 121 } 122 123 return 1; 124 } 125 arch_initcall(lpc32xx_check_uid); 126