URL
https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk
Subversion Repositories openrisc_me
[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [ebsa285/] [v2_0/] [support/] [linux/] [safl_util/] [safl.c] - Rev 401
Go to most recent revision | Compare with Previous | Blame | View Log
// #======================================================================== // # // # safl.c // # // # Linux driver for Intel(R) StrongARM(R) PCI-based coprocessor boards. // # // #======================================================================== //####ECOSGPLCOPYRIGHTBEGIN#### // ------------------------------------------- // This file is part of eCos, the Embedded Configurable Operating System. // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. // // eCos is free software; you can redistribute it and/or modify it under // the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 or (at your option) any later version. // // eCos is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License // for more details. // // You should have received a copy of the GNU General Public License along // with eCos; if not, write to the Free Software Foundation, Inc., // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. // // As a special exception, if other files instantiate templates or use macros // or inline functions from this file, or you compile this file and link it // with other works to produce a work based on this file, this file does not // by itself cause the resulting work to be covered by the GNU General Public // License. However the source code for this file must still be made available // in accordance with section (3) of the GNU General Public License. // // This exception does not invalidate any other reasons why a work based on // this file might be covered by the GNU General Public License. // // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. // at http://sources.redhat.com/ecos/ecos-license/ // ------------------------------------------- //####ECOSGPLCOPYRIGHTEND#### // #======================================================================== // ######DESCRIPTIONBEGIN#### // # // # Author(s): msalter // # Contributors: msalter // # Date: 1999-04-02 // # Purpose: Linux driver for Intel(R) StrongARM(R) PCI-based // # coprocessor boards // # Description: This module currently supports EBSA-285 and SA-IOP. // # Intel is a Registered Trademark of Intel Corporation. // # StrongARM is a Registered Trademark of Advanced RISC // # Machines Limited. // # Other Brands and Trademarks are the property of their // # respective owners. // # // #####DESCRIPTIONEND#### // # // #======================================================================== static char *version = "safl.c:v0.01H 04/02/99 Mark Salter, Red Hat.\n"; #include <linux/module.h> #include <linux/config.h> #include <linux/version.h> #ifdef MODVERSIONS #include <linux/modversions.h> #endif #include <linux/types.h> #include <linux/errno.h> #include <linux/kernel.h> #include <linux/miscdevice.h> #include <linux/malloc.h> #include <linux/mm.h> #include <linux/pci.h> #include <linux/signal.h> #include <linux/ioport.h> #include <linux/fcntl.h> #include <asm/pgtable.h> #include <asm/page.h> #include <linux/sched.h> #include <asm/segment.h> #ifdef CONFIG_PROC_FS #include <linux/proc_fs.h> #endif #include <asm/io.h> #include <asm/system.h> #if LINUX_VERSION_CODE >= 0x020100 #include <linux/init.h> #include <linux/vmalloc.h> #else #include <linux/bios32.h> #define __initfunc(x) x #endif #if LINUX_VERSION_CODE < 0x20155 #define PCI_SUPPORT_VER1 #else #define PCI_SUPPORT_VER2 #endif #if defined(MODULE) && LINUX_VERSION_CODE > 0x20115 MODULE_AUTHOR("Mark Salter <msalter@redhat.com>"); MODULE_DESCRIPTION("Intel(R) StrongARM(R) FLASH driver for PCI EVBs"); #endif /* This isn't in /usr/include/linux/pci.h */ #ifndef PCI_DEVICE_ID_DEC_IOP #define PCI_DEVICE_ID_DEC_21554 0x46 #endif #ifndef PCI_DEVICE_ID_DEC_21285 #define PCI_DEVICE_ID_DEC_21285 0x1065 #endif /* somewhat arbitrary minor number. Major number is 10 (misc). */ #define SAFL_MINOR 178 #define FLASH_SZ (4 * 1024 * 1024) static int safl_open( struct inode *inode, struct file *file ); static int safl_close( struct inode *inode, struct file *file ); #if LINUX_VERSION_CODE >= 0x020100 static int safl_mmap(struct file * file, struct vm_area_struct * vma); #else static int safl_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma); #endif static int safl_debug = 0; static unsigned long csr_ioaddr; static unsigned long flash_addr; static struct file_operations safl_fops = { NULL, /* lseek */ NULL, /* read */ NULL, /* write */ NULL, /* readdir */ NULL, /* poll */ NULL, /* ioctl */ safl_mmap, /* mmap */ safl_open, /* open */ NULL, /* flush */ safl_close /* close */ }; static struct miscdevice safl_dev = { SAFL_MINOR, "SA-FLASH", &safl_fops }; /* PCI configuration space information. */ static u8 safl_pci_bus, safl_pci_devfn; static int safl_devid; #ifdef PCI_SUPPORT_VER2 static struct pci_dev *safl_pdev; #endif static int safl_open_cnt = 0; /* #times opened */ __initfunc(int safl_scan(void)) { if (pcibios_present()) { int index; /* * Search for an EBSA-285 board or an IOP board. Stop at * first one found. */ for (index = 0; index < 8; index++) { if (pcibios_find_device (PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21554, index, &safl_pci_bus, &safl_pci_devfn) == PCIBIOS_SUCCESSFUL) { safl_devid = PCI_DEVICE_ID_DEC_21554; break; } if (pcibios_find_device (PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, index, &safl_pci_bus, &safl_pci_devfn) == PCIBIOS_SUCCESSFUL) { safl_devid = PCI_DEVICE_ID_DEC_21285; break; } } if (index < 8) { #ifdef PCI_SUPPORT_VER2 safl_pdev = pci_find_slot(safl_pci_bus, safl_pci_devfn); #endif misc_register(&safl_dev); return 0; } } if (safl_debug) printk(KERN_INFO "Can't find device.\n"); return -ENODEV; } int init_module(void) { if (safl_debug) printk(KERN_INFO "%s", version); return safl_scan(); } /* * Dword read from configuration space of secondary PCI bus. */ static unsigned int sconfig_read(int addr) { unsigned int val; outw(2, csr_ioaddr + 0x12); /* enable downstream config */ outl(addr | (1<<24), csr_ioaddr + 0x00); val = inl(csr_ioaddr + 4); outw(0, csr_ioaddr + 0x12); /* disable downstream config */ return val; } /* * Dword write to configuration space of secondary PCI bus. */ static void sconfig_write(int addr, int val) { outw(2, csr_ioaddr + 0x12); /* enable downstream config */ outl(addr | (1<<24), csr_ioaddr + 0x00); outl(val, csr_ioaddr + 4); outw(0, csr_ioaddr + 0x12); /* disable downstream config */ } /* * Dword read from configuration space of primary PCI bus. */ static unsigned int pconfig_read(int addr) { unsigned int val; #ifdef PCI_SUPPORT_VER2 pci_read_config_dword(safl_pdev, addr, &val); #else pcibios_read_config_dword(safl_pci_bus, safl_pci_devfn, addr, &val); #endif return val; } /* * Dword write to configuration space of primary PCI bus. */ static void pconfig_write(int addr, int val) { #ifdef PCI_SUPPORT_VER2 pci_write_config_dword(safl_pdev, addr, val); #else pcibios_write_config_dword(safl_pci_bus, safl_pci_devfn, addr, val); #endif } static int safl_open( struct inode *inode, struct file *file ) { if (safl_open_cnt) { if (safl_debug) printk(KERN_INFO "SA-Flash already open.\n"); return( -EBUSY ); } if (safl_devid == PCI_DEVICE_ID_DEC_21554) { csr_ioaddr = pconfig_read(PCI_BASE_ADDRESS_1) & PCI_BASE_ADDRESS_IO_MASK; flash_addr = pconfig_read(PCI_BASE_ADDRESS_3) & PCI_BASE_ADDRESS_MEM_MASK; if (safl_debug) { printk(KERN_INFO "IOP: csr_io[%lx].\n", csr_ioaddr); printk(KERN_INFO "IOP: flash_add[%lx].\n", flash_addr); } /* * Need to configure downstream side of 21554. * These addresses are pretty arbitrary. */ pconfig_write(0x50, 0xf0000000); /* secondary CSR memory */ pconfig_write(0x54, 0xf201); /* secondary CSR I/O */ pconfig_write(0x58, 0xf401); /* Upstream I/O */ pconfig_write(0x5c, 0xf1000008); /* Upstream memory 1 */ pconfig_write(0x44, 0x29000017); /* enable mem an I/O */ /* set downstream mem2 xlate base */ pconfig_write(0x9c, 0xA0000000); /* set 21285 ROM address to same */ sconfig_write(0x30, 0xA0000001); /* set 21285 ROM write byte address */ sconfig_write(0x68, 0); } else if (safl_devid == PCI_DEVICE_ID_DEC_21285) { /* * I'm not sure how best to handle this. Basically, you want * to assign a physical address for the expansion ROM space * of the 21285. There doesn't appear to be a good way to * find an unused physical space for the PCI bus. This seems * to work for the limited number of motherboards that this * code has been tested on. YMMV. */ flash_addr = 0xb0000000; pconfig_write(PCI_ROM_ADDRESS, flash_addr | PCI_ROM_ADDRESS_ENABLE); } safl_open_cnt++; MOD_INC_USE_COUNT; return 0; } static int safl_close( struct inode *inode, struct file *file ) { safl_open_cnt--; if (safl_devid == PCI_DEVICE_ID_DEC_21285) pconfig_write(PCI_ROM_ADDRESS, 0); if (safl_devid == PCI_DEVICE_ID_DEC_21554) sconfig_write(0x30, 0); MOD_DEC_USE_COUNT; return 0; } static inline unsigned long pgprot_noncached(unsigned long prot) { #if LINUX_VERSION_CODE >= 0x020100 if (boot_cpu_data.x86 > 3) prot |= _PAGE_PCD; #endif return prot; } static int #if LINUX_VERSION_CODE >= 0x020100 safl_mmap(struct file * file, struct vm_area_struct * vma) #else safl_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma) #endif { unsigned long size; if (vma->vm_offset != 0) return -EINVAL; size = vma->vm_end - vma->vm_start; if (size > FLASH_SZ) return -EINVAL; pgprot_val(vma->vm_page_prot) = pgprot_noncached(pgprot_val(vma->vm_page_prot)); #if LINUX_VERSION_CODE >= 0x020100 vma->vm_flags |= VM_IO; #endif if (remap_page_range(vma->vm_start, flash_addr, size, vma->vm_page_prot)) return -EAGAIN; #if LINUX_VERSION_CODE < 0x020100 vma->vm_inode = inode; inode->i_count++; #endif return 0; } void cleanup_module(void) { misc_deregister(&safl_dev); } /* * Local variables: * compile-command: "cc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c safl.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`" * End: */
Go to most recent revision | Compare with Previous | Blame | View Log