1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  Board device initialization		File: lausanne_pci.c
5    *
6    *  This is the part of the board support package for boards
7    *  that support PCI. It describes the board-specific slots/devices
8    *  and wiring thereof.
9    *
10    *********************************************************************
11    *
12    *  Copyright 2000,2001,2002,2003
13    *  Broadcom Corporation. All rights reserved.
14    *
15    *  This software is furnished under license and may be used and
16    *  copied only in accordance with the following terms and
17    *  conditions.  Subject to these conditions, you may download,
18    *  copy, install, use, modify and distribute modified or unmodified
19    *  copies of this software in source and/or binary form.  No title
20    *  or ownership is transferred hereby.
21    *
22    *  1) Any source code used, modified or distributed must reproduce
23    *     and retain this copyright notice and list of conditions
24    *     as they appear in the source file.
25    *
26    *  2) No right is granted to use any trade name, trademark, or
27    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
28    *     name may not be used to endorse or promote products derived
29    *     from this software without the prior written permission of
30    *     Broadcom Corporation.
31    *
32    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
33    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
34    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
35    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
36    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
37    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
38    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
40    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
42    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
43    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
44    *     THE POSSIBILITY OF SUCH DAMAGE.
45    ********************************************************************* */
46
47#include "lib_types.h"
48
49#include "pcireg.h"
50#include "pcivar.h"
51#include "pci_internal.h"
52
53/* PCI interrupt mapping on the Lausanne board:
54   Device ids 5, 6, 7 and 8 are implemented as PCI connectors,
55   and there are no on-board devices.
56
57   Slot    IDSEL   DevID  INT{A,B,C,D}   shift
58  (PHB)      -       0       {A,-,-,-}     0
59  (LHB)      -       1       not connected
60    0       16       5       {A,B,C,D}     0 (identity)
61    1       17       6       {B,C,D,A}     1 (A->B, B->C, C->D, D->A)
62    2       18       7       {C,D,A,B}     2 (A->C, B->D, C->A, D->B)
63    3       19       8       {D,A,B,C}     3 (A->D, B->A, C->B, D->C)
64
65   Device 1 is the LDT host bridge, which is disabled on this board.
66*/
67
68extern int _pciverbose;
69
70/* Return the base shift of a slot or device on the motherboard.
71   This is board specific, for the Lausanne only. */
72uint8_t
73pci_int_shift_0(pcitag_t tag)
74{
75    int bus, device;
76
77    pci_break_tag(tag, NULL, &bus, &device, NULL);
78
79    if (bus != 0)
80	return 0;
81    switch (device) {
82    case 0:
83	return 0;
84    case 5: case 6: case 7: case 8:
85        return ((device - 5) % 4);
86    default:
87	return 0;
88    }
89}
90
91/* Return the mapping of a Lausanne device/function interrupt to an
92   interrupt line.  For the SB-1250, return 1-4 to indicate the
93   pci_inta - pci_intd inputs to the interrupt mapper, respectively,
94   or 0 if there is no mapping.  This is board specific, and the
95   version below is for Lausanne only. */
96uint8_t
97pci_int_map_0(pcitag_t tag)
98{
99    pcireg_t data;
100    int pin, bus, device;
101
102    data = pci_conf_read(tag, PCI_BPARAM_INTERRUPT_REG);
103    pin = PCI_INTERRUPT_PIN(data);
104    if (pin == 0) {
105	/* No IRQ used. */
106	return 0;
107    }
108    if (pin > 4) {
109	if (_pciverbose >= 1)
110	    pci_tagprintf(tag, "pci_map_int: bad interrupt pin %d\n", pin);
111	return 0;
112    }
113
114    pci_break_tag(tag, NULL, &bus, &device, NULL);
115
116    if (bus != 0)
117	return 0;
118
119    switch (device) {
120    case 0:
121    case 5: case 6: case 7: case 8:
122        return (((pin - 1) + pci_int_shift_0(tag)) % 4) + 1;
123    default:
124        return 0;
125    }
126}
127