]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/mips/rm7000/ocelot/v2_0/src/plf_misc.c
Initial revision
[karo-tx-redboot.git] / packages / hal / mips / rm7000 / ocelot / v2_0 / src / plf_misc.c
1 //==========================================================================
2 //
3 //      plf_misc.c
4 //
5 //      HAL platform miscellaneous functions
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):    jskov
44 // Contributors: jskov
45 // Date:         2000-11-30
46 // Purpose:      HAL miscellaneous functions
47 // Description:  This file contains miscellaneous functions provided by the
48 //               HAL.
49 //
50 //####DESCRIPTIONEND####
51 //
52 //==========================================================================
53
54 #include <pkgconf/hal.h>
55
56 #include <cyg/infra/cyg_type.h>         // Base types
57
58 #include <cyg/hal/hal_arch.h>           // architectural definitions
59 #include <cyg/hal/hal_intr.h>           // Interrupt handling
60
61 #include <cyg/hal/hal_if.h>             // Calling interface definitions
62
63 #if defined(CYGPKG_IO_PCI)
64 #include <cyg/io/pci_hw.h>
65 #include <cyg/io/pci.h>
66 #endif
67
68 //--------------------------------------------------------------------------
69
70 void hal_platform_init(void)
71 {
72     hal_if_init();
73
74     // FIXME: Set up Galileo interrupt controller?
75
76     // Unmask vectors which are entry points for interrupt controllers
77 //    HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_21555);
78 //    HAL_INTERRUPT_UNMASK(CYGNUM_HAL_INTERRUPT_GALILEO);
79 }
80
81 //--------------------------------------------------------------------------
82 // PCI support
83 #if defined(CYGPKG_IO_PCI)
84
85 static int __check_bar(cyg_uint32 addr, cyg_uint32 size)
86 {
87     int n;
88
89     for (n = 0; n <= 31; n++)
90         if (size == (1 << n)) {
91             /* Check that address is naturally aligned */
92             if (addr != (addr & ~(size-1)))
93                 return 0;
94             return size - 1;
95         }
96     return 0;
97 }
98
99
100 // One-time PCI initialization.
101
102 void cyg_hal_plf_pci_init(void)
103 {
104     cyg_uint32 bar_ena, start10, start32, end, size;
105     cyg_uint8  next_bus;
106
107     // Program PCI window in CPU address space and CPU->PCI remap
108     HAL_GALILEO_PUTREG(HAL_GALILEO_PCIMEM0_LD_OFFSET, 
109                        HAL_OCELOT_PCI_MEM0_BASE >> HAL_GALILEO_CPU_DECODE_SHIFT);
110     HAL_GALILEO_PUTREG(HAL_GALILEO_PCIMEM0_HD_OFFSET, 
111                        (HAL_OCELOT_PCI_MEM0_BASE+HAL_OCELOT_PCI_MEM0_SIZE-1) >> HAL_GALILEO_CPU_DECODE_SHIFT);
112
113     HAL_GALILEO_PUTREG(HAL_GALILEO_PCIMEM1_LD_OFFSET, 
114                        HAL_OCELOT_PCI_MEM1_BASE >> HAL_GALILEO_CPU_DECODE_SHIFT);
115     HAL_GALILEO_PUTREG(HAL_GALILEO_PCIMEM1_HD_OFFSET, 
116                        (HAL_OCELOT_PCI_MEM1_BASE+HAL_OCELOT_PCI_MEM1_SIZE-1) >> HAL_GALILEO_CPU_DECODE_SHIFT);
117
118     HAL_GALILEO_PUTREG(HAL_GALILEO_PCIIO_LD_OFFSET, 
119                        HAL_OCELOT_PCI_IO_BASE >> HAL_GALILEO_CPU_DECODE_SHIFT);
120     HAL_GALILEO_PUTREG(HAL_GALILEO_PCIIO_HD_OFFSET, 
121                        (HAL_OCELOT_PCI_IO_BASE+HAL_OCELOT_PCI_IO_SIZE-1) >> HAL_GALILEO_CPU_DECODE_SHIFT);
122
123     // Setup for bus mastering
124     cyg_hal_plf_pci_cfg_write_dword(0, CYG_PCI_DEV_MAKE_DEVFN(0,0),
125                                     CYG_PCI_CFG_COMMAND,
126                                     CYG_PCI_CFG_COMMAND_IO |
127                                     CYG_PCI_CFG_COMMAND_MEMORY |
128                                     CYG_PCI_CFG_COMMAND_MASTER |
129                                     CYG_PCI_CFG_COMMAND_PARITY |
130                                     CYG_PCI_CFG_COMMAND_SERR);
131
132     // Setup latency timer field
133     cyg_hal_plf_pci_cfg_write_byte(0, CYG_PCI_DEV_MAKE_DEVFN(0,0),
134                                    CYG_PCI_CFG_LATENCY_TIMER, 6);
135
136     // Disable all BARs
137     bar_ena = 0x1ff;
138
139     // Allow PCI bus to access local memory
140     // Check for active SCS10
141     start10 = HAL_GALILEO_GETREG(HAL_GALILEO_SCS10_LD_OFFSET) << HAL_GALILEO_CPU_DECODE_SHIFT;
142     end   = ((HAL_GALILEO_GETREG(HAL_GALILEO_SCS10_HD_OFFSET) & 0x7f) + 1) << HAL_GALILEO_CPU_DECODE_SHIFT;
143     if (end > start10) {
144         if ((size = __check_bar(start10, end - start10)) != 0) {
145             // Enable BAR
146             HAL_GALILEO_PUTREG(HAL_GALILEO_PCI0_SCS10_SIZE_OFFSET, size);
147             bar_ena &= ~HAL_GALILEO_BAR_ENA_SCS10;
148         }
149     }
150
151     // Check for active SCS32
152     start32 = HAL_GALILEO_GETREG(HAL_GALILEO_SCS32_LD_OFFSET) << HAL_GALILEO_CPU_DECODE_SHIFT;
153     end   = ((HAL_GALILEO_GETREG(HAL_GALILEO_SCS32_HD_OFFSET) & 0x7f) + 1) << HAL_GALILEO_CPU_DECODE_SHIFT;
154     if (end > start32) {
155         if ((size = __check_bar(start32, end - start32)) != 0) {
156             // Enable BAR
157             HAL_GALILEO_PUTREG(HAL_GALILEO_PCI0_SCS32_SIZE_OFFSET, size);
158             bar_ena &= ~HAL_GALILEO_BAR_ENA_SCS32;
159         }
160     }
161
162     bar_ena &= ~HAL_GALILEO_BAR_ENA_SCS10;
163
164     HAL_GALILEO_PUTREG(HAL_GALILEO_BAR_ENA_OFFSET, bar_ena);
165
166     cyg_hal_plf_pci_cfg_write_dword(0, CYG_PCI_DEV_MAKE_DEVFN(0,0),
167                                     CYG_PCI_CFG_BAR_0, 0xffffffff);
168
169     end = cyg_hal_plf_pci_cfg_read_dword(0, CYG_PCI_DEV_MAKE_DEVFN(0,0),
170                                          CYG_PCI_CFG_BAR_0);
171         
172     cyg_hal_plf_pci_cfg_write_dword(0, CYG_PCI_DEV_MAKE_DEVFN(0,0),
173                                     CYG_PCI_CFG_BAR_0, start10);
174
175
176     cyg_hal_plf_pci_cfg_write_dword(0, CYG_PCI_DEV_MAKE_DEVFN(0,0),
177                                     CYG_PCI_CFG_BAR_1, 0xffffffff);
178
179     end = cyg_hal_plf_pci_cfg_read_dword(0, CYG_PCI_DEV_MAKE_DEVFN(0,0),
180                                          CYG_PCI_CFG_BAR_1);
181
182     cyg_hal_plf_pci_cfg_write_dword(0, CYG_PCI_DEV_MAKE_DEVFN(0,0),
183                                     CYG_PCI_CFG_BAR_1, start32);
184
185     // Configure PCI bus.
186     next_bus = 1;
187     cyg_pci_configure_bus(0, &next_bus);
188 }
189
190
191 // Check for configuration error.
192 static int pci_config_errcheck(void)
193 {
194     cyg_uint32  irq;
195
196     // Check for master or target abort
197     irq = HAL_GALILEO_GETREG(HAL_GALILEO_IRQ_CAUSE_OFFSET);
198
199     if (irq & (HAL_GALILEO_IRQCAUSE_MASABT | HAL_GALILEO_IRQCAUSE_TARABT)) {
200         // Error. Clear bits.
201         HAL_GALILEO_PUTREG(HAL_GALILEO_IRQ_CAUSE_OFFSET,
202                            ~(HAL_GALILEO_IRQCAUSE_MASABT | HAL_GALILEO_IRQCAUSE_TARABT));
203         return 1;
204     }
205     return 0;
206 }
207
208 cyg_uint32 cyg_hal_plf_pci_cfg_read_dword (cyg_uint32 bus,
209                                            cyg_uint32 devfn,
210                                            cyg_uint32 offset)
211 {
212     cyg_uint32 config_dword;
213
214     HAL_GALILEO_PUTREG(HAL_GALILEO_PCI0_CONFIG_ADDR_OFFSET,
215                        HAL_GALILEO_PCI0_CONFIG_ADDR_ENABLE |
216                        (bus << 16) | (devfn << 8) | offset);
217
218     HAL_GALILEO_GETPCI(bus, devfn,
219                        HAL_GALILEO_PCI0_CONFIG_DATA_OFFSET, config_dword);
220
221     if (pci_config_errcheck())
222         return 0xffffffff;
223     return config_dword;
224 }
225
226 cyg_uint16 cyg_hal_plf_pci_cfg_read_word (cyg_uint32 bus,
227                                           cyg_uint32 devfn,
228                                           cyg_uint32 offset)
229 {
230     cyg_uint32 config_dword;
231     cyg_uint16 config_word;
232
233     HAL_GALILEO_PUTREG(HAL_GALILEO_PCI0_CONFIG_ADDR_OFFSET,
234                        HAL_GALILEO_PCI0_CONFIG_ADDR_ENABLE |
235                        (bus << 16) | (devfn << 8) | (offset & ~3));
236
237     HAL_GALILEO_GETPCI(bus, devfn,
238                        HAL_GALILEO_PCI0_CONFIG_DATA_OFFSET, config_dword);
239     config_word = (cyg_uint16)((config_dword >> ((offset & 3) * 8)) & 0xffff);
240
241     if (pci_config_errcheck())
242         return 0xffff;
243
244     return config_word;
245 }
246
247 cyg_uint8 cyg_hal_plf_pci_cfg_read_byte (cyg_uint32 bus,
248                                          cyg_uint32 devfn,
249                                          cyg_uint32 offset)
250 {
251     cyg_uint32 config_dword;
252     cyg_uint8 config_byte;
253
254     HAL_GALILEO_PUTREG(HAL_GALILEO_PCI0_CONFIG_ADDR_OFFSET,
255                        HAL_GALILEO_PCI0_CONFIG_ADDR_ENABLE |
256                        (bus << 16) | (devfn << 8) | (offset & ~3));
257
258     HAL_GALILEO_GETPCI(bus, devfn,
259                        HAL_GALILEO_PCI0_CONFIG_DATA_OFFSET, config_dword);
260     config_byte = (cyg_uint8)((config_dword >> ((offset & 3) * 8)) & 0xff);
261
262     if (pci_config_errcheck())
263         return 0xff;
264
265     return config_byte;
266 }
267
268 void cyg_hal_plf_pci_cfg_write_dword (cyg_uint32 bus,
269                                       cyg_uint32 devfn,
270                                       cyg_uint32 offset,
271                                       cyg_uint32 data)
272 {
273     HAL_GALILEO_PUTREG(HAL_GALILEO_PCI0_CONFIG_ADDR_OFFSET,
274                        HAL_GALILEO_PCI0_CONFIG_ADDR_ENABLE |
275                        (bus << 16) | (devfn << 8) | offset);
276
277     HAL_GALILEO_PUTPCI(bus, devfn,
278                        HAL_GALILEO_PCI0_CONFIG_DATA_OFFSET, data);
279
280     (void)pci_config_errcheck();
281 }
282
283 void cyg_hal_plf_pci_cfg_write_word (cyg_uint32 bus,
284                                      cyg_uint32 devfn,
285                                      cyg_uint32 offset,
286                                      cyg_uint16 data)
287 {
288     cyg_uint32 config_dword, shift;
289
290     HAL_GALILEO_PUTREG(HAL_GALILEO_PCI0_CONFIG_ADDR_OFFSET,
291                        HAL_GALILEO_PCI0_CONFIG_ADDR_ENABLE |
292                        (bus << 16) | (devfn << 8) | (offset & ~3));
293
294
295     HAL_GALILEO_GETPCI(bus, devfn,
296                        HAL_GALILEO_PCI0_CONFIG_DATA_OFFSET, config_dword);
297     if (pci_config_errcheck())
298         return;
299
300     shift = (offset & 3) * 8;
301     config_dword &= ~(0xffff << shift);
302     config_dword |= (data << shift);
303
304     HAL_GALILEO_PUTPCI(bus, devfn,
305                        HAL_GALILEO_PCI0_CONFIG_DATA_OFFSET, config_dword);
306
307     (void)pci_config_errcheck();
308 }
309
310 void cyg_hal_plf_pci_cfg_write_byte (cyg_uint32 bus,
311                                      cyg_uint32 devfn,
312                                      cyg_uint32 offset,
313                                      cyg_uint8  data)
314 {
315     cyg_uint32 config_dword, shift;
316
317     HAL_GALILEO_PUTREG(HAL_GALILEO_PCI0_CONFIG_ADDR_OFFSET,
318                        HAL_GALILEO_PCI0_CONFIG_ADDR_ENABLE |
319                        (bus << 16) | (devfn << 8) | (offset & ~3));
320
321     HAL_GALILEO_GETPCI(bus, devfn,
322                        HAL_GALILEO_PCI0_CONFIG_DATA_OFFSET, config_dword);
323     if (pci_config_errcheck())
324         return;
325
326     shift = (offset & 3) * 8;
327     config_dword &= ~(0xff << shift);
328     config_dword |= (data << shift);
329
330     HAL_GALILEO_PUTPCI(bus, devfn,
331                        HAL_GALILEO_PCI0_CONFIG_DATA_OFFSET, config_dword);
332
333     (void)pci_config_errcheck();
334 }
335
336 #endif // CYGPKG_IO_PCI
337
338 //--------------------------------------------------------------------------
339 // End of plf_misc.c