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_FLAT_TREE)
23 #elif defined(CONFIG_OF_LIBFDT)
27 #include <asm/fsl_i2c.h>
29 DECLARE_GLOBAL_DATA_PTR
;
31 #if defined(CONFIG_PCI)
32 #define PCI_FUNCTION_CONFIG 0x44
33 #define PCI_FUNCTION_CFG_LOCK 0x20
36 * Initialize PCI Devices, report devices found
38 #ifndef CONFIG_PCI_PNP
39 static struct pci_config_table pci_mpc83xxemds_config_table
[] = {
41 PCI_ANY_ID
, PCI_ANY_ID
, PCI_ANY_ID
, PCI_ANY_ID
,
42 pci_cfgfunc_config_device
,
45 PCI_COMMON_MEMORY
| PCI_COMMAND_MASTER
}
50 static struct pci_controller hose
[] = {
52 #ifndef CONFIG_PCI_PNP
53 config_table
:pci_mpc83xxemds_config_table
,
58 /**********************************************************************
60 *********************************************************************/
61 void pci_init_board(void)
62 #ifdef CONFIG_PCISLAVE
65 volatile immap_t
*immr
;
66 volatile law83xx_t
*pci_law
;
67 volatile pot83xx_t
*pci_pot
;
68 volatile pcictrl83xx_t
*pci_ctrl
;
69 volatile pciconf83xx_t
*pci_conf
;
71 immr
= (immap_t
*) CFG_IMMR
;
72 pci_law
= immr
->sysconf
.pcilaw
;
73 pci_pot
= immr
->ios
.pot
;
74 pci_ctrl
= immr
->pci_ctrl
;
75 pci_conf
= immr
->pci_conf
;
77 * Configure PCI Inbound Translation Windows
79 pci_ctrl
[0].pitar0
= 0x0;
80 pci_ctrl
[0].pibar0
= 0x0;
81 pci_ctrl
[0].piwar0
= PIWAR_EN
| PIWAR_RTT_SNOOP
|
82 PIWAR_WTT_SNOOP
| PIWAR_IWS_4K
;
84 pci_ctrl
[0].pitar1
= 0x0;
85 pci_ctrl
[0].pibar1
= 0x0;
86 pci_ctrl
[0].piebar1
= 0x0;
87 pci_ctrl
[0].piwar1
&= ~PIWAR_EN
;
89 pci_ctrl
[0].pitar2
= 0x0;
90 pci_ctrl
[0].pibar2
= 0x0;
91 pci_ctrl
[0].piebar2
= 0x0;
92 pci_ctrl
[0].piwar2
&= ~PIWAR_EN
;
94 hose
[0].first_busno
= 0;
95 hose
[0].last_busno
= 0xff;
96 pci_setup_indirect(&hose
[0],
97 (CFG_IMMR
+ 0x8300), (CFG_IMMR
+ 0x8304));
100 pci_hose_read_config_word(&hose
[0], PCI_BDF(0, 0, 0),
101 PCI_COMMAND
, ®16
);
102 reg16
|= PCI_COMMAND_SERR
| PCI_COMMAND_MEMORY
;
103 pci_hose_write_config_word(&hose
[0], PCI_BDF(0, 0, 0),
107 * Clear non-reserved bits in status register.
109 pci_hose_write_config_word(&hose
[0], PCI_BDF(0, 0, 0),
111 pci_hose_write_config_byte(&hose
[0], PCI_BDF(0, 0, 0),
112 PCI_LATENCY_TIMER
, 0x80);
115 * Unlock configuration lock in PCI function configuration register.
117 pci_hose_read_config_word(&hose
[0], PCI_BDF(0, 0, 0),
118 PCI_FUNCTION_CONFIG
, ®16
);
119 reg16
&= ~(PCI_FUNCTION_CFG_LOCK
);
120 pci_hose_write_config_word(&hose
[0], PCI_BDF(0, 0, 0),
121 PCI_FUNCTION_CONFIG
, reg16
);
123 printf("Enabled PCI 32bit Agent Mode\n");
127 volatile immap_t
*immr
;
128 volatile clk83xx_t
*clk
;
129 volatile law83xx_t
*pci_law
;
130 volatile pot83xx_t
*pci_pot
;
131 volatile pcictrl83xx_t
*pci_ctrl
;
132 volatile pciconf83xx_t
*pci_conf
;
138 immr
= (immap_t
*) CFG_IMMR
;
139 clk
= (clk83xx_t
*) & immr
->clk
;
140 pci_law
= immr
->sysconf
.pcilaw
;
141 pci_pot
= immr
->ios
.pot
;
142 pci_ctrl
= immr
->pci_ctrl
;
143 pci_conf
= immr
->pci_conf
;
145 * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
150 clk
->occr
= OCCR_PCICOE0
| OCCR_PCICOE1
| OCCR_PCICOE2
;
151 printf("PCI clock is 66MHz\n");
152 #elif defined(PCI_33M)
153 clk
->occr
= OCCR_PCICOE0
| OCCR_PCICOE1
| OCCR_PCICOE2
|
154 OCCR_PCICD0
| OCCR_PCICD1
| OCCR_PCICD2
| OCCR_PCICR
;
155 printf("PCI clock is 33MHz\n");
157 clk
->occr
= OCCR_PCICOE0
| OCCR_PCICOE1
| OCCR_PCICOE2
;
158 printf("PCI clock is 66MHz\n");
163 * Configure PCI Local Access Windows
165 pci_law
[0].bar
= CFG_PCI_MEM_PHYS
& LAWBAR_BAR
;
166 pci_law
[0].ar
= LAWAR_EN
| LAWAR_SIZE_512M
;
168 pci_law
[1].bar
= CFG_PCI_IO_PHYS
& LAWBAR_BAR
;
169 pci_law
[1].ar
= LAWAR_EN
| LAWAR_SIZE_1M
;
172 * Configure PCI Outbound Translation Windows
175 /* PCI mem space - prefetch */
176 pci_pot
[0].potar
= (CFG_PCI_MEM_BASE
>> 12) & POTAR_TA_MASK
;
177 pci_pot
[0].pobar
= (CFG_PCI_MEM_PHYS
>> 12) & POBAR_BA_MASK
;
179 POCMR_EN
| POCMR_SE
| (POCMR_CM_256M
& POCMR_CM_MASK
);
181 /* PCI mmio - non-prefetch mem space */
182 pci_pot
[1].potar
= (CFG_PCI_MMIO_BASE
>> 12) & POTAR_TA_MASK
;
183 pci_pot
[1].pobar
= (CFG_PCI_MMIO_PHYS
>> 12) & POBAR_BA_MASK
;
184 pci_pot
[1].pocmr
= POCMR_EN
| (POCMR_CM_256M
& POCMR_CM_MASK
);
187 pci_pot
[2].potar
= (CFG_PCI_IO_BASE
>> 12) & POTAR_TA_MASK
;
188 pci_pot
[2].pobar
= (CFG_PCI_IO_PHYS
>> 12) & POBAR_BA_MASK
;
189 pci_pot
[2].pocmr
= POCMR_EN
| POCMR_IO
| (POCMR_CM_1M
& POCMR_CM_MASK
);
192 * Configure PCI Inbound Translation Windows
194 pci_ctrl
[0].pitar1
= (CFG_PCI_SLV_MEM_LOCAL
>> 12) & PITAR_TA_MASK
;
195 pci_ctrl
[0].pibar1
= (CFG_PCI_SLV_MEM_BUS
>> 12) & PIBAR_MASK
;
196 pci_ctrl
[0].piebar1
= 0x0;
198 PIWAR_EN
| PIWAR_PF
| PIWAR_RTT_SNOOP
| PIWAR_WTT_SNOOP
|
202 * Release PCI RST Output signal
208 hose
[0].first_busno
= 0;
209 hose
[0].last_busno
= 0xff;
211 /* PCI memory prefetch space */
212 pci_set_region(hose
[0].regions
+ 0,
215 CFG_PCI_MEM_SIZE
, PCI_REGION_MEM
| PCI_REGION_PREFETCH
);
217 /* PCI memory space */
218 pci_set_region(hose
[0].regions
+ 1,
220 CFG_PCI_MMIO_PHYS
, CFG_PCI_MMIO_SIZE
, PCI_REGION_MEM
);
223 pci_set_region(hose
[0].regions
+ 2,
225 CFG_PCI_IO_PHYS
, CFG_PCI_IO_SIZE
, PCI_REGION_IO
);
227 /* System memory space */
228 pci_set_region(hose
[0].regions
+ 3,
229 CFG_PCI_SLV_MEM_LOCAL
,
231 CFG_PCI_SLV_MEM_SIZE
,
232 PCI_REGION_MEM
| PCI_REGION_MEMORY
);
234 hose
[0].region_count
= 4;
236 pci_setup_indirect(&hose
[0],
237 (CFG_IMMR
+ 0x8300), (CFG_IMMR
+ 0x8304));
239 pci_register_hose(hose
);
242 * Write command register
245 dev
= PCI_BDF(0, 0, 0);
246 pci_hose_read_config_word(&hose
[0], dev
, PCI_COMMAND
, ®16
);
247 reg16
|= PCI_COMMAND_SERR
| PCI_COMMAND_MASTER
| PCI_COMMAND_MEMORY
;
248 pci_hose_write_config_word(&hose
[0], dev
, PCI_COMMAND
, reg16
);
251 * Clear non-reserved bits in status register.
253 pci_hose_write_config_word(&hose
[0], dev
, PCI_STATUS
, 0xffff);
254 pci_hose_write_config_byte(&hose
[0], dev
, PCI_LATENCY_TIMER
, 0x80);
255 pci_hose_write_config_byte(&hose
[0], dev
, PCI_CACHE_LINE_SIZE
, 0x08);
260 hose
->last_busno
= pci_hose_scan(hose
);
262 #endif /* CONFIG_PCISLAVE */
264 #if defined(CONFIG_OF_LIBFDT)
266 ft_pci_setup(void *blob
, bd_t
*bd
)
272 nodeoffset
= fdt_path_offset(blob
, "/" OF_SOC
"/pci@8500");
273 if (nodeoffset
>= 0) {
274 tmp
[0] = cpu_to_be32(hose
[0].first_busno
);
275 tmp
[1] = cpu_to_be32(hose
[0].last_busno
);
276 err
= fdt_setprop(blob
, nodeoffset
, "bus-range",
279 tmp
[0] = cpu_to_be32(gd
->pci_clk
);
280 err
= fdt_setprop(blob
, nodeoffset
, "clock-frequency",
281 tmp
, sizeof(tmp
[0]));
284 #elif defined(CONFIG_OF_FLAT_TREE)
286 ft_pci_setup(void *blob
, bd_t
*bd
)
291 p
= (u32
*)ft_get_prop(blob
, "/" OF_SOC
"/pci@8500/bus-range", &len
);
293 p
[0] = hose
[0].first_busno
;
294 p
[1] = hose
[0].last_busno
;
297 #endif /* CONFIG_OF_FLAT_TREE */
298 #endif /* CONFIG_PCI */