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/mm.h> 16 #include <linux/sched.h> 17 #include <linux/interrupt.h> 18 #include <linux/ioport.h> 19 #include <linux/mtd/physmap.h> 20 #include <linux/platform_device.h> 21 #include <linux/m48t86.h> 22 #include <asm/io.h> 23 #include <asm/hardware.h> 24 #include <asm/mach-types.h> 25 #include <asm/mach/arch.h> 26 #include <asm/mach/map.h> 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 static struct physmap_flash_data ts72xx_flash_data = { 115 .width = 1, 116 }; 117 118 static struct resource ts72xx_flash_resource = { 119 .start = TS72XX_NOR_PHYS_BASE, 120 .end = TS72XX_NOR_PHYS_BASE + 0x00ffffff, 121 .flags = IORESOURCE_MEM, 122 }; 123 124 static struct platform_device ts72xx_flash = { 125 .name = "physmap-flash", 126 .id = 0, 127 .dev = { 128 .platform_data = &ts72xx_flash_data, 129 }, 130 .num_resources = 1, 131 .resource = &ts72xx_flash_resource, 132 }; 133 134 static unsigned char ts72xx_rtc_readbyte(unsigned long addr) 135 { 136 __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); 137 return __raw_readb(TS72XX_RTC_DATA_VIRT_BASE); 138 } 139 140 static void ts72xx_rtc_writebyte(unsigned char value, unsigned long addr) 141 { 142 __raw_writeb(addr, TS72XX_RTC_INDEX_VIRT_BASE); 143 __raw_writeb(value, TS72XX_RTC_DATA_VIRT_BASE); 144 } 145 146 static struct m48t86_ops ts72xx_rtc_ops = { 147 .readbyte = ts72xx_rtc_readbyte, 148 .writebyte = ts72xx_rtc_writebyte, 149 }; 150 151 static struct platform_device ts72xx_rtc_device = { 152 .name = "rtc-m48t86", 153 .id = -1, 154 .dev = { 155 .platform_data = &ts72xx_rtc_ops, 156 }, 157 .num_resources = 0, 158 }; 159 160 static struct ep93xx_eth_data ts72xx_eth_data = { 161 .phy_id = 1, 162 }; 163 164 static struct resource ts72xx_eth_resource[] = { 165 { 166 .start = EP93XX_ETHERNET_PHYS_BASE, 167 .end = EP93XX_ETHERNET_PHYS_BASE + 0xffff, 168 .flags = IORESOURCE_MEM, 169 }, { 170 .start = IRQ_EP93XX_ETHERNET, 171 .end = IRQ_EP93XX_ETHERNET, 172 .flags = IORESOURCE_IRQ, 173 } 174 }; 175 176 static struct platform_device ts72xx_eth_device = { 177 .name = "ep93xx-eth", 178 .id = -1, 179 .dev = { 180 .platform_data = &ts72xx_eth_data, 181 }, 182 .num_resources = 2, 183 .resource = ts72xx_eth_resource, 184 }; 185 186 static void __init ts72xx_init_machine(void) 187 { 188 ep93xx_init_devices(); 189 if (board_is_ts7200()) 190 platform_device_register(&ts72xx_flash); 191 platform_device_register(&ts72xx_rtc_device); 192 193 memcpy(ts72xx_eth_data.dev_addr, 194 (void *)(EP93XX_ETHERNET_BASE + 0x50), 6); 195 platform_device_register(&ts72xx_eth_device); 196 } 197 198 MACHINE_START(TS72XX, "Technologic Systems TS-72xx SBC") 199 /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ 200 .phys_io = EP93XX_APB_PHYS_BASE, 201 .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, 202 .boot_params = 0x00000100, 203 .map_io = ts72xx_map_io, 204 .init_irq = ep93xx_init_irq, 205 .timer = &ep93xx_timer, 206 .init_machine = ts72xx_init_machine, 207 MACHINE_END 208