2 * Copyright (C) 2006 Freescale Semiconductor, Inc.
4 * See file CREDITS for list of people who contributed to this
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
14 * PCI Configuration space access support for MPC83xx PCI Bridge
21 #if defined(CONFIG_OF_LIBFDT)
23 #include <fdt_support.h>
26 #include <asm/fsl_i2c.h>
28 DECLARE_GLOBAL_DATA_PTR
;
30 #if defined(CONFIG_PCI)
31 #define PCI_FUNCTION_CONFIG 0x44
32 #define PCI_FUNCTION_CFG_LOCK 0x20
35 * Initialize PCI Devices, report devices found
37 #ifndef CONFIG_PCI_PNP
38 static struct pci_config_table pci_mpc83xxemds_config_table
[] = {
40 PCI_ANY_ID
, PCI_ANY_ID
, PCI_ANY_ID
, PCI_ANY_ID
,
41 pci_cfgfunc_config_device
,
44 PCI_COMMON_MEMORY
| PCI_COMMAND_MASTER
}
49 static struct pci_controller hose
[] = {
51 #ifndef CONFIG_PCI_PNP
52 config_table
:pci_mpc83xxemds_config_table
,
57 /**********************************************************************
59 *********************************************************************/
60 void pci_init_board(void)
61 #ifdef CONFIG_PCISLAVE
64 volatile immap_t
*immr
;
65 volatile law83xx_t
*pci_law
;
66 volatile pot83xx_t
*pci_pot
;
67 volatile pcictrl83xx_t
*pci_ctrl
;
68 volatile pciconf83xx_t
*pci_conf
;
70 immr
= (immap_t
*) CONFIG_SYS_IMMR
;
71 pci_law
= immr
->sysconf
.pcilaw
;
72 pci_pot
= immr
->ios
.pot
;
73 pci_ctrl
= immr
->pci_ctrl
;
74 pci_conf
= immr
->pci_conf
;
76 * Configure PCI Inbound Translation Windows
78 pci_ctrl
[0].pitar0
= 0x0;
79 pci_ctrl
[0].pibar0
= 0x0;
80 pci_ctrl
[0].piwar0
= PIWAR_EN
| PIWAR_RTT_SNOOP
|
81 PIWAR_WTT_SNOOP
| PIWAR_IWS_4K
;
83 pci_ctrl
[0].pitar1
= 0x0;
84 pci_ctrl
[0].pibar1
= 0x0;
85 pci_ctrl
[0].piebar1
= 0x0;
86 pci_ctrl
[0].piwar1
&= ~PIWAR_EN
;
88 pci_ctrl
[0].pitar2
= 0x0;
89 pci_ctrl
[0].pibar2
= 0x0;
90 pci_ctrl
[0].piebar2
= 0x0;
91 pci_ctrl
[0].piwar2
&= ~PIWAR_EN
;
93 hose
[0].first_busno
= 0;
94 hose
[0].last_busno
= 0xff;
95 pci_setup_indirect(&hose
[0],
96 (CONFIG_SYS_IMMR
+ 0x8300), (CONFIG_SYS_IMMR
+ 0x8304));
99 pci_hose_read_config_word(&hose
[0], PCI_BDF(0, 0, 0),
100 PCI_COMMAND
, ®16
);
101 reg16
|= PCI_COMMAND_SERR
| PCI_COMMAND_MEMORY
;
102 pci_hose_write_config_word(&hose
[0], PCI_BDF(0, 0, 0),
106 * Clear non-reserved bits in status register.
108 pci_hose_write_config_word(&hose
[0], PCI_BDF(0, 0, 0),
110 pci_hose_write_config_byte(&hose
[0], PCI_BDF(0, 0, 0),
111 PCI_LATENCY_TIMER
, 0x80);
114 * Unlock configuration lock in PCI function configuration register.
116 pci_hose_read_config_word(&hose
[0], PCI_BDF(0, 0, 0),
117 PCI_FUNCTION_CONFIG
, ®16
);
118 reg16
&= ~(PCI_FUNCTION_CFG_LOCK
);
119 pci_hose_write_config_word(&hose
[0], PCI_BDF(0, 0, 0),
120 PCI_FUNCTION_CONFIG
, reg16
);
122 printf("Enabled PCI 32bit Agent Mode\n");
126 volatile immap_t
*immr
;
127 volatile clk83xx_t
*clk
;
128 volatile law83xx_t
*pci_law
;
129 volatile pot83xx_t
*pci_pot
;
130 volatile pcictrl83xx_t
*pci_ctrl
;
131 volatile pciconf83xx_t
*pci_conf
;
137 immr
= (immap_t
*) CONFIG_SYS_IMMR
;
138 clk
= (clk83xx_t
*) & immr
->clk
;
139 pci_law
= immr
->sysconf
.pcilaw
;
140 pci_pot
= immr
->ios
.pot
;
141 pci_ctrl
= immr
->pci_ctrl
;
142 pci_conf
= immr
->pci_conf
;
144 * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
149 clk
->occr
= OCCR_PCICOE0
| OCCR_PCICOE1
| OCCR_PCICOE2
;
150 printf("PCI clock is 66MHz\n");
151 #elif defined(PCI_33M)
152 clk
->occr
= OCCR_PCICOE0
| OCCR_PCICOE1
| OCCR_PCICOE2
|
153 OCCR_PCICD0
| OCCR_PCICD1
| OCCR_PCICD2
| OCCR_PCICR
;
154 printf("PCI clock is 33MHz\n");
156 clk
->occr
= OCCR_PCICOE0
| OCCR_PCICOE1
| OCCR_PCICOE2
;
157 printf("PCI clock is 66MHz\n");
162 * Configure PCI Local Access Windows
164 pci_law
[0].bar
= CONFIG_SYS_PCI_MEM_PHYS
& LAWBAR_BAR
;
165 pci_law
[0].ar
= LAWAR_EN
| LAWAR_SIZE_512M
;
167 pci_law
[1].bar
= CONFIG_SYS_PCI_IO_PHYS
& LAWBAR_BAR
;
168 pci_law
[1].ar
= LAWAR_EN
| LAWAR_SIZE_1M
;
171 * Configure PCI Outbound Translation Windows
174 /* PCI mem space - prefetch */
175 pci_pot
[0].potar
= (CONFIG_SYS_PCI_MEM_BASE
>> 12) & POTAR_TA_MASK
;
176 pci_pot
[0].pobar
= (CONFIG_SYS_PCI_MEM_PHYS
>> 12) & POBAR_BA_MASK
;
178 POCMR_EN
| POCMR_SE
| (POCMR_CM_256M
& POCMR_CM_MASK
);
180 /* PCI mmio - non-prefetch mem space */
181 pci_pot
[1].potar
= (CONFIG_SYS_PCI_MMIO_BASE
>> 12) & POTAR_TA_MASK
;
182 pci_pot
[1].pobar
= (CONFIG_SYS_PCI_MMIO_PHYS
>> 12) & POBAR_BA_MASK
;
183 pci_pot
[1].pocmr
= POCMR_EN
| (POCMR_CM_256M
& POCMR_CM_MASK
);
186 pci_pot
[2].potar
= (CONFIG_SYS_PCI_IO_BASE
>> 12) & POTAR_TA_MASK
;
187 pci_pot
[2].pobar
= (CONFIG_SYS_PCI_IO_PHYS
>> 12) & POBAR_BA_MASK
;
188 pci_pot
[2].pocmr
= POCMR_EN
| POCMR_IO
| (POCMR_CM_1M
& POCMR_CM_MASK
);
191 * Configure PCI Inbound Translation Windows
193 pci_ctrl
[0].pitar1
= (CONFIG_SYS_PCI_SLV_MEM_LOCAL
>> 12) & PITAR_TA_MASK
;
194 pci_ctrl
[0].pibar1
= (CONFIG_SYS_PCI_SLV_MEM_BUS
>> 12) & PIBAR_MASK
;
195 pci_ctrl
[0].piebar1
= 0x0;
197 PIWAR_EN
| PIWAR_PF
| PIWAR_RTT_SNOOP
| PIWAR_WTT_SNOOP
|
201 * Release PCI RST Output signal
207 hose
[0].first_busno
= 0;
208 hose
[0].last_busno
= 0xff;
210 /* PCI memory prefetch space */
211 pci_set_region(hose
[0].regions
+ 0,
212 CONFIG_SYS_PCI_MEM_BASE
,
213 CONFIG_SYS_PCI_MEM_PHYS
,
214 CONFIG_SYS_PCI_MEM_SIZE
, PCI_REGION_MEM
| PCI_REGION_PREFETCH
);
216 /* PCI memory space */
217 pci_set_region(hose
[0].regions
+ 1,
218 CONFIG_SYS_PCI_MMIO_BASE
,
219 CONFIG_SYS_PCI_MMIO_PHYS
, CONFIG_SYS_PCI_MMIO_SIZE
, PCI_REGION_MEM
);
222 pci_set_region(hose
[0].regions
+ 2,
223 CONFIG_SYS_PCI_IO_BASE
,
224 CONFIG_SYS_PCI_IO_PHYS
, CONFIG_SYS_PCI_IO_SIZE
, PCI_REGION_IO
);
226 /* System memory space */
227 pci_set_region(hose
[0].regions
+ 3,
228 CONFIG_SYS_PCI_SLV_MEM_LOCAL
,
229 CONFIG_SYS_PCI_SLV_MEM_BUS
,
230 CONFIG_SYS_PCI_SLV_MEM_SIZE
,
231 PCI_REGION_MEM
| PCI_REGION_SYS_MEMORY
);
233 hose
[0].region_count
= 4;
235 pci_setup_indirect(&hose
[0],
236 (CONFIG_SYS_IMMR
+ 0x8300), (CONFIG_SYS_IMMR
+ 0x8304));
238 pci_register_hose(hose
);
241 * Write command register
244 dev
= PCI_BDF(0, 0, 0);
245 pci_hose_read_config_word(&hose
[0], dev
, PCI_COMMAND
, ®16
);
246 reg16
|= PCI_COMMAND_SERR
| PCI_COMMAND_MASTER
| PCI_COMMAND_MEMORY
;
247 pci_hose_write_config_word(&hose
[0], dev
, PCI_COMMAND
, reg16
);
250 * Clear non-reserved bits in status register.
252 pci_hose_write_config_word(&hose
[0], dev
, PCI_STATUS
, 0xffff);
253 pci_hose_write_config_byte(&hose
[0], dev
, PCI_LATENCY_TIMER
, 0x80);
254 pci_hose_write_config_byte(&hose
[0], dev
, PCI_CACHE_LINE_SIZE
, 0x08);
259 hose
->last_busno
= pci_hose_scan(hose
);
261 #endif /* CONFIG_PCISLAVE */
263 #if defined(CONFIG_OF_LIBFDT)
264 void ft_pci_setup(void *blob
, bd_t
*bd
)
270 nodeoffset
= fdt_path_offset(blob
, "/aliases");
271 if (nodeoffset
>= 0) {
272 path
= fdt_getprop(blob
, nodeoffset
, "pci0", NULL
);
274 tmp
[0] = cpu_to_be32(hose
[0].first_busno
);
275 tmp
[1] = cpu_to_be32(hose
[0].last_busno
);
276 do_fixup_by_path(blob
, path
, "bus-range",
277 &tmp
, sizeof(tmp
), 1);
279 tmp
[0] = cpu_to_be32(gd
->pci_clk
);
280 do_fixup_by_path(blob
, path
, "clock-frequency",
281 &tmp
, sizeof(tmp
[0]), 1);
285 #endif /* CONFIG_OF_LIBFDT */
286 #endif /* CONFIG_PCI */