OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [mips/] [pci/] [ops-bonito64.c] - Blame information for rev 1275

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * Carsten Langgaard, carstenl@mips.com
3
 * Copyright (C) 1999, 2000 MIPS Technologies, Inc.  All rights reserved.
4
 *
5
 *  This program is free software; you can distribute it and/or modify it
6
 *  under the terms of the GNU General Public License (Version 2) as
7
 *  published by the Free Software Foundation.
8
 *
9
 *  This program is distributed in the hope it will be useful, but WITHOUT
10
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
 *  for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License along
15
 *  with this program; if not, write to the Free Software Foundation, Inc.,
16
 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
17
 */
18
#include <linux/types.h>
19
#include <linux/pci.h>
20
#include <linux/kernel.h>
21
#include <linux/init.h>
22
 
23
#include <asm/mips-boards/bonito64.h>
24
 
25
#define PCI_ACCESS_READ  0
26
#define PCI_ACCESS_WRITE 1
27
 
28
/*
29
 *  PCI configuration cycle AD bus definition
30
 */
31
/* Type 0 */
32
#define PCI_CFG_TYPE0_REG_SHF           0
33
#define PCI_CFG_TYPE0_FUNC_SHF          8
34
 
35
/* Type 1 */
36
#define PCI_CFG_TYPE1_REG_SHF           0
37
#define PCI_CFG_TYPE1_FUNC_SHF          8
38
#define PCI_CFG_TYPE1_DEV_SHF           11
39
#define PCI_CFG_TYPE1_BUS_SHF           16
40
 
41
static int bonito64_config_access(unsigned char access_type,
42
        struct pci_dev *dev, unsigned char where, u32 *data)
43
{
44
        unsigned char bus = dev->bus->number;
45
        unsigned char dev_fn = dev->devfn;
46
        unsigned char type;
47
        u32 intr, dummy;
48
        u64 pci_addr;
49
 
50
        if ((bus == 0) && (PCI_SLOT(dev_fn) == 0))
51
                return -1;
52
 
53
        /* Clear cause register bits */
54
        BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR | BONITO_PCICMD_MTABORT_CLR);
55
 
56
        /*
57
         * Setup pattern to be used as PCI "address" for Type 0 cycle
58
         */
59
        if (bus == 0) {
60
                /* IDSEL */
61
                pci_addr = (u64)1 << (PCI_SLOT(dev_fn) + 10);
62
        } else {
63
                /* Bus number */
64
                pci_addr = bus << PCI_CFG_TYPE1_BUS_SHF;
65
 
66
                /* Device number */
67
                pci_addr |= PCI_SLOT(dev_fn) << PCI_CFG_TYPE1_DEV_SHF;
68
        }
69
 
70
        /* Function (same for Type 0/1) */
71
        pci_addr |= PCI_FUNC(dev_fn) << PCI_CFG_TYPE0_FUNC_SHF;
72
 
73
        /* Register number (same for Type 0/1) */
74
        pci_addr |= (where & ~0x3) << PCI_CFG_TYPE0_REG_SHF;
75
 
76
        if (bus == 0) {
77
                /* Type 0 */
78
                BONITO_PCIMAP_CFG = pci_addr >> 16;
79
        } else {
80
                /* Type 1 */
81
                BONITO_PCIMAP_CFG = (pci_addr >> 16) | 0x10000;
82
        }
83
 
84
        /* Flush Bonito register block */
85
        dummy = BONITO_PCIMAP_CFG;
86
        iob();    /* sync */
87
 
88
        /* Perform access */
89
        if (access_type == PCI_ACCESS_WRITE) {
90
                *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE +
91
                                  (pci_addr & 0xffff))) = *(u32 *)data;
92
 
93
                /* Wait till done */
94
                while (BONITO_PCIMSTAT & 0xF)
95
                        ;
96
        } else {
97
                *(u32 *)data =
98
                          *(volatile u32 *)(KSEG1ADDR(BONITO_PCICFG_BASE +
99
                                    (pci_addr & 0xffff)));
100
        }
101
 
102
        /* Detect Master/Target abort */
103
        if (BONITO_PCICMD & (BONITO_PCICMD_MABORT_CLR |
104
                             BONITO_PCICMD_MTABORT_CLR)) {
105
                /* Error occurred */
106
 
107
                /* Clear bits */
108
                BONITO_PCICMD |= (BONITO_PCICMD_MABORT_CLR |
109
                                  BONITO_PCICMD_MTABORT_CLR);
110
 
111
                return -1;
112
        }
113
 
114
        return 0;
115
}
116
 
117
 
118
/*
119
 * We can't address 8 and 16 bit words directly.  Instead we have to
120
 * read/write a 32bit word and mask/modify the data we actually want.
121
 */
122
static int bonito64_read_config_byte (struct pci_dev *dev, int where,
123
        u8 *val)
124
{
125
        u32 data = 0;
126
 
127
        if (bonito64_config_access(PCI_ACCESS_READ, dev, where, &data))
128
                return -1;
129
 
130
        *val = (data >> ((where & 3) << 3)) & 0xff;
131
 
132
        return PCIBIOS_SUCCESSFUL;
133
}
134
 
135
static int bonito64_read_config_word (struct pci_dev *dev, int where,
136
        u16 *val)
137
{
138
        u32 data = 0;
139
 
140
        if (where & 1)
141
                return PCIBIOS_BAD_REGISTER_NUMBER;
142
 
143
        if (bonito64_config_access(PCI_ACCESS_READ, dev, where, &data))
144
               return -1;
145
 
146
        *val = (data >> ((where & 3) << 3)) & 0xffff;
147
 
148
        return PCIBIOS_SUCCESSFUL;
149
}
150
 
151
static int bonito64_read_config_dword (struct pci_dev *dev, int where,
152
        u32 *val)
153
{
154
        u32 data = 0;
155
 
156
        if (where & 3)
157
                return PCIBIOS_BAD_REGISTER_NUMBER;
158
 
159
        if (bonito64_config_access(PCI_ACCESS_READ, dev, where, &data))
160
                return -1;
161
 
162
        *val = data;
163
 
164
        return PCIBIOS_SUCCESSFUL;
165
}
166
 
167
static int bonito64_write_config_byte (struct pci_dev *dev, int where,
168
        u8 val)
169
{
170
        u32 data = 0;
171
 
172
        if (bonito64_config_access(PCI_ACCESS_READ, dev, where, &data))
173
                return -1;
174
 
175
        data = (data & ~(0xff << ((where & 3) << 3))) |
176
               (val << ((where & 3) << 3));
177
 
178
        if (bonito64_config_access(PCI_ACCESS_WRITE, dev, where, &data))
179
                return -1;
180
 
181
        return PCIBIOS_SUCCESSFUL;
182
}
183
 
184
static int bonito64_write_config_word (struct pci_dev *dev, int where,
185
        u16 val)
186
{
187
        u32 data = 0;
188
 
189
        if (where & 1)
190
                return PCIBIOS_BAD_REGISTER_NUMBER;
191
 
192
        if (bonito64_config_access(PCI_ACCESS_READ, dev, where, &data))
193
               return -1;
194
 
195
        data = (data & ~(0xffff << ((where & 3) << 3))) |
196
               (val << ((where & 3) << 3));
197
 
198
        if (bonito64_config_access(PCI_ACCESS_WRITE, dev, where, &data))
199
               return -1;
200
 
201
 
202
        return PCIBIOS_SUCCESSFUL;
203
}
204
 
205
static int bonito64_write_config_dword(struct pci_dev *dev, int where,
206
        u32 val)
207
{
208
        if (where & 3)
209
                return PCIBIOS_BAD_REGISTER_NUMBER;
210
 
211
        if (bonito64_config_access(PCI_ACCESS_WRITE, dev, where, &val))
212
               return -1;
213
 
214
        return PCIBIOS_SUCCESSFUL;
215
}
216
 
217
struct pci_ops bonito64_pci_ops = {
218
        bonito64_read_config_byte,
219
        bonito64_read_config_word,
220
        bonito64_read_config_dword,
221
        bonito64_write_config_byte,
222
        bonito64_write_config_word,
223
        bonito64_write_config_dword
224
};

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.