1/* 2 * Virtex hard ppc405 core common device listing 3 * 4 * Copyright 2005-2007 Secret Lab Technologies Ltd. 5 * Copyright 2005 Freescale Semiconductor Inc. 6 * Copyright 2002-2004 MontaVista Software, Inc. 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 */ 13 14#include <linux/init.h> 15#include <linux/module.h> 16#include <linux/device.h> 17#include <linux/serial_8250.h> 18#include <syslib/virtex_devices.h> 19#include <platforms/4xx/xparameters/xparameters.h> 20#include <asm/io.h> 21 22/* 23 * UARTLITE: shortcut macro for single instance 24 */ 25#define XPAR_UARTLITE(num) { \ 26 .name = "uartlite", \ 27 .id = num, \ 28 .num_resources = 2, \ 29 .resource = (struct resource[]) { \ 30 { \ 31 .start = XPAR_UARTLITE_##num##_BASEADDR + 3, \ 32 .end = XPAR_UARTLITE_##num##_HIGHADDR, \ 33 .flags = IORESOURCE_MEM, \ 34 }, \ 35 { \ 36 .start = XPAR_INTC_0_UARTLITE_##num##_VEC_ID, \ 37 .flags = IORESOURCE_IRQ, \ 38 }, \ 39 }, \ 40} 41 42/* 43 * Full UART: shortcut macro for single instance + platform data structure 44 */ 45#define XPAR_UART(num) { \ 46 .mapbase = XPAR_UARTNS550_##num##_BASEADDR + 3, \ 47 .irq = XPAR_INTC_0_UARTNS550_##num##_VEC_ID, \ 48 .iotype = UPIO_MEM, \ 49 .uartclk = XPAR_UARTNS550_##num##_CLOCK_FREQ_HZ, \ 50 .flags = UPF_BOOT_AUTOCONF, \ 51 .regshift = 2, \ 52} 53 54/* 55 * SystemACE: shortcut macro for single instance 56 */ 57#define XPAR_SYSACE(num) { \ 58 .name = "xsysace", \ 59 .id = XPAR_SYSACE_##num##_DEVICE_ID, \ 60 .num_resources = 2, \ 61 .resource = (struct resource[]) { \ 62 { \ 63 .start = XPAR_SYSACE_##num##_BASEADDR, \ 64 .end = XPAR_SYSACE_##num##_HIGHADDR, \ 65 .flags = IORESOURCE_MEM, \ 66 }, \ 67 { \ 68 .start = XPAR_INTC_0_SYSACE_##num##_VEC_ID, \ 69 .flags = IORESOURCE_IRQ, \ 70 }, \ 71 }, \ 72} 73 74 75/* UART 8250 driver platform data table */ 76struct plat_serial8250_port virtex_serial_platform_data[] = { 77#if defined(XPAR_UARTNS550_0_BASEADDR) 78 XPAR_UART(0), 79#endif 80#if defined(XPAR_UARTNS550_1_BASEADDR) 81 XPAR_UART(1), 82#endif 83#if defined(XPAR_UARTNS550_2_BASEADDR) 84 XPAR_UART(2), 85#endif 86#if defined(XPAR_UARTNS550_3_BASEADDR) 87 XPAR_UART(3), 88#endif 89#if defined(XPAR_UARTNS550_4_BASEADDR) 90 XPAR_UART(4), 91#endif 92#if defined(XPAR_UARTNS550_5_BASEADDR) 93 XPAR_UART(5), 94#endif 95#if defined(XPAR_UARTNS550_6_BASEADDR) 96 XPAR_UART(6), 97#endif 98#if defined(XPAR_UARTNS550_7_BASEADDR) 99 XPAR_UART(7), 100#endif 101 { }, /* terminated by empty record */ 102}; 103 104 105struct platform_device virtex_platform_devices[] = { 106 /* UARTLITE instances */ 107#if defined(XPAR_UARTLITE_0_BASEADDR) 108 XPAR_UARTLITE(0), 109#endif 110#if defined(XPAR_UARTLITE_1_BASEADDR) 111 XPAR_UARTLITE(1), 112#endif 113#if defined(XPAR_UARTLITE_2_BASEADDR) 114 XPAR_UARTLITE(2), 115#endif 116#if defined(XPAR_UARTLITE_3_BASEADDR) 117 XPAR_UARTLITE(3), 118#endif 119#if defined(XPAR_UARTLITE_4_BASEADDR) 120 XPAR_UARTLITE(4), 121#endif 122#if defined(XPAR_UARTLITE_5_BASEADDR) 123 XPAR_UARTLITE(5), 124#endif 125#if defined(XPAR_UARTLITE_6_BASEADDR) 126 XPAR_UARTLITE(6), 127#endif 128#if defined(XPAR_UARTLITE_7_BASEADDR) 129 XPAR_UARTLITE(7), 130#endif 131 132 /* Full UART instances */ 133#if defined(XPAR_UARTNS550_0_BASEADDR) 134 { 135 .name = "serial8250", 136 .id = 0, 137 .dev.platform_data = virtex_serial_platform_data, 138 }, 139#endif 140 141 /* SystemACE instances */ 142#if defined(XPAR_SYSACE_0_BASEADDR) 143 XPAR_SYSACE(0), 144#endif 145#if defined(XPAR_SYSACE_1_BASEADDR) 146 XPAR_SYSACE(1), 147#endif 148 149 /* ML300/403 reference design framebuffer */ 150#if defined(XPAR_TFT_0_BASEADDR) 151 { 152 .name = "xilinxfb", 153 .id = 0, 154 .num_resources = 1, 155 .resource = (struct resource[]) { 156 { 157 .start = XPAR_TFT_0_BASEADDR, 158 .end = XPAR_TFT_0_BASEADDR+7, 159 .flags = IORESOURCE_IO, 160 }, 161 }, 162 }, 163#endif 164}; 165 166/* Early serial support functions */ 167static void __init 168virtex_early_serial_init(int num, struct plat_serial8250_port *pdata) 169{ 170#if defined(CONFIG_SERIAL_TEXT_DEBUG) || defined(CONFIG_KGDB) 171 struct uart_port serial_req; 172 173 memset(&serial_req, 0, sizeof(serial_req)); 174 serial_req.mapbase = pdata->mapbase; 175 serial_req.membase = pdata->membase; 176 serial_req.irq = pdata->irq; 177 serial_req.uartclk = pdata->uartclk; 178 serial_req.regshift = pdata->regshift; 179 serial_req.iotype = pdata->iotype; 180 serial_req.flags = pdata->flags; 181 gen550_init(num, &serial_req); 182#endif 183} 184 185void __init 186virtex_early_serial_map(void) 187{ 188#ifdef CONFIG_SERIAL_8250 189 struct plat_serial8250_port *pdata; 190 int i = 0; 191 192 pdata = virtex_serial_platform_data; 193 while(pdata && pdata->flags) { 194 pdata->membase = ioremap(pdata->mapbase, 0x100); 195 virtex_early_serial_init(i, pdata); 196 pdata++; 197 i++; 198 } 199#endif /* CONFIG_SERIAL_8250 */ 200} 201 202/* 203 * default fixup routine; do nothing and return success. 204 * 205 * Reimplement this routine in your custom board support file to 206 * override the default behaviour 207 */ 208int __attribute__ ((weak)) 209virtex_device_fixup(struct platform_device *dev) 210{ 211 return 0; 212} 213 214static int __init virtex_init(void) 215{ 216 struct platform_device *index = virtex_platform_devices; 217 unsigned int ret = 0; 218 int i; 219 220 for (i = 0; i < ARRAY_SIZE(virtex_platform_devices); i++, index++) { 221 if (virtex_device_fixup(index) != 0) 222 continue; 223 224 if (platform_device_register(index)) { 225 ret = 1; 226 printk(KERN_ERR "cannot register dev %s:%d\n", 227 index->name, index->id); 228 } 229 } 230 return ret; 231} 232 233subsys_initcall(virtex_init); 234