xref: /freebsd/sys/powerpc/mpc85xx/mpc85xx.c (revision e845939dc1fb5e0035bc2dd266505fa4ccb5e2d2)
1a1cd472aSRafal Jaworowski /*-
2a1cd472aSRafal Jaworowski  * Copyright (C) 2008 Semihalf, Rafal Jaworowski
3a1cd472aSRafal Jaworowski  * All rights reserved.
4a1cd472aSRafal Jaworowski  *
5a1cd472aSRafal Jaworowski  * Redistribution and use in source and binary forms, with or without
6a1cd472aSRafal Jaworowski  * modification, are permitted provided that the following conditions
7a1cd472aSRafal Jaworowski  * are met:
8a1cd472aSRafal Jaworowski  * 1. Redistributions of source code must retain the above copyright
9a1cd472aSRafal Jaworowski  *    notice, this list of conditions and the following disclaimer.
10a1cd472aSRafal Jaworowski  * 2. Redistributions in binary form must reproduce the above copyright
11a1cd472aSRafal Jaworowski  *    notice, this list of conditions and the following disclaimer in the
12a1cd472aSRafal Jaworowski  *    documentation and/or other materials provided with the distribution.
13a1cd472aSRafal Jaworowski  *
14a1cd472aSRafal Jaworowski  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15a1cd472aSRafal Jaworowski  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16a1cd472aSRafal Jaworowski  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17a1cd472aSRafal Jaworowski  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
18a1cd472aSRafal Jaworowski  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19a1cd472aSRafal Jaworowski  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20a1cd472aSRafal Jaworowski  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21a1cd472aSRafal Jaworowski  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22a1cd472aSRafal Jaworowski  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23a1cd472aSRafal Jaworowski  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24a1cd472aSRafal Jaworowski  * SUCH DAMAGE.
25a1cd472aSRafal Jaworowski  */
26a1cd472aSRafal Jaworowski 
27a1cd472aSRafal Jaworowski #include <sys/cdefs.h>
28a1cd472aSRafal Jaworowski __FBSDID("$FreeBSD$");
29a1cd472aSRafal Jaworowski 
30a1cd472aSRafal Jaworowski #include <sys/param.h>
31a1cd472aSRafal Jaworowski #include <sys/systm.h>
32d1d3233eSRafal Jaworowski #include <sys/lock.h>
33d1d3233eSRafal Jaworowski #include <sys/mutex.h>
34d1d3233eSRafal Jaworowski #include <sys/rman.h>
35a1cd472aSRafal Jaworowski 
368b79898eSRafal Jaworowski #include <vm/vm.h>
378b79898eSRafal Jaworowski #include <vm/vm_param.h>
388b79898eSRafal Jaworowski 
39a1cd472aSRafal Jaworowski #include <machine/cpu.h>
40a1cd472aSRafal Jaworowski #include <machine/cpufunc.h>
412a134f71SNathan Whitehorn #include <machine/pio.h>
42a1cd472aSRafal Jaworowski #include <machine/spr.h>
43a1cd472aSRafal Jaworowski 
44fe48da3fSRafal Jaworowski #include <powerpc/mpc85xx/mpc85xx.h>
458b79898eSRafal Jaworowski 
46a1cd472aSRafal Jaworowski /*
47a1cd472aSRafal Jaworowski  * MPC85xx system specific routines
48a1cd472aSRafal Jaworowski  */
49a1cd472aSRafal Jaworowski 
50fe48da3fSRafal Jaworowski uint32_t
51fe48da3fSRafal Jaworowski ccsr_read4(uintptr_t addr)
52a1cd472aSRafal Jaworowski {
53fe48da3fSRafal Jaworowski 	volatile uint32_t *ptr = (void *)addr;
54a1cd472aSRafal Jaworowski 
55fe48da3fSRafal Jaworowski 	return (*ptr);
56fe48da3fSRafal Jaworowski }
57fe48da3fSRafal Jaworowski 
58fe48da3fSRafal Jaworowski void
59fe48da3fSRafal Jaworowski ccsr_write4(uintptr_t addr, uint32_t val)
60fe48da3fSRafal Jaworowski {
61fe48da3fSRafal Jaworowski 	volatile uint32_t *ptr = (void *)addr;
62fe48da3fSRafal Jaworowski 
63fe48da3fSRafal Jaworowski 	*ptr = val;
6413d47f30SNathan Whitehorn 	powerpc_iomb();
65fe48da3fSRafal Jaworowski }
66fe48da3fSRafal Jaworowski 
67389e4721SRafal Jaworowski int
6825c22eb4SRafal Jaworowski law_getmax(void)
6925c22eb4SRafal Jaworowski {
7025c22eb4SRafal Jaworowski 	uint32_t ver;
7125c22eb4SRafal Jaworowski 
7225c22eb4SRafal Jaworowski 	ver = SVR_VER(mfspr(SPR_SVR));
738a4b7c64SMarcel Moolenaar 	if (ver == SVR_MPC8555E || ver == SVR_MPC8555)
7425c22eb4SRafal Jaworowski 		return (8);
758a4b7c64SMarcel Moolenaar 	if (ver == SVR_MPC8548E || ver == SVR_MPC8548 ||
768a4b7c64SMarcel Moolenaar 	    ver == SVR_MPC8533E || ver == SVR_MPC8533)
778a4b7c64SMarcel Moolenaar 		return (10);
788a4b7c64SMarcel Moolenaar 
798a4b7c64SMarcel Moolenaar 	return (12);
8025c22eb4SRafal Jaworowski }
8125c22eb4SRafal Jaworowski 
8225c22eb4SRafal Jaworowski #define	_LAW_SR(trgt,size)	(0x80000000 | (trgt << 20) | (ffsl(size) - 2))
8325c22eb4SRafal Jaworowski #define	_LAW_BAR(addr)		(addr >> 12)
8425c22eb4SRafal Jaworowski 
8525c22eb4SRafal Jaworowski int
8625c22eb4SRafal Jaworowski law_enable(int trgt, u_long addr, u_long size)
8725c22eb4SRafal Jaworowski {
8825c22eb4SRafal Jaworowski 	uint32_t bar, sr;
8925c22eb4SRafal Jaworowski 	int i, law_max;
9025c22eb4SRafal Jaworowski 
91*e845939dSMarcel Moolenaar 	if (size == 0)
92*e845939dSMarcel Moolenaar 		return (0);
93*e845939dSMarcel Moolenaar 
9425c22eb4SRafal Jaworowski 	law_max = law_getmax();
9525c22eb4SRafal Jaworowski 	bar = _LAW_BAR(addr);
9625c22eb4SRafal Jaworowski 	sr = _LAW_SR(trgt, size);
9725c22eb4SRafal Jaworowski 
9825c22eb4SRafal Jaworowski 	/* Bail if already programmed. */
9925c22eb4SRafal Jaworowski 	for (i = 0; i < law_max; i++)
10025c22eb4SRafal Jaworowski 		if (sr == ccsr_read4(OCP85XX_LAWSR(i)) &&
10125c22eb4SRafal Jaworowski 		    bar == ccsr_read4(OCP85XX_LAWBAR(i)))
10225c22eb4SRafal Jaworowski 			return (0);
10325c22eb4SRafal Jaworowski 
10425c22eb4SRafal Jaworowski 	/* Find an unused access window. */
10525c22eb4SRafal Jaworowski 	for (i = 0; i < law_max; i++)
10625c22eb4SRafal Jaworowski 		if ((ccsr_read4(OCP85XX_LAWSR(i)) & 0x80000000) == 0)
10725c22eb4SRafal Jaworowski 			break;
10825c22eb4SRafal Jaworowski 
10925c22eb4SRafal Jaworowski 	if (i == law_max)
11025c22eb4SRafal Jaworowski 		return (ENOSPC);
11125c22eb4SRafal Jaworowski 
11225c22eb4SRafal Jaworowski 	ccsr_write4(OCP85XX_LAWBAR(i), bar);
11325c22eb4SRafal Jaworowski 	ccsr_write4(OCP85XX_LAWSR(i), sr);
11425c22eb4SRafal Jaworowski 	return (0);
11525c22eb4SRafal Jaworowski }
11625c22eb4SRafal Jaworowski 
11725c22eb4SRafal Jaworowski int
11825c22eb4SRafal Jaworowski law_disable(int trgt, u_long addr, u_long size)
11925c22eb4SRafal Jaworowski {
12025c22eb4SRafal Jaworowski 	uint32_t bar, sr;
12125c22eb4SRafal Jaworowski 	int i, law_max;
12225c22eb4SRafal Jaworowski 
12325c22eb4SRafal Jaworowski 	law_max = law_getmax();
12425c22eb4SRafal Jaworowski 	bar = _LAW_BAR(addr);
12525c22eb4SRafal Jaworowski 	sr = _LAW_SR(trgt, size);
12625c22eb4SRafal Jaworowski 
12725c22eb4SRafal Jaworowski 	/* Find and disable requested LAW. */
12825c22eb4SRafal Jaworowski 	for (i = 0; i < law_max; i++)
12925c22eb4SRafal Jaworowski 		if (sr == ccsr_read4(OCP85XX_LAWSR(i)) &&
13025c22eb4SRafal Jaworowski 		    bar == ccsr_read4(OCP85XX_LAWBAR(i))) {
13125c22eb4SRafal Jaworowski 			ccsr_write4(OCP85XX_LAWBAR(i), 0);
13225c22eb4SRafal Jaworowski 			ccsr_write4(OCP85XX_LAWSR(i), 0);
13325c22eb4SRafal Jaworowski 			return (0);
13425c22eb4SRafal Jaworowski 		}
13525c22eb4SRafal Jaworowski 
13625c22eb4SRafal Jaworowski 	return (ENOENT);
13725c22eb4SRafal Jaworowski }
13825c22eb4SRafal Jaworowski 
139d1d3233eSRafal Jaworowski int
140d1d3233eSRafal Jaworowski law_pci_target(struct resource *res, int *trgt_mem, int *trgt_io)
141d1d3233eSRafal Jaworowski {
142d1d3233eSRafal Jaworowski 	u_long start;
143d1d3233eSRafal Jaworowski 	uint32_t ver;
144d1d3233eSRafal Jaworowski 	int trgt, rv;
145d1d3233eSRafal Jaworowski 
146d1d3233eSRafal Jaworowski 	ver = SVR_VER(mfspr(SPR_SVR));
147d1d3233eSRafal Jaworowski 
148d1d3233eSRafal Jaworowski 	start = rman_get_start(res) & 0xf000;
149d1d3233eSRafal Jaworowski 
150d1d3233eSRafal Jaworowski 	rv = 0;
151d1d3233eSRafal Jaworowski 	trgt = -1;
152d1d3233eSRafal Jaworowski 	switch (start) {
153d1d3233eSRafal Jaworowski 	case 0x8000:
154d1d3233eSRafal Jaworowski 		trgt = 0;
155d1d3233eSRafal Jaworowski 		break;
156d1d3233eSRafal Jaworowski 	case 0x9000:
157d1d3233eSRafal Jaworowski 		trgt = 1;
158d1d3233eSRafal Jaworowski 		break;
159d1d3233eSRafal Jaworowski 	case 0xa000:
1608a4b7c64SMarcel Moolenaar 		if (ver == SVR_MPC8548E || ver == SVR_MPC8548)
1618a4b7c64SMarcel Moolenaar 			trgt = 3;
162d1d3233eSRafal Jaworowski 		else
1638a4b7c64SMarcel Moolenaar 			trgt = 2;
1648a4b7c64SMarcel Moolenaar 		break;
1658a4b7c64SMarcel Moolenaar 	case 0xb000:
1668a4b7c64SMarcel Moolenaar 		if (ver == SVR_MPC8548E || ver == SVR_MPC8548)
167d1d3233eSRafal Jaworowski 			rv = EINVAL;
1688a4b7c64SMarcel Moolenaar 		else
1698a4b7c64SMarcel Moolenaar 			trgt = 3;
170d1d3233eSRafal Jaworowski 		break;
171d1d3233eSRafal Jaworowski 	default:
172d1d3233eSRafal Jaworowski 		rv = ENXIO;
173d1d3233eSRafal Jaworowski 	}
174*e845939dSMarcel Moolenaar 	if (rv == 0) {
175*e845939dSMarcel Moolenaar 		*trgt_mem = trgt;
176*e845939dSMarcel Moolenaar 		*trgt_io = trgt;
177*e845939dSMarcel Moolenaar 	}
178d1d3233eSRafal Jaworowski 	return (rv);
179d1d3233eSRafal Jaworowski }
180d1d3233eSRafal Jaworowski 
181