blob: a9b3fd89fb6d37da5596cd523130e3cf3d67363a [file] [log] [blame]
Wolfgang Denk56811f62005-10-09 01:04:33 +02001/*
2 * (C) Copyright 2003
3 * AMIRIX Systems Inc.
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24#include <common.h>
25#include <ppc4xx.h>
26#include <asm/processor.h>
27#include <pci.h>
28
29#define PCI_MEM_82559ER_CSR_BASE 0x30200000
30#define PCI_IO_82559ER_CSR_BASE 0x40000200
31
32/** AP1100 specific values */
Wolfgang Denk3193a652005-10-09 01:41:48 +020033#define PSII_BASE 0x30000000 /**< PowerSpan II dual bridge local bus register address */
34#define PSII_CONFIG_ADDR 0x30000290 /**< PowerSpan II Configuration Cycle Address configuration register */
35#define PSII_CONFIG_DATA 0x30000294 /**< PowerSpan II Configuration Cycle Data register. */
36#define PSII_CONFIG_DEST_PCI2 0x01000000 /**< PowerSpan II configuration cycle destination selection, set for PCI2 bus */
37#define PSII_PCI_MEM_BASE 0x30200000 /**< Local Bus address for start of PCI memory space on PCI2 bus. */
38#define PSII_PCI_MEM_SIZE 0x1BE00000 /**< PCI Memory space about 510 Meg. */
39#define AP1000_SYS_MEM_START 0x00000000 /**< System memory starts at 0. */
40#define AP1000_SYS_MEM_SIZE 0x08000000 /**< System memory is 128 Meg. */
Wolfgang Denk56811f62005-10-09 01:04:33 +020041
42/* static int G_verbosity_level = 1; */
43#define G_verbosity_level 1
44
Wolfgang Denk3193a652005-10-09 01:41:48 +020045void write1 (unsigned long addr, unsigned char val)
46{
47 volatile unsigned char *p = (volatile unsigned char *) addr;
Wolfgang Denk56811f62005-10-09 01:04:33 +020048
Wolfgang Denk3193a652005-10-09 01:41:48 +020049 if (G_verbosity_level > 1)
50 printf ("write1: addr=%08x val=%02x\n", (unsigned int) addr,
51 val);
52 *p = val;
53 asm ("eieio");
Wolfgang Denk56811f62005-10-09 01:04:33 +020054}
55
Wolfgang Denk3193a652005-10-09 01:41:48 +020056unsigned char read1 (unsigned long addr)
57{
58 unsigned char val;
59 volatile unsigned char *p = (volatile unsigned char *) addr;
Wolfgang Denk56811f62005-10-09 01:04:33 +020060
Wolfgang Denk3193a652005-10-09 01:41:48 +020061 if (G_verbosity_level > 1)
62 printf ("read1: addr=%08x ", (unsigned int) addr);
63 val = *p;
64 asm ("eieio");
65 if (G_verbosity_level > 1)
66 printf ("val=%08x\n", val);
67 return val;
Wolfgang Denk56811f62005-10-09 01:04:33 +020068}
69
Wolfgang Denk3193a652005-10-09 01:41:48 +020070void write2 (unsigned long addr, unsigned short val)
71{
72 volatile unsigned short *p = (volatile unsigned short *) addr;
Wolfgang Denk56811f62005-10-09 01:04:33 +020073
Wolfgang Denk3193a652005-10-09 01:41:48 +020074 if (G_verbosity_level > 1)
75 printf ("write2: addr=%08x val=%04x -> *p=%04x\n",
76 (unsigned int) addr, val,
77 ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8));
Wolfgang Denk56811f62005-10-09 01:04:33 +020078
Wolfgang Denk3193a652005-10-09 01:41:48 +020079 *p = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8);
80 asm ("eieio");
Wolfgang Denk56811f62005-10-09 01:04:33 +020081}
82
Wolfgang Denk3193a652005-10-09 01:41:48 +020083unsigned short read2 (unsigned long addr)
84{
85 unsigned short val;
86 volatile unsigned short *p = (volatile unsigned short *) addr;
Wolfgang Denk56811f62005-10-09 01:04:33 +020087
Wolfgang Denk3193a652005-10-09 01:41:48 +020088 if (G_verbosity_level > 1)
89 printf ("read2: addr=%08x ", (unsigned int) addr);
90 val = *p;
91 val = ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8);
92 asm ("eieio");
93 if (G_verbosity_level > 1)
94 printf ("*p=%04x -> val=%04x\n",
95 ((val & 0xFF00) >> 8) | ((val & 0x00FF) << 8), val);
96 return val;
Wolfgang Denk56811f62005-10-09 01:04:33 +020097}
98
Wolfgang Denk3193a652005-10-09 01:41:48 +020099void write4 (unsigned long addr, unsigned long val)
100{
101 volatile unsigned long *p = (volatile unsigned long *) addr;
Wolfgang Denk56811f62005-10-09 01:04:33 +0200102
Wolfgang Denk3193a652005-10-09 01:41:48 +0200103 if (G_verbosity_level > 1)
104 printf ("write4: addr=%08x val=%08x -> *p=%08x\n",
105 (unsigned int) addr, (unsigned int) val,
106 (unsigned int) (((val & 0xFF000000) >> 24) |
107 ((val & 0x000000FF) << 24) |
108 ((val & 0x00FF0000) >> 8) |
109 ((val & 0x0000FF00) << 8)));
Wolfgang Denk56811f62005-10-09 01:04:33 +0200110
Wolfgang Denk3193a652005-10-09 01:41:48 +0200111 *p = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
112 ((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8);
113 asm ("eieio");
Wolfgang Denk56811f62005-10-09 01:04:33 +0200114}
115
Wolfgang Denk3193a652005-10-09 01:41:48 +0200116unsigned long read4 (unsigned long addr)
117{
118 unsigned long val;
119 volatile unsigned long *p = (volatile unsigned long *) addr;
Wolfgang Denk56811f62005-10-09 01:04:33 +0200120
Wolfgang Denk3193a652005-10-09 01:41:48 +0200121 if (G_verbosity_level > 1)
122 printf ("read4: addr=%08x", (unsigned int) addr);
Wolfgang Denk56811f62005-10-09 01:04:33 +0200123
Wolfgang Denk3193a652005-10-09 01:41:48 +0200124 val = *p;
125 val = ((val & 0xFF000000) >> 24) | ((val & 0x000000FF) << 24) |
126 ((val & 0x00FF0000) >> 8) | ((val & 0x0000FF00) << 8);
127 asm ("eieio");
Wolfgang Denk56811f62005-10-09 01:04:33 +0200128
Wolfgang Denk3193a652005-10-09 01:41:48 +0200129 if (G_verbosity_level > 1)
130 printf ("*p=%04x -> val=%04x\n",
131 (unsigned int) (((val & 0xFF000000) >> 24) |
132 ((val & 0x000000FF) << 24) |
133 ((val & 0x00FF0000) >> 8) |
134 ((val & 0x0000FF00) << 8)),
135 (unsigned int) val);
136 return val;
Wolfgang Denk56811f62005-10-09 01:04:33 +0200137}
138
Wolfgang Denk3193a652005-10-09 01:41:48 +0200139void write4be (unsigned long addr, unsigned long val)
140{
141 volatile unsigned long *p = (volatile unsigned long *) addr;
Wolfgang Denk56811f62005-10-09 01:04:33 +0200142
Wolfgang Denk3193a652005-10-09 01:41:48 +0200143 if (G_verbosity_level > 1)
144 printf ("write4: addr=%08x val=%08x\n", (unsigned int) addr,
145 (unsigned int) val);
146 *p = val;
147 asm ("eieio");
Wolfgang Denk56811f62005-10-09 01:04:33 +0200148}
149
150/** One byte configuration write on PSII.
151 * Currently fixes destination PCI bus to PCI2, onboard
152 * pci.
153 * @param hose PCI Host controller information. Ignored.
154 * @param dev Encoded PCI device/Bus and Function value.
155 * @param reg PCI Configuration register number.
156 * @param val Address of location for received byte.
157 * @return Always Zero.
158 */
Wolfgang Denk3193a652005-10-09 01:41:48 +0200159static int psII_read_config_byte (struct pci_controller *hose,
160 pci_dev_t dev, int reg, u8 * val)
Wolfgang Denk56811f62005-10-09 01:04:33 +0200161{
Wolfgang Denk3193a652005-10-09 01:41:48 +0200162 write4be (PSII_CONFIG_ADDR, PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */
163 (PCI_BUS (dev) << 16) | (PCI_DEV (dev) << 11) | (PCI_FUNC (dev) << 8) | ((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */
Wolfgang Denk56811f62005-10-09 01:04:33 +0200164
Wolfgang Denk3193a652005-10-09 01:41:48 +0200165 *val = read1 (PSII_CONFIG_DATA + (reg & 0x03));
166 return (0);
Wolfgang Denk56811f62005-10-09 01:04:33 +0200167}
168
169/** One byte configuration write on PSII.
170 * Currently fixes destination bus to PCI2, onboard
171 * pci.
172 * @param hose PCI Host controller information. Ignored.
173 * @param dev Encoded PCI device/Bus and Function value.
174 * @param reg PCI Configuration register number.
175 * @param val Output byte.
176 * @return Always Zero.
177 */
Wolfgang Denk3193a652005-10-09 01:41:48 +0200178static int psII_write_config_byte (struct pci_controller *hose,
179 pci_dev_t dev, int reg, u8 val)
Wolfgang Denk56811f62005-10-09 01:04:33 +0200180{
Wolfgang Denk3193a652005-10-09 01:41:48 +0200181 write4be (PSII_CONFIG_ADDR, PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */
182 (PCI_BUS (dev) << 16) | (PCI_DEV (dev) << 11) | (PCI_FUNC (dev) << 8) | ((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */
Wolfgang Denk56811f62005-10-09 01:04:33 +0200183
Wolfgang Denk3193a652005-10-09 01:41:48 +0200184 write1 (PSII_CONFIG_DATA + (reg & 0x03), (unsigned char) val);
Wolfgang Denk56811f62005-10-09 01:04:33 +0200185
Wolfgang Denk3193a652005-10-09 01:41:48 +0200186 return (0);
Wolfgang Denk56811f62005-10-09 01:04:33 +0200187}
188
189/** One word (16 bit) configuration read on PSII.
190 * Currently fixes destination PCI bus to PCI2, onboard
191 * pci.
192 * @param hose PCI Host controller information. Ignored.
193 * @param dev Encoded PCI device/Bus and Function value.
194 * @param reg PCI Configuration register number.
195 * @param val Address of location for received word.
196 * @return Always Zero.
197 */
Wolfgang Denk3193a652005-10-09 01:41:48 +0200198static int psII_read_config_word (struct pci_controller *hose,
199 pci_dev_t dev, int reg, u16 * val)
Wolfgang Denk56811f62005-10-09 01:04:33 +0200200{
Wolfgang Denk3193a652005-10-09 01:41:48 +0200201 write4be (PSII_CONFIG_ADDR, PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */
202 (PCI_BUS (dev) << 16) | (PCI_DEV (dev) << 11) | (PCI_FUNC (dev) << 8) | ((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */
Wolfgang Denk56811f62005-10-09 01:04:33 +0200203
Wolfgang Denk3193a652005-10-09 01:41:48 +0200204 *val = read2 (PSII_CONFIG_DATA + (reg & 0x03));
205 return (0);
Wolfgang Denk56811f62005-10-09 01:04:33 +0200206}
207
208/** One word (16 bit) configuration write on PSII.
209 * Currently fixes destination bus to PCI2, onboard
210 * pci.
211 * @param hose PCI Host controller information. Ignored.
212 * @param dev Encoded PCI device/Bus and Function value.
213 * @param reg PCI Configuration register number.
214 * @param val Output word.
215 * @return Always Zero.
216 */
Wolfgang Denk3193a652005-10-09 01:41:48 +0200217static int psII_write_config_word (struct pci_controller *hose,
218 pci_dev_t dev, int reg, u16 val)
Wolfgang Denk56811f62005-10-09 01:04:33 +0200219{
Wolfgang Denk3193a652005-10-09 01:41:48 +0200220 write4be (PSII_CONFIG_ADDR, PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */
221 (PCI_BUS (dev) << 16) | (PCI_DEV (dev) << 11) | (PCI_FUNC (dev) << 8) | ((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */
Wolfgang Denk56811f62005-10-09 01:04:33 +0200222
Wolfgang Denk3193a652005-10-09 01:41:48 +0200223 write2 (PSII_CONFIG_DATA + (reg & 0x03), (unsigned short) val);
Wolfgang Denk56811f62005-10-09 01:04:33 +0200224
Wolfgang Denk3193a652005-10-09 01:41:48 +0200225 return (0);
Wolfgang Denk56811f62005-10-09 01:04:33 +0200226}
227
228/** One DWord (32 bit) configuration read on PSII.
229 * Currently fixes destination PCI bus to PCI2, onboard
230 * pci.
231 * @param hose PCI Host controller information. Ignored.
232 * @param dev Encoded PCI device/Bus and Function value.
233 * @param reg PCI Configuration register number.
234 * @param val Address of location for received byte.
235 * @return Always Zero.
236 */
Wolfgang Denk3193a652005-10-09 01:41:48 +0200237static int psII_read_config_dword (struct pci_controller *hose,
238 pci_dev_t dev, int reg, u32 * val)
Wolfgang Denk56811f62005-10-09 01:04:33 +0200239{
Wolfgang Denk3193a652005-10-09 01:41:48 +0200240 write4be (PSII_CONFIG_ADDR, PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */
241 (PCI_BUS (dev) << 16) | (PCI_DEV (dev) << 11) | (PCI_FUNC (dev) << 8) | ((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */
Wolfgang Denk56811f62005-10-09 01:04:33 +0200242
Wolfgang Denk3193a652005-10-09 01:41:48 +0200243 *val = read4 (PSII_CONFIG_DATA);
244 return (0);
Wolfgang Denk56811f62005-10-09 01:04:33 +0200245}
246
247/** One DWord (32 bit) configuration write on PSII.
248 * Currently fixes destination bus to PCI2, onboard
249 * pci.
250 * @param hose PCI Host controller information. Ignored.
251 * @param dev Encoded PCI device/Bus and Function value.
252 * @param reg PCI Configuration register number.
253 * @param val Output Dword.
254 * @return Always Zero.
255 */
Wolfgang Denk3193a652005-10-09 01:41:48 +0200256static int psII_write_config_dword (struct pci_controller *hose,
257 pci_dev_t dev, int reg, u32 val)
Wolfgang Denk56811f62005-10-09 01:04:33 +0200258{
Wolfgang Denk3193a652005-10-09 01:41:48 +0200259 write4be (PSII_CONFIG_ADDR, PSII_CONFIG_DEST_PCI2 | /* Operate on PCI2 bus interface . */
260 (PCI_BUS (dev) << 16) | (PCI_DEV (dev) << 11) | (PCI_FUNC (dev) << 8) | ((reg & 0xFF) & ~3)); /* Configuation cycle type 0 */
Wolfgang Denk56811f62005-10-09 01:04:33 +0200261
Wolfgang Denk3193a652005-10-09 01:41:48 +0200262 write4 (PSII_CONFIG_DATA, (unsigned long) val);
Wolfgang Denk56811f62005-10-09 01:04:33 +0200263
Wolfgang Denk3193a652005-10-09 01:41:48 +0200264 return (0);
Wolfgang Denk56811f62005-10-09 01:04:33 +0200265}
266
Wolfgang Denk3193a652005-10-09 01:41:48 +0200267static struct pci_config_table ap1000_config_table[] = {
Wolfgang Denk56811f62005-10-09 01:04:33 +0200268#ifdef CONFIG_AP1000
Wolfgang Denk3193a652005-10-09 01:41:48 +0200269 {PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200270 PCI_BUS (CONFIG_SYS_ETH_DEV_FN), PCI_DEV (CONFIG_SYS_ETH_DEV_FN),
271 PCI_FUNC (CONFIG_SYS_ETH_DEV_FN),
Wolfgang Denk3193a652005-10-09 01:41:48 +0200272 pci_cfgfunc_config_device,
Jean-Christophe PLAGNIOL-VILLARD03836942008-10-16 15:01:15 +0200273 {CONFIG_SYS_ETH_IOBASE, CONFIG_SYS_ETH_MEMBASE,
Wolfgang Denk3193a652005-10-09 01:41:48 +0200274 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER}},
Wolfgang Denk56811f62005-10-09 01:04:33 +0200275#endif
Wolfgang Denk3193a652005-10-09 01:41:48 +0200276 {}
Wolfgang Denk56811f62005-10-09 01:04:33 +0200277};
278
Wolfgang Denk56811f62005-10-09 01:04:33 +0200279static struct pci_controller psII_hose = {
Wolfgang Denk3193a652005-10-09 01:41:48 +0200280 config_table:ap1000_config_table,
Wolfgang Denk56811f62005-10-09 01:04:33 +0200281};
282
Wolfgang Denk3193a652005-10-09 01:41:48 +0200283void pci_init_board (void)
Wolfgang Denk56811f62005-10-09 01:04:33 +0200284{
Wolfgang Denk3193a652005-10-09 01:41:48 +0200285 struct pci_controller *hose = &psII_hose;
Wolfgang Denk56811f62005-10-09 01:04:33 +0200286
Wolfgang Denk3193a652005-10-09 01:41:48 +0200287 /*
288 * Register the hose
289 */
290 hose->first_busno = 0;
291 hose->last_busno = 0xff;
Wolfgang Denk56811f62005-10-09 01:04:33 +0200292
Wolfgang Denk3193a652005-10-09 01:41:48 +0200293 /* System memory space */
294 pci_set_region (hose->regions + 0,
295 AP1000_SYS_MEM_START, AP1000_SYS_MEM_START,
296 AP1000_SYS_MEM_SIZE,
297 PCI_REGION_MEM | PCI_REGION_MEMORY);
Wolfgang Denk56811f62005-10-09 01:04:33 +0200298
Wolfgang Denk3193a652005-10-09 01:41:48 +0200299 /* PCI Memory space */
300 pci_set_region (hose->regions + 1,
301 PSII_PCI_MEM_BASE, PSII_PCI_MEM_BASE,
302 PSII_PCI_MEM_SIZE, PCI_REGION_MEM);
Wolfgang Denk56811f62005-10-09 01:04:33 +0200303
Wolfgang Denk3193a652005-10-09 01:41:48 +0200304 /* No IO Memory space - for now */
Wolfgang Denk56811f62005-10-09 01:04:33 +0200305
Wolfgang Denk3193a652005-10-09 01:41:48 +0200306 pci_set_ops (hose,
307 psII_read_config_byte,
308 psII_read_config_word,
309 psII_read_config_dword,
310 psII_write_config_byte,
311 psII_write_config_word, psII_write_config_dword);
Wolfgang Denk56811f62005-10-09 01:04:33 +0200312
Wolfgang Denk3193a652005-10-09 01:41:48 +0200313 hose->region_count = 2;
Wolfgang Denk56811f62005-10-09 01:04:33 +0200314
Wolfgang Denk3193a652005-10-09 01:41:48 +0200315 pci_register_hose (hose);
Wolfgang Denk56811f62005-10-09 01:04:33 +0200316
Wolfgang Denk3193a652005-10-09 01:41:48 +0200317 hose->last_busno = pci_hose_scan (hose);
Wolfgang Denk56811f62005-10-09 01:04:33 +0200318}