source: trunk/target/linux/atheros/patches-2.6.32/105-ar2315_pci.patch @ 20197

Last change on this file since 20197 was 20197, checked in by juhosg, 6 years ago

atheros: refresh 2.6.32 patches

File size: 8.6 KB
  • arch/mips/ar231x/Makefile

    a b  
    1111obj-y += board.o prom.o devices.o 
    1212obj-$(CONFIG_ATHEROS_AR5312) += ar5312.o 
    1313obj-$(CONFIG_ATHEROS_AR2315) += ar2315.o 
     14obj-$(CONFIG_ATHEROS_AR2315_PCI) += pci.o 
  • new file arch/mips/ar231x/pci.c

    - +  
     1/* 
     2 * This program is free software; you can redistribute it and/or 
     3 * modify it under the terms of the GNU General Public License 
     4 * as published by the Free Software Foundation; either version 2 
     5 * of the License, or (at your option) any later version. 
     6 * 
     7 * This program is distributed in the hope that it will be useful, 
     8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
     10 * GNU General Public License for more details. 
     11 * 
     12 * You should have received a copy of the GNU General Public License 
     13 * along with this program; if not, write to the Free Software 
     14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
     15 */ 
     16 
     17#include <linux/types.h> 
     18#include <linux/pci.h> 
     19#include <linux/kernel.h> 
     20#include <linux/init.h> 
     21#include <linux/mm.h> 
     22#include <linux/spinlock.h> 
     23#include <linux/delay.h> 
     24#include <linux/irq.h> 
     25#include <asm/bootinfo.h> 
     26#include <asm/paccess.h> 
     27#include <asm/irq_cpu.h> 
     28#include <asm/io.h> 
     29#include <ar231x_platform.h> 
     30#include <ar231x.h> 
     31#include <ar2315_regs.h> 
     32#include "devices.h" 
     33 
     34#define AR531X_MEM_BASE    0x80800000UL 
     35#define AR531X_MEM_SIZE    0x00ffffffUL 
     36#define AR531X_IO_SIZE     0x00007fffUL 
     37 
     38static unsigned long configspace; 
     39 
     40static int config_access(int devfn, int where, int size, u32 *ptr, bool write) 
     41{ 
     42        unsigned long flags; 
     43        int func = PCI_FUNC(devfn); 
     44        int dev = PCI_SLOT(devfn); 
     45        u32 value = 0; 
     46        int err = 0; 
     47        u32 addr; 
     48 
     49        if (((dev != 0) && (dev != 3)) || (func > 2)) 
     50                return PCIBIOS_DEVICE_NOT_FOUND; 
     51 
     52        /* Select Configuration access */ 
     53        local_irq_save(flags); 
     54        ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, 0, AR2315_PCIMISC_CFG_SEL); 
     55        mb(); 
     56 
     57        addr = (u32) configspace + (1 << (13 + dev)) + (func << 8) + where; 
     58        if (size == 1) 
     59                addr ^= 0x3; 
     60        else if (size == 2) 
     61                addr ^= 0x2; 
     62 
     63        if (write) { 
     64                value = *ptr; 
     65                if (size == 1) 
     66                        err = put_dbe(value, (u8 *) addr); 
     67                else if (size == 2) 
     68                        err = put_dbe(value, (u16 *) addr); 
     69                else if (size == 4) 
     70                        err = put_dbe(value, (u32 *) addr); 
     71        } else { 
     72                if (size == 1) 
     73                        err = get_dbe(value, (u8 *) addr); 
     74                else if (size == 2) 
     75                        err = get_dbe(value, (u16 *) addr); 
     76                else if (size == 4) 
     77                        err = get_dbe(value, (u32 *) addr); 
     78                if (err) 
     79                        *ptr = 0xffffffff; 
     80                else 
     81                        *ptr = value; 
     82        } 
     83 
     84        /* Select Memory access */ 
     85        ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_CFG_SEL, 0); 
     86        local_irq_restore(flags); 
     87 
     88        return (err ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL); 
     89} 
     90 
     91static int ar231x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * value) 
     92{ 
     93        return config_access(devfn, where, size, value, 0); 
     94} 
     95 
     96static int ar231x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 value) 
     97{ 
     98        return config_access(devfn, where, size, &value, 1); 
     99} 
     100 
     101struct pci_ops ar231x_pci_ops = { 
     102        .read   = ar231x_pci_read, 
     103        .write  = ar231x_pci_write, 
     104}; 
     105 
     106static struct resource ar231x_mem_resource = { 
     107        .name   = "AR531x PCI MEM", 
     108        .start  = AR531X_MEM_BASE, 
     109        .end    = AR531X_MEM_BASE + AR531X_MEM_SIZE - AR531X_IO_SIZE - 1 + 0x4000000, 
     110        .flags  = IORESOURCE_MEM, 
     111}; 
     112 
     113static struct resource ar231x_io_resource = { 
     114        .name   = "AR531x PCI I/O", 
     115        .start  = AR531X_MEM_BASE + AR531X_MEM_SIZE - AR531X_IO_SIZE, 
     116        .end    = AR531X_MEM_BASE + AR531X_MEM_SIZE - 1, 
     117        .flags  = IORESOURCE_IO, 
     118}; 
     119 
     120struct pci_controller ar231x_pci_controller = { 
     121        .pci_ops                = &ar231x_pci_ops, 
     122        .mem_resource   = &ar231x_mem_resource, 
     123        .io_resource    = &ar231x_io_resource, 
     124        .mem_offset     = 0x00000000UL, 
     125        .io_offset      = 0x00000000UL, 
     126}; 
     127 
     128int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 
     129{ 
     130        return AR2315_IRQ_LCBUS_PCI; 
     131} 
     132 
     133int pcibios_plat_dev_init(struct pci_dev *dev) 
     134{ 
     135        pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 5); 
     136        pci_write_config_word(dev, 0x40, 0); 
     137 
     138        /* Clear any pending Abort or external Interrupts 
     139         * and enable interrupt processing */ 
     140        ar231x_mask_reg(AR2315_PCI_INTEN_REG, AR2315_PCI_INT_ENABLE, 0); 
     141        ar231x_write_reg(AR2315_PCI_INT_STATUS, (AR2315_PCI_ABORT_INT | AR2315_PCI_EXT_INT)); 
     142        ar231x_write_reg(AR2315_PCI_INT_MASK, (AR2315_PCI_ABORT_INT | AR2315_PCI_EXT_INT)); 
     143        ar231x_mask_reg(AR2315_PCI_INTEN_REG, 0, AR2315_PCI_INT_ENABLE); 
     144 
     145        return 0; 
     146} 
     147 
     148static void 
     149ar2315_pci_fixup(struct pci_dev *dev) 
     150{ 
     151        unsigned int devfn = dev->devfn; 
     152 
     153        if (dev->bus->number != 0) 
     154                return; 
     155 
     156        /* Only fix up the PCI host settings */ 
     157        if ((PCI_SLOT(devfn) != 3) || (PCI_FUNC(devfn) != 0)) 
     158                return; 
     159 
     160        /* Fix up MBARs */ 
     161        pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, HOST_PCI_MBAR0); 
     162        pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, HOST_PCI_MBAR1); 
     163        pci_write_config_dword(dev, PCI_BASE_ADDRESS_2, HOST_PCI_MBAR2); 
     164        pci_write_config_dword(dev, PCI_COMMAND, 
     165                PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_SPECIAL | 
     166                PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | 
     167                PCI_COMMAND_FAST_BACK); 
     168} 
     169DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, ar2315_pci_fixup); 
     170 
     171static int __init 
     172ar2315_pci_init(void) 
     173{ 
     174        u32 reg; 
     175 
     176        if (ar231x_devtype != DEV_TYPE_AR2315) 
     177                return -ENODEV; 
     178 
     179        configspace = (unsigned long) ioremap_nocache(0x80000000, 1*1024*1024); /* Remap PCI config space */ 
     180        ar231x_pci_controller.io_map_base = 
     181                (unsigned long) ioremap_nocache(AR531X_MEM_BASE + AR531X_MEM_SIZE, AR531X_IO_SIZE); 
     182        set_io_port_base(ar231x_pci_controller.io_map_base); /* PCI I/O space */ 
     183 
     184        reg = ar231x_mask_reg(AR2315_RESET, 0, AR2315_RESET_PCIDMA); 
     185        msleep(10); 
     186 
     187        reg &= ~AR2315_RESET_PCIDMA; 
     188        ar231x_write_reg(AR2315_RESET, reg); 
     189        msleep(10); 
     190 
     191        ar231x_mask_reg(AR2315_ENDIAN_CTL, 0, 
     192                AR2315_CONFIG_PCIAHB | AR2315_CONFIG_PCIAHB_BRIDGE); 
     193 
     194        ar231x_write_reg(AR2315_PCICLK, AR2315_PCICLK_PLLC_CLKM | 
     195                (AR2315_PCICLK_IN_FREQ_DIV_6 << AR2315_PCICLK_DIV_S)); 
     196        ar231x_mask_reg(AR2315_AHB_ARB_CTL, 0, AR2315_ARB_PCI); 
     197        ar231x_mask_reg(AR2315_IF_CTL, AR2315_IF_PCI_CLK_MASK | AR2315_IF_MASK, 
     198                AR2315_IF_PCI | AR2315_IF_PCI_HOST | AR2315_IF_PCI_INTR | 
     199                 (AR2315_IF_PCI_CLK_OUTPUT_CLK << AR2315_IF_PCI_CLK_SHIFT)); 
     200 
     201        /* Reset the PCI bus by setting bits 5-4 in PCI_MCFG */ 
     202        ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_RST_MODE, 
     203                AR2315_PCIRST_LOW); 
     204        msleep(100); 
     205 
     206        /* Bring the PCI out of reset */ 
     207        ar231x_mask_reg(AR2315_PCI_MISC_CONFIG, AR2315_PCIMISC_RST_MODE, 
     208                AR2315_PCIRST_HIGH | AR2315_PCICACHE_DIS | 0x8); 
     209 
     210        ar231x_write_reg(AR2315_PCI_UNCACHE_CFG, 
     211                        0x1E | /* 1GB uncached */ 
     212                        (1 << 5) | /* Enable uncached */ 
     213                        (0x2 << 30) /* Base: 0x80000000 */ 
     214        ); 
     215        ar231x_read_reg(AR2315_PCI_UNCACHE_CFG); 
     216 
     217        msleep(500); 
     218 
     219        /* dirty hack - anyone with a datasheet that knows the memory map ? */ 
     220        ioport_resource.start = 0x10000000; 
     221        ioport_resource.end = 0xffffffff; 
     222        iomem_resource.start = 0x10000000; 
     223        iomem_resource.end = 0xffffffff; 
     224 
     225        register_pci_controller(&ar231x_pci_controller); 
     226 
     227        return 0; 
     228} 
     229 
     230arch_initcall(ar2315_pci_init); 
  • arch/mips/ar231x/Kconfig

    a b config ATHEROS_AR2315 
    1515        select SYS_SUPPORTS_BIG_ENDIAN 
    1616        select GENERIC_GPIO 
    1717        default y 
     18 
     19config ATHEROS_AR2315_PCI 
     20        bool "PCI support" 
     21        depends on ATHEROS_AR2315 
     22        select HW_HAS_PCI 
     23        select PCI 
     24        select USB_ARCH_HAS_HCD 
     25        select USB_ARCH_HAS_OHCI 
     26        select USB_ARCH_HAS_EHCI 
     27        default y 
  • arch/mips/ar231x/ar2315.c

    a b static inline void ar2315_gpio_irq(void) 
    6363                do_IRQ(AR531X_GPIO_IRQ_BASE + bit); 
    6464} 
    6565 
     66#ifdef CONFIG_ATHEROS_AR2315_PCI 
     67static inline void pci_abort_irq(void) 
     68{ 
     69        ar231x_write_reg(AR2315_PCI_INT_STATUS, AR2315_PCI_ABORT_INT); 
     70} 
     71 
     72static inline void pci_ack_irq(void) 
     73{ 
     74        ar231x_write_reg(AR2315_PCI_INT_STATUS, AR2315_PCI_EXT_INT); 
     75} 
     76 
     77void ar2315_pci_irq(int irq) 
     78{ 
     79        if (ar231x_read_reg(AR2315_PCI_INT_STATUS) == AR2315_PCI_ABORT_INT) 
     80                pci_abort_irq(); 
     81        else { 
     82                do_IRQ(irq); 
     83                pci_ack_irq(); 
     84        } 
     85} 
     86#endif /* CONFIG_ATHEROS_AR2315_PCI */ 
    6687 
    6788/* 
    6889 * Called when an interrupt is received, this function 
    ar2315_irq_dispatch(void) 
    81102                do_IRQ(AR2315_IRQ_WLAN0_INTRS); 
    82103        else if (pending & CAUSEF_IP4) 
    83104                do_IRQ(AR2315_IRQ_ENET0_INTRS); 
     105#ifdef CONFIG_ATHEROS_AR2315_PCI 
     106        else if (pending & CAUSEF_IP5) 
     107                ar2315_pci_irq(AR2315_IRQ_LCBUS_PCI); 
     108#endif 
    84109        else if (pending & CAUSEF_IP2) { 
    85110                unsigned int misc_intr = ar231x_read_reg(AR2315_ISR) & ar231x_read_reg(AR2315_IMR); 
    86111 
Note: See TracBrowser for help on using the repository browser.