]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/mips/idt/idtpci.c
As <machine/pmap.h> is included from <vm/pmap.h>, there is no need to
[FreeBSD/FreeBSD.git] / sys / mips / idt / idtpci.c
1 /* $NetBSD: idtpci.c,v 1.1 2007/03/20 08:52:02 dyoung Exp $ */
2
3 /*-
4  * Copyright (c) 2007 David Young.
5  * Copyright (c) 2007 Oleskandr Tymoshenko.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or
8  * without modification, are permitted provided that the following
9  * conditions are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above
13  *    copyright notice, this list of conditions and the following
14  *    disclaimer in the documentation and/or other materials provided
15  *    with the distribution.
16  * 3. The name of the author may not be used to endorse or promote
17  *    products derived from this software without specific prior
18  *    written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
21  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
25  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
27  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
29  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
31  * OF SUCH DAMAGE.
32  */
33 /*-
34  * Copyright (c) 2006 Itronix Inc.
35  * All rights reserved.
36  *
37  * Written by Garrett D'Amore for Itronix Inc.
38  *
39  * Redistribution and use in source and binary forms, with or without
40  * modification, are permitted provided that the following conditions
41  * are met:
42  * 1. Redistributions of source code must retain the above copyright
43  *    notice, this list of conditions and the following disclaimer.
44  * 2. Redistributions in binary form must reproduce the above copyright
45  *    notice, this list of conditions and the following disclaimer in the
46  *    documentation and/or other materials provided with the distribution.
47  * 3. The name of Itronix Inc. may not be used to endorse
48  *    or promote products derived from this software without specific
49  *    prior written permission.
50  *
51  * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
52  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
53  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
54  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
55  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
56  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
58  * ON ANY THEORY OF LIABILITY, WHETHER IN
59  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
60  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
61  * POSSIBILITY OF SUCH DAMAGE.
62  */ 
63
64 #include <sys/cdefs.h>
65 __FBSDID("$FreeBSD$");
66
67 #include <sys/param.h>
68 #include <sys/systm.h>
69
70 #include <sys/bus.h>
71 #include <sys/interrupt.h>
72 #include <sys/malloc.h>
73 #include <sys/kernel.h>
74 #include <sys/module.h>
75 #include <sys/rman.h>
76
77 #include <vm/vm.h>
78 #include <vm/pmap.h>
79 #include <vm/vm_extern.h>
80
81 #include <machine/bus.h>
82 #include <machine/cpu.h>
83
84 #include <dev/pci/pcivar.h>
85 #include <dev/pci/pcireg.h>
86
87 #include <dev/pci/pcib_private.h>
88 #include "pcib_if.h"
89
90 #include <mips/idt/idtreg.h>
91
92 #ifdef IDTPCI_DEBUG
93 int idtpci_debug = 1;
94 #define IDTPCI_DPRINTF(__fmt, ...)              \
95 do {                                            \
96         if (idtpci_debug)                       \
97                 printf((__fmt), __VA_ARGS__);   \
98 } while (/*CONSTCOND*/0)
99 #else /* !IDTPCI_DEBUG */
100 #define IDTPCI_DPRINTF(__fmt, ...)      do { } while (/*CONSTCOND*/0)
101 #endif /* IDTPCI_DEBUG */
102
103 #define IDTPCI_TAG_BUS_MASK             0x007f0000
104 #define IDTPCI_TAG_DEVICE_MASK          0x00007800
105 #define IDTPCI_TAG_FUNCTION_MASK        0x00000300
106 #define IDTPCI_TAG_REGISTER_MASK        0x0000007c
107
108 #define IDTPCI_MAX_DEVICE
109
110 #define REG_READ(o) *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1(IDT_BASE_PCI + (o)))
111 #define REG_WRITE(o,v) (REG_READ(o)) = (v)
112
113 unsigned int korina_fixup[24] = { 
114         0x00000157, 0x00000000, 0x00003c04, 0x00000008, 0x18800001, 0x18000001,
115         0x48000008, 0x00000000, 0x00000000, 0x00000000, 0x011d0214, 0x00000000,
116         0x00000000, 0x00000000, 0x38080101, 0x00008080, 0x00000d6e, 0x00000000,
117         0x00000051, 0x00000000, 0x00000055, 0x18000000, 0x00000000, 0x00000000 
118 };
119
120 struct idtpci_softc {
121         device_t                sc_dev;
122
123         int                     sc_busno;
124         struct rman             sc_mem_rman[2];
125         struct rman             sc_io_rman[2];
126         struct rman             sc_irq_rman;
127 };
128
129 static uint32_t
130 idtpci_make_addr(int bus, int slot, int func, int reg)
131 {
132
133         return 0x80000000 | (bus << 16) | (slot << 11) | (func << 8) | reg;
134 }
135
136 static int
137 idtpci_probe(device_t dev)
138 {
139
140         return (0);
141 }
142
143 static int
144 idtpci_attach(device_t dev)
145 {
146         int busno = 0;
147         struct idtpci_softc *sc = device_get_softc(dev);
148         unsigned int pci_data, force_endianess = 0;
149         int             i;
150         bus_addr_t      addr;
151
152         sc->sc_dev = dev;
153         sc->sc_busno = busno;
154
155         /* TODO: Check for host mode */
156
157         /* Enabled PCI, IG mode, EAP mode */
158         REG_WRITE(IDT_PCI_CNTL, IDT_PCI_CNTL_IGM | IDT_PCI_CNTL_EAP |
159             IDT_PCI_CNTL_EN);
160         /* Wait while "Reset in progress bit" set */
161         while(1) {
162                 pci_data = REG_READ(IDT_PCI_STATUS);
163                 if((pci_data & IDT_PCI_STATUS_RIP) == 0)
164                         break;
165         }
166
167         /* Reset status register */
168         REG_WRITE(IDT_PCI_STATUS, 0);
169         /* Mask interrupts related to status register */
170         REG_WRITE(IDT_PCI_STATUS_MASK, 0xffffffff);
171
172         /* Disable PCI decoupled access */
173         REG_WRITE(IDT_PCI_DAC, 0);
174         /* Zero status and mask DA interrupts */
175         REG_WRITE(IDT_PCI_DAS, 0);
176         REG_WRITE(IDT_PCI_DASM, 0x7f);
177
178         /* Init PCI messaging unit */
179         /* Disable messaging interrupts */
180         REG_WRITE(IDT_PCI_IIC, 0);
181         REG_WRITE(IDT_PCI_IIM, 0xffffffff);
182         REG_WRITE(IDT_PCI_OIC, 0);
183         REG_WRITE(IDT_PCI_OIM, 0);
184
185 #ifdef  __MIPSEB__
186         force_endianess = IDT_PCI_LBA_FE;
187 #endif
188
189         /* LBA0 -- memory window */
190         REG_WRITE(IDT_PCI_LBA0, IDT_PCIMEM0_BASE);
191         REG_WRITE(IDT_PCI_LBA0_MAP, IDT_PCIMEM0_BASE);
192         REG_WRITE(IDT_PCI_LBA0_CNTL, IDT_PCI_LBA_SIZE_16MB | force_endianess);
193         pci_data = REG_READ(IDT_PCI_LBA0_CNTL); 
194
195         /* LBA1 -- memory window */
196         REG_WRITE(IDT_PCI_LBA1, IDT_PCIMEM1_BASE);
197         REG_WRITE(IDT_PCI_LBA1_MAP, IDT_PCIMEM1_BASE);
198         REG_WRITE(IDT_PCI_LBA1_CNTL, IDT_PCI_LBA_SIZE_256MB | force_endianess);
199         pci_data = REG_READ(IDT_PCI_LBA1_CNTL); 
200
201         /* LBA2 -- IO window */
202         REG_WRITE(IDT_PCI_LBA2, IDT_PCIMEM2_BASE);
203         REG_WRITE(IDT_PCI_LBA2_MAP, IDT_PCIMEM2_BASE);
204         REG_WRITE(IDT_PCI_LBA2_CNTL, IDT_PCI_LBA_SIZE_4MB | IDT_PCI_LBA_MSI |
205             force_endianess);
206         pci_data = REG_READ(IDT_PCI_LBA2_CNTL); 
207
208         /* LBA3 -- IO window */
209         REG_WRITE(IDT_PCI_LBA3, IDT_PCIMEM3_BASE);
210         REG_WRITE(IDT_PCI_LBA3_MAP, IDT_PCIMEM3_BASE);
211         REG_WRITE(IDT_PCI_LBA3_CNTL, IDT_PCI_LBA_SIZE_1MB | IDT_PCI_LBA_MSI |
212             force_endianess);
213         pci_data = REG_READ(IDT_PCI_LBA3_CNTL); 
214
215
216         pci_data = REG_READ(IDT_PCI_CNTL) & ~IDT_PCI_CNTL_TNR; 
217         REG_WRITE(IDT_PCI_CNTL, pci_data);
218         pci_data = REG_READ(IDT_PCI_CNTL);
219
220         /* Rewrite Target Control register with default values */
221         REG_WRITE(IDT_PCI_TC, (IDT_PCI_TC_DTIMER << 8) | IDT_PCI_TC_RTIMER);
222
223         /* Perform Korina fixup */
224         addr = idtpci_make_addr(0, 0, 0, 4);
225         for (i = 0; i < 24; i++) {
226
227                 REG_WRITE(IDT_PCI_CFG_ADDR, addr);
228                 REG_WRITE(IDT_PCI_CFG_DATA, korina_fixup[i]);
229                 __asm__ volatile ("sync");
230
231                 REG_WRITE(IDT_PCI_CFG_ADDR, 0);
232                 REG_WRITE(IDT_PCI_CFG_DATA, 0);
233                 addr += 4;
234         }
235
236         /* Use KSEG1 to access IO ports for it is uncached */
237         sc->sc_io_rman[0].rm_type = RMAN_ARRAY;
238         sc->sc_io_rman[0].rm_descr = "IDTPCI I/O Ports window 1";
239         if (rman_init(&sc->sc_io_rman[0]) != 0 ||
240           rman_manage_region(&sc->sc_io_rman[0], 
241               IDT_PCIMEM2_BASE, IDT_PCIMEM2_BASE + IDT_PCIMEM2_SIZE - 1) != 0) {
242                 panic("idtpci_attach: failed to set up I/O rman");
243         }
244
245         sc->sc_io_rman[1].rm_type = RMAN_ARRAY;
246         sc->sc_io_rman[1].rm_descr = "IDTPCI I/O Ports window 2";
247         if (rman_init(&sc->sc_io_rman[1]) != 0 ||
248           rman_manage_region(&sc->sc_io_rman[1], 
249               IDT_PCIMEM3_BASE, IDT_PCIMEM3_BASE + IDT_PCIMEM3_SIZE - 1) != 0) {
250                 panic("idtpci_attach: failed to set up I/O rman");
251         }
252
253         /* Use KSEG1 to access PCI memory for it is uncached */
254         sc->sc_mem_rman[0].rm_type = RMAN_ARRAY;
255         sc->sc_mem_rman[0].rm_descr = "IDTPCI PCI Memory window 1";
256         if (rman_init(&sc->sc_mem_rman[0]) != 0 ||
257             rman_manage_region(&sc->sc_mem_rman[0], 
258             IDT_PCIMEM0_BASE, IDT_PCIMEM0_BASE + IDT_PCIMEM0_SIZE) != 0) {
259                 panic("idtpci_attach: failed to set up memory rman");
260         }
261
262         sc->sc_mem_rman[1].rm_type = RMAN_ARRAY;
263         sc->sc_mem_rman[1].rm_descr = "IDTPCI PCI Memory window 2";
264         if (rman_init(&sc->sc_mem_rman[1]) != 0 ||
265             rman_manage_region(&sc->sc_mem_rman[1], 
266             IDT_PCIMEM1_BASE, IDT_PCIMEM1_BASE + IDT_PCIMEM1_SIZE) != 0) {
267                 panic("idtpci_attach: failed to set up memory rman");
268         }
269
270         sc->sc_irq_rman.rm_type = RMAN_ARRAY;
271         sc->sc_irq_rman.rm_descr = "IDTPCI PCI IRQs";
272         if (rman_init(&sc->sc_irq_rman) != 0 ||
273             rman_manage_region(&sc->sc_irq_rman, PCI_IRQ_BASE, 
274                 PCI_IRQ_END) != 0)
275                 panic("idtpci_attach: failed to set up IRQ rman");
276
277         device_add_child(dev, "pci", -1);
278         return (bus_generic_attach(dev));
279 }
280
281 static int
282 idtpci_maxslots(device_t dev)
283 {
284
285         return (PCI_SLOTMAX);
286 }
287
288 static uint32_t
289 idtpci_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
290     int bytes)
291 {
292         uint32_t data;
293         uint32_t shift, mask;
294         bus_addr_t addr;
295
296         IDTPCI_DPRINTF("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, 
297                         bus, slot, func, reg, bytes);
298
299         addr = idtpci_make_addr(bus, slot, func, reg);
300
301         REG_WRITE(IDT_PCI_CFG_ADDR, addr);
302         data = REG_READ(IDT_PCI_CFG_DATA);
303
304         switch (reg % 4) {
305         case 3:
306                 shift = 24;
307                 break;
308         case 2:
309                 shift = 16;
310                 break;
311         case 1:
312                 shift = 8;
313                 break;
314         default:
315                 shift = 0;
316                 break;
317         }       
318
319         switch (bytes) {
320         case 1:
321                 mask = 0xff;
322                 data = (data >> shift) & mask;
323                 break;
324         case 2:
325                 mask = 0xffff;
326                 if (reg % 4 == 0)
327                         data = data & mask;
328                 else
329                         data = (data >> 16) & mask;
330                 break;
331         case 4:
332                 break;
333         default:
334                 panic("%s: wrong bytes count", __func__);
335                 break;
336         }
337
338         __asm__ volatile ("sync");
339         IDTPCI_DPRINTF("%s: read 0x%x\n", __func__, data);
340
341         return (data);
342 }
343
344 static void
345 idtpci_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
346     uint32_t data, int bytes)
347 {
348         bus_addr_t addr;
349         uint32_t reg_data;
350         uint32_t shift, mask;
351
352         IDTPCI_DPRINTF("%s: tag (%x, %x, %x) reg %d(%d) data %08x\n", __func__, 
353                         bus, slot, func, reg, bytes, data);
354
355         if (bytes != 4) {
356                 reg_data = idtpci_read_config(dev, bus, slot, func, reg, 4);
357
358                 switch (reg % 4) {
359                 case 3:
360                         shift = 24;
361                         break;
362                 case 2:
363                         shift = 16;
364                         break;
365                 case 1:
366                         shift = 8;
367                         break;
368                 default:
369                         shift = 0;
370                         break;
371                 }       
372
373                 switch (bytes) {
374                 case 1:
375                         mask = 0xff;
376                         data = (reg_data & ~ (mask << shift)) | (data << shift);
377                         break;
378                 case 2:
379                         mask = 0xffff;
380                         if (reg % 4 == 0)
381                                 data = (reg_data & ~mask) | data;
382                         else
383                                 data = (reg_data & ~ (mask << shift)) | 
384                                     (data << shift);
385                         break;
386                 case 4:
387                         break;
388                 default:
389                         panic("%s: wrong bytes count", __func__);
390                         break;
391                 }
392         }
393
394         addr = idtpci_make_addr(bus, slot, func, reg);
395
396
397         REG_WRITE(IDT_PCI_CFG_ADDR, addr);
398         REG_WRITE(IDT_PCI_CFG_DATA, data);
399         __asm__ volatile ("sync");
400
401         REG_WRITE(IDT_PCI_CFG_ADDR, 0);
402         REG_WRITE(IDT_PCI_CFG_DATA, 0);
403 }
404
405 static int
406 idtpci_route_interrupt(device_t pcib, device_t device, int pin)
407 {
408         static int idt_pci_table[2][12] =
409         {
410                 { 0, 0, 2, 3, 2, 3, 0, 0, 0, 0, 0, 1 },
411                 { 0, 0, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3 }
412         };
413         int dev, bus, irq;
414         
415         dev = pci_get_slot(device);
416         bus = pci_get_bus(device);
417         if (bootverbose)
418                 device_printf(pcib, "routing pin %d for %s\n", pin,
419                     device_get_nameunit(device));
420         if (bus >= 0 && bus <= 1 &&
421             dev >= 0 && dev <= 11) {
422                 irq = IP_IRQ(6, idt_pci_table[bus][dev] + 4);
423                 if (bootverbose)
424                         printf("idtpci: %d/%d/%d -> IRQ%d\n",
425                             pci_get_bus(device), dev, pci_get_function(device),
426                             irq);
427                 return (irq);
428         } else
429                 printf("idtpci: no mapping for %d/%d/%d\n",
430                         pci_get_bus(device), dev, pci_get_function(device));
431
432         return (-1);
433 }
434
435 static int
436 idtpci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
437 {
438         struct idtpci_softc *sc = device_get_softc(dev);
439
440         switch (which) {
441         case PCIB_IVAR_DOMAIN:
442                 *result = 0;
443                 return (0);
444         case PCIB_IVAR_BUS:
445                 *result = sc->sc_busno;
446                 return (0);
447         }
448
449         return (ENOENT);
450 }
451
452 static int
453 idtpci_write_ivar(device_t dev, device_t child, int which, uintptr_t result)
454 {
455         struct idtpci_softc * sc = device_get_softc(dev);
456
457         switch (which) {
458         case PCIB_IVAR_BUS:
459                 sc->sc_busno = result;
460                 return (0);
461         }
462         return (ENOENT);
463 }
464
465 static struct resource *
466 idtpci_alloc_resource(device_t bus, device_t child, int type, int *rid,
467     rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
468 {
469
470         struct idtpci_softc *sc = device_get_softc(bus);        
471         struct resource *rv = NULL;
472         struct rman *rm1, *rm2;
473
474         switch (type) {
475         case SYS_RES_IRQ:
476                 rm1 = &sc->sc_irq_rman;
477                 rm2 = NULL;
478                 break;
479         case SYS_RES_MEMORY:
480                 rm1 = &sc->sc_mem_rman[0];
481                 rm2 = &sc->sc_mem_rman[1];
482                 break;
483         case SYS_RES_IOPORT:
484                 rm1 = &sc->sc_io_rman[0];
485                 rm2 = &sc->sc_io_rman[1];
486                 break;
487         default:
488                 return (NULL);
489         }
490
491         rv = rman_reserve_resource(rm1, start, end, count, flags, child);
492
493         /* Try second window if it exists */
494         if ((rv == NULL) && (rm2 != NULL))
495                 rv = rman_reserve_resource(rm2, start, end, count, flags, 
496                     child);
497
498         if (rv == NULL)
499                 return (NULL);
500
501         rman_set_rid(rv, *rid);
502
503         if (flags & RF_ACTIVE) {
504                 if (bus_activate_resource(child, type, *rid, rv)) {
505                         rman_release_resource(rv);
506                         return (NULL);
507                 }
508         } 
509
510         return (rv);
511 }
512
513 static int
514 idtpci_teardown_intr(device_t dev, device_t child, struct resource *res,
515     void *cookie)
516 {
517
518         return (intr_event_remove_handler(cookie));
519 }
520
521 static device_method_t idtpci_methods[] = {
522         /* Device interface */
523         DEVMETHOD(device_probe,         idtpci_probe),
524         DEVMETHOD(device_attach,        idtpci_attach),
525         DEVMETHOD(device_shutdown,      bus_generic_shutdown),
526         DEVMETHOD(device_suspend,       bus_generic_suspend),
527         DEVMETHOD(device_resume,        bus_generic_resume),
528
529         /* Bus interface */
530         DEVMETHOD(bus_read_ivar,        idtpci_read_ivar),
531         DEVMETHOD(bus_write_ivar,       idtpci_write_ivar),
532         DEVMETHOD(bus_alloc_resource,   idtpci_alloc_resource),
533         DEVMETHOD(bus_release_resource, bus_generic_release_resource),
534         DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
535         DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
536         DEVMETHOD(bus_setup_intr,       bus_generic_setup_intr),
537         DEVMETHOD(bus_teardown_intr,    idtpci_teardown_intr),
538
539         /* pcib interface */
540         DEVMETHOD(pcib_maxslots,        idtpci_maxslots),
541         DEVMETHOD(pcib_read_config,     idtpci_read_config),
542         DEVMETHOD(pcib_write_config,    idtpci_write_config),
543         DEVMETHOD(pcib_route_interrupt, idtpci_route_interrupt),
544
545         DEVMETHOD_END
546 };
547
548 static driver_t idtpci_driver = {
549         "pcib",
550         idtpci_methods,
551         sizeof(struct idtpci_softc),
552 };
553
554 static devclass_t idtpci_devclass;
555
556 DRIVER_MODULE(idtpci, obio, idtpci_driver, idtpci_devclass, 0, 0);