3 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
5 * SPDX-License-Identifier: GPL-2.0+
9 #include <asm/ppc4xx.h>
10 #include <asm/processor.h>
14 u_long pci9054_iobase
;
17 #define PCI_PRIMARY_CAR (0x500000dc) /* PCI config address reg */
18 #define PCI_PRIMARY_CDR (0x80000000) /* PCI config data reg */
21 /*-----------------------------------------------------------------------------+
22 | Subroutine: pci9054_read_config_dword
23 | Description: Read a PCI configuration register
26 | dev PCI Bus+Device+Function number
27 | offset Configuration register number
28 | value Address of the configuration register value
31 +-----------------------------------------------------------------------------*/
32 int pci9054_read_config_dword(struct pci_controller
*hose
,
33 pci_dev_t dev
, int offset
, u32
* value
)
35 unsigned long conAdrVal
;
38 /* generate coded value for CON_ADR register */
39 conAdrVal
= dev
| (offset
& 0xfc) | 0x80000000;
41 /* Load the CON_ADR (CAR) value first, then read from CON_DATA (CDR) */
42 *(unsigned long *)PCI_PRIMARY_CAR
= conAdrVal
;
44 /* Note: *pResult comes back as -1 if machine check happened */
45 val
= in32r(PCI_PRIMARY_CDR
);
47 *value
= (unsigned long) val
;
49 out32r(PCI_PRIMARY_CAR
, 0);
51 if ((*(unsigned long *)0x50000304) & 0x60000000)
53 /* clear pci master/target abort bits */
54 *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304;
60 /*-----------------------------------------------------------------------------+
61 | Subroutine: pci9054_write_config_dword
62 | Description: Write a PCI configuration register.
65 | dev PCI Bus+Device+Function number
66 | offset Configuration register number
67 | Value Configuration register value
70 | Updated for pass2 errata #6. Need to disable interrupts and clear the
71 | PCICFGADR reg after writing the PCICFGDATA reg.
72 +-----------------------------------------------------------------------------*/
73 int pci9054_write_config_dword(struct pci_controller
*hose
,
74 pci_dev_t dev
, int offset
, u32 value
)
76 unsigned long conAdrVal
;
78 conAdrVal
= dev
| (offset
& 0xfc) | 0x80000000;
80 *(unsigned long *)PCI_PRIMARY_CAR
= conAdrVal
;
82 out32r(PCI_PRIMARY_CDR
, value
);
84 out32r(PCI_PRIMARY_CAR
, 0);
86 /* clear pci master/target abort bits */
87 *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304;
92 /*-----------------------------------------------------------------------
95 #ifdef CONFIG_DASA_SIM
96 static void pci_dasa_sim_config_pci9054(struct pci_controller
*hose
, pci_dev_t dev
,
97 struct pci_config_table
*_
)
100 unsigned short status
= 0;
104 * Configure PLX PCI9054
106 pci_read_config_word(CONFIG_SYS_PCI9054_DEV_FN
, PCI_COMMAND
, &status
);
107 status
|= PCI_COMMAND_MASTER
| PCI_COMMAND_IO
| PCI_COMMAND_MEMORY
;
108 pci_write_config_word(CONFIG_SYS_PCI9054_DEV_FN
, PCI_COMMAND
, status
);
110 /* Check the latency timer for values >= 0x60.
112 pci_read_config_byte(CONFIG_SYS_PCI9054_DEV_FN
, PCI_LATENCY_TIMER
, &timer
);
115 pci_write_config_byte(CONFIG_SYS_PCI9054_DEV_FN
, PCI_LATENCY_TIMER
, 0x60);
118 /* Set I/O base register.
120 pci_write_config_dword(CONFIG_SYS_PCI9054_DEV_FN
, PCI_BASE_ADDRESS_0
, CONFIG_SYS_PCI9054_IOBASE
);
121 pci_read_config_dword(CONFIG_SYS_PCI9054_DEV_FN
, PCI_BASE_ADDRESS_0
, &iobase
);
123 pci9054_iobase
= pci_mem_to_phys(CONFIG_SYS_PCI9054_DEV_FN
, iobase
& PCI_BASE_ADDRESS_MEM_MASK
);
125 if (pci9054_iobase
== 0xffffffff)
127 printf("Error: Can not set I/O base register.\n");
133 static struct pci_config_table pci9054_config_table
[] = {
134 #ifndef CONFIG_PCI_PNP
135 { PCI_ANY_ID
, PCI_ANY_ID
, PCI_ANY_ID
,
136 PCI_BUS(CONFIG_SYS_ETH_DEV_FN
), PCI_DEV(CONFIG_SYS_ETH_DEV_FN
), PCI_FUNC(CONFIG_SYS_ETH_DEV_FN
),
137 pci_cfgfunc_config_device
, { CONFIG_SYS_ETH_IOBASE
,
138 CONFIG_SYS_ETH_IOBASE
,
139 PCI_COMMAND_IO
| PCI_COMMAND_MASTER
}},
140 #ifdef CONFIG_DASA_SIM
141 { PCI_ANY_ID
, PCI_ANY_ID
, PCI_ANY_ID
,
142 PCI_BUS(CONFIG_SYS_PCI9054_DEV_FN
), PCI_DEV(CONFIG_SYS_PCI9054_DEV_FN
), PCI_FUNC(CONFIG_SYS_PCI9054_DEV_FN
),
143 pci_dasa_sim_config_pci9054
},
149 static struct pci_controller pci9054_hose
= {
150 config_table
: pci9054_config_table
,
153 void pci_init_board(void)
155 struct pci_controller
*hose
= &pci9054_hose
;
160 hose
->first_busno
= 0;
161 hose
->last_busno
= 0xff;
163 /* System memory space */
164 pci_set_region(hose
->regions
+ 0,
165 0x00000000, 0x00000000, 0x01000000,
166 PCI_REGION_MEM
| PCI_REGION_SYS_MEMORY
);
168 /* PCI Memory space */
169 pci_set_region(hose
->regions
+ 1,
170 0x00000000, 0xc0000000, 0x10000000,
174 pci_hose_read_config_byte_via_dword
,
175 pci_hose_read_config_word_via_dword
,
176 pci9054_read_config_dword
,
177 pci_hose_write_config_byte_via_dword
,
178 pci_hose_write_config_word_via_dword
,
179 pci9054_write_config_dword
);
181 hose
->region_count
= 2;
183 pci_register_hose(hose
);
185 hose
->last_busno
= pci_hose_scan(hose
);