Merge ../linus
[pandora-kernel.git] / drivers / pci / msi.h
1 /*
2  * Copyright (C) 2003-2004 Intel
3  * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com)
4  */
5
6 #ifndef MSI_H
7 #define MSI_H
8
9 /*
10  * MSI operation vector.  Used by the msi core code (drivers/pci/msi.c)
11  * to abstract platform-specific tasks relating to MSI address generation
12  * and resource management.
13  */
14 struct msi_ops {
15         /**
16          * setup - generate an MSI bus address and data for a given vector
17          * @pdev: PCI device context (in)
18          * @vector: vector allocated by the msi core (in)
19          * @addr_hi: upper 32 bits of PCI bus MSI address (out)
20          * @addr_lo: lower 32 bits of PCI bus MSI address (out)
21          * @data: MSI data payload (out)
22          *
23          * Description: The setup op is used to generate a PCI bus addres and
24          * data which the msi core will program into the card MSI capability
25          * registers.  The setup routine is responsible for picking an initial
26          * cpu to target the MSI at.  The setup routine is responsible for
27          * examining pdev to determine the MSI capabilities of the card and
28          * generating a suitable address/data.  The setup routine is
29          * responsible for allocating and tracking any system resources it
30          * needs to route the MSI to the cpu it picks, and for associating
31          * those resources with the passed in vector.
32          *
33          * Returns 0 if the MSI address/data was successfully setup.
34          **/
35
36         int     (*setup)    (struct pci_dev *pdev, unsigned int vector,
37                              u32 *addr_hi, u32 *addr_lo, u32 *data);
38
39         /**
40          * teardown - release resources allocated by setup
41          * @vector: vector context for resources (in)
42          *
43          * Description:  The teardown op is used to release any resources
44          * that were allocated in the setup routine associated with the passed
45          * in vector.
46          **/
47
48         void    (*teardown) (unsigned int vector);
49
50         /**
51          * target - retarget an MSI at a different cpu
52          * @vector: vector context for resources (in)
53          * @cpu:  new cpu to direct vector at (in)
54          * @addr_hi: new value of PCI bus upper 32 bits (in/out)
55          * @addr_lo: new value of PCI bus lower 32 bits (in/out)
56          *
57          * Description:  The target op is used to redirect an MSI vector
58          * at a different cpu.  addr_hi/addr_lo coming in are the existing
59          * values that the MSI core has programmed into the card.  The
60          * target code is responsible for freeing any resources (if any)
61          * associated with the old address, and generating a new PCI bus
62          * addr_hi/addr_lo that will redirect the vector at the indicated cpu.
63          **/
64
65         void    (*target)   (unsigned int vector, unsigned int cpu,
66                              u32 *addr_hi, u32 *addr_lo);
67 };
68
69 extern int msi_register(struct msi_ops *ops);
70
71 #include <asm/msi.h>
72
73 /*
74  * Assume the maximum number of hot plug slots supported by the system is about
75  * ten. The worstcase is that each of these slots is hot-added with a device,
76  * which has two MSI/MSI-X capable functions. To avoid any MSI-X driver, which
77  * attempts to request all available vectors, NR_HP_RESERVED_VECTORS is defined
78  * as below to ensure at least one message is assigned to each detected MSI/
79  * MSI-X device function.
80  */
81 #define NR_HP_RESERVED_VECTORS  20
82
83 extern int vector_irq[NR_VECTORS];
84 extern void (*interrupt[NR_IRQS])(void);
85 extern int pci_vector_resources(int last, int nr_released);
86
87 /*
88  * MSI-X Address Register
89  */
90 #define PCI_MSIX_FLAGS_QSIZE            0x7FF
91 #define PCI_MSIX_FLAGS_ENABLE           (1 << 15)
92 #define PCI_MSIX_FLAGS_BIRMASK          (7 << 0)
93 #define PCI_MSIX_FLAGS_BITMASK          (1 << 0)
94
95 #define PCI_MSIX_ENTRY_SIZE                     16
96 #define  PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET       0
97 #define  PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET       4
98 #define  PCI_MSIX_ENTRY_DATA_OFFSET             8
99 #define  PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET      12
100
101 #define msi_control_reg(base)           (base + PCI_MSI_FLAGS)
102 #define msi_lower_address_reg(base)     (base + PCI_MSI_ADDRESS_LO)
103 #define msi_upper_address_reg(base)     (base + PCI_MSI_ADDRESS_HI)
104 #define msi_data_reg(base, is64bit)     \
105         ( (is64bit == 1) ? base+PCI_MSI_DATA_64 : base+PCI_MSI_DATA_32 )
106 #define msi_mask_bits_reg(base, is64bit) \
107         ( (is64bit == 1) ? base+PCI_MSI_MASK_BIT : base+PCI_MSI_MASK_BIT-4)
108 #define msi_disable(control)            control &= ~PCI_MSI_FLAGS_ENABLE
109 #define multi_msi_capable(control) \
110         (1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1))
111 #define multi_msi_enable(control, num) \
112         control |= (((num >> 1) << 4) & PCI_MSI_FLAGS_QSIZE);
113 #define is_64bit_address(control)       (control & PCI_MSI_FLAGS_64BIT)
114 #define is_mask_bit_support(control)    (control & PCI_MSI_FLAGS_MASKBIT)
115 #define msi_enable(control, num) multi_msi_enable(control, num); \
116         control |= PCI_MSI_FLAGS_ENABLE
117
118 #define msix_table_offset_reg(base)     (base + 0x04)
119 #define msix_pba_offset_reg(base)       (base + 0x08)
120 #define msix_enable(control)            control |= PCI_MSIX_FLAGS_ENABLE
121 #define msix_disable(control)           control &= ~PCI_MSIX_FLAGS_ENABLE
122 #define msix_table_size(control)        ((control & PCI_MSIX_FLAGS_QSIZE)+1)
123 #define multi_msix_capable              msix_table_size
124 #define msix_unmask(address)            (address & ~PCI_MSIX_FLAGS_BITMASK)
125 #define msix_mask(address)              (address | PCI_MSIX_FLAGS_BITMASK)
126 #define msix_is_pending(address)        (address & PCI_MSIX_FLAGS_PENDMASK)
127
128 struct msi_desc {
129         struct {
130                 __u8    type    : 5;    /* {0: unused, 5h:MSI, 11h:MSI-X} */
131                 __u8    maskbit : 1;    /* mask-pending bit supported ?   */
132                 __u8    state   : 1;    /* {0: free, 1: busy}             */
133                 __u8    reserved: 1;    /* reserved                       */
134                 __u8    entry_nr;       /* specific enabled entry         */
135                 __u8    default_vector; /* default pre-assigned vector    */
136                 __u8    unused;         /* formerly unused destination cpu*/
137         }msi_attrib;
138
139         struct {
140                 __u16   head;
141                 __u16   tail;
142         }link;
143
144         void __iomem *mask_base;
145         struct pci_dev *dev;
146
147 #ifdef CONFIG_PM
148         /* PM save area for MSIX address/data */
149
150         u32     address_hi_save;
151         u32     address_lo_save;
152         u32     data_save;
153 #endif
154 };
155
156 #endif /* MSI_H */