xref: /netbsd-src/sys/arch/evbppc/ev64260/gt_mainbus.c (revision cd4f72f2664d69a50e2678cb8a6f158444231783)
1 /*	$NetBSD: gt_mainbus.c,v 1.18 2013/04/21 15:42:11 kiyohara Exp $	*/
2 
3 /*
4  * Copyright (c) 2002 Wasabi Systems, Inc.
5  * All rights reserved.
6  *
7  * Written by Allen Briggs for Wasabi Systems, Inc.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. All advertising materials mentioning features or use of this software
18  *    must display the following acknowledgement:
19  *      This product includes software developed for the NetBSD Project by
20  *      Wasabi Systems, Inc.
21  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22  *    or promote products derived from this software without specific prior
23  *    written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35  * POSSIBILITY OF SUCH DAMAGE.
36  */
37 
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: gt_mainbus.c,v 1.18 2013/04/21 15:42:11 kiyohara Exp $");
40 
41 #include "opt_ev64260.h"
42 #include "opt_pci.h"
43 #include "pci.h"
44 
45 #include <sys/types.h>
46 #include <sys/param.h>
47 #include <sys/device.h>
48 #include <sys/errno.h>
49 #include <sys/extent.h>
50 
51 #define _POWERPC_BUS_DMA_PRIVATE
52 #include <sys/bus.h>
53 
54 #include "opt_pci.h"
55 #include <dev/pci/pcivar.h>
56 #include <dev/pci/pciconf.h>
57 
58 #include "opt_marvell.h"
59 #include <dev/marvell/gtreg.h>
60 #include <dev/marvell/gtvar.h>
61 #include <dev/marvell/gtintrreg.h>
62 #include <dev/marvell/gtpcireg.h>
63 #include <dev/marvell/gtpcivar.h>
64 #include <dev/marvell/marvellvar.h>
65 #include <dev/marvell/gtsdmareg.h>
66 #include <dev/marvell/gtmpscreg.h>
67 #ifdef MPSC_CONSOLE
68 #include <dev/marvell/gtmpscvar.h>
69 #endif
70 
71 #include <evbppc/ev64260/ev64260.h>
72 
73 #include <powerpc/pic/picvar.h>
74 
75 
76 static int gt_match(device_t, cfdata_t, void *);
77 static void gt_attach(device_t, device_t, void *);
78 
79 void gtpci_md_conf_interrupt(void *, int, int, int, int, int *);
80 int gtpci_md_conf_hook(void *, int, int, int, pcireg_t);
81 
82 CFATTACH_DECL_NEW(gt, sizeof(struct gt_softc), gt_match, gt_attach, NULL, NULL);
83 
84 struct gtpci_prot gtpci_prot = {
85 	GTPCI_GT64260_ACBL_PCISWAP_NOSWAP	|
86 	GTPCI_GT64260_ACBL_WBURST_8_QW		|
87 	GTPCI_GT64260_ACBL_RDMULPREFETCH	|
88 	GTPCI_GT64260_ACBL_RDLINEPREFETCH	|
89 	GTPCI_GT64260_ACBL_RDPREFETCH		|
90 	GTPCI_GT64260_ACBL_PREFETCHEN,
91 	0,
92 };
93 
94 int
gt_match(device_t parent,cfdata_t cf,void * aux)95 gt_match(device_t parent, cfdata_t cf, void *aux)
96 {
97 	struct mainbus_attach_args *mba = aux;
98 
99 	if (strcmp(mba->mba_name, "gt") != 0)
100 		return 0;
101 
102 	return 1;
103 }
104 
105 void
gt_attach(device_t parent,device_t self,void * aux)106 gt_attach(device_t parent, device_t self, void *aux)
107 {
108 	extern struct powerpc_bus_space ev64260_gt_bs_tag;
109 	extern struct powerpc_bus_dma_tag ev64260_bus_dma_tag;
110 	struct mainbus_attach_args *mba = aux;
111 	struct gt_softc *sc = device_private(self);
112 	uint32_t cpumstr, cr, r;
113 
114 	sc->sc_dev = self;
115 	sc->sc_addr = mba->mba_addr;
116 	sc->sc_iot = &ev64260_gt_bs_tag;
117 	sc->sc_dmat = &ev64260_bus_dma_tag;
118 
119 #ifdef MPSC_CONSOLE
120 	{
121 		/* First, unmap already mapped console space. */
122 		gtmpsc_softc_t *gtmpsc = &gtmpsc_cn_softc;
123 
124 		bus_space_unmap(gtmpsc->sc_iot, gtmpsc->sc_mpsch, GTMPSC_SIZE);
125 		bus_space_unmap(gtmpsc->sc_iot, gtmpsc->sc_sdmah, GTSDMA_SIZE);
126 	}
127 #endif
128 	if (bus_space_map(sc->sc_iot, sc->sc_addr, GT_SIZE, 0, &sc->sc_ioh) !=
129 	    0) {
130 		aprint_error_dev(self, "registers map failed\n");
131 		return;
132 	}
133 #ifdef MPSC_CONSOLE
134 	{
135 		/* Next, remap console space. */
136 		gtmpsc_softc_t *gtmpsc = &gtmpsc_cn_softc;
137 
138 		if (bus_space_subregion(sc->sc_iot, sc->sc_ioh,
139 		    GTMPSC_BASE(gtmpsc->sc_unit), GTMPSC_SIZE,
140 		    &gtmpsc->sc_mpsch)) {
141 			aprint_error_dev(self, "Cannot map MPSC registers\n");
142 			return;
143 		}
144 		if (bus_space_subregion(sc->sc_iot, sc->sc_ioh,
145 		    GTSDMA_BASE(gtmpsc->sc_unit), GTSDMA_SIZE,
146 		    &gtmpsc->sc_sdmah)) {
147 			aprint_error_dev(self, "Cannot map SDMA registers\n");
148 			return;
149 		}
150 	}
151 #endif
152 
153 	/*
154 	 * Set MPSC Routing:
155 	 *	MR0 --> Serial Port 0
156 	 *	MR1 --> Serial Port 1
157 	 */
158 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTMPSC_MRR, GTMPSC_MRR_RES);
159 
160 	/*
161 	 * RX and TX Clock Routing:
162 	 *	CRR0 --> BRG0
163 	 *	CRR1 --> BRG1
164 	 */
165 	cr = GTMPSC_CRR(0, GTMPSC_CRR_BRG0) | GTMPSC_CRR(1, GTMPSC_CRR_BRG1);
166 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTMPSC_RCRR, cr);
167 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GTMPSC_TCRR, cr);
168 
169 	/*
170 	 * Setup Multi-Purpose Pins (MPP).
171 	 *   Change to GPP.
172 	 *     GPP 21 (DUART channel A intr)
173 	 *     GPP 22 (DUART channel B intr)
174 	 *     GPP 26 (RTC INT)
175 	 *     GPP 27 (PCI 0 INTA)
176 	 *     GPP 29 (PCI 1 INTA)
177 	 */
178 #define PIN2SHIFT(pin)	((pin % 8) * 4)
179 	r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GT_MPP_Control2);
180 	r |= ((0xf << PIN2SHIFT(21)) | (0xf << PIN2SHIFT(22)));
181 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_MPP_Control2, r);
182 	r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GT_MPP_Control3);
183 	r |= ((0xf << PIN2SHIFT(26)));
184 	r |= ((0xf << PIN2SHIFT(27)) | (0xf << PIN2SHIFT(29)));
185 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_MPP_Control3, r);
186 
187 	/* Also configure GPP. */
188 #define GPP_EXTERNAL_INTERRUPS \
189 	    ((1 << 21) | (1 << 22) | (1 << 26) | (1 << 27) | (1 << 29))
190 	r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GT_GPP_IO_Control);
191 	r &= ~GPP_EXTERNAL_INTERRUPS;
192 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_GPP_IO_Control, r);
193 	r = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GT_GPP_Level_Control);
194 	r |= GPP_EXTERNAL_INTERRUPS;
195 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_GPP_Level_Control, r);
196 
197 	/* clear interrupts */
198 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, ICR_CIM_LO, 0);
199 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, ICR_CIM_HI, 0);
200 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_GPP_Interrupt_Cause,
201 	    ~GPP_EXTERNAL_INTERRUPS);
202 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_GPP_Interrupt_Mask,
203 	    GPP_EXTERNAL_INTERRUPS);
204 
205 	discovery_pic->pic_cookie = sc;
206 	intr_establish(IRQ_GPP7_0, IST_LEVEL, IPL_HIGH,
207 	    pic_handle_intr, discovery_gpp_pic[0]);
208 	intr_establish(IRQ_GPP15_8, IST_LEVEL, IPL_HIGH,
209 	    pic_handle_intr, discovery_gpp_pic[1]);
210 	intr_establish(IRQ_GPP23_16, IST_LEVEL, IPL_HIGH,
211 	    pic_handle_intr, discovery_gpp_pic[2]);
212 	intr_establish(IRQ_GPP31_24, IST_LEVEL, IPL_HIGH,
213 	    pic_handle_intr, discovery_gpp_pic[3]);
214 
215 	cpumstr = bus_space_read_4(sc->sc_iot, sc->sc_ioh, GT_CPU_Master_Ctl);
216 	cpumstr &= ~(GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock);
217 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, GT_CPU_Master_Ctl, cpumstr);
218 
219 	gt_attach_common(sc);
220 }
221 
222 
223 void
gtpci_md_conf_interrupt(void * v,int bus,int dev,int pin,int swiz,int * iline)224 gtpci_md_conf_interrupt(void *v, int bus, int dev, int pin, int swiz,
225 			int *iline)
226 {
227 #ifdef PCI_NETBSD_CONFIGURE
228 	struct gtpci_softc *sc = v;
229 
230 	*iline = (sc->sc_unit == 0 ? 27 : 29);
231 
232 #define IRQ_GPP_BASE	(discovery_pic->pic_numintrs);
233 
234 	if (*iline != 0xff)
235 		*iline += IRQ_GPP_BASE;
236 #endif /* PCI_NETBSD_CONFIGURE */
237 }
238 
239 int
gtpci_md_conf_hook(void * v,int bus,int dev,int func,pcireg_t id)240 gtpci_md_conf_hook(void *v, int bus, int dev, int func, pcireg_t id)
241 {
242 	struct gtpci_softc *sc = v;
243 
244 	return gtpci_conf_hook(sc->sc_pc, bus, dev, func, id);
245 }
246 
247 
248 void *
marvell_intr_establish(int irq,int ipl,int (* func)(void *),void * arg)249 marvell_intr_establish(int irq, int ipl, int (*func)(void *), void *arg)
250 {
251 
252 	/* pass through */
253 	return intr_establish(irq, IST_LEVEL, ipl, func, arg);
254 }
255