[lantiq] move files/ -> files-3.3/
[openwrt.git] / target / linux / lantiq / files-3.3 / arch / mips / pci / pcie-lantiq-msi.c
1 /******************************************************************************
2 **
3 ** FILE NAME    : ifxmips_pcie_msi.c
4 ** PROJECT      : IFX UEIP for VRX200
5 ** MODULES      : PCI MSI sub module
6 **
7 ** DATE         : 02 Mar 2009
8 ** AUTHOR       : Lei Chuanhua
9 ** DESCRIPTION  : PCIe MSI Driver
10 ** COPYRIGHT    :       Copyright (c) 2009
11 **                      Infineon Technologies AG
12 **                      Am Campeon 1-12, 85579 Neubiberg, Germany
13 **
14 **    This program is free software; you can redistribute it and/or modify
15 **    it under the terms of the GNU General Public License as published by
16 **    the Free Software Foundation; either version 2 of the License, or
17 **    (at your option) any later version.
18 ** HISTORY
19 ** $Date        $Author         $Comment
20 ** 02 Mar,2009  Lei Chuanhua    Initial version
21 *******************************************************************************/
22 /*!
23  \defgroup IFX_PCIE_MSI MSI OS APIs
24  \ingroup IFX_PCIE
25  \brief PCIe bus driver OS interface functions
26 */
27
28 /*!
29  \file ifxmips_pcie_msi.c
30  \ingroup IFX_PCIE 
31  \brief PCIe MSI OS interface file
32 */
33
34 #include <linux/init.h>
35 #include <linux/sched.h>
36 #include <linux/slab.h>
37 #include <linux/interrupt.h>
38 #include <linux/kernel_stat.h>
39 #include <linux/pci.h>
40 #include <linux/msi.h>
41 #include <linux/module.h>
42 #include <asm/bootinfo.h>
43 #include <asm/irq.h>
44 #include <asm/traps.h>
45
46 #include "pcie-lantiq.h"
47
48 #define IFX_MSI_IRQ_NUM    16
49 #define SM(_v, _f)              (((_v) << _f##_S) & (_f))
50
51 #define IFX_MSI_PIC_REG_BASE                    (KSEG1 | 0x1F700000)
52 #define IFX_PCIE_MSI_IR0                (INT_NUM_IM4_IRL0 + 27)
53 #define IFX_PCIE_MSI_IR1                (INT_NUM_IM4_IRL0 + 28)
54 #define IFX_PCIE_MSI_IR2                (INT_NUM_IM4_IRL0 + 29)
55 #define IFX_PCIE_MSI_IR3                (INT_NUM_IM0_IRL0 + 30)
56
57 #define IFX_MSI_PCI_INT_DISABLE                 0x80000000
58 #define IFX_MSI_PIC_INT_LINE                    0x30000000
59 #define IFX_MSI_PIC_MSG_ADDR                    0x0FFF0000
60 #define IFX_MSI_PIC_MSG_DATA                    0x0000FFFF
61 #define IFX_MSI_PIC_BIG_ENDIAN                  1
62 #define IFX_MSI_PIC_INT_LINE_S                  28
63 #define IFX_MSI_PIC_MSG_ADDR_S                  16
64 #define IFX_MSI_PIC_MSG_DATA_S                  0x0
65
66 enum {
67     IFX_PCIE_MSI_IDX0 = 0,
68     IFX_PCIE_MSI_IDX1,
69     IFX_PCIE_MSI_IDX2,
70     IFX_PCIE_MSI_IDX3,
71 };
72
73 typedef struct ifx_msi_irq_idx {
74     const int irq;
75     const int idx;
76 }ifx_msi_irq_idx_t;
77
78 struct ifx_msi_pic {
79     volatile u32  pic_table[IFX_MSI_IRQ_NUM];
80     volatile u32  pic_endian;    /* 0x40  */
81 };
82 typedef struct ifx_msi_pic *ifx_msi_pic_t;
83
84 typedef struct ifx_msi_irq {
85     const volatile ifx_msi_pic_t msi_pic_p;
86     const u32 msi_phy_base;
87     const ifx_msi_irq_idx_t msi_irq_idx[IFX_MSI_IRQ_NUM];
88     /*
89      * Each bit in msi_free_irq_bitmask represents a MSI interrupt that is 
90      * in use.
91      */
92     u16 msi_free_irq_bitmask;
93
94     /*
95      * Each bit in msi_multiple_irq_bitmask tells that the device using 
96      * this bit in msi_free_irq_bitmask is also using the next bit. This 
97      * is used so we can disable all of the MSI interrupts when a device 
98      * uses multiple.
99      */
100     u16 msi_multiple_irq_bitmask;
101 }ifx_msi_irq_t;
102
103 static ifx_msi_irq_t msi_irqs[IFX_PCIE_CORE_NR] = {
104     {
105         .msi_pic_p = (const volatile ifx_msi_pic_t)IFX_MSI_PIC_REG_BASE,
106         .msi_phy_base = PCIE_MSI_PHY_BASE,
107         .msi_irq_idx = {
108             {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
109             {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
110             {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
111             {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
112             {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
113             {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
114             {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
115             {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
116         },
117         .msi_free_irq_bitmask = 0,
118         .msi_multiple_irq_bitmask= 0,
119     },
120 #ifdef CONFIG_IFX_PCIE_2ND_CORE
121     {
122         .msi_pic_p = (const volatile ifx_msi_pic_t)IFX_MSI1_PIC_REG_BASE,
123         .msi_phy_base = PCIE1_MSI_PHY_BASE,
124         .msi_irq_idx = {
125             {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
126             {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
127             {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
128             {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
129             {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
130             {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
131             {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
132             {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
133         },
134         .msi_free_irq_bitmask = 0,
135         .msi_multiple_irq_bitmask= 0,
136
137     },
138 #endif /* CONFIG_IFX_PCIE_2ND_CORE */
139 };
140
141 /* 
142  * This lock controls updates to msi_free_irq_bitmask, 
143  * msi_multiple_irq_bitmask and pic register settting
144  */ 
145 static DEFINE_SPINLOCK(ifx_pcie_msi_lock);
146
147 void pcie_msi_pic_init(int pcie_port)
148 {
149     spin_lock(&ifx_pcie_msi_lock);
150     msi_irqs[pcie_port].msi_pic_p->pic_endian = IFX_MSI_PIC_BIG_ENDIAN;
151     spin_unlock(&ifx_pcie_msi_lock);
152 }
153
154 /** 
155  * \fn int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
156  * \brief Called when a driver request MSI interrupts instead of the 
157  * legacy INT A-D. This routine will allocate multiple interrupts 
158  * for MSI devices that support them. A device can override this by 
159  * programming the MSI control bits [6:4] before calling 
160  * pci_enable_msi(). 
161  * 
162  * \param[in] pdev   Device requesting MSI interrupts 
163  * \param[in] desc   MSI descriptor 
164  * 
165  * \return   -EINVAL Invalid pcie root port or invalid msi bit
166  * \return    0        OK
167  * \ingroup IFX_PCIE_MSI
168  */
169 int 
170 arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
171 {
172     int  irq, pos;
173     u16  control;
174     int  irq_idx;
175     int  irq_step;
176     int configured_private_bits;
177     int request_private_bits;
178     struct msi_msg msg;
179     u16 search_mask;
180     struct ifx_pci_controller *ctrl = pdev->bus->sysdata;
181     int pcie_port = ctrl->port;
182
183     IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s %s enter\n", __func__, pci_name(pdev));
184
185     /* XXX, skip RC MSI itself */
186     if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
187         IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s RC itself doesn't use MSI interrupt\n", __func__);
188         return -EINVAL;
189     }
190
191     /*
192      * Read the MSI config to figure out how many IRQs this device 
193      * wants.  Most devices only want 1, which will give 
194      * configured_private_bits and request_private_bits equal 0. 
195      */
196     pci_read_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS, &control);
197
198     /*
199      * If the number of private bits has been configured then use 
200      * that value instead of the requested number. This gives the 
201      * driver the chance to override the number of interrupts 
202      * before calling pci_enable_msi(). 
203      */
204     configured_private_bits = (control & PCI_MSI_FLAGS_QSIZE) >> 4; 
205     if (configured_private_bits == 0) {
206         /* Nothing is configured, so use the hardware requested size */
207         request_private_bits = (control & PCI_MSI_FLAGS_QMASK) >> 1;
208     }
209     else {
210         /*
211          * Use the number of configured bits, assuming the 
212          * driver wanted to override the hardware request 
213          * value.
214          */
215         request_private_bits = configured_private_bits;
216     }
217
218     /*
219      * The PCI 2.3 spec mandates that there are at most 32
220      * interrupts. If this device asks for more, only give it one.
221      */
222     if (request_private_bits > 5) {
223         request_private_bits = 0;
224     }
225 again:
226     /*
227      * The IRQs have to be aligned on a power of two based on the
228      * number being requested.
229      */
230     irq_step = (1 << request_private_bits);
231
232     /* Mask with one bit for each IRQ */
233     search_mask = (1 << irq_step) - 1;
234
235     /*
236      * We're going to search msi_free_irq_bitmask_lock for zero 
237      * bits. This represents an MSI interrupt number that isn't in 
238      * use.
239      */
240     spin_lock(&ifx_pcie_msi_lock);
241     for (pos = 0; pos < IFX_MSI_IRQ_NUM; pos += irq_step) {
242         if ((msi_irqs[pcie_port].msi_free_irq_bitmask & (search_mask << pos)) == 0) {
243             msi_irqs[pcie_port].msi_free_irq_bitmask |= search_mask << pos; 
244             msi_irqs[pcie_port].msi_multiple_irq_bitmask |= (search_mask >> 1) << pos;
245             break; 
246         }
247     }
248     spin_unlock(&ifx_pcie_msi_lock); 
249
250     /* Make sure the search for available interrupts didn't fail */ 
251     if (pos >= IFX_MSI_IRQ_NUM) {
252         if (request_private_bits) {
253             IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s: Unable to find %d free "
254                   "interrupts, trying just one", __func__, 1 << request_private_bits);
255             request_private_bits = 0;
256             goto again;
257         }
258         else {
259             printk(KERN_ERR "%s: Unable to find a free MSI interrupt\n", __func__);
260             return -EINVAL;
261         }
262     } 
263     irq = msi_irqs[pcie_port].msi_irq_idx[pos].irq;
264     irq_idx = msi_irqs[pcie_port].msi_irq_idx[pos].idx;
265
266     IFX_PCIE_PRINT(PCIE_MSG_MSI, "pos %d, irq %d irq_idx %d\n", pos, irq, irq_idx);
267
268     /*
269      * Initialize MSI. This has to match the memory-write endianess from the device 
270      * Address bits [23:12]
271      */
272     spin_lock(&ifx_pcie_msi_lock); 
273     msi_irqs[pcie_port].msi_pic_p->pic_table[pos] = SM(irq_idx, IFX_MSI_PIC_INT_LINE) |
274                     SM((msi_irqs[pcie_port].msi_phy_base >> 12), IFX_MSI_PIC_MSG_ADDR) |
275                     SM((1 << pos), IFX_MSI_PIC_MSG_DATA);
276
277     /* Enable this entry */
278     msi_irqs[pcie_port].msi_pic_p->pic_table[pos] &= ~IFX_MSI_PCI_INT_DISABLE;
279     spin_unlock(&ifx_pcie_msi_lock);
280
281     IFX_PCIE_PRINT(PCIE_MSG_MSI, "pic_table[%d]: 0x%08x\n",
282         pos, msi_irqs[pcie_port].msi_pic_p->pic_table[pos]);
283
284     /* Update the number of IRQs the device has available to it */
285     control &= ~PCI_MSI_FLAGS_QSIZE;
286     control |= (request_private_bits << 4);
287     pci_write_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS, control);
288
289     irq_set_msi_desc(irq, desc);
290     msg.address_hi = 0x0;
291     msg.address_lo = msi_irqs[pcie_port].msi_phy_base;
292     msg.data = SM((1 << pos), IFX_MSI_PIC_MSG_DATA);
293     IFX_PCIE_PRINT(PCIE_MSG_MSI, "msi_data: pos %d 0x%08x\n", pos, msg.data);
294
295     write_msi_msg(irq, &msg);
296     IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s exit\n", __func__);
297     return 0;
298 }
299
300 static int
301 pcie_msi_irq_to_port(unsigned int irq, int *port)
302 {
303     int ret = 0;
304
305     if (irq == IFX_PCIE_MSI_IR0 || irq == IFX_PCIE_MSI_IR1 ||
306         irq == IFX_PCIE_MSI_IR2 || irq == IFX_PCIE_MSI_IR3) {
307         *port = IFX_PCIE_PORT0;
308     }
309 #ifdef CONFIG_IFX_PCIE_2ND_CORE
310     else if (irq == IFX_PCIE1_MSI_IR0 || irq == IFX_PCIE1_MSI_IR1 ||
311         irq == IFX_PCIE1_MSI_IR2 || irq == IFX_PCIE1_MSI_IR3) {
312         *port = IFX_PCIE_PORT1;
313     }
314 #endif /* CONFIG_IFX_PCIE_2ND_CORE */
315     else {
316         printk(KERN_ERR "%s: Attempted to teardown illegal " 
317             "MSI interrupt (%d)\n", __func__, irq);
318         ret = -EINVAL;
319     }
320     return ret;
321 }
322
323 /** 
324  * \fn void arch_teardown_msi_irq(unsigned int irq)
325  * \brief Called when a device no longer needs its MSI interrupts. All 
326  * MSI interrupts for the device are freed. 
327  * 
328  * \param irq   The devices first irq number. There may be multple in sequence.
329  * \return none
330  * \ingroup IFX_PCIE_MSI
331  */
332 void 
333 arch_teardown_msi_irq(unsigned int irq)
334 {
335     int pos;
336     int number_irqs; 
337     u16 bitmask;
338     int pcie_port;
339
340     IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s enter\n", __func__);
341
342     BUG_ON(irq > (INT_NUM_IM4_IRL0 + 31));
343
344     if (pcie_msi_irq_to_port(irq, &pcie_port) != 0) {
345         return;
346     }
347
348     /* Shift the mask to the correct bit location, not always correct 
349      * Probally, the first match will be chosen.
350      */
351     for (pos = 0; pos < IFX_MSI_IRQ_NUM; pos++) {
352         if ((msi_irqs[pcie_port].msi_irq_idx[pos].irq == irq) 
353             && (msi_irqs[pcie_port].msi_free_irq_bitmask & ( 1 << pos))) {
354             break;
355         }
356     }
357     if (pos >= IFX_MSI_IRQ_NUM) {
358         printk(KERN_ERR "%s: Unable to find a matched MSI interrupt\n", __func__);
359         return;
360     }
361     spin_lock(&ifx_pcie_msi_lock);
362     /* Disable this entry */
363     msi_irqs[pcie_port].msi_pic_p->pic_table[pos] |= IFX_MSI_PCI_INT_DISABLE;
364     msi_irqs[pcie_port].msi_pic_p->pic_table[pos] &= ~(IFX_MSI_PIC_INT_LINE | IFX_MSI_PIC_MSG_ADDR | IFX_MSI_PIC_MSG_DATA);
365     spin_unlock(&ifx_pcie_msi_lock); 
366     /*
367      * Count the number of IRQs we need to free by looking at the
368      * msi_multiple_irq_bitmask. Each bit set means that the next
369      * IRQ is also owned by this device.
370      */ 
371     number_irqs = 0; 
372     while (((pos + number_irqs) < IFX_MSI_IRQ_NUM) && 
373         (msi_irqs[pcie_port].msi_multiple_irq_bitmask & (1 << (pos + number_irqs)))) {
374         number_irqs++;
375     }
376     number_irqs++;
377
378     /* Mask with one bit for each IRQ */
379     bitmask = (1 << number_irqs) - 1;
380
381     bitmask <<= pos;
382     if ((msi_irqs[pcie_port].msi_free_irq_bitmask & bitmask) != bitmask) {
383         printk(KERN_ERR "%s: Attempted to teardown MSI "
384              "interrupt (%d) not in use\n", __func__, irq);
385         return;
386     }
387     /* Checks are done, update the in use bitmask */
388     spin_lock(&ifx_pcie_msi_lock);
389     msi_irqs[pcie_port].msi_free_irq_bitmask &= ~bitmask;
390     msi_irqs[pcie_port].msi_multiple_irq_bitmask &= ~(bitmask >> 1);
391     spin_unlock(&ifx_pcie_msi_lock);
392     IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s exit\n", __func__);
393 }
394
395 MODULE_LICENSE("GPL");
396 MODULE_AUTHOR("Chuanhua.Lei@infineon.com");
397 MODULE_SUPPORTED_DEVICE("Infineon PCIe IP builtin MSI PIC module");
398 MODULE_DESCRIPTION("Infineon PCIe IP builtin MSI PIC driver");
399