1 /* 2 * arch/arm/mach-lpc32xx/common.c 3 * 4 * Author: Kevin Wells <kevin.wells@nxp.com> 5 * 6 * Copyright (C) 2010 NXP Semiconductors 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 */ 18 19 #include <linux/init.h> 20 21 #include <asm/mach/map.h> 22 #include <asm/system_info.h> 23 24 #include <mach/hardware.h> 25 #include <mach/platform.h> 26 #include "common.h" 27 28 /* 29 * Returns the unique ID for the device 30 */ 31 void lpc32xx_get_uid(u32 devid[4]) 32 { 33 int i; 34 35 for (i = 0; i < 4; i++) 36 devid[i] = __raw_readl(LPC32XX_CLKPWR_DEVID(i << 2)); 37 } 38 39 /* 40 * Detects and returns IRAM size for the device variation 41 */ 42 #define LPC32XX_IRAM_BANK_SIZE SZ_128K 43 static u32 iram_size; 44 u32 lpc32xx_return_iram_size(void) 45 { 46 if (iram_size == 0) { 47 u32 savedval1, savedval2; 48 void __iomem *iramptr1, *iramptr2; 49 50 iramptr1 = io_p2v(LPC32XX_IRAM_BASE); 51 iramptr2 = io_p2v(LPC32XX_IRAM_BASE + LPC32XX_IRAM_BANK_SIZE); 52 savedval1 = __raw_readl(iramptr1); 53 savedval2 = __raw_readl(iramptr2); 54 55 if (savedval1 == savedval2) { 56 __raw_writel(savedval2 + 1, iramptr2); 57 if (__raw_readl(iramptr1) == savedval2 + 1) 58 iram_size = LPC32XX_IRAM_BANK_SIZE; 59 else 60 iram_size = LPC32XX_IRAM_BANK_SIZE * 2; 61 __raw_writel(savedval2, iramptr2); 62 } else 63 iram_size = LPC32XX_IRAM_BANK_SIZE * 2; 64 } 65 66 return iram_size; 67 } 68 EXPORT_SYMBOL_GPL(lpc32xx_return_iram_size); 69 70 static struct map_desc lpc32xx_io_desc[] __initdata = { 71 { 72 .virtual = (unsigned long)IO_ADDRESS(LPC32XX_AHB0_START), 73 .pfn = __phys_to_pfn(LPC32XX_AHB0_START), 74 .length = LPC32XX_AHB0_SIZE, 75 .type = MT_DEVICE 76 }, 77 { 78 .virtual = (unsigned long)IO_ADDRESS(LPC32XX_AHB1_START), 79 .pfn = __phys_to_pfn(LPC32XX_AHB1_START), 80 .length = LPC32XX_AHB1_SIZE, 81 .type = MT_DEVICE 82 }, 83 { 84 .virtual = (unsigned long)IO_ADDRESS(LPC32XX_FABAPB_START), 85 .pfn = __phys_to_pfn(LPC32XX_FABAPB_START), 86 .length = LPC32XX_FABAPB_SIZE, 87 .type = MT_DEVICE 88 }, 89 { 90 .virtual = (unsigned long)IO_ADDRESS(LPC32XX_IRAM_BASE), 91 .pfn = __phys_to_pfn(LPC32XX_IRAM_BASE), 92 .length = (LPC32XX_IRAM_BANK_SIZE * 2), 93 .type = MT_DEVICE 94 }, 95 }; 96 97 void __init lpc32xx_map_io(void) 98 { 99 iotable_init(lpc32xx_io_desc, ARRAY_SIZE(lpc32xx_io_desc)); 100 } 101 102 static int __init lpc32xx_check_uid(void) 103 { 104 u32 uid[4]; 105 106 lpc32xx_get_uid(uid); 107 108 printk(KERN_INFO "LPC32XX unique ID: %08x%08x%08x%08x\n", 109 uid[3], uid[2], uid[1], uid[0]); 110 111 if (!system_serial_low && !system_serial_high) { 112 system_serial_low = uid[0]; 113 system_serial_high = uid[1]; 114 } 115 116 return 1; 117 } 118 arch_initcall(lpc32xx_check_uid); 119