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 12 #include <asm/mach/map.h> 13 #include <asm/system_info.h> 14 15 #include <mach/hardware.h> 16 #include <mach/platform.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_size(void) 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 57 return iram_size; 58 } 59 EXPORT_SYMBOL_GPL(lpc32xx_return_iram_size); 60 61 static struct map_desc lpc32xx_io_desc[] __initdata = { 62 { 63 .virtual = (unsigned long)IO_ADDRESS(LPC32XX_AHB0_START), 64 .pfn = __phys_to_pfn(LPC32XX_AHB0_START), 65 .length = LPC32XX_AHB0_SIZE, 66 .type = MT_DEVICE 67 }, 68 { 69 .virtual = (unsigned long)IO_ADDRESS(LPC32XX_AHB1_START), 70 .pfn = __phys_to_pfn(LPC32XX_AHB1_START), 71 .length = LPC32XX_AHB1_SIZE, 72 .type = MT_DEVICE 73 }, 74 { 75 .virtual = (unsigned long)IO_ADDRESS(LPC32XX_FABAPB_START), 76 .pfn = __phys_to_pfn(LPC32XX_FABAPB_START), 77 .length = LPC32XX_FABAPB_SIZE, 78 .type = MT_DEVICE 79 }, 80 { 81 .virtual = (unsigned long)IO_ADDRESS(LPC32XX_IRAM_BASE), 82 .pfn = __phys_to_pfn(LPC32XX_IRAM_BASE), 83 .length = (LPC32XX_IRAM_BANK_SIZE * 2), 84 .type = MT_DEVICE 85 }, 86 }; 87 88 void __init lpc32xx_map_io(void) 89 { 90 iotable_init(lpc32xx_io_desc, ARRAY_SIZE(lpc32xx_io_desc)); 91 } 92 93 static int __init lpc32xx_check_uid(void) 94 { 95 u32 uid[4]; 96 97 lpc32xx_get_uid(uid); 98 99 printk(KERN_INFO "LPC32XX unique ID: %08x%08x%08x%08x\n", 100 uid[3], uid[2], uid[1], uid[0]); 101 102 if (!system_serial_low && !system_serial_high) { 103 system_serial_low = uid[0]; 104 system_serial_high = uid[1]; 105 } 106 107 return 1; 108 } 109 arch_initcall(lpc32xx_check_uid); 110