Root/target/linux/amazon/files/arch/mips/amazon/pci.c

1/*
2 * Carsten Langgaard, carstenl@mips.com
3 * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved.
4 * Copyright (C) 2007 Felix Fietkau <nbd@openwrt.org>
5 *
6 * This program is free software; you can distribute it and/or modify it
7 * under the terms of the GNU General Public License (Version 2) as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
18 */
19
20/* FIXME: convert nasty volatile register derefs to readl/writel calls */
21
22#include <linux/types.h>
23#include <linux/pci.h>
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/delay.h>
28#include <asm/io.h>
29#include <asm/paccess.h>
30#include <asm/amazon/irq.h>
31#include <asm/amazon/amazon.h>
32
33#define AMAZON_PCI_REG32( addr ) (*(volatile u32 *)(addr))
34#ifndef AMAZON_PCI_MEM_BASE
35#define AMAZON_PCI_MEM_BASE 0xb2000000
36#endif
37#define AMAZON_PCI_MEM_SIZE 0x00400000
38#define AMAZON_PCI_IO_BASE 0xb2400000
39#define AMAZON_PCI_IO_SIZE 0x00200000
40
41#define AMAZON_PCI_CFG_BUSNUM_SHF 16
42#define AMAZON_PCI_CFG_DEVNUM_SHF 11
43#define AMAZON_PCI_CFG_FUNNUM_SHF 8
44
45#define PCI_ACCESS_READ 0
46#define PCI_ACCESS_WRITE 1
47
48static struct resource pci_io_resource = {
49    .name = "io pci IO space",
50#if 1
51    .start = AMAZON_PCI_IO_BASE,
52    .end = AMAZON_PCI_IO_BASE + AMAZON_PCI_IO_SIZE - 1,
53#else
54    .start = 0,
55    .end = 0x00002000 - 1,
56#endif
57    .flags = IORESOURCE_IO
58};
59
60static struct resource pci_mem_resource = {
61    .name = "ext pci memory space",
62    .start = AMAZON_PCI_MEM_BASE,
63    .end = AMAZON_PCI_MEM_BASE + AMAZON_PCI_MEM_SIZE - 1,
64    .flags = IORESOURCE_MEM
65};
66
67static int amazon_pci_config_access(unsigned char access_type,
68    struct pci_bus *bus, unsigned int devfn, unsigned int where, u32 *data)
69{
70    unsigned long flags;
71    u32 pci_addr;
72    u32 val;
73    int ret;
74
75    /* Amazon support slot from 0 to 15 */
76    /* devfn 0 & 0x20 is itself */
77    if ((bus->number != 0) || (devfn > 0x7f) || (devfn == 0) || (devfn == 0x20))
78        return 1;
79
80    local_irq_save(flags);
81
82    pci_addr = AMAZON_PCI_CFG_BASE |
83        bus->number << AMAZON_PCI_CFG_BUSNUM_SHF |
84        devfn << AMAZON_PCI_CFG_FUNNUM_SHF |
85        (where & ~0x3);
86
87    if (access_type == PCI_ACCESS_WRITE)
88    {
89#ifdef CONFIG_SWAP_IO_SPACE
90        val = swab32(*data);
91#endif
92        ret = put_dbe(val, (u32 *)pci_addr);
93    } else {
94        ret = get_dbe(val, (u32 *)pci_addr);
95#ifdef CONFIG_SWAP_IO_SPACE
96        *data = swab32(val);
97#else
98        *data = val;
99#endif
100    }
101
102    amazon_writel(amazon_readl(PCI_MODE) & (~(1<<PCI_MODE_cfgok_bit)), PCI_MODE);
103    amazon_writel(amazon_readl(STATUS_COMMAND_ADDR), STATUS_COMMAND_ADDR);
104    amazon_writel(amazon_readl(PCI_MODE) | (~(1<<PCI_MODE_cfgok_bit)), PCI_MODE);
105    mb();
106    local_irq_restore(flags);
107
108    if (((*data) == 0xffffffff) && (access_type == PCI_ACCESS_READ))
109        return 1;
110
111    return ret;
112}
113
114
115static int amazon_pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val)
116{
117    u32 data = 0;
118
119    if (amazon_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
120        return PCIBIOS_DEVICE_NOT_FOUND;
121
122    if (size == 1)
123        *val = (data >> ((where & 3) << 3)) & 0xff;
124    else if (size == 2)
125        *val = (data >> ((where & 3) << 3)) & 0xffff;
126    else
127        *val = data;
128
129    return PCIBIOS_SUCCESSFUL;
130}
131
132
133static int amazon_pci_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
134{
135    u32 data = 0;
136
137    if (size == 4)
138    {
139        data = val;
140    } else {
141        if (amazon_pci_config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
142            return PCIBIOS_DEVICE_NOT_FOUND;
143
144        if (size == 1)
145            data = (data & ~(0xff << ((where & 3) << 3))) |
146                (val << ((where & 3) << 3));
147        else if (size == 2)
148            data = (data & ~(0xffff << ((where & 3) << 3))) |
149                (val << ((where & 3) << 3));
150    }
151
152    if (amazon_pci_config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
153        return PCIBIOS_DEVICE_NOT_FOUND;
154
155    return PCIBIOS_SUCCESSFUL;
156}
157
158static struct pci_ops amazon_pci_ops = {
159    amazon_pci_read,
160    amazon_pci_write
161};
162
163static struct pci_controller amazon_pci_controller = {
164    .pci_ops = &amazon_pci_ops,
165    .mem_resource = &pci_mem_resource,
166    .mem_offset = 0x00000000UL,
167    .io_resource = &pci_io_resource,
168    .io_offset = 0x00000000UL,
169};
170
171int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
172{
173    switch (slot) {
174        case 13:
175            /* IDSEL = AD29 --> USB Host Controller */
176            return INT_NUM_IM2_IRL15;
177        case 14:
178            /* IDSEL = AD30 --> mini PCI connector */
179            return INT_NUM_IM2_IRL14;
180        default:
181            printk("Warning: no IRQ found for PCI device in slot %d, pin %d\n", slot, pin);
182            return 0;
183    }
184}
185
186int pcibios_plat_dev_init(struct pci_dev *dev)
187{
188    switch(dev->irq) {
189        case INT_NUM_IM2_IRL15:
190            /*
191             * IDSEL = AD29 --> USB Host Controller
192             * PCI_INTA/B/C--GPIO Port0.2--EXIN3
193             * IN/ALT0:1 ALT1:0
194             * PULL UP
195             */
196            (*AMAZON_GPIO_P0_DIR) = (*AMAZON_GPIO_P0_DIR) & 0xfffffffb;
197            (*AMAZON_GPIO_P0_ALTSEL0) = (*AMAZON_GPIO_P0_ALTSEL0)| 4;
198            (*AMAZON_GPIO_P0_ALTSEL1) = (*AMAZON_GPIO_P0_ALTSEL1)& 0xfffffffb;
199            (*AMAZON_GPIO_P0_PUDSEL) = (*AMAZON_GPIO_P0_PUDSEL) | 4;
200            (*AMAZON_GPIO_P0_PUDEN) = (*AMAZON_GPIO_P0_PUDEN) | 4;
201            //External Interrupt Node
202            (*AMAZON_ICU_EXTINTCR) = (*AMAZON_ICU_EXTINTCR)|0x6000; /* Low Level triggered */
203            (*AMAZON_ICU_IRNEN) = (*AMAZON_ICU_IRNEN)|0x8;
204            pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
205            break;
206        case INT_NUM_IM2_IRL14:
207            /*
208             * IDSEL = AD30 --> mini PCI connector
209             * PCI_INTA--GPIO Port0.1--EXIN2
210             * IN/ALT0:1 ALT1:0
211             * PULL UP
212             */
213            (*AMAZON_GPIO_P0_DIR) = (*AMAZON_GPIO_P0_DIR) & 0xfffffffd;
214            (*AMAZON_GPIO_P0_ALTSEL0) = (*AMAZON_GPIO_P0_ALTSEL0)| 2;
215            (*AMAZON_GPIO_P0_ALTSEL1) = (*AMAZON_GPIO_P0_ALTSEL1)& 0xfffffffd;
216            (*AMAZON_GPIO_P0_PUDSEL) = (*AMAZON_GPIO_P0_PUDSEL) | 2;
217            (*AMAZON_GPIO_P0_PUDEN) = (*AMAZON_GPIO_P0_PUDEN) | 2;
218            //External Interrupt Node
219            (*AMAZON_ICU_EXTINTCR) = (*AMAZON_ICU_EXTINTCR)|0x600;
220            (*AMAZON_ICU_IRNEN) = (*AMAZON_ICU_IRNEN)|0x4;
221            pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
222            break;
223        default:
224            return 1;
225    }
226    return 0;
227}
228
229int __init amazon_pci_init(void)
230{
231    u32 temp_buffer;
232
233#ifdef CONFIG_SWAP_IO_SPACE
234    AMAZON_PCI_REG32(IRM) = AMAZON_PCI_REG32(IRM) | (1<<27) | (1<<28);
235    wmb();
236#endif
237
238    AMAZON_PCI_REG32(CLOCK_CONTROL) = AMAZON_PCI_REG32(CLOCK_CONTROL) | (1<<ARB_CTRL_bit);
239    amazon_writel(amazon_readl(PCI_MODE) & (~(1<<PCI_MODE_cfgok_bit)), PCI_MODE);
240
241    AMAZON_PCI_REG32(STATUS_COMMAND_ADDR) = AMAZON_PCI_REG32(STATUS_COMMAND_ADDR) | (1<<BUS_MASTER_ENABLE_BIT) |(1<<MEM_SPACE_ENABLE_BIT);
242
243    temp_buffer = AMAZON_PCI_REG32(PCI_ARB_CTRL_STATUS_ADDR);
244    temp_buffer = temp_buffer | (1<< INTERNAL_ARB_ENABLE_BIT);
245    temp_buffer = temp_buffer & ~(3<< PCI_MASTER0_REQ_MASK_2BITS);
246    temp_buffer = temp_buffer & ~(3<< PCI_MASTER0_GNT_MASK_2BITS);
247
248    /* flash */
249    temp_buffer = temp_buffer & ~(3<< PCI_MASTER1_REQ_MASK_2BITS);
250    temp_buffer = temp_buffer & ~(3<< PCI_MASTER1_GNT_MASK_2BITS);
251
252    /* external master */
253    temp_buffer = temp_buffer & ~(3<< PCI_MASTER2_REQ_MASK_2BITS);
254    temp_buffer = temp_buffer & ~(3<< PCI_MASTER2_GNT_MASK_2BITS);
255
256    AMAZON_PCI_REG32(PCI_ARB_CTRL_STATUS_ADDR) = temp_buffer;
257    wmb();
258
259    AMAZON_PCI_REG32(FPI_ADDRESS_MAP_0) = 0xb2000000;
260    AMAZON_PCI_REG32(FPI_ADDRESS_MAP_1) = 0xb2100000;
261    AMAZON_PCI_REG32(FPI_ADDRESS_MAP_2) = 0xb2200000;
262    AMAZON_PCI_REG32(FPI_ADDRESS_MAP_3) = 0xb2300000;
263    AMAZON_PCI_REG32(FPI_ADDRESS_MAP_4) = 0xb2400000;
264    AMAZON_PCI_REG32(FPI_ADDRESS_MAP_5) = 0xb2500000;
265    AMAZON_PCI_REG32(FPI_ADDRESS_MAP_6) = 0xb2600000;
266    AMAZON_PCI_REG32(FPI_ADDRESS_MAP_7) = 0xb2700000;
267
268    AMAZON_PCI_REG32(BAR11_MASK) = 0x0c000008;
269    AMAZON_PCI_REG32(PCI_ADDRESS_MAP_11) = 0x0;
270    AMAZON_PCI_REG32(BAR1_ADDR) = 0x0;
271    amazon_writel(amazon_readl(PCI_MODE) | (~(1<<PCI_MODE_cfgok_bit)), PCI_MODE);
272    //use 8 dw burse length
273    AMAZON_PCI_REG32(FPI_BURST_LENGTH) = 0x303;
274
275    amazon_pci_controller.io_map_base = (unsigned long)ioremap(AMAZON_PCI_IO_BASE, AMAZON_PCI_IO_SIZE - 1);
276    register_pci_controller(&amazon_pci_controller);
277    return 0;
278}
279arch_initcall(amazon_pci_init);
280

Archive Download this file



interactive