1/* 2 * hades-pci.c - Hardware specific PCI BIOS functions the Hades Atari clone. 3 * 4 * Written by Wout Klaren. 5 */ 6 7#include <linux/init.h> 8#include <linux/kernel.h> 9#include <asm/io.h> 10 11# define DBG_DEVS(args) 12 13#if defined(CONFIG_PCI) && defined(CONFIG_HADES) 14 15#include <linux/slab.h> 16#include <linux/mm.h> 17#include <linux/pci.h> 18 19#include <asm/atarihw.h> 20#include <asm/atariints.h> 21#include <asm/byteorder.h> 22#include <asm/pci.h> 23 24#define HADES_MEM_BASE 0x80000000 25#define HADES_MEM_SIZE 0x20000000 26#define HADES_CONFIG_BASE 0xA0000000 27#define HADES_CONFIG_SIZE 0x10000000 28#define HADES_IO_BASE 0xB0000000 29#define HADES_IO_SIZE 0x10000000 30#define HADES_VIRT_IO_SIZE 0x00010000 /* Only 64k is remapped and actually used. */ 31 32#define N_SLOTS 4 /* Number of PCI slots. */ 33 34static const char pci_mem_name[] = "PCI memory space"; 35static const char pci_io_name[] = "PCI I/O space"; 36static const char pci_config_name[] = "PCI config space"; 37 38static struct resource config_space = { 39 .name = pci_config_name, 40 .start = HADES_CONFIG_BASE, 41 .end = HADES_CONFIG_BASE + HADES_CONFIG_SIZE - 1 42}; 43static struct resource io_space = { 44 .name = pci_io_name, 45 .start = HADES_IO_BASE, 46 .end = HADES_IO_BASE + HADES_IO_SIZE - 1 47}; 48 49static const unsigned long pci_conf_base_phys[] = { 50 0xA0080000, 0xA0040000, 0xA0020000, 0xA0010000 51}; 52static unsigned long pci_conf_base_virt[N_SLOTS]; 53static unsigned long pci_io_base_virt; 54 55/* 56 * static void *mk_conf_addr(unsigned char bus, unsigned char device_fn, 57 * unsigned char where) 58 * 59 * Calculate the address of the PCI configuration area of the given 60 * device. 61 * 62 * BUG: boards with multiple functions are probably not correctly 63 * supported. 64 */ 65 66static void *mk_conf_addr(struct pci_dev *dev, int where) 67{ 68 int device = dev->devfn >> 3, function = dev->devfn & 7; 69 void *result; 70 71 DBG_DEVS(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, pci_addr=0x%p)\n", 72 dev->bus->number, dev->devfn, where, pci_addr)); 73 74 if (device > 3) 75 { 76 DBG_DEVS(("mk_conf_addr: device (%d) > 3, returning NULL\n", device)); 77 return NULL; 78 } 79 80 if (dev->bus->number != 0) 81 { 82 DBG_DEVS(("mk_conf_addr: bus (%d) > 0, returning NULL\n", device)); 83 return NULL; 84 } 85 86 result = (void *) (pci_conf_base_virt[device] | (function << 8) | (where)); 87 DBG_DEVS(("mk_conf_addr: returning pci_addr 0x%lx\n", (unsigned long) result)); 88 return result; 89} 90 91static int hades_read_config_byte(struct pci_dev *dev, int where, u8 *value) 92{ 93 volatile unsigned char *pci_addr; 94 95 *value = 0xff; 96 97 if ((pci_addr = (unsigned char *) mk_conf_addr(dev, where)) == NULL) 98 return PCIBIOS_DEVICE_NOT_FOUND; 99 100 *value = *pci_addr; 101 102 return PCIBIOS_SUCCESSFUL; 103} 104 105static int hades_read_config_word(struct pci_dev *dev, int where, u16 *value) 106{ 107 volatile unsigned short *pci_addr; 108 109 *value = 0xffff; 110 111 if (where & 0x1) 112 return PCIBIOS_BAD_REGISTER_NUMBER; 113 114 if ((pci_addr = (unsigned short *) mk_conf_addr(dev, where)) == NULL) 115 return PCIBIOS_DEVICE_NOT_FOUND; 116 117 *value = le16_to_cpu(*pci_addr); 118 119 return PCIBIOS_SUCCESSFUL; 120} 121 122static int hades_read_config_dword(struct pci_dev *dev, int where, u32 *value) 123{ 124 volatile unsigned int *pci_addr; 125 unsigned char header_type; 126 int result; 127 128 *value = 0xffffffff; 129 130 if (where & 0x3) 131 return PCIBIOS_BAD_REGISTER_NUMBER; 132 133 if ((pci_addr = (unsigned int *) mk_conf_addr(dev, where)) == NULL) 134 return PCIBIOS_DEVICE_NOT_FOUND; 135 136 *value = le32_to_cpu(*pci_addr); 137 138 /* 139 * Check if the value is an address on the bus. If true, add the 140 * base address of the PCI memory or PCI I/O area on the Hades. 141 */ 142 143 if ((result = hades_read_config_byte(dev, PCI_HEADER_TYPE, 144 &header_type)) != PCIBIOS_SUCCESSFUL) 145 return result; 146 147 if (((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_1)) || 148 ((header_type != PCI_HEADER_TYPE_BRIDGE) && ((where >= PCI_BASE_ADDRESS_2) && 149 (where <= PCI_BASE_ADDRESS_5)))) 150 { 151 if ((*value & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) 152 { 153 /* 154 * Base address register that contains an I/O address. If the 155 * address is valid on the Hades (0 <= *value < HADES_VIRT_IO_SIZE), 156 * add 'pci_io_base_virt' to the value. 157 */ 158 159 if (*value < HADES_VIRT_IO_SIZE) 160 *value += pci_io_base_virt; 161 } 162 else 163 { 164 /* 165 * Base address register that contains an memory address. If the 166 * address is valid on the Hades (0 <= *value < HADES_MEM_SIZE), 167 * add HADES_MEM_BASE to the value. 168 */ 169 170 if (*value == 0) 171 { 172 /* 173 * Base address is 0. Test if this base 174 * address register is used. 175 */ 176 177 *pci_addr = 0xffffffff; 178 if (*pci_addr != 0) 179 { 180 *pci_addr = *value; 181 if (*value < HADES_MEM_SIZE) 182 *value += HADES_MEM_BASE; 183 } 184 } 185 else 186 { 187 if (*value < HADES_MEM_SIZE) 188 *value += HADES_MEM_BASE; 189 } 190 } 191 } 192 193 return PCIBIOS_SUCCESSFUL; 194} 195 196static int hades_write_config_byte(struct pci_dev *dev, int where, u8 value) 197{ 198 volatile unsigned char *pci_addr; 199 200 if ((pci_addr = (unsigned char *) mk_conf_addr(dev, where)) == NULL) 201 return PCIBIOS_DEVICE_NOT_FOUND; 202 203 *pci_addr = value; 204 205 return PCIBIOS_SUCCESSFUL; 206} 207 208static int hades_write_config_word(struct pci_dev *dev, int where, u16 value) 209{ 210 volatile unsigned short *pci_addr; 211 212 if ((pci_addr = (unsigned short *) mk_conf_addr(dev, where)) == NULL) 213 return PCIBIOS_DEVICE_NOT_FOUND; 214 215 *pci_addr = cpu_to_le16(value); 216 217 return PCIBIOS_SUCCESSFUL; 218} 219 220static int hades_write_config_dword(struct pci_dev *dev, int where, u32 value) 221{ 222 volatile unsigned int *pci_addr; 223 unsigned char header_type; 224 int result; 225 226 if ((pci_addr = (unsigned int *) mk_conf_addr(dev, where)) == NULL) 227 return PCIBIOS_DEVICE_NOT_FOUND; 228 229 /* 230 * Check if the value is an address on the bus. If true, subtract the 231 * base address of the PCI memory or PCI I/O area on the Hades. 232 */ 233 234 if ((result = hades_read_config_byte(dev, PCI_HEADER_TYPE, 235 &header_type)) != PCIBIOS_SUCCESSFUL) 236 return result; 237 238 if (((where >= PCI_BASE_ADDRESS_0) && (where <= PCI_BASE_ADDRESS_1)) || 239 ((header_type != PCI_HEADER_TYPE_BRIDGE) && ((where >= PCI_BASE_ADDRESS_2) && 240 (where <= PCI_BASE_ADDRESS_5)))) 241 { 242 if ((value & PCI_BASE_ADDRESS_SPACE) == 243 PCI_BASE_ADDRESS_SPACE_IO) 244 { 245 /* 246 * I/O address. Check if the address is valid address on 247 * the Hades (pci_io_base_virt <= value < pci_io_base_virt + 248 * HADES_VIRT_IO_SIZE) or if the value is 0xffffffff. If not 249 * true do not write the base address register. If it is a 250 * valid base address subtract 'pci_io_base_virt' from the value. 251 */ 252 253 if ((value >= pci_io_base_virt) && (value < (pci_io_base_virt + 254 HADES_VIRT_IO_SIZE))) 255 value -= pci_io_base_virt; 256 else 257 { 258 if (value != 0xffffffff) 259 return PCIBIOS_SET_FAILED; 260 } 261 } 262 else 263 { 264 /* 265 * Memory address. Check if the address is valid address on 266 * the Hades (HADES_MEM_BASE <= value < HADES_MEM_BASE + HADES_MEM_SIZE) or 267 * if the value is 0xffffffff. If not true do not write 268 * the base address register. If it is a valid base address 269 * subtract HADES_MEM_BASE from the value. 270 */ 271 272 if ((value >= HADES_MEM_BASE) && (value < (HADES_MEM_BASE + HADES_MEM_SIZE))) 273 value -= HADES_MEM_BASE; 274 else 275 { 276 if (value != 0xffffffff) 277 return PCIBIOS_SET_FAILED; 278 } 279 } 280 } 281 282 *pci_addr = cpu_to_le32(value); 283 284 return PCIBIOS_SUCCESSFUL; 285} 286 287/* 288 * static inline void hades_fixup(void) 289 * 290 * Assign IRQ numbers as used by Linux to the interrupt pins 291 * of the PCI cards. 292 */ 293 294static void __init hades_fixup(int pci_modify) 295{ 296 char irq_tab[4] = { 297 [0] = IRQ_TT_MFP_IO0, /* Slot 0. */ 298 [1] = IRQ_TT_MFP_IO1, /* Slot 1. */ 299 [2] = IRQ_TT_MFP_SCC, /* Slot 2. */ 300 [3] = IRQ_TT_MFP_SCSIDMA /* Slot 3. */ 301 }; 302 struct pci_dev *dev = NULL; 303 unsigned char slot; 304 305 /* 306 * Go through all devices, fixing up irqs as we see fit: 307 */ 308 309 while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) 310 { 311 if (dev->class >> 16 != PCI_BASE_CLASS_BRIDGE) 312 { 313 slot = PCI_SLOT(dev->devfn); /* Determine slot number. */ 314 dev->irq = irq_tab[slot]; 315 if (pci_modify) 316 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 317 } 318 } 319} 320 321/* 322 * static void hades_conf_device(struct pci_dev *dev) 323 * 324 * Machine dependent Configure the given device. 325 * 326 * Parameters: 327 * 328 * dev - the pci device. 329 */ 330 331static void __init hades_conf_device(struct pci_dev *dev) 332{ 333 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0); 334} 335 336static struct pci_ops hades_pci_ops = { 337 .read_byte = hades_read_config_byte, 338 .read_word = hades_read_config_word, 339 .read_dword = hades_read_config_dword, 340 .write_byte = hades_write_config_byte, 341 .write_word = hades_write_config_word, 342 .write_dword = hades_write_config_dword 343}; 344 345/* 346 * struct pci_bus_info *init_hades_pci(void) 347 * 348 * Machine specific initialisation: 349 * 350 * - Allocate and initialise a 'pci_bus_info' structure 351 * - Initialise hardware 352 * 353 * Result: pointer to 'pci_bus_info' structure. 354 */ 355 356struct pci_bus_info * __init init_hades_pci(void) 357{ 358 struct pci_bus_info *bus; 359 int i; 360 361 /* 362 * Remap I/O and configuration space. 363 */ 364 365 pci_io_base_virt = (unsigned long) ioremap(HADES_IO_BASE, HADES_VIRT_IO_SIZE); 366 367 for (i = 0; i < N_SLOTS; i++) 368 pci_conf_base_virt[i] = (unsigned long) ioremap(pci_conf_base_phys[i], 0x10000); 369 370 /* 371 * Allocate memory for bus info structure. 372 */ 373 374 bus = kzalloc(sizeof(struct pci_bus_info), GFP_KERNEL); 375 if (!bus) 376 return NULL; 377 378 /* 379 * Claim resources. The m68k has no separate I/O space, both 380 * PCI memory space and PCI I/O space are in memory space. Therefore 381 * the I/O resources are requested in memory space as well. 382 */ 383 384 if (request_resource(&iomem_resource, &config_space) != 0) 385 { 386 kfree(bus); 387 return NULL; 388 } 389 390 if (request_resource(&iomem_resource, &io_space) != 0) 391 { 392 release_resource(&config_space); 393 kfree(bus); 394 return NULL; 395 } 396 397 bus->mem_space.start = HADES_MEM_BASE; 398 bus->mem_space.end = HADES_MEM_BASE + HADES_MEM_SIZE - 1; 399 bus->mem_space.name = pci_mem_name; 400 if (request_resource(&iomem_resource, &bus->mem_space) != 0) 401 { 402 release_resource(&io_space); 403 release_resource(&config_space); 404 kfree(bus); 405 return NULL; 406 } 407 bus->io_space.start = pci_io_base_virt; 408 bus->io_space.end = pci_io_base_virt + HADES_VIRT_IO_SIZE - 1; 409 bus->io_space.name = pci_io_name; 410 if (request_resource(&ioport_resource, &bus->io_space) != 0) 411 { 412 release_resource(&bus->mem_space); 413 release_resource(&io_space); 414 release_resource(&config_space); 415 kfree(bus); 416 return NULL; 417 } 418 /* 419 * Set hardware dependent functions. 420 */ 421 422 bus->m68k_pci_ops = &hades_pci_ops; 423 bus->fixup = hades_fixup; 424 bus->conf_device = hades_conf_device; 425 426 /* 427 * Select high to low edge for PCI interrupts. 428 */ 429 430 tt_mfp.active_edge &= ~0x27; 431 432 return bus; 433} 434#endif 435