1 /* 2 * arch/arm/mach-ep93xx/ts72xx.c 3 * Technologic Systems TS72xx SBC support. 4 * 5 * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or (at 10 * your option) any later version. 11 */ 12 13 #include <linux/kernel.h> 14 #include <linux/init.h> 15 #include <linux/platform_device.h> 16 #include <linux/io.h> 17 #include <linux/m48t86.h> 18 #include <linux/mtd/physmap.h> 19 20 #include <mach/hardware.h> 21 #include <mach/ts72xx.h> 22 23 #include <asm/mach-types.h> 24 #include <asm/mach/map.h> 25 #include <asm/mach/arch.h> 26 27 28 static struct map_desc ts72xx_io_desc[] __initdata = { 29 { 30 .virtual = TS72XX_MODEL_VIRT_BASE, 31 .pfn = __phys_to_pfn(TS72XX_MODEL_PHYS_BASE), 32 .length = TS72XX_MODEL_SIZE, 33 .type = MT_DEVICE, 34 }, { 35 .virtual = TS72XX_OPTIONS_VIRT_BASE, 36 .pfn = __phys_to_pfn(TS72XX_OPTIONS_PHYS_BASE), 37 .length = TS72XX_OPTIONS_SIZE, 38 .type = MT_DEVICE, 39 }, { 40 .virtual = TS72XX_OPTIONS2_VIRT_BASE, 41 .pfn = __phys_to_pfn(TS72XX_OPTIONS2_PHYS_BASE), 42 .length = TS72XX_OPTIONS2_SIZE, 43 .type = MT_DEVICE, 44 }, { 45 .virtual = TS72XX_RTC_INDEX_VIRT_BASE, 46 .pfn = __phys_to_pfn(TS72XX_RTC_INDEX_PHYS_BASE), 47 .length = TS72XX_RTC_INDEX_SIZE, 48 .type = MT_DEVICE, 49 }, { 50 .virtual = TS72XX_RTC_DATA_VIRT_BASE, 51 .pfn = __phys_to_pfn(TS72XX_RTC_DATA_PHYS_BASE), 52 .length = TS72XX_RTC_DATA_SIZE, 53 .type = MT_DEVICE, 54 } 55 }; 56 57 static struct map_desc ts72xx_nand_io_desc[] __initdata = { 58 { 59 .virtual = TS72XX_NAND_DATA_VIRT_BASE, 60 .pfn = __phys_to_pfn(TS72XX_NAND1_DATA_PHYS_BASE), 61 .length = TS72XX_NAND_DATA_SIZE, 62 .type = MT_DEVICE, 63 }, { 64 .virtual = TS72XX_NAND_CONTROL_VIRT_BASE, 65 .pfn = __phys_to_pfn(TS72XX_NAND1_CONTROL_PHYS_BASE), 66 .length = TS72XX_NAND_CONTROL_SIZE, 67 .type = MT_DEVICE, 68 }, { 69 .virtual = TS72XX_NAND_BUSY_VIRT_BASE, 70 .pfn = __phys_to_pfn(TS72XX_NAND1_BUSY_PHYS_BASE), 71 .length = TS72XX_NAND_BUSY_SIZE, 72 .type = MT_DEVICE, 73 } 74 }; 75 76 static struct map_desc ts72xx_alternate_nand_io_desc[] __initdata = { 77 { 78 .virtual = TS72XX_NAND_DATA_VIRT_BASE, 79 .pfn = __phys_to_pfn(TS72XX_NAND2_DATA_PHYS_BASE), 80 .length = TS72XX_NAND_DATA_SIZE, 81 .type = MT_DEVICE, 82 }, { 83 .virtual = TS72XX_NAND_CONTROL_VIRT_BASE, 84 .pfn = __phys_to_pfn(TS72XX_NAND2_CONTROL_PHYS_BASE), 85 .length = TS72XX_NAND_CONTROL_SIZE, 86 .type = MT_DEVICE, 87 }, { 88 .virtual = TS72XX_NAND_BUSY_VIRT_BASE, 89 .pfn = __phys_to_pfn(TS72XX_NAND2_BUSY_PHYS_BASE), 90 .length = TS72XX_NAND_BUSY_SIZE, 91 .type = MT_DEVICE, 92 } 93 }; 94 95 static void __init ts72xx_map_io(void) 96 { 97 ep93xx_map_io(); 98 iotable_init(ts72xx_io_desc, ARRAY_SIZE(ts72xx_io_desc)); 99 100 /* 101 * The TS-7200 has NOR flash, the other models have NAND flash. 102 */ 103 if (!board_is_ts7200()) { 104 if (is_ts9420_installed()) { 105 iotable_init(ts72xx_alternate_nand_io_desc, 106 ARRAY_SIZE(ts72xx_alternate_nand_io_desc)); 107 } else { 108 iotable_init(ts72xx_nand_io_desc, 109 ARRAY_SIZE(ts72xx_nand_io_desc)); 110 } 111 } 112 } 113 114 /************************************************************************* 115 * NOR flash (TS-7200 only) 116 *************************************************************************/ 117 static struct physmap_flash_data ts72xx_flash_data = { 118 .width = 2, 119 }; 120 121 static struct resource ts72xx_flash_resource = { 122 .start = EP93XX_CS6_PHYS_BASE, 123 .end = EP93XX_CS6_PHYS_BASE + SZ_16M - 1, 124 .flags = IORESOURCE_MEM, 125 }; 126 127 static struct platform_device ts72xx_flash = { 128 .name = "physmap-flash", 129 .id = 0, 130 .dev = { 131 .platform_data = &ts72xx_flash_data, 132 }, 133 .num_resources = 1, 134 .resource = &ts72xx_flash_resource, 135 }; 136 137 static void __init ts72xx_register_flash(void) 138 { 139 if (board_is_ts7200()) 140 platform_device_register(&ts72xx_flash); 141 } 142 143 static unsigned char ts72xx_rtc_readbyte(unsigned long addr) 144 { 145 __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); 146 return __raw_readb(TS72XX_RTC_DATA_VIRT_BASE); 147 } 148 149 static void ts72xx_rtc_writebyte(unsigned char value, unsigned long addr) 150 { 151 __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); 152 __raw_writeb(value, TS72XX_RTC_DATA_VIRT_BASE); 153 } 154 155 static struct m48t86_ops ts72xx_rtc_ops = { 156 .readbyte = ts72xx_rtc_readbyte, 157 .writebyte = ts72xx_rtc_writebyte, 158 }; 159 160 static struct platform_device ts72xx_rtc_device = { 161 .name = "rtc-m48t86", 162 .id = -1, 163 .dev = { 164 .platform_data = &ts72xx_rtc_ops, 165 }, 166 .num_resources = 0, 167 }; 168 169 static struct ep93xx_eth_data ts72xx_eth_data = { 170 .phy_id = 1, 171 }; 172 173 static void __init ts72xx_init_machine(void) 174 { 175 ep93xx_init_devices(); 176 ts72xx_register_flash(); 177 platform_device_register(&ts72xx_rtc_device); 178 179 ep93xx_register_eth(&ts72xx_eth_data, 1); 180 } 181 182 MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC") 183 /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ 184 .phys_io = EP93XX_APB_PHYS_BASE, 185 .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, 186 .boot_params = EP93XX_SDCE3_PHYS_BASE_SYNC + 0x100, 187 .map_io = ts72xx_map_io, 188 .init_irq = ep93xx_init_irq, 189 .timer = &ep93xx_timer, 190 .init_machine = ts72xx_init_machine, 191 MACHINE_END 192