xref: /openbmc/linux/arch/powerpc/sysdev/fsl_rmu.c (revision 6ec4bedbf153a8ef71aeba99a40efef556b57798)
1*6ec4bedbSLiu Gang /*
2*6ec4bedbSLiu Gang  * Freescale MPC85xx/MPC86xx RapidIO RMU support
3*6ec4bedbSLiu Gang  *
4*6ec4bedbSLiu Gang  * Copyright 2009 Sysgo AG
5*6ec4bedbSLiu Gang  * Thomas Moll <thomas.moll@sysgo.com>
6*6ec4bedbSLiu Gang  * - fixed maintenance access routines, check for aligned access
7*6ec4bedbSLiu Gang  *
8*6ec4bedbSLiu Gang  * Copyright 2009 Integrated Device Technology, Inc.
9*6ec4bedbSLiu Gang  * Alex Bounine <alexandre.bounine@idt.com>
10*6ec4bedbSLiu Gang  * - Added Port-Write message handling
11*6ec4bedbSLiu Gang  * - Added Machine Check exception handling
12*6ec4bedbSLiu Gang  *
13*6ec4bedbSLiu Gang  * Copyright (C) 2007, 2008, 2010, 2011 Freescale Semiconductor, Inc.
14*6ec4bedbSLiu Gang  * Zhang Wei <wei.zhang@freescale.com>
15*6ec4bedbSLiu Gang  * Lian Minghuan-B31939 <Minghuan.Lian@freescale.com>
16*6ec4bedbSLiu Gang  * Liu Gang <Gang.Liu@freescale.com>
17*6ec4bedbSLiu Gang  *
18*6ec4bedbSLiu Gang  * Copyright 2005 MontaVista Software, Inc.
19*6ec4bedbSLiu Gang  * Matt Porter <mporter@kernel.crashing.org>
20*6ec4bedbSLiu Gang  *
21*6ec4bedbSLiu Gang  * This program is free software; you can redistribute  it and/or modify it
22*6ec4bedbSLiu Gang  * under  the terms of  the GNU General  Public License as published by the
23*6ec4bedbSLiu Gang  * Free Software Foundation;  either version 2 of the  License, or (at your
24*6ec4bedbSLiu Gang  * option) any later version.
25*6ec4bedbSLiu Gang  */
26*6ec4bedbSLiu Gang 
27*6ec4bedbSLiu Gang #include <linux/types.h>
28*6ec4bedbSLiu Gang #include <linux/dma-mapping.h>
29*6ec4bedbSLiu Gang #include <linux/interrupt.h>
30*6ec4bedbSLiu Gang #include <linux/of_platform.h>
31*6ec4bedbSLiu Gang #include <linux/slab.h>
32*6ec4bedbSLiu Gang 
33*6ec4bedbSLiu Gang #include "fsl_rio.h"
34*6ec4bedbSLiu Gang 
35*6ec4bedbSLiu Gang #define GET_RMM_HANDLE(mport) \
36*6ec4bedbSLiu Gang 		(((struct rio_priv *)(mport->priv))->rmm_handle)
37*6ec4bedbSLiu Gang 
38*6ec4bedbSLiu Gang /* RapidIO definition irq, which read from OF-tree */
39*6ec4bedbSLiu Gang #define IRQ_RIO_PW(m)		(((struct rio_priv *)(m->priv))->pwirq)
40*6ec4bedbSLiu Gang #define IRQ_RIO_BELL(m) (((struct fsl_rmu *)(GET_RMM_HANDLE(m)))->bellirq)
41*6ec4bedbSLiu Gang #define IRQ_RIO_TX(m) (((struct fsl_rmu *)(GET_RMM_HANDLE(m)))->txirq)
42*6ec4bedbSLiu Gang #define IRQ_RIO_RX(m) (((struct fsl_rmu *)(GET_RMM_HANDLE(m)))->rxirq)
43*6ec4bedbSLiu Gang 
44*6ec4bedbSLiu Gang #define RIO_MIN_TX_RING_SIZE	2
45*6ec4bedbSLiu Gang #define RIO_MAX_TX_RING_SIZE	2048
46*6ec4bedbSLiu Gang #define RIO_MIN_RX_RING_SIZE	2
47*6ec4bedbSLiu Gang #define RIO_MAX_RX_RING_SIZE	2048
48*6ec4bedbSLiu Gang 
49*6ec4bedbSLiu Gang #define RIO_IPWMR_SEN		0x00100000
50*6ec4bedbSLiu Gang #define RIO_IPWMR_QFIE		0x00000100
51*6ec4bedbSLiu Gang #define RIO_IPWMR_EIE		0x00000020
52*6ec4bedbSLiu Gang #define RIO_IPWMR_CQ		0x00000002
53*6ec4bedbSLiu Gang #define RIO_IPWMR_PWE		0x00000001
54*6ec4bedbSLiu Gang 
55*6ec4bedbSLiu Gang #define RIO_IPWSR_QF		0x00100000
56*6ec4bedbSLiu Gang #define RIO_IPWSR_TE		0x00000080
57*6ec4bedbSLiu Gang #define RIO_IPWSR_QFI		0x00000010
58*6ec4bedbSLiu Gang #define RIO_IPWSR_PWD		0x00000008
59*6ec4bedbSLiu Gang #define RIO_IPWSR_PWB		0x00000004
60*6ec4bedbSLiu Gang 
61*6ec4bedbSLiu Gang #define RIO_EPWISR		0x10010
62*6ec4bedbSLiu Gang /* EPWISR Error match value */
63*6ec4bedbSLiu Gang #define RIO_EPWISR_PINT1	0x80000000
64*6ec4bedbSLiu Gang #define RIO_EPWISR_PINT2	0x40000000
65*6ec4bedbSLiu Gang #define RIO_EPWISR_MU		0x00000002
66*6ec4bedbSLiu Gang #define RIO_EPWISR_PW		0x00000001
67*6ec4bedbSLiu Gang 
68*6ec4bedbSLiu Gang #define IPWSR_CLEAR		0x98
69*6ec4bedbSLiu Gang #define OMSR_CLEAR		0x1cb3
70*6ec4bedbSLiu Gang #define IMSR_CLEAR		0x491
71*6ec4bedbSLiu Gang #define IDSR_CLEAR		0x91
72*6ec4bedbSLiu Gang #define ODSR_CLEAR		0x1c00
73*6ec4bedbSLiu Gang #define LTLEECSR_ENABLE_ALL	0xFFC000FC
74*6ec4bedbSLiu Gang #define RIO_LTLEECSR		0x060c
75*6ec4bedbSLiu Gang 
76*6ec4bedbSLiu Gang #define RIO_IM0SR		0x13064
77*6ec4bedbSLiu Gang #define RIO_IM1SR		0x13164
78*6ec4bedbSLiu Gang #define RIO_OM0SR		0x13004
79*6ec4bedbSLiu Gang #define RIO_OM1SR		0x13104
80*6ec4bedbSLiu Gang 
81*6ec4bedbSLiu Gang #define RIO_P_MSG_REGS_OFFSET	0x11000
82*6ec4bedbSLiu Gang #define RIO_S_MSG_REGS_OFFSET	0x13000
83*6ec4bedbSLiu Gang 
84*6ec4bedbSLiu Gang #define RIO_DBELL_WIN_SIZE	0x1000
85*6ec4bedbSLiu Gang 
86*6ec4bedbSLiu Gang #define RIO_MSG_OMR_MUI		0x00000002
87*6ec4bedbSLiu Gang #define RIO_MSG_OSR_TE		0x00000080
88*6ec4bedbSLiu Gang #define RIO_MSG_OSR_QOI		0x00000020
89*6ec4bedbSLiu Gang #define RIO_MSG_OSR_QFI		0x00000010
90*6ec4bedbSLiu Gang #define RIO_MSG_OSR_MUB		0x00000004
91*6ec4bedbSLiu Gang #define RIO_MSG_OSR_EOMI	0x00000002
92*6ec4bedbSLiu Gang #define RIO_MSG_OSR_QEI		0x00000001
93*6ec4bedbSLiu Gang 
94*6ec4bedbSLiu Gang #define RIO_MSG_IMR_MI		0x00000002
95*6ec4bedbSLiu Gang #define RIO_MSG_ISR_TE		0x00000080
96*6ec4bedbSLiu Gang #define RIO_MSG_ISR_QFI		0x00000010
97*6ec4bedbSLiu Gang #define RIO_MSG_ISR_DIQI	0x00000001
98*6ec4bedbSLiu Gang 
99*6ec4bedbSLiu Gang #define RIO_MSG_DESC_SIZE	32
100*6ec4bedbSLiu Gang #define RIO_MSG_BUFFER_SIZE	4096
101*6ec4bedbSLiu Gang 
102*6ec4bedbSLiu Gang #define DOORBELL_DMR_DI		0x00000002
103*6ec4bedbSLiu Gang #define DOORBELL_DSR_TE		0x00000080
104*6ec4bedbSLiu Gang #define DOORBELL_DSR_QFI	0x00000010
105*6ec4bedbSLiu Gang #define DOORBELL_DSR_DIQI	0x00000001
106*6ec4bedbSLiu Gang #define DOORBELL_TID_OFFSET	0x02
107*6ec4bedbSLiu Gang #define DOORBELL_SID_OFFSET	0x04
108*6ec4bedbSLiu Gang #define DOORBELL_INFO_OFFSET	0x06
109*6ec4bedbSLiu Gang 
110*6ec4bedbSLiu Gang #define DOORBELL_MESSAGE_SIZE	0x08
111*6ec4bedbSLiu Gang #define DBELL_SID(x)		(*(u16 *)(x + DOORBELL_SID_OFFSET))
112*6ec4bedbSLiu Gang #define DBELL_TID(x)		(*(u16 *)(x + DOORBELL_TID_OFFSET))
113*6ec4bedbSLiu Gang #define DBELL_INF(x)		(*(u16 *)(x + DOORBELL_INFO_OFFSET))
114*6ec4bedbSLiu Gang 
115*6ec4bedbSLiu Gang struct rio_msg_regs {
116*6ec4bedbSLiu Gang 	u32 omr;	/* 0xD_3000 - Outbound message 0 mode register */
117*6ec4bedbSLiu Gang 	u32 osr;	/* 0xD_3004 - Outbound message 0 status register */
118*6ec4bedbSLiu Gang 	u32 pad1;
119*6ec4bedbSLiu Gang 	u32 odqdpar;	/* 0xD_300C - Outbound message 0 descriptor queue
120*6ec4bedbSLiu Gang 			   dequeue pointer address register */
121*6ec4bedbSLiu Gang 	u32 pad2;
122*6ec4bedbSLiu Gang 	u32 osar;	/* 0xD_3014 - Outbound message 0 source address
123*6ec4bedbSLiu Gang 			   register */
124*6ec4bedbSLiu Gang 	u32 odpr;	/* 0xD_3018 - Outbound message 0 destination port
125*6ec4bedbSLiu Gang 			   register */
126*6ec4bedbSLiu Gang 	u32 odatr;	/* 0xD_301C - Outbound message 0 destination attributes
127*6ec4bedbSLiu Gang 			   Register*/
128*6ec4bedbSLiu Gang 	u32 odcr;	/* 0xD_3020 - Outbound message 0 double-word count
129*6ec4bedbSLiu Gang 			   register */
130*6ec4bedbSLiu Gang 	u32 pad3;
131*6ec4bedbSLiu Gang 	u32 odqepar;	/* 0xD_3028 - Outbound message 0 descriptor queue
132*6ec4bedbSLiu Gang 			   enqueue pointer address register */
133*6ec4bedbSLiu Gang 	u32 pad4[13];
134*6ec4bedbSLiu Gang 	u32 imr;	/* 0xD_3060 - Inbound message 0 mode register */
135*6ec4bedbSLiu Gang 	u32 isr;	/* 0xD_3064 - Inbound message 0 status register */
136*6ec4bedbSLiu Gang 	u32 pad5;
137*6ec4bedbSLiu Gang 	u32 ifqdpar;	/* 0xD_306C - Inbound message 0 frame queue dequeue
138*6ec4bedbSLiu Gang 			   pointer address register*/
139*6ec4bedbSLiu Gang 	u32 pad6;
140*6ec4bedbSLiu Gang 	u32 ifqepar;	/* 0xD_3074 - Inbound message 0 frame queue enqueue
141*6ec4bedbSLiu Gang 			   pointer address register */
142*6ec4bedbSLiu Gang 	u32 pad7[226];
143*6ec4bedbSLiu Gang 	u32 odmr;	/* 0xD_3400 - Outbound doorbell mode register */
144*6ec4bedbSLiu Gang 	u32 odsr;	/* 0xD_3404 - Outbound doorbell status register */
145*6ec4bedbSLiu Gang 	u32 res0[4];
146*6ec4bedbSLiu Gang 	u32 oddpr;	/* 0xD_3418 - Outbound doorbell destination port
147*6ec4bedbSLiu Gang 			   register */
148*6ec4bedbSLiu Gang 	u32 oddatr;	/* 0xD_341c - Outbound doorbell destination attributes
149*6ec4bedbSLiu Gang 			   register */
150*6ec4bedbSLiu Gang 	u32 res1[3];
151*6ec4bedbSLiu Gang 	u32 odretcr;	/* 0xD_342C - Outbound doorbell retry error threshold
152*6ec4bedbSLiu Gang 			   configuration register */
153*6ec4bedbSLiu Gang 	u32 res2[12];
154*6ec4bedbSLiu Gang 	u32 dmr;	/* 0xD_3460 - Inbound doorbell mode register */
155*6ec4bedbSLiu Gang 	u32 dsr;	/* 0xD_3464 - Inbound doorbell status register */
156*6ec4bedbSLiu Gang 	u32 pad8;
157*6ec4bedbSLiu Gang 	u32 dqdpar;	/* 0xD_346C - Inbound doorbell queue dequeue Pointer
158*6ec4bedbSLiu Gang 			   address register */
159*6ec4bedbSLiu Gang 	u32 pad9;
160*6ec4bedbSLiu Gang 	u32 dqepar;	/* 0xD_3474 - Inbound doorbell Queue enqueue pointer
161*6ec4bedbSLiu Gang 			   address register */
162*6ec4bedbSLiu Gang 	u32 pad10[26];
163*6ec4bedbSLiu Gang 	u32 pwmr;	/* 0xD_34E0 - Inbound port-write mode register */
164*6ec4bedbSLiu Gang 	u32 pwsr;	/* 0xD_34E4 - Inbound port-write status register */
165*6ec4bedbSLiu Gang 	u32 epwqbar;	/* 0xD_34E8 - Extended Port-Write Queue Base Address
166*6ec4bedbSLiu Gang 			   register */
167*6ec4bedbSLiu Gang 	u32 pwqbar;	/* 0xD_34EC - Inbound port-write queue base address
168*6ec4bedbSLiu Gang 			   register */
169*6ec4bedbSLiu Gang };
170*6ec4bedbSLiu Gang 
171*6ec4bedbSLiu Gang struct rio_tx_desc {
172*6ec4bedbSLiu Gang 	u32 res1;
173*6ec4bedbSLiu Gang 	u32 saddr;
174*6ec4bedbSLiu Gang 	u32 dport;
175*6ec4bedbSLiu Gang 	u32 dattr;
176*6ec4bedbSLiu Gang 	u32 res2;
177*6ec4bedbSLiu Gang 	u32 res3;
178*6ec4bedbSLiu Gang 	u32 dwcnt;
179*6ec4bedbSLiu Gang 	u32 res4;
180*6ec4bedbSLiu Gang };
181*6ec4bedbSLiu Gang 
182*6ec4bedbSLiu Gang struct rio_dbell_ring {
183*6ec4bedbSLiu Gang 	void *virt;
184*6ec4bedbSLiu Gang 	dma_addr_t phys;
185*6ec4bedbSLiu Gang };
186*6ec4bedbSLiu Gang 
187*6ec4bedbSLiu Gang struct rio_msg_tx_ring {
188*6ec4bedbSLiu Gang 	void *virt;
189*6ec4bedbSLiu Gang 	dma_addr_t phys;
190*6ec4bedbSLiu Gang 	void *virt_buffer[RIO_MAX_TX_RING_SIZE];
191*6ec4bedbSLiu Gang 	dma_addr_t phys_buffer[RIO_MAX_TX_RING_SIZE];
192*6ec4bedbSLiu Gang 	int tx_slot;
193*6ec4bedbSLiu Gang 	int size;
194*6ec4bedbSLiu Gang 	void *dev_id;
195*6ec4bedbSLiu Gang };
196*6ec4bedbSLiu Gang 
197*6ec4bedbSLiu Gang struct rio_msg_rx_ring {
198*6ec4bedbSLiu Gang 	void *virt;
199*6ec4bedbSLiu Gang 	dma_addr_t phys;
200*6ec4bedbSLiu Gang 	void *virt_buffer[RIO_MAX_RX_RING_SIZE];
201*6ec4bedbSLiu Gang 	int rx_slot;
202*6ec4bedbSLiu Gang 	int size;
203*6ec4bedbSLiu Gang 	void *dev_id;
204*6ec4bedbSLiu Gang };
205*6ec4bedbSLiu Gang 
206*6ec4bedbSLiu Gang struct fsl_rmu {
207*6ec4bedbSLiu Gang 	struct rio_atmu_regs __iomem *dbell_atmu_regs;
208*6ec4bedbSLiu Gang 	void __iomem *dbell_win;
209*6ec4bedbSLiu Gang 	struct rio_msg_regs __iomem *msg_regs;
210*6ec4bedbSLiu Gang 	struct rio_dbell_ring dbell_ring;
211*6ec4bedbSLiu Gang 	struct rio_msg_tx_ring msg_tx_ring;
212*6ec4bedbSLiu Gang 	struct rio_msg_rx_ring msg_rx_ring;
213*6ec4bedbSLiu Gang 	int bellirq;
214*6ec4bedbSLiu Gang 	int txirq;
215*6ec4bedbSLiu Gang 	int rxirq;
216*6ec4bedbSLiu Gang };
217*6ec4bedbSLiu Gang 
218*6ec4bedbSLiu Gang /**
219*6ec4bedbSLiu Gang  * fsl_rio_tx_handler - MPC85xx outbound message interrupt handler
220*6ec4bedbSLiu Gang  * @irq: Linux interrupt number
221*6ec4bedbSLiu Gang  * @dev_instance: Pointer to interrupt-specific data
222*6ec4bedbSLiu Gang  *
223*6ec4bedbSLiu Gang  * Handles outbound message interrupts. Executes a register outbound
224*6ec4bedbSLiu Gang  * mailbox event handler and acks the interrupt occurrence.
225*6ec4bedbSLiu Gang  */
226*6ec4bedbSLiu Gang static irqreturn_t
227*6ec4bedbSLiu Gang fsl_rio_tx_handler(int irq, void *dev_instance)
228*6ec4bedbSLiu Gang {
229*6ec4bedbSLiu Gang 	int osr;
230*6ec4bedbSLiu Gang 	struct rio_mport *port = (struct rio_mport *)dev_instance;
231*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu = GET_RMM_HANDLE(port);
232*6ec4bedbSLiu Gang 
233*6ec4bedbSLiu Gang 	osr = in_be32(&rmu->msg_regs->osr);
234*6ec4bedbSLiu Gang 
235*6ec4bedbSLiu Gang 	if (osr & RIO_MSG_OSR_TE) {
236*6ec4bedbSLiu Gang 		pr_info("RIO: outbound message transmission error\n");
237*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->osr, RIO_MSG_OSR_TE);
238*6ec4bedbSLiu Gang 		goto out;
239*6ec4bedbSLiu Gang 	}
240*6ec4bedbSLiu Gang 
241*6ec4bedbSLiu Gang 	if (osr & RIO_MSG_OSR_QOI) {
242*6ec4bedbSLiu Gang 		pr_info("RIO: outbound message queue overflow\n");
243*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->osr, RIO_MSG_OSR_QOI);
244*6ec4bedbSLiu Gang 		goto out;
245*6ec4bedbSLiu Gang 	}
246*6ec4bedbSLiu Gang 
247*6ec4bedbSLiu Gang 	if (osr & RIO_MSG_OSR_EOMI) {
248*6ec4bedbSLiu Gang 		u32 dqp = in_be32(&rmu->msg_regs->odqdpar);
249*6ec4bedbSLiu Gang 		int slot = (dqp - rmu->msg_tx_ring.phys) >> 5;
250*6ec4bedbSLiu Gang 		port->outb_msg[0].mcback(port, rmu->msg_tx_ring.dev_id, -1,
251*6ec4bedbSLiu Gang 				slot);
252*6ec4bedbSLiu Gang 
253*6ec4bedbSLiu Gang 		/* Ack the end-of-message interrupt */
254*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->osr, RIO_MSG_OSR_EOMI);
255*6ec4bedbSLiu Gang 	}
256*6ec4bedbSLiu Gang 
257*6ec4bedbSLiu Gang out:
258*6ec4bedbSLiu Gang 	return IRQ_HANDLED;
259*6ec4bedbSLiu Gang }
260*6ec4bedbSLiu Gang 
261*6ec4bedbSLiu Gang /**
262*6ec4bedbSLiu Gang  * fsl_rio_rx_handler - MPC85xx inbound message interrupt handler
263*6ec4bedbSLiu Gang  * @irq: Linux interrupt number
264*6ec4bedbSLiu Gang  * @dev_instance: Pointer to interrupt-specific data
265*6ec4bedbSLiu Gang  *
266*6ec4bedbSLiu Gang  * Handles inbound message interrupts. Executes a registered inbound
267*6ec4bedbSLiu Gang  * mailbox event handler and acks the interrupt occurrence.
268*6ec4bedbSLiu Gang  */
269*6ec4bedbSLiu Gang static irqreturn_t
270*6ec4bedbSLiu Gang fsl_rio_rx_handler(int irq, void *dev_instance)
271*6ec4bedbSLiu Gang {
272*6ec4bedbSLiu Gang 	int isr;
273*6ec4bedbSLiu Gang 	struct rio_mport *port = (struct rio_mport *)dev_instance;
274*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu = GET_RMM_HANDLE(port);
275*6ec4bedbSLiu Gang 
276*6ec4bedbSLiu Gang 	isr = in_be32(&rmu->msg_regs->isr);
277*6ec4bedbSLiu Gang 
278*6ec4bedbSLiu Gang 	if (isr & RIO_MSG_ISR_TE) {
279*6ec4bedbSLiu Gang 		pr_info("RIO: inbound message reception error\n");
280*6ec4bedbSLiu Gang 		out_be32((void *)&rmu->msg_regs->isr, RIO_MSG_ISR_TE);
281*6ec4bedbSLiu Gang 		goto out;
282*6ec4bedbSLiu Gang 	}
283*6ec4bedbSLiu Gang 
284*6ec4bedbSLiu Gang 	/* XXX Need to check/dispatch until queue empty */
285*6ec4bedbSLiu Gang 	if (isr & RIO_MSG_ISR_DIQI) {
286*6ec4bedbSLiu Gang 		/*
287*6ec4bedbSLiu Gang 		 * We implement *only* mailbox 0, but can receive messages
288*6ec4bedbSLiu Gang 		 * for any mailbox/letter to that mailbox destination. So,
289*6ec4bedbSLiu Gang 		 * make the callback with an unknown/invalid mailbox number
290*6ec4bedbSLiu Gang 		 * argument.
291*6ec4bedbSLiu Gang 		 */
292*6ec4bedbSLiu Gang 		port->inb_msg[0].mcback(port, rmu->msg_rx_ring.dev_id, -1, -1);
293*6ec4bedbSLiu Gang 
294*6ec4bedbSLiu Gang 		/* Ack the queueing interrupt */
295*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->isr, RIO_MSG_ISR_DIQI);
296*6ec4bedbSLiu Gang 	}
297*6ec4bedbSLiu Gang 
298*6ec4bedbSLiu Gang out:
299*6ec4bedbSLiu Gang 	return IRQ_HANDLED;
300*6ec4bedbSLiu Gang }
301*6ec4bedbSLiu Gang 
302*6ec4bedbSLiu Gang /**
303*6ec4bedbSLiu Gang  * fsl_rio_dbell_handler - MPC85xx doorbell interrupt handler
304*6ec4bedbSLiu Gang  * @irq: Linux interrupt number
305*6ec4bedbSLiu Gang  * @dev_instance: Pointer to interrupt-specific data
306*6ec4bedbSLiu Gang  *
307*6ec4bedbSLiu Gang  * Handles doorbell interrupts. Parses a list of registered
308*6ec4bedbSLiu Gang  * doorbell event handlers and executes a matching event handler.
309*6ec4bedbSLiu Gang  */
310*6ec4bedbSLiu Gang static irqreturn_t
311*6ec4bedbSLiu Gang fsl_rio_dbell_handler(int irq, void *dev_instance)
312*6ec4bedbSLiu Gang {
313*6ec4bedbSLiu Gang 	int dsr;
314*6ec4bedbSLiu Gang 	struct rio_mport *port = (struct rio_mport *)dev_instance;
315*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu = GET_RMM_HANDLE(port);
316*6ec4bedbSLiu Gang 
317*6ec4bedbSLiu Gang 	dsr = in_be32(&rmu->msg_regs->dsr);
318*6ec4bedbSLiu Gang 
319*6ec4bedbSLiu Gang 	if (dsr & DOORBELL_DSR_TE) {
320*6ec4bedbSLiu Gang 		pr_info("RIO: doorbell reception error\n");
321*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->dsr, DOORBELL_DSR_TE);
322*6ec4bedbSLiu Gang 		goto out;
323*6ec4bedbSLiu Gang 	}
324*6ec4bedbSLiu Gang 
325*6ec4bedbSLiu Gang 	if (dsr & DOORBELL_DSR_QFI) {
326*6ec4bedbSLiu Gang 		pr_info("RIO: doorbell queue full\n");
327*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->dsr, DOORBELL_DSR_QFI);
328*6ec4bedbSLiu Gang 	}
329*6ec4bedbSLiu Gang 
330*6ec4bedbSLiu Gang 	/* XXX Need to check/dispatch until queue empty */
331*6ec4bedbSLiu Gang 	if (dsr & DOORBELL_DSR_DIQI) {
332*6ec4bedbSLiu Gang 		u32 dmsg =
333*6ec4bedbSLiu Gang 			(u32) rmu->dbell_ring.virt +
334*6ec4bedbSLiu Gang 			(in_be32(&rmu->msg_regs->dqdpar) & 0xfff);
335*6ec4bedbSLiu Gang 		struct rio_dbell *dbell;
336*6ec4bedbSLiu Gang 		int found = 0;
337*6ec4bedbSLiu Gang 
338*6ec4bedbSLiu Gang 		pr_debug
339*6ec4bedbSLiu Gang 			("RIO: processing doorbell,"
340*6ec4bedbSLiu Gang 			" sid %2.2x tid %2.2x info %4.4x\n",
341*6ec4bedbSLiu Gang 			DBELL_SID(dmsg), DBELL_TID(dmsg), DBELL_INF(dmsg));
342*6ec4bedbSLiu Gang 
343*6ec4bedbSLiu Gang 		list_for_each_entry(dbell, &port->dbells, node) {
344*6ec4bedbSLiu Gang 			if ((dbell->res->start <= DBELL_INF(dmsg)) &&
345*6ec4bedbSLiu Gang 				(dbell->res->end >= DBELL_INF(dmsg))) {
346*6ec4bedbSLiu Gang 				found = 1;
347*6ec4bedbSLiu Gang 				break;
348*6ec4bedbSLiu Gang 			}
349*6ec4bedbSLiu Gang 		}
350*6ec4bedbSLiu Gang 		if (found) {
351*6ec4bedbSLiu Gang 			dbell->dinb(port, dbell->dev_id,
352*6ec4bedbSLiu Gang 					DBELL_SID(dmsg),
353*6ec4bedbSLiu Gang 					DBELL_TID(dmsg), DBELL_INF(dmsg));
354*6ec4bedbSLiu Gang 		} else {
355*6ec4bedbSLiu Gang 			pr_debug
356*6ec4bedbSLiu Gang 				("RIO: spurious doorbell,"
357*6ec4bedbSLiu Gang 				" sid %2.2x tid %2.2x info %4.4x\n",
358*6ec4bedbSLiu Gang 				DBELL_SID(dmsg), DBELL_TID(dmsg),
359*6ec4bedbSLiu Gang 				DBELL_INF(dmsg));
360*6ec4bedbSLiu Gang 		}
361*6ec4bedbSLiu Gang 		setbits32(&rmu->msg_regs->dmr, DOORBELL_DMR_DI);
362*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->dsr, DOORBELL_DSR_DIQI);
363*6ec4bedbSLiu Gang 	}
364*6ec4bedbSLiu Gang 
365*6ec4bedbSLiu Gang out:
366*6ec4bedbSLiu Gang 	return IRQ_HANDLED;
367*6ec4bedbSLiu Gang }
368*6ec4bedbSLiu Gang 
369*6ec4bedbSLiu Gang void msg_unit_error_handler(struct rio_mport *port)
370*6ec4bedbSLiu Gang {
371*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu = GET_RMM_HANDLE(port);
372*6ec4bedbSLiu Gang 
373*6ec4bedbSLiu Gang 	/*XXX: Error recovery is not implemented, we just clear errors */
374*6ec4bedbSLiu Gang 	out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), 0);
375*6ec4bedbSLiu Gang 
376*6ec4bedbSLiu Gang 	out_be32((u32 *)(rio_regs_win + RIO_IM0SR), IMSR_CLEAR);
377*6ec4bedbSLiu Gang 	out_be32((u32 *)(rio_regs_win + RIO_IM1SR), IMSR_CLEAR);
378*6ec4bedbSLiu Gang 	out_be32((u32 *)(rio_regs_win + RIO_OM0SR), OMSR_CLEAR);
379*6ec4bedbSLiu Gang 	out_be32((u32 *)(rio_regs_win + RIO_OM1SR), OMSR_CLEAR);
380*6ec4bedbSLiu Gang 
381*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->odsr, ODSR_CLEAR);
382*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->dsr, IDSR_CLEAR);
383*6ec4bedbSLiu Gang 
384*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->pwsr, IPWSR_CLEAR);
385*6ec4bedbSLiu Gang }
386*6ec4bedbSLiu Gang 
387*6ec4bedbSLiu Gang /**
388*6ec4bedbSLiu Gang  * fsl_rio_port_write_handler - MPC85xx port write interrupt handler
389*6ec4bedbSLiu Gang  * @irq: Linux interrupt number
390*6ec4bedbSLiu Gang  * @dev_instance: Pointer to interrupt-specific data
391*6ec4bedbSLiu Gang  *
392*6ec4bedbSLiu Gang  * Handles port write interrupts. Parses a list of registered
393*6ec4bedbSLiu Gang  * port write event handlers and executes a matching event handler.
394*6ec4bedbSLiu Gang  */
395*6ec4bedbSLiu Gang static irqreturn_t
396*6ec4bedbSLiu Gang fsl_rio_port_write_handler(int irq, void *dev_instance)
397*6ec4bedbSLiu Gang {
398*6ec4bedbSLiu Gang 	u32 ipwmr, ipwsr;
399*6ec4bedbSLiu Gang 	struct rio_mport *port = (struct rio_mport *)dev_instance;
400*6ec4bedbSLiu Gang 	struct rio_priv *priv = port->priv;
401*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu;
402*6ec4bedbSLiu Gang 	u32 epwisr, tmp;
403*6ec4bedbSLiu Gang 
404*6ec4bedbSLiu Gang 	rmu = GET_RMM_HANDLE(port);
405*6ec4bedbSLiu Gang 	epwisr = in_be32(priv->regs_win + RIO_EPWISR);
406*6ec4bedbSLiu Gang 	if (!(epwisr & RIO_EPWISR_PW))
407*6ec4bedbSLiu Gang 		goto pw_done;
408*6ec4bedbSLiu Gang 
409*6ec4bedbSLiu Gang 	ipwmr = in_be32(&rmu->msg_regs->pwmr);
410*6ec4bedbSLiu Gang 	ipwsr = in_be32(&rmu->msg_regs->pwsr);
411*6ec4bedbSLiu Gang 
412*6ec4bedbSLiu Gang #ifdef DEBUG_PW
413*6ec4bedbSLiu Gang 	pr_debug("PW Int->IPWMR: 0x%08x IPWSR: 0x%08x (", ipwmr, ipwsr);
414*6ec4bedbSLiu Gang 	if (ipwsr & RIO_IPWSR_QF)
415*6ec4bedbSLiu Gang 		pr_debug(" QF");
416*6ec4bedbSLiu Gang 	if (ipwsr & RIO_IPWSR_TE)
417*6ec4bedbSLiu Gang 		pr_debug(" TE");
418*6ec4bedbSLiu Gang 	if (ipwsr & RIO_IPWSR_QFI)
419*6ec4bedbSLiu Gang 		pr_debug(" QFI");
420*6ec4bedbSLiu Gang 	if (ipwsr & RIO_IPWSR_PWD)
421*6ec4bedbSLiu Gang 		pr_debug(" PWD");
422*6ec4bedbSLiu Gang 	if (ipwsr & RIO_IPWSR_PWB)
423*6ec4bedbSLiu Gang 		pr_debug(" PWB");
424*6ec4bedbSLiu Gang 	pr_debug(" )\n");
425*6ec4bedbSLiu Gang #endif
426*6ec4bedbSLiu Gang 	/* Schedule deferred processing if PW was received */
427*6ec4bedbSLiu Gang 	if (ipwsr & RIO_IPWSR_QFI) {
428*6ec4bedbSLiu Gang 		/* Save PW message (if there is room in FIFO),
429*6ec4bedbSLiu Gang 		 * otherwise discard it.
430*6ec4bedbSLiu Gang 		 */
431*6ec4bedbSLiu Gang 		if (kfifo_avail(&priv->pw_fifo) >= RIO_PW_MSG_SIZE) {
432*6ec4bedbSLiu Gang 			priv->port_write_msg.msg_count++;
433*6ec4bedbSLiu Gang 			kfifo_in(&priv->pw_fifo, priv->port_write_msg.virt,
434*6ec4bedbSLiu Gang 				 RIO_PW_MSG_SIZE);
435*6ec4bedbSLiu Gang 		} else {
436*6ec4bedbSLiu Gang 			priv->port_write_msg.discard_count++;
437*6ec4bedbSLiu Gang 			pr_debug("RIO: ISR Discarded Port-Write Msg(s) (%d)\n",
438*6ec4bedbSLiu Gang 				 priv->port_write_msg.discard_count);
439*6ec4bedbSLiu Gang 		}
440*6ec4bedbSLiu Gang 		/* Clear interrupt and issue Clear Queue command. This allows
441*6ec4bedbSLiu Gang 		 * another port-write to be received.
442*6ec4bedbSLiu Gang 		 */
443*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->pwsr,	RIO_IPWSR_QFI);
444*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->pwmr, ipwmr | RIO_IPWMR_CQ);
445*6ec4bedbSLiu Gang 
446*6ec4bedbSLiu Gang 		schedule_work(&priv->pw_work);
447*6ec4bedbSLiu Gang 	}
448*6ec4bedbSLiu Gang 
449*6ec4bedbSLiu Gang 	if ((ipwmr & RIO_IPWMR_EIE) && (ipwsr & RIO_IPWSR_TE)) {
450*6ec4bedbSLiu Gang 		priv->port_write_msg.err_count++;
451*6ec4bedbSLiu Gang 		pr_debug("RIO: Port-Write Transaction Err (%d)\n",
452*6ec4bedbSLiu Gang 			 priv->port_write_msg.err_count);
453*6ec4bedbSLiu Gang 		/* Clear Transaction Error: port-write controller should be
454*6ec4bedbSLiu Gang 		 * disabled when clearing this error
455*6ec4bedbSLiu Gang 		 */
456*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->pwmr, ipwmr & ~RIO_IPWMR_PWE);
457*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->pwsr,	RIO_IPWSR_TE);
458*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->pwmr, ipwmr);
459*6ec4bedbSLiu Gang 	}
460*6ec4bedbSLiu Gang 
461*6ec4bedbSLiu Gang 	if (ipwsr & RIO_IPWSR_PWD) {
462*6ec4bedbSLiu Gang 		priv->port_write_msg.discard_count++;
463*6ec4bedbSLiu Gang 		pr_debug("RIO: Port Discarded Port-Write Msg(s) (%d)\n",
464*6ec4bedbSLiu Gang 			 priv->port_write_msg.discard_count);
465*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->pwsr, RIO_IPWSR_PWD);
466*6ec4bedbSLiu Gang 	}
467*6ec4bedbSLiu Gang 
468*6ec4bedbSLiu Gang pw_done:
469*6ec4bedbSLiu Gang 	if (epwisr & RIO_EPWISR_PINT1) {
470*6ec4bedbSLiu Gang 		tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
471*6ec4bedbSLiu Gang 		pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp);
472*6ec4bedbSLiu Gang 		fsl_rio_port_error_handler(port, 0);
473*6ec4bedbSLiu Gang 	}
474*6ec4bedbSLiu Gang 
475*6ec4bedbSLiu Gang 	if (epwisr & RIO_EPWISR_PINT2) {
476*6ec4bedbSLiu Gang 		tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
477*6ec4bedbSLiu Gang 		pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp);
478*6ec4bedbSLiu Gang 		fsl_rio_port_error_handler(port, 1);
479*6ec4bedbSLiu Gang 	}
480*6ec4bedbSLiu Gang 
481*6ec4bedbSLiu Gang 	if (epwisr & RIO_EPWISR_MU) {
482*6ec4bedbSLiu Gang 		tmp = in_be32(priv->regs_win + RIO_LTLEDCSR);
483*6ec4bedbSLiu Gang 		pr_debug("RIO_LTLEDCSR = 0x%x\n", tmp);
484*6ec4bedbSLiu Gang 		msg_unit_error_handler(port);
485*6ec4bedbSLiu Gang 	}
486*6ec4bedbSLiu Gang 
487*6ec4bedbSLiu Gang 	return IRQ_HANDLED;
488*6ec4bedbSLiu Gang }
489*6ec4bedbSLiu Gang 
490*6ec4bedbSLiu Gang static void fsl_pw_dpc(struct work_struct *work)
491*6ec4bedbSLiu Gang {
492*6ec4bedbSLiu Gang 	struct rio_priv *priv = container_of(work, struct rio_priv, pw_work);
493*6ec4bedbSLiu Gang 	unsigned long flags;
494*6ec4bedbSLiu Gang 	u32 msg_buffer[RIO_PW_MSG_SIZE/sizeof(u32)];
495*6ec4bedbSLiu Gang 
496*6ec4bedbSLiu Gang 	/*
497*6ec4bedbSLiu Gang 	 * Process port-write messages
498*6ec4bedbSLiu Gang 	 */
499*6ec4bedbSLiu Gang 	spin_lock_irqsave(&priv->pw_fifo_lock, flags);
500*6ec4bedbSLiu Gang 	while (kfifo_out(&priv->pw_fifo, (unsigned char *)msg_buffer,
501*6ec4bedbSLiu Gang 			 RIO_PW_MSG_SIZE)) {
502*6ec4bedbSLiu Gang 		/* Process one message */
503*6ec4bedbSLiu Gang 		spin_unlock_irqrestore(&priv->pw_fifo_lock, flags);
504*6ec4bedbSLiu Gang #ifdef DEBUG_PW
505*6ec4bedbSLiu Gang 		{
506*6ec4bedbSLiu Gang 		u32 i;
507*6ec4bedbSLiu Gang 		pr_debug("%s : Port-Write Message:", __func__);
508*6ec4bedbSLiu Gang 		for (i = 0; i < RIO_PW_MSG_SIZE/sizeof(u32); i++) {
509*6ec4bedbSLiu Gang 			if ((i%4) == 0)
510*6ec4bedbSLiu Gang 				pr_debug("\n0x%02x: 0x%08x", i*4,
511*6ec4bedbSLiu Gang 					 msg_buffer[i]);
512*6ec4bedbSLiu Gang 			else
513*6ec4bedbSLiu Gang 				pr_debug(" 0x%08x", msg_buffer[i]);
514*6ec4bedbSLiu Gang 		}
515*6ec4bedbSLiu Gang 		pr_debug("\n");
516*6ec4bedbSLiu Gang 		}
517*6ec4bedbSLiu Gang #endif
518*6ec4bedbSLiu Gang 		/* Pass the port-write message to RIO core for processing */
519*6ec4bedbSLiu Gang 		rio_inb_pwrite_handler((union rio_pw_msg *)msg_buffer);
520*6ec4bedbSLiu Gang 		spin_lock_irqsave(&priv->pw_fifo_lock, flags);
521*6ec4bedbSLiu Gang 	}
522*6ec4bedbSLiu Gang 	spin_unlock_irqrestore(&priv->pw_fifo_lock, flags);
523*6ec4bedbSLiu Gang }
524*6ec4bedbSLiu Gang 
525*6ec4bedbSLiu Gang /**
526*6ec4bedbSLiu Gang  * fsl_rio_pw_enable - enable/disable port-write interface init
527*6ec4bedbSLiu Gang  * @mport: Master port implementing the port write unit
528*6ec4bedbSLiu Gang  * @enable: 1=enable; 0=disable port-write message handling
529*6ec4bedbSLiu Gang  */
530*6ec4bedbSLiu Gang int fsl_rio_pw_enable(struct rio_mport *mport, int enable)
531*6ec4bedbSLiu Gang {
532*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu;
533*6ec4bedbSLiu Gang 	u32 rval;
534*6ec4bedbSLiu Gang 
535*6ec4bedbSLiu Gang 	rmu = GET_RMM_HANDLE(mport);
536*6ec4bedbSLiu Gang 
537*6ec4bedbSLiu Gang 	rval = in_be32(&rmu->msg_regs->pwmr);
538*6ec4bedbSLiu Gang 
539*6ec4bedbSLiu Gang 	if (enable)
540*6ec4bedbSLiu Gang 		rval |= RIO_IPWMR_PWE;
541*6ec4bedbSLiu Gang 	else
542*6ec4bedbSLiu Gang 		rval &= ~RIO_IPWMR_PWE;
543*6ec4bedbSLiu Gang 
544*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->pwmr, rval);
545*6ec4bedbSLiu Gang 
546*6ec4bedbSLiu Gang 	return 0;
547*6ec4bedbSLiu Gang }
548*6ec4bedbSLiu Gang 
549*6ec4bedbSLiu Gang /**
550*6ec4bedbSLiu Gang  * fsl_rio_port_write_init - MPC85xx port write interface init
551*6ec4bedbSLiu Gang  * @mport: Master port implementing the port write unit
552*6ec4bedbSLiu Gang  *
553*6ec4bedbSLiu Gang  * Initializes port write unit hardware and DMA buffer
554*6ec4bedbSLiu Gang  * ring. Called from fsl_rio_setup(). Returns %0 on success
555*6ec4bedbSLiu Gang  * or %-ENOMEM on failure.
556*6ec4bedbSLiu Gang  */
557*6ec4bedbSLiu Gang 
558*6ec4bedbSLiu Gang int fsl_rio_port_write_init(struct rio_mport *mport)
559*6ec4bedbSLiu Gang {
560*6ec4bedbSLiu Gang 	struct rio_priv *priv = mport->priv;
561*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu;
562*6ec4bedbSLiu Gang 	int rc = 0;
563*6ec4bedbSLiu Gang 
564*6ec4bedbSLiu Gang 	rmu = GET_RMM_HANDLE(mport);
565*6ec4bedbSLiu Gang 
566*6ec4bedbSLiu Gang 	/* Following configurations require a disabled port write controller */
567*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->pwmr,
568*6ec4bedbSLiu Gang 		 in_be32(&rmu->msg_regs->pwmr) & ~RIO_IPWMR_PWE);
569*6ec4bedbSLiu Gang 
570*6ec4bedbSLiu Gang 	/* Initialize port write */
571*6ec4bedbSLiu Gang 	priv->port_write_msg.virt = dma_alloc_coherent(priv->dev,
572*6ec4bedbSLiu Gang 					RIO_PW_MSG_SIZE,
573*6ec4bedbSLiu Gang 					&priv->port_write_msg.phys, GFP_KERNEL);
574*6ec4bedbSLiu Gang 	if (!priv->port_write_msg.virt) {
575*6ec4bedbSLiu Gang 		pr_err("RIO: unable allocate port write queue\n");
576*6ec4bedbSLiu Gang 		return -ENOMEM;
577*6ec4bedbSLiu Gang 	}
578*6ec4bedbSLiu Gang 
579*6ec4bedbSLiu Gang 	priv->port_write_msg.err_count = 0;
580*6ec4bedbSLiu Gang 	priv->port_write_msg.discard_count = 0;
581*6ec4bedbSLiu Gang 
582*6ec4bedbSLiu Gang 	/* Point dequeue/enqueue pointers at first entry */
583*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->epwqbar, 0);
584*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->pwqbar, (u32) priv->port_write_msg.phys);
585*6ec4bedbSLiu Gang 
586*6ec4bedbSLiu Gang 	pr_debug("EIPWQBAR: 0x%08x IPWQBAR: 0x%08x\n",
587*6ec4bedbSLiu Gang 		 in_be32(&rmu->msg_regs->epwqbar),
588*6ec4bedbSLiu Gang 		 in_be32(&rmu->msg_regs->pwqbar));
589*6ec4bedbSLiu Gang 
590*6ec4bedbSLiu Gang 	/* Clear interrupt status IPWSR */
591*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->pwsr,
592*6ec4bedbSLiu Gang 		 (RIO_IPWSR_TE | RIO_IPWSR_QFI | RIO_IPWSR_PWD));
593*6ec4bedbSLiu Gang 
594*6ec4bedbSLiu Gang 	/* Configure port write contoller for snooping enable all reporting,
595*6ec4bedbSLiu Gang 	   clear queue full */
596*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->pwmr,
597*6ec4bedbSLiu Gang 		 RIO_IPWMR_SEN | RIO_IPWMR_QFIE | RIO_IPWMR_EIE | RIO_IPWMR_CQ);
598*6ec4bedbSLiu Gang 
599*6ec4bedbSLiu Gang 
600*6ec4bedbSLiu Gang 	/* Hook up port-write handler */
601*6ec4bedbSLiu Gang 	rc = request_irq(IRQ_RIO_PW(mport), fsl_rio_port_write_handler,
602*6ec4bedbSLiu Gang 			IRQF_SHARED, "port-write", (void *)mport);
603*6ec4bedbSLiu Gang 	if (rc < 0) {
604*6ec4bedbSLiu Gang 		pr_err("MPC85xx RIO: unable to request inbound doorbell irq");
605*6ec4bedbSLiu Gang 		goto err_out;
606*6ec4bedbSLiu Gang 	}
607*6ec4bedbSLiu Gang 	/* Enable Error Interrupt */
608*6ec4bedbSLiu Gang 	out_be32((u32 *)(rio_regs_win + RIO_LTLEECSR), LTLEECSR_ENABLE_ALL);
609*6ec4bedbSLiu Gang 
610*6ec4bedbSLiu Gang 	INIT_WORK(&priv->pw_work, fsl_pw_dpc);
611*6ec4bedbSLiu Gang 	spin_lock_init(&priv->pw_fifo_lock);
612*6ec4bedbSLiu Gang 	if (kfifo_alloc(&priv->pw_fifo, RIO_PW_MSG_SIZE * 32, GFP_KERNEL)) {
613*6ec4bedbSLiu Gang 		pr_err("FIFO allocation failed\n");
614*6ec4bedbSLiu Gang 		rc = -ENOMEM;
615*6ec4bedbSLiu Gang 		goto err_out_irq;
616*6ec4bedbSLiu Gang 	}
617*6ec4bedbSLiu Gang 
618*6ec4bedbSLiu Gang 	pr_debug("IPWMR: 0x%08x IPWSR: 0x%08x\n",
619*6ec4bedbSLiu Gang 		 in_be32(&rmu->msg_regs->pwmr),
620*6ec4bedbSLiu Gang 		 in_be32(&rmu->msg_regs->pwsr));
621*6ec4bedbSLiu Gang 
622*6ec4bedbSLiu Gang 	return rc;
623*6ec4bedbSLiu Gang 
624*6ec4bedbSLiu Gang err_out_irq:
625*6ec4bedbSLiu Gang 	free_irq(IRQ_RIO_PW(mport), (void *)mport);
626*6ec4bedbSLiu Gang err_out:
627*6ec4bedbSLiu Gang 	dma_free_coherent(priv->dev, RIO_PW_MSG_SIZE,
628*6ec4bedbSLiu Gang 		priv->port_write_msg.virt,
629*6ec4bedbSLiu Gang 		priv->port_write_msg.phys);
630*6ec4bedbSLiu Gang 	return rc;
631*6ec4bedbSLiu Gang }
632*6ec4bedbSLiu Gang 
633*6ec4bedbSLiu Gang /**
634*6ec4bedbSLiu Gang  * fsl_rio_doorbell_send - Send a MPC85xx doorbell message
635*6ec4bedbSLiu Gang  * @mport: RapidIO master port info
636*6ec4bedbSLiu Gang  * @index: ID of RapidIO interface
637*6ec4bedbSLiu Gang  * @destid: Destination ID of target device
638*6ec4bedbSLiu Gang  * @data: 16-bit info field of RapidIO doorbell message
639*6ec4bedbSLiu Gang  *
640*6ec4bedbSLiu Gang  * Sends a MPC85xx doorbell message. Returns %0 on success or
641*6ec4bedbSLiu Gang  * %-EINVAL on failure.
642*6ec4bedbSLiu Gang  */
643*6ec4bedbSLiu Gang static int fsl_rio_doorbell_send(struct rio_mport *mport,
644*6ec4bedbSLiu Gang 				int index, u16 destid, u16 data)
645*6ec4bedbSLiu Gang {
646*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu = GET_RMM_HANDLE(mport);
647*6ec4bedbSLiu Gang 
648*6ec4bedbSLiu Gang 	pr_debug("fsl_doorbell_send: index %d destid %4.4x data %4.4x\n",
649*6ec4bedbSLiu Gang 		 index, destid, data);
650*6ec4bedbSLiu Gang 	switch (mport->phy_type) {
651*6ec4bedbSLiu Gang 	case RIO_PHY_PARALLEL:
652*6ec4bedbSLiu Gang 		out_be32(&rmu->dbell_atmu_regs->rowtar, destid << 22);
653*6ec4bedbSLiu Gang 		out_be16(rmu->dbell_win, data);
654*6ec4bedbSLiu Gang 		break;
655*6ec4bedbSLiu Gang 	case RIO_PHY_SERIAL:
656*6ec4bedbSLiu Gang 		/* In the serial version silicons, such as MPC8548, MPC8641,
657*6ec4bedbSLiu Gang 		 * below operations is must be.
658*6ec4bedbSLiu Gang 		 */
659*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->odmr, 0x00000000);
660*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->odretcr, 0x00000004);
661*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->oddpr, destid << 16);
662*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->oddatr, data);
663*6ec4bedbSLiu Gang 		out_be32(&rmu->msg_regs->odmr, 0x00000001);
664*6ec4bedbSLiu Gang 		break;
665*6ec4bedbSLiu Gang 	}
666*6ec4bedbSLiu Gang 
667*6ec4bedbSLiu Gang 	return 0;
668*6ec4bedbSLiu Gang }
669*6ec4bedbSLiu Gang 
670*6ec4bedbSLiu Gang /**
671*6ec4bedbSLiu Gang  * fsl_add_outb_message - Add message to the MPC85xx outbound message queue
672*6ec4bedbSLiu Gang  * @mport: Master port with outbound message queue
673*6ec4bedbSLiu Gang  * @rdev: Target of outbound message
674*6ec4bedbSLiu Gang  * @mbox: Outbound mailbox
675*6ec4bedbSLiu Gang  * @buffer: Message to add to outbound queue
676*6ec4bedbSLiu Gang  * @len: Length of message
677*6ec4bedbSLiu Gang  *
678*6ec4bedbSLiu Gang  * Adds the @buffer message to the MPC85xx outbound message queue. Returns
679*6ec4bedbSLiu Gang  * %0 on success or %-EINVAL on failure.
680*6ec4bedbSLiu Gang  */
681*6ec4bedbSLiu Gang static int
682*6ec4bedbSLiu Gang fsl_add_outb_message(struct rio_mport *mport, struct rio_dev *rdev, int mbox,
683*6ec4bedbSLiu Gang 			void *buffer, size_t len)
684*6ec4bedbSLiu Gang {
685*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu = GET_RMM_HANDLE(mport);
686*6ec4bedbSLiu Gang 	u32 omr;
687*6ec4bedbSLiu Gang 	struct rio_tx_desc *desc = (struct rio_tx_desc *)rmu->msg_tx_ring.virt
688*6ec4bedbSLiu Gang 					+ rmu->msg_tx_ring.tx_slot;
689*6ec4bedbSLiu Gang 	int ret = 0;
690*6ec4bedbSLiu Gang 
691*6ec4bedbSLiu Gang 	pr_debug("RIO: fsl_add_outb_message(): destid %4.4x mbox %d buffer " \
692*6ec4bedbSLiu Gang 		 "%8.8x len %8.8x\n", rdev->destid, mbox, (int)buffer, len);
693*6ec4bedbSLiu Gang 
694*6ec4bedbSLiu Gang 	if ((len < 8) || (len > RIO_MAX_MSG_SIZE)) {
695*6ec4bedbSLiu Gang 		ret = -EINVAL;
696*6ec4bedbSLiu Gang 		goto out;
697*6ec4bedbSLiu Gang 	}
698*6ec4bedbSLiu Gang 
699*6ec4bedbSLiu Gang 	/* Copy and clear rest of buffer */
700*6ec4bedbSLiu Gang 	memcpy(rmu->msg_tx_ring.virt_buffer[rmu->msg_tx_ring.tx_slot], buffer,
701*6ec4bedbSLiu Gang 			len);
702*6ec4bedbSLiu Gang 	if (len < (RIO_MAX_MSG_SIZE - 4))
703*6ec4bedbSLiu Gang 		memset(rmu->msg_tx_ring.virt_buffer[rmu->msg_tx_ring.tx_slot]
704*6ec4bedbSLiu Gang 				+ len, 0, RIO_MAX_MSG_SIZE - len);
705*6ec4bedbSLiu Gang 
706*6ec4bedbSLiu Gang 	switch (mport->phy_type) {
707*6ec4bedbSLiu Gang 	case RIO_PHY_PARALLEL:
708*6ec4bedbSLiu Gang 		/* Set mbox field for message */
709*6ec4bedbSLiu Gang 		desc->dport = mbox & 0x3;
710*6ec4bedbSLiu Gang 
711*6ec4bedbSLiu Gang 		/* Enable EOMI interrupt, set priority, and set destid */
712*6ec4bedbSLiu Gang 		desc->dattr = 0x28000000 | (rdev->destid << 2);
713*6ec4bedbSLiu Gang 		break;
714*6ec4bedbSLiu Gang 	case RIO_PHY_SERIAL:
715*6ec4bedbSLiu Gang 		/* Set mbox field for message, and set destid */
716*6ec4bedbSLiu Gang 		desc->dport = (rdev->destid << 16) | (mbox & 0x3);
717*6ec4bedbSLiu Gang 
718*6ec4bedbSLiu Gang 		/* Enable EOMI interrupt and priority */
719*6ec4bedbSLiu Gang 		desc->dattr = 0x28000000;
720*6ec4bedbSLiu Gang 		break;
721*6ec4bedbSLiu Gang 	}
722*6ec4bedbSLiu Gang 
723*6ec4bedbSLiu Gang 	/* Set transfer size aligned to next power of 2 (in double words) */
724*6ec4bedbSLiu Gang 	desc->dwcnt = is_power_of_2(len) ? len : 1 << get_bitmask_order(len);
725*6ec4bedbSLiu Gang 
726*6ec4bedbSLiu Gang 	/* Set snooping and source buffer address */
727*6ec4bedbSLiu Gang 	desc->saddr = 0x00000004
728*6ec4bedbSLiu Gang 		| rmu->msg_tx_ring.phys_buffer[rmu->msg_tx_ring.tx_slot];
729*6ec4bedbSLiu Gang 
730*6ec4bedbSLiu Gang 	/* Increment enqueue pointer */
731*6ec4bedbSLiu Gang 	omr = in_be32(&rmu->msg_regs->omr);
732*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->omr, omr | RIO_MSG_OMR_MUI);
733*6ec4bedbSLiu Gang 
734*6ec4bedbSLiu Gang 	/* Go to next descriptor */
735*6ec4bedbSLiu Gang 	if (++rmu->msg_tx_ring.tx_slot == rmu->msg_tx_ring.size)
736*6ec4bedbSLiu Gang 		rmu->msg_tx_ring.tx_slot = 0;
737*6ec4bedbSLiu Gang 
738*6ec4bedbSLiu Gang out:
739*6ec4bedbSLiu Gang 	return ret;
740*6ec4bedbSLiu Gang }
741*6ec4bedbSLiu Gang 
742*6ec4bedbSLiu Gang /**
743*6ec4bedbSLiu Gang  * fsl_open_outb_mbox - Initialize MPC85xx outbound mailbox
744*6ec4bedbSLiu Gang  * @mport: Master port implementing the outbound message unit
745*6ec4bedbSLiu Gang  * @dev_id: Device specific pointer to pass on event
746*6ec4bedbSLiu Gang  * @mbox: Mailbox to open
747*6ec4bedbSLiu Gang  * @entries: Number of entries in the outbound mailbox ring
748*6ec4bedbSLiu Gang  *
749*6ec4bedbSLiu Gang  * Initializes buffer ring, request the outbound message interrupt,
750*6ec4bedbSLiu Gang  * and enables the outbound message unit. Returns %0 on success and
751*6ec4bedbSLiu Gang  * %-EINVAL or %-ENOMEM on failure.
752*6ec4bedbSLiu Gang  */
753*6ec4bedbSLiu Gang static int
754*6ec4bedbSLiu Gang fsl_open_outb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
755*6ec4bedbSLiu Gang {
756*6ec4bedbSLiu Gang 	int i, j, rc = 0;
757*6ec4bedbSLiu Gang 	struct rio_priv *priv = mport->priv;
758*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu = GET_RMM_HANDLE(mport);
759*6ec4bedbSLiu Gang 
760*6ec4bedbSLiu Gang 	if ((entries < RIO_MIN_TX_RING_SIZE) ||
761*6ec4bedbSLiu Gang 		(entries > RIO_MAX_TX_RING_SIZE) || (!is_power_of_2(entries))) {
762*6ec4bedbSLiu Gang 		rc = -EINVAL;
763*6ec4bedbSLiu Gang 		goto out;
764*6ec4bedbSLiu Gang 	}
765*6ec4bedbSLiu Gang 
766*6ec4bedbSLiu Gang 	/* Initialize shadow copy ring */
767*6ec4bedbSLiu Gang 	rmu->msg_tx_ring.dev_id = dev_id;
768*6ec4bedbSLiu Gang 	rmu->msg_tx_ring.size = entries;
769*6ec4bedbSLiu Gang 
770*6ec4bedbSLiu Gang 	for (i = 0; i < rmu->msg_tx_ring.size; i++) {
771*6ec4bedbSLiu Gang 		rmu->msg_tx_ring.virt_buffer[i] =
772*6ec4bedbSLiu Gang 			dma_alloc_coherent(priv->dev, RIO_MSG_BUFFER_SIZE,
773*6ec4bedbSLiu Gang 				&rmu->msg_tx_ring.phys_buffer[i], GFP_KERNEL);
774*6ec4bedbSLiu Gang 		if (!rmu->msg_tx_ring.virt_buffer[i]) {
775*6ec4bedbSLiu Gang 			rc = -ENOMEM;
776*6ec4bedbSLiu Gang 			for (j = 0; j < rmu->msg_tx_ring.size; j++)
777*6ec4bedbSLiu Gang 				if (rmu->msg_tx_ring.virt_buffer[j])
778*6ec4bedbSLiu Gang 					dma_free_coherent(priv->dev,
779*6ec4bedbSLiu Gang 							RIO_MSG_BUFFER_SIZE,
780*6ec4bedbSLiu Gang 							rmu->msg_tx_ring.
781*6ec4bedbSLiu Gang 							virt_buffer[j],
782*6ec4bedbSLiu Gang 							rmu->msg_tx_ring.
783*6ec4bedbSLiu Gang 							phys_buffer[j]);
784*6ec4bedbSLiu Gang 			goto out;
785*6ec4bedbSLiu Gang 		}
786*6ec4bedbSLiu Gang 	}
787*6ec4bedbSLiu Gang 
788*6ec4bedbSLiu Gang 	/* Initialize outbound message descriptor ring */
789*6ec4bedbSLiu Gang 	rmu->msg_tx_ring.virt = dma_alloc_coherent(priv->dev,
790*6ec4bedbSLiu Gang 				rmu->msg_tx_ring.size * RIO_MSG_DESC_SIZE,
791*6ec4bedbSLiu Gang 				&rmu->msg_tx_ring.phys, GFP_KERNEL);
792*6ec4bedbSLiu Gang 	if (!rmu->msg_tx_ring.virt) {
793*6ec4bedbSLiu Gang 		rc = -ENOMEM;
794*6ec4bedbSLiu Gang 		goto out_dma;
795*6ec4bedbSLiu Gang 	}
796*6ec4bedbSLiu Gang 	memset(rmu->msg_tx_ring.virt, 0,
797*6ec4bedbSLiu Gang 			rmu->msg_tx_ring.size * RIO_MSG_DESC_SIZE);
798*6ec4bedbSLiu Gang 	rmu->msg_tx_ring.tx_slot = 0;
799*6ec4bedbSLiu Gang 
800*6ec4bedbSLiu Gang 	/* Point dequeue/enqueue pointers at first entry in ring */
801*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->odqdpar, rmu->msg_tx_ring.phys);
802*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->odqepar, rmu->msg_tx_ring.phys);
803*6ec4bedbSLiu Gang 
804*6ec4bedbSLiu Gang 	/* Configure for snooping */
805*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->osar, 0x00000004);
806*6ec4bedbSLiu Gang 
807*6ec4bedbSLiu Gang 	/* Clear interrupt status */
808*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->osr, 0x000000b3);
809*6ec4bedbSLiu Gang 
810*6ec4bedbSLiu Gang 	/* Hook up outbound message handler */
811*6ec4bedbSLiu Gang 	rc = request_irq(IRQ_RIO_TX(mport), fsl_rio_tx_handler, 0,
812*6ec4bedbSLiu Gang 			 "msg_tx", (void *)mport);
813*6ec4bedbSLiu Gang 	if (rc < 0)
814*6ec4bedbSLiu Gang 		goto out_irq;
815*6ec4bedbSLiu Gang 
816*6ec4bedbSLiu Gang 	/*
817*6ec4bedbSLiu Gang 	 * Configure outbound message unit
818*6ec4bedbSLiu Gang 	 *      Snooping
819*6ec4bedbSLiu Gang 	 *      Interrupts (all enabled, except QEIE)
820*6ec4bedbSLiu Gang 	 *      Chaining mode
821*6ec4bedbSLiu Gang 	 *      Disable
822*6ec4bedbSLiu Gang 	 */
823*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->omr, 0x00100220);
824*6ec4bedbSLiu Gang 
825*6ec4bedbSLiu Gang 	/* Set number of entries */
826*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->omr,
827*6ec4bedbSLiu Gang 		 in_be32(&rmu->msg_regs->omr) |
828*6ec4bedbSLiu Gang 		 ((get_bitmask_order(entries) - 2) << 12));
829*6ec4bedbSLiu Gang 
830*6ec4bedbSLiu Gang 	/* Now enable the unit */
831*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->omr, in_be32(&rmu->msg_regs->omr) | 0x1);
832*6ec4bedbSLiu Gang 
833*6ec4bedbSLiu Gang out:
834*6ec4bedbSLiu Gang 	return rc;
835*6ec4bedbSLiu Gang 
836*6ec4bedbSLiu Gang out_irq:
837*6ec4bedbSLiu Gang 	dma_free_coherent(priv->dev,
838*6ec4bedbSLiu Gang 		rmu->msg_tx_ring.size * RIO_MSG_DESC_SIZE,
839*6ec4bedbSLiu Gang 		rmu->msg_tx_ring.virt, rmu->msg_tx_ring.phys);
840*6ec4bedbSLiu Gang 
841*6ec4bedbSLiu Gang out_dma:
842*6ec4bedbSLiu Gang 	for (i = 0; i < rmu->msg_tx_ring.size; i++)
843*6ec4bedbSLiu Gang 		dma_free_coherent(priv->dev, RIO_MSG_BUFFER_SIZE,
844*6ec4bedbSLiu Gang 		rmu->msg_tx_ring.virt_buffer[i],
845*6ec4bedbSLiu Gang 		rmu->msg_tx_ring.phys_buffer[i]);
846*6ec4bedbSLiu Gang 
847*6ec4bedbSLiu Gang 	return rc;
848*6ec4bedbSLiu Gang }
849*6ec4bedbSLiu Gang 
850*6ec4bedbSLiu Gang /**
851*6ec4bedbSLiu Gang  * fsl_close_outb_mbox - Shut down MPC85xx outbound mailbox
852*6ec4bedbSLiu Gang  * @mport: Master port implementing the outbound message unit
853*6ec4bedbSLiu Gang  * @mbox: Mailbox to close
854*6ec4bedbSLiu Gang  *
855*6ec4bedbSLiu Gang  * Disables the outbound message unit, free all buffers, and
856*6ec4bedbSLiu Gang  * frees the outbound message interrupt.
857*6ec4bedbSLiu Gang  */
858*6ec4bedbSLiu Gang static void fsl_close_outb_mbox(struct rio_mport *mport, int mbox)
859*6ec4bedbSLiu Gang {
860*6ec4bedbSLiu Gang 	struct rio_priv *priv = mport->priv;
861*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu = GET_RMM_HANDLE(mport);
862*6ec4bedbSLiu Gang 
863*6ec4bedbSLiu Gang 	/* Disable inbound message unit */
864*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->omr, 0);
865*6ec4bedbSLiu Gang 
866*6ec4bedbSLiu Gang 	/* Free ring */
867*6ec4bedbSLiu Gang 	dma_free_coherent(priv->dev,
868*6ec4bedbSLiu Gang 	rmu->msg_tx_ring.size * RIO_MSG_DESC_SIZE,
869*6ec4bedbSLiu Gang 	rmu->msg_tx_ring.virt, rmu->msg_tx_ring.phys);
870*6ec4bedbSLiu Gang 
871*6ec4bedbSLiu Gang 	/* Free interrupt */
872*6ec4bedbSLiu Gang 	free_irq(IRQ_RIO_TX(mport), (void *)mport);
873*6ec4bedbSLiu Gang }
874*6ec4bedbSLiu Gang 
875*6ec4bedbSLiu Gang /**
876*6ec4bedbSLiu Gang  * fsl_open_inb_mbox - Initialize MPC85xx inbound mailbox
877*6ec4bedbSLiu Gang  * @mport: Master port implementing the inbound message unit
878*6ec4bedbSLiu Gang  * @dev_id: Device specific pointer to pass on event
879*6ec4bedbSLiu Gang  * @mbox: Mailbox to open
880*6ec4bedbSLiu Gang  * @entries: Number of entries in the inbound mailbox ring
881*6ec4bedbSLiu Gang  *
882*6ec4bedbSLiu Gang  * Initializes buffer ring, request the inbound message interrupt,
883*6ec4bedbSLiu Gang  * and enables the inbound message unit. Returns %0 on success
884*6ec4bedbSLiu Gang  * and %-EINVAL or %-ENOMEM on failure.
885*6ec4bedbSLiu Gang  */
886*6ec4bedbSLiu Gang static int
887*6ec4bedbSLiu Gang fsl_open_inb_mbox(struct rio_mport *mport, void *dev_id, int mbox, int entries)
888*6ec4bedbSLiu Gang {
889*6ec4bedbSLiu Gang 	int i, rc = 0;
890*6ec4bedbSLiu Gang 	struct rio_priv *priv = mport->priv;
891*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu = GET_RMM_HANDLE(mport);
892*6ec4bedbSLiu Gang 
893*6ec4bedbSLiu Gang 	if ((entries < RIO_MIN_RX_RING_SIZE) ||
894*6ec4bedbSLiu Gang 		(entries > RIO_MAX_RX_RING_SIZE) || (!is_power_of_2(entries))) {
895*6ec4bedbSLiu Gang 		rc = -EINVAL;
896*6ec4bedbSLiu Gang 		goto out;
897*6ec4bedbSLiu Gang 	}
898*6ec4bedbSLiu Gang 
899*6ec4bedbSLiu Gang 	/* Initialize client buffer ring */
900*6ec4bedbSLiu Gang 	rmu->msg_rx_ring.dev_id = dev_id;
901*6ec4bedbSLiu Gang 	rmu->msg_rx_ring.size = entries;
902*6ec4bedbSLiu Gang 	rmu->msg_rx_ring.rx_slot = 0;
903*6ec4bedbSLiu Gang 	for (i = 0; i < rmu->msg_rx_ring.size; i++)
904*6ec4bedbSLiu Gang 		rmu->msg_rx_ring.virt_buffer[i] = NULL;
905*6ec4bedbSLiu Gang 
906*6ec4bedbSLiu Gang 	/* Initialize inbound message ring */
907*6ec4bedbSLiu Gang 	rmu->msg_rx_ring.virt = dma_alloc_coherent(priv->dev,
908*6ec4bedbSLiu Gang 				rmu->msg_rx_ring.size * RIO_MAX_MSG_SIZE,
909*6ec4bedbSLiu Gang 				&rmu->msg_rx_ring.phys, GFP_KERNEL);
910*6ec4bedbSLiu Gang 	if (!rmu->msg_rx_ring.virt) {
911*6ec4bedbSLiu Gang 		rc = -ENOMEM;
912*6ec4bedbSLiu Gang 		goto out;
913*6ec4bedbSLiu Gang 	}
914*6ec4bedbSLiu Gang 
915*6ec4bedbSLiu Gang 	/* Point dequeue/enqueue pointers at first entry in ring */
916*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->ifqdpar, (u32) rmu->msg_rx_ring.phys);
917*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->ifqepar, (u32) rmu->msg_rx_ring.phys);
918*6ec4bedbSLiu Gang 
919*6ec4bedbSLiu Gang 	/* Clear interrupt status */
920*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->isr, 0x00000091);
921*6ec4bedbSLiu Gang 
922*6ec4bedbSLiu Gang 	/* Hook up inbound message handler */
923*6ec4bedbSLiu Gang 	rc = request_irq(IRQ_RIO_RX(mport), fsl_rio_rx_handler, 0,
924*6ec4bedbSLiu Gang 			 "msg_rx", (void *)mport);
925*6ec4bedbSLiu Gang 	if (rc < 0) {
926*6ec4bedbSLiu Gang 		dma_free_coherent(priv->dev, RIO_MSG_BUFFER_SIZE,
927*6ec4bedbSLiu Gang 			rmu->msg_tx_ring.virt_buffer[i],
928*6ec4bedbSLiu Gang 			rmu->msg_tx_ring.phys_buffer[i]);
929*6ec4bedbSLiu Gang 		goto out;
930*6ec4bedbSLiu Gang 	}
931*6ec4bedbSLiu Gang 
932*6ec4bedbSLiu Gang 	/*
933*6ec4bedbSLiu Gang 	 * Configure inbound message unit:
934*6ec4bedbSLiu Gang 	 *      Snooping
935*6ec4bedbSLiu Gang 	 *      4KB max message size
936*6ec4bedbSLiu Gang 	 *      Unmask all interrupt sources
937*6ec4bedbSLiu Gang 	 *      Disable
938*6ec4bedbSLiu Gang 	 */
939*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->imr, 0x001b0060);
940*6ec4bedbSLiu Gang 
941*6ec4bedbSLiu Gang 	/* Set number of queue entries */
942*6ec4bedbSLiu Gang 	setbits32(&rmu->msg_regs->imr, (get_bitmask_order(entries) - 2) << 12);
943*6ec4bedbSLiu Gang 
944*6ec4bedbSLiu Gang 	/* Now enable the unit */
945*6ec4bedbSLiu Gang 	setbits32(&rmu->msg_regs->imr, 0x1);
946*6ec4bedbSLiu Gang 
947*6ec4bedbSLiu Gang out:
948*6ec4bedbSLiu Gang 	return rc;
949*6ec4bedbSLiu Gang }
950*6ec4bedbSLiu Gang 
951*6ec4bedbSLiu Gang /**
952*6ec4bedbSLiu Gang  * fsl_close_inb_mbox - Shut down MPC85xx inbound mailbox
953*6ec4bedbSLiu Gang  * @mport: Master port implementing the inbound message unit
954*6ec4bedbSLiu Gang  * @mbox: Mailbox to close
955*6ec4bedbSLiu Gang  *
956*6ec4bedbSLiu Gang  * Disables the inbound message unit, free all buffers, and
957*6ec4bedbSLiu Gang  * frees the inbound message interrupt.
958*6ec4bedbSLiu Gang  */
959*6ec4bedbSLiu Gang static void fsl_close_inb_mbox(struct rio_mport *mport, int mbox)
960*6ec4bedbSLiu Gang {
961*6ec4bedbSLiu Gang 	struct rio_priv *priv = mport->priv;
962*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu = GET_RMM_HANDLE(mport);
963*6ec4bedbSLiu Gang 
964*6ec4bedbSLiu Gang 	/* Disable inbound message unit */
965*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->imr, 0);
966*6ec4bedbSLiu Gang 
967*6ec4bedbSLiu Gang 	/* Free ring */
968*6ec4bedbSLiu Gang 	dma_free_coherent(priv->dev, rmu->msg_rx_ring.size * RIO_MAX_MSG_SIZE,
969*6ec4bedbSLiu Gang 			  rmu->msg_rx_ring.virt, rmu->msg_rx_ring.phys);
970*6ec4bedbSLiu Gang 
971*6ec4bedbSLiu Gang 	/* Free interrupt */
972*6ec4bedbSLiu Gang 	free_irq(IRQ_RIO_RX(mport), (void *)mport);
973*6ec4bedbSLiu Gang }
974*6ec4bedbSLiu Gang 
975*6ec4bedbSLiu Gang /**
976*6ec4bedbSLiu Gang  * fsl_add_inb_buffer - Add buffer to the MPC85xx inbound message queue
977*6ec4bedbSLiu Gang  * @mport: Master port implementing the inbound message unit
978*6ec4bedbSLiu Gang  * @mbox: Inbound mailbox number
979*6ec4bedbSLiu Gang  * @buf: Buffer to add to inbound queue
980*6ec4bedbSLiu Gang  *
981*6ec4bedbSLiu Gang  * Adds the @buf buffer to the MPC85xx inbound message queue. Returns
982*6ec4bedbSLiu Gang  * %0 on success or %-EINVAL on failure.
983*6ec4bedbSLiu Gang  */
984*6ec4bedbSLiu Gang static int fsl_add_inb_buffer(struct rio_mport *mport, int mbox, void *buf)
985*6ec4bedbSLiu Gang {
986*6ec4bedbSLiu Gang 	int rc = 0;
987*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu = GET_RMM_HANDLE(mport);
988*6ec4bedbSLiu Gang 
989*6ec4bedbSLiu Gang 	pr_debug("RIO: fsl_add_inb_buffer(), msg_rx_ring.rx_slot %d\n",
990*6ec4bedbSLiu Gang 		 rmu->msg_rx_ring.rx_slot);
991*6ec4bedbSLiu Gang 
992*6ec4bedbSLiu Gang 	if (rmu->msg_rx_ring.virt_buffer[rmu->msg_rx_ring.rx_slot]) {
993*6ec4bedbSLiu Gang 		printk(KERN_ERR
994*6ec4bedbSLiu Gang 			"RIO: error adding inbound buffer %d, buffer exists\n",
995*6ec4bedbSLiu Gang 			rmu->msg_rx_ring.rx_slot);
996*6ec4bedbSLiu Gang 		rc = -EINVAL;
997*6ec4bedbSLiu Gang 		goto out;
998*6ec4bedbSLiu Gang 	}
999*6ec4bedbSLiu Gang 
1000*6ec4bedbSLiu Gang 	rmu->msg_rx_ring.virt_buffer[rmu->msg_rx_ring.rx_slot] = buf;
1001*6ec4bedbSLiu Gang 	if (++rmu->msg_rx_ring.rx_slot == rmu->msg_rx_ring.size)
1002*6ec4bedbSLiu Gang 		rmu->msg_rx_ring.rx_slot = 0;
1003*6ec4bedbSLiu Gang 
1004*6ec4bedbSLiu Gang out:
1005*6ec4bedbSLiu Gang 	return rc;
1006*6ec4bedbSLiu Gang }
1007*6ec4bedbSLiu Gang 
1008*6ec4bedbSLiu Gang /**
1009*6ec4bedbSLiu Gang  * fsl_get_inb_message - Fetch inbound message from the MPC85xx message unit
1010*6ec4bedbSLiu Gang  * @mport: Master port implementing the inbound message unit
1011*6ec4bedbSLiu Gang  * @mbox: Inbound mailbox number
1012*6ec4bedbSLiu Gang  *
1013*6ec4bedbSLiu Gang  * Gets the next available inbound message from the inbound message queue.
1014*6ec4bedbSLiu Gang  * A pointer to the message is returned on success or NULL on failure.
1015*6ec4bedbSLiu Gang  */
1016*6ec4bedbSLiu Gang static void *fsl_get_inb_message(struct rio_mport *mport, int mbox)
1017*6ec4bedbSLiu Gang {
1018*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu = GET_RMM_HANDLE(mport);
1019*6ec4bedbSLiu Gang 	u32 phys_buf, virt_buf;
1020*6ec4bedbSLiu Gang 	void *buf = NULL;
1021*6ec4bedbSLiu Gang 	int buf_idx;
1022*6ec4bedbSLiu Gang 
1023*6ec4bedbSLiu Gang 	phys_buf = in_be32(&rmu->msg_regs->ifqdpar);
1024*6ec4bedbSLiu Gang 
1025*6ec4bedbSLiu Gang 	/* If no more messages, then bail out */
1026*6ec4bedbSLiu Gang 	if (phys_buf == in_be32(&rmu->msg_regs->ifqepar))
1027*6ec4bedbSLiu Gang 		goto out2;
1028*6ec4bedbSLiu Gang 
1029*6ec4bedbSLiu Gang 	virt_buf = (u32) rmu->msg_rx_ring.virt + (phys_buf
1030*6ec4bedbSLiu Gang 						- rmu->msg_rx_ring.phys);
1031*6ec4bedbSLiu Gang 	buf_idx = (phys_buf - rmu->msg_rx_ring.phys) / RIO_MAX_MSG_SIZE;
1032*6ec4bedbSLiu Gang 	buf = rmu->msg_rx_ring.virt_buffer[buf_idx];
1033*6ec4bedbSLiu Gang 
1034*6ec4bedbSLiu Gang 	if (!buf) {
1035*6ec4bedbSLiu Gang 		printk(KERN_ERR
1036*6ec4bedbSLiu Gang 			"RIO: inbound message copy failed, no buffers\n");
1037*6ec4bedbSLiu Gang 		goto out1;
1038*6ec4bedbSLiu Gang 	}
1039*6ec4bedbSLiu Gang 
1040*6ec4bedbSLiu Gang 	/* Copy max message size, caller is expected to allocate that big */
1041*6ec4bedbSLiu Gang 	memcpy(buf, (void *)virt_buf, RIO_MAX_MSG_SIZE);
1042*6ec4bedbSLiu Gang 
1043*6ec4bedbSLiu Gang 	/* Clear the available buffer */
1044*6ec4bedbSLiu Gang 	rmu->msg_rx_ring.virt_buffer[buf_idx] = NULL;
1045*6ec4bedbSLiu Gang 
1046*6ec4bedbSLiu Gang out1:
1047*6ec4bedbSLiu Gang 	setbits32(&rmu->msg_regs->imr, RIO_MSG_IMR_MI);
1048*6ec4bedbSLiu Gang 
1049*6ec4bedbSLiu Gang out2:
1050*6ec4bedbSLiu Gang 	return buf;
1051*6ec4bedbSLiu Gang }
1052*6ec4bedbSLiu Gang 
1053*6ec4bedbSLiu Gang /**
1054*6ec4bedbSLiu Gang  * fsl_rio_doorbell_init - MPC85xx doorbell interface init
1055*6ec4bedbSLiu Gang  * @mport: Master port implementing the inbound doorbell unit
1056*6ec4bedbSLiu Gang  *
1057*6ec4bedbSLiu Gang  * Initializes doorbell unit hardware and inbound DMA buffer
1058*6ec4bedbSLiu Gang  * ring. Called from fsl_rio_setup(). Returns %0 on success
1059*6ec4bedbSLiu Gang  * or %-ENOMEM on failure.
1060*6ec4bedbSLiu Gang  */
1061*6ec4bedbSLiu Gang static int fsl_rio_doorbell_init(struct rio_mport *mport)
1062*6ec4bedbSLiu Gang {
1063*6ec4bedbSLiu Gang 	struct rio_priv *priv = mport->priv;
1064*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu = GET_RMM_HANDLE(mport);
1065*6ec4bedbSLiu Gang 	int rc = 0;
1066*6ec4bedbSLiu Gang 
1067*6ec4bedbSLiu Gang 	/* Map outbound doorbell window immediately after maintenance window */
1068*6ec4bedbSLiu Gang 	rmu->dbell_win = ioremap(mport->iores.start + RIO_MAINT_WIN_SIZE,
1069*6ec4bedbSLiu Gang 		RIO_DBELL_WIN_SIZE);
1070*6ec4bedbSLiu Gang 	if (!rmu->dbell_win) {
1071*6ec4bedbSLiu Gang 		printk(KERN_ERR
1072*6ec4bedbSLiu Gang 			"RIO: unable to map outbound doorbell window\n");
1073*6ec4bedbSLiu Gang 		rc = -ENOMEM;
1074*6ec4bedbSLiu Gang 		goto out;
1075*6ec4bedbSLiu Gang 	}
1076*6ec4bedbSLiu Gang 
1077*6ec4bedbSLiu Gang 	/* Initialize inbound doorbells */
1078*6ec4bedbSLiu Gang 	rmu->dbell_ring.virt = dma_alloc_coherent(priv->dev, 512 *
1079*6ec4bedbSLiu Gang 		DOORBELL_MESSAGE_SIZE, &rmu->dbell_ring.phys, GFP_KERNEL);
1080*6ec4bedbSLiu Gang 	if (!rmu->dbell_ring.virt) {
1081*6ec4bedbSLiu Gang 		printk(KERN_ERR "RIO: unable allocate inbound doorbell ring\n");
1082*6ec4bedbSLiu Gang 		rc = -ENOMEM;
1083*6ec4bedbSLiu Gang 		iounmap(rmu->dbell_win);
1084*6ec4bedbSLiu Gang 		goto out;
1085*6ec4bedbSLiu Gang 	}
1086*6ec4bedbSLiu Gang 
1087*6ec4bedbSLiu Gang 	/* Point dequeue/enqueue pointers at first entry in ring */
1088*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->dqdpar, (u32) rmu->dbell_ring.phys);
1089*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->dqepar, (u32) rmu->dbell_ring.phys);
1090*6ec4bedbSLiu Gang 
1091*6ec4bedbSLiu Gang 	/* Clear interrupt status */
1092*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->dsr, 0x00000091);
1093*6ec4bedbSLiu Gang 
1094*6ec4bedbSLiu Gang 	/* Hook up doorbell handler */
1095*6ec4bedbSLiu Gang 	rc = request_irq(IRQ_RIO_BELL(mport), fsl_rio_dbell_handler, 0,
1096*6ec4bedbSLiu Gang 			 "dbell_rx", (void *)mport);
1097*6ec4bedbSLiu Gang 	if (rc < 0) {
1098*6ec4bedbSLiu Gang 		iounmap(rmu->dbell_win);
1099*6ec4bedbSLiu Gang 		dma_free_coherent(priv->dev, 512 * DOORBELL_MESSAGE_SIZE,
1100*6ec4bedbSLiu Gang 			rmu->dbell_ring.virt, rmu->dbell_ring.phys);
1101*6ec4bedbSLiu Gang 		printk(KERN_ERR
1102*6ec4bedbSLiu Gang 			"MPC85xx RIO: unable to request inbound doorbell irq");
1103*6ec4bedbSLiu Gang 		goto out;
1104*6ec4bedbSLiu Gang 	}
1105*6ec4bedbSLiu Gang 
1106*6ec4bedbSLiu Gang 	/* Configure doorbells for snooping, 512 entries, and enable */
1107*6ec4bedbSLiu Gang 	out_be32(&rmu->msg_regs->dmr, 0x00108161);
1108*6ec4bedbSLiu Gang 
1109*6ec4bedbSLiu Gang out:
1110*6ec4bedbSLiu Gang 	return rc;
1111*6ec4bedbSLiu Gang }
1112*6ec4bedbSLiu Gang 
1113*6ec4bedbSLiu Gang int fsl_rio_setup_rmu(struct rio_mport *mport, struct device_node *node)
1114*6ec4bedbSLiu Gang {
1115*6ec4bedbSLiu Gang 	struct rio_priv *priv;
1116*6ec4bedbSLiu Gang 	struct fsl_rmu *rmu;
1117*6ec4bedbSLiu Gang 	struct rio_ops *ops;
1118*6ec4bedbSLiu Gang 
1119*6ec4bedbSLiu Gang 	if (!mport || !mport->priv || !node)
1120*6ec4bedbSLiu Gang 		return -1;
1121*6ec4bedbSLiu Gang 
1122*6ec4bedbSLiu Gang 	rmu = kzalloc(sizeof(struct fsl_rmu), GFP_KERNEL);
1123*6ec4bedbSLiu Gang 	if (!rmu)
1124*6ec4bedbSLiu Gang 		return -ENOMEM;
1125*6ec4bedbSLiu Gang 
1126*6ec4bedbSLiu Gang 	priv = mport->priv;
1127*6ec4bedbSLiu Gang 	priv->rmm_handle = rmu;
1128*6ec4bedbSLiu Gang 	rmu->dbell_atmu_regs = priv->atmu_regs + 2;
1129*6ec4bedbSLiu Gang 	rmu->msg_regs = (struct rio_msg_regs *)(priv->regs_win +
1130*6ec4bedbSLiu Gang 			 ((mport->phy_type == RIO_PHY_SERIAL) ?
1131*6ec4bedbSLiu Gang 			 RIO_S_MSG_REGS_OFFSET : RIO_P_MSG_REGS_OFFSET));
1132*6ec4bedbSLiu Gang 
1133*6ec4bedbSLiu Gang 	rmu->bellirq = irq_of_parse_and_map(node, 2);
1134*6ec4bedbSLiu Gang 	rmu->txirq = irq_of_parse_and_map(node, 3);
1135*6ec4bedbSLiu Gang 	rmu->rxirq = irq_of_parse_and_map(node, 4);
1136*6ec4bedbSLiu Gang 	dev_info(priv->dev, "bellirq: %d, txirq: %d, rxirq %d\n",
1137*6ec4bedbSLiu Gang 			rmu->bellirq, rmu->txirq, rmu->rxirq);
1138*6ec4bedbSLiu Gang 
1139*6ec4bedbSLiu Gang 	ops = mport->ops;
1140*6ec4bedbSLiu Gang 
1141*6ec4bedbSLiu Gang 	ops->dsend = fsl_rio_doorbell_send;
1142*6ec4bedbSLiu Gang 	ops->open_outb_mbox = fsl_open_outb_mbox;
1143*6ec4bedbSLiu Gang 	ops->open_inb_mbox = fsl_open_inb_mbox;
1144*6ec4bedbSLiu Gang 	ops->close_outb_mbox = fsl_close_outb_mbox;
1145*6ec4bedbSLiu Gang 	ops->close_inb_mbox = fsl_close_inb_mbox;
1146*6ec4bedbSLiu Gang 	ops->add_outb_message = fsl_add_outb_message;
1147*6ec4bedbSLiu Gang 	ops->add_inb_buffer = fsl_add_inb_buffer;
1148*6ec4bedbSLiu Gang 	ops->get_inb_message = fsl_get_inb_message;
1149*6ec4bedbSLiu Gang 
1150*6ec4bedbSLiu Gang 	rio_init_dbell_res(&mport->riores[RIO_DOORBELL_RESOURCE], 0, 0xffff);
1151*6ec4bedbSLiu Gang 	rio_init_mbox_res(&mport->riores[RIO_INB_MBOX_RESOURCE], 0, 0);
1152*6ec4bedbSLiu Gang 	rio_init_mbox_res(&mport->riores[RIO_OUTB_MBOX_RESOURCE], 0, 0);
1153*6ec4bedbSLiu Gang 
1154*6ec4bedbSLiu Gang 	/* Configure outbound doorbell window */
1155*6ec4bedbSLiu Gang 	out_be32(&rmu->dbell_atmu_regs->rowbar,
1156*6ec4bedbSLiu Gang 			(mport->iores.start + RIO_MAINT_WIN_SIZE) >> 12);
1157*6ec4bedbSLiu Gang 	/* 4k window size */
1158*6ec4bedbSLiu Gang 	out_be32(&rmu->dbell_atmu_regs->rowar, 0x8004200b);
1159*6ec4bedbSLiu Gang 
1160*6ec4bedbSLiu Gang 	fsl_rio_doorbell_init(mport);
1161*6ec4bedbSLiu Gang 
1162*6ec4bedbSLiu Gang 	return 0;
1163*6ec4bedbSLiu Gang }
1164