Deleted Added
sdiff udiff text old ( 257178 ) new ( 291008 )
full compact
1/*-
2 * Copyright (C) 2008 Semihalf, Rafal Jaworowski
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/powerpc/mpc85xx/mpc85xx.c 257178 2013-10-26 18:18:14Z nwhitehorn $");
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/lock.h>
33#include <sys/mutex.h>
34#include <sys/rman.h>
35
36#include <vm/vm.h>
37#include <vm/vm_param.h>
38
39#include <machine/cpu.h>
40#include <machine/cpufunc.h>
41#include <machine/pio.h>
42#include <machine/spr.h>
43
44#include <dev/fdt/fdt_common.h>
45
46#include <powerpc/mpc85xx/mpc85xx.h>
47
48/*
49 * MPC85xx system specific routines
50 */
51
52uint32_t
53ccsr_read4(uintptr_t addr)
54{
55 volatile uint32_t *ptr = (void *)addr;

--- 9 unchanged lines hidden (view full) ---

65 *ptr = val;
66 powerpc_iomb();
67}
68
69int
70law_getmax(void)
71{
72 uint32_t ver;
73
74 ver = SVR_VER(mfspr(SPR_SVR));
75 if (ver == SVR_MPC8555E || ver == SVR_MPC8555)
76 return (8);
77 if (ver == SVR_MPC8548E || ver == SVR_MPC8548 ||
78 ver == SVR_MPC8533E || ver == SVR_MPC8533)
79 return (10);
80
81 return (12);
82}
83
84#define _LAW_SR(trgt,size) (0x80000000 | (trgt << 20) | (ffsl(size) - 2))
85#define _LAW_BAR(addr) (addr >> 12)
86
87int
88law_enable(int trgt, u_long addr, u_long size)
89{
90 uint32_t bar, sr;
91 int i, law_max;
92
93 if (size == 0)
94 return (0);
95
96 law_max = law_getmax();
97 bar = _LAW_BAR(addr);
98 sr = _LAW_SR(trgt, size);
99
100 /* Bail if already programmed. */
101 for (i = 0; i < law_max; i++)
102 if (sr == ccsr_read4(OCP85XX_LAWSR(i)) &&
103 bar == ccsr_read4(OCP85XX_LAWBAR(i)))
104 return (0);
105
106 /* Find an unused access window. */
107 for (i = 0; i < law_max; i++)
108 if ((ccsr_read4(OCP85XX_LAWSR(i)) & 0x80000000) == 0)
109 break;
110
111 if (i == law_max)
112 return (ENOSPC);
113
114 ccsr_write4(OCP85XX_LAWBAR(i), bar);
115 ccsr_write4(OCP85XX_LAWSR(i), sr);
116 return (0);
117}
118
119int
120law_disable(int trgt, u_long addr, u_long size)
121{
122 uint32_t bar, sr;
123 int i, law_max;
124
125 law_max = law_getmax();
126 bar = _LAW_BAR(addr);
127 sr = _LAW_SR(trgt, size);
128
129 /* Find and disable requested LAW. */
130 for (i = 0; i < law_max; i++)
131 if (sr == ccsr_read4(OCP85XX_LAWSR(i)) &&
132 bar == ccsr_read4(OCP85XX_LAWBAR(i))) {
133 ccsr_write4(OCP85XX_LAWBAR(i), 0);
134 ccsr_write4(OCP85XX_LAWSR(i), 0);
135 return (0);
136 }
137
138 return (ENOENT);
139}
140
141int
142law_pci_target(struct resource *res, int *trgt_mem, int *trgt_io)
143{
144 u_long start;
145 uint32_t ver;
146 int trgt, rv;
147
148 ver = SVR_VER(mfspr(SPR_SVR));
149
150 start = rman_get_start(res) & 0xf000;
151
152 rv = 0;
153 trgt = -1;
154 switch (start) {
155 case 0x8000:
156 trgt = 0;
157 break;
158 case 0x9000:
159 trgt = 1;
160 break;
161 case 0xa000:
162 if (ver == SVR_MPC8548E || ver == SVR_MPC8548)
163 trgt = 3;
164 else
165 trgt = 2;
166 break;
167 case 0xb000:
168 if (ver == SVR_MPC8548E || ver == SVR_MPC8548)
169 rv = EINVAL;
170 else
171 trgt = 3;
172 break;
173 default:
174 rv = ENXIO;
175 }
176 if (rv == 0) {
177 *trgt_mem = trgt;
178 *trgt_io = trgt;
179 }
180 return (rv);
181}
182