Deleted Added
full compact
mv_common.c (186899) mv_common.c (186909)
1/*-
2 * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
3 * All rights reserved.
4 *
5 * Developed by Semihalf.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of MARVELL nor the names of contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <sys/cdefs.h>
1/*-
2 * Copyright (C) 2008 MARVELL INTERNATIONAL LTD.
3 * All rights reserved.
4 *
5 * Developed by Semihalf.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of MARVELL nor the names of contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: head/sys/arm/mv/common.c 186899 2009-01-08 13:20:28Z raj $");
33__FBSDID("$FreeBSD: head/sys/arm/mv/common.c 186909 2009-01-08 18:31:43Z raj $");
34
35#include <sys/systm.h>
36#include <sys/bus.h>
37
38#include <machine/bus.h>
39
40#include <arm/mv/mvreg.h>
41#include <arm/mv/mvvar.h>
42
43static int win_eth_can_remap(int i);
44
45static int decode_win_cpu_valid(void);
46static int decode_win_usb_valid(void);
47static int decode_win_eth_valid(void);
48static int decode_win_pcie_valid(void);
34
35#include <sys/systm.h>
36#include <sys/bus.h>
37
38#include <machine/bus.h>
39
40#include <arm/mv/mvreg.h>
41#include <arm/mv/mvvar.h>
42
43static int win_eth_can_remap(int i);
44
45static int decode_win_cpu_valid(void);
46static int decode_win_usb_valid(void);
47static int decode_win_eth_valid(void);
48static int decode_win_pcie_valid(void);
49static int decode_win_sata_valid(void);
50static int decode_win_cesa_valid(void);
49
50static void decode_win_cpu_setup(void);
51
52static void decode_win_cpu_setup(void);
51static void decode_win_usb_setup(uint32_t ctrl);
53static void decode_win_usb_setup(void);
52static void decode_win_eth_setup(uint32_t base);
53static void decode_win_pcie_setup(uint32_t base);
54static void decode_win_eth_setup(uint32_t base);
55static void decode_win_pcie_setup(uint32_t base);
56static void decode_win_sata_setup(void);
57static void decode_win_cesa_setup(void);
54
58
55static uint32_t dev, rev;
59static void decode_win_cesa_dump(void);
60static void decode_win_usb_dump(void);
61
56static uint32_t used_cpu_wins;
57
58uint32_t
59read_cpu_ctrl(uint32_t reg)
60{
61
62 return (bus_space_read_4(obio_tag, MV_CPU_CONTROL_BASE, reg));
63}
64
65void
66write_cpu_ctrl(uint32_t reg, uint32_t val)
67{
68
69 bus_space_write_4(obio_tag, MV_CPU_CONTROL_BASE, reg, val);
70}
71
72void
73cpu_reset(void)
74{
75
76 write_cpu_ctrl(RSTOUTn_MASK, SOFT_RST_OUT_EN);
77 write_cpu_ctrl(SYSTEM_SOFT_RESET, SYS_SOFT_RST);
78 while (1);
79}
80
81uint32_t
82cpu_extra_feat(void)
83{
62static uint32_t used_cpu_wins;
63
64uint32_t
65read_cpu_ctrl(uint32_t reg)
66{
67
68 return (bus_space_read_4(obio_tag, MV_CPU_CONTROL_BASE, reg));
69}
70
71void
72write_cpu_ctrl(uint32_t reg, uint32_t val)
73{
74
75 bus_space_write_4(obio_tag, MV_CPU_CONTROL_BASE, reg, val);
76}
77
78void
79cpu_reset(void)
80{
81
82 write_cpu_ctrl(RSTOUTn_MASK, SOFT_RST_OUT_EN);
83 write_cpu_ctrl(SYSTEM_SOFT_RESET, SYS_SOFT_RST);
84 while (1);
85}
86
87uint32_t
88cpu_extra_feat(void)
89{
90 uint32_t dev, rev;
84 uint32_t ef = 0;
85
86 soc_id(&dev, &rev);
87 if (dev == MV_DEV_88F6281 || dev == MV_DEV_MV78100)
88 __asm __volatile("mrc p15, 1, %0, c15, c1, 0" : "=r" (ef));
89 else if (dev == MV_DEV_88F5182 || dev == MV_DEV_88F5281)
90 __asm __volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (ef));
91 else if (bootverbose)
92 printf("This ARM Core does not support any extra features\n");
93
94 return (ef);
95}
96
97uint32_t
98soc_power_ctrl_get(uint32_t mask)
99{
100
101 if (mask != CPU_PM_CTRL_NONE)
102 mask &= read_cpu_ctrl(CPU_PM_CTRL);
103
104 return (mask);
105}
106
107void
108soc_id(uint32_t *dev, uint32_t *rev)
109{
110
111 /*
112 * Notice: system identifiers are available in the registers range of
113 * PCIE controller, so using this function is only allowed (and
114 * possible) after the internal registers range has been mapped in via
115 * pmap_devmap_bootstrap().
116 */
117 *dev = bus_space_read_4(obio_tag, MV_PCIE_BASE, 0) >> 16;
118 *rev = bus_space_read_4(obio_tag, MV_PCIE_BASE, 8) & 0xff;
119}
120
121void
122soc_identify(void)
123{
124 uint32_t d, r;
125 const char *dev;
126 const char *rev;
127
128 soc_id(&d, &r);
129
130 printf("SOC: ");
131 if (bootverbose)
132 printf("(0x%4x:0x%02x) ", d, r);
133
134 rev = "";
135 switch (d) {
136 case MV_DEV_88F5181:
137 dev = "Marvell 88F5181";
138 if (r == 3)
139 rev = "B1";
140 break;
141 case MV_DEV_88F5182:
142 dev = "Marvell 88F5182";
143 if (r == 2)
144 rev = "A2";
145 break;
146 case MV_DEV_88F5281:
147 dev = "Marvell 88F5281";
148 if (r == 4)
149 rev = "D0";
150 else if (r == 5)
151 rev = "D1";
152 else if (r == 6)
153 rev = "D2";
154 break;
155 case MV_DEV_88F6281:
156 dev = "Marvell 88F6281";
157 if (r == 0)
158 rev = "Z0";
159 else if (r == 2)
160 rev = "A0";
161 break;
162 case MV_DEV_MV78100:
163 dev = "Marvell MV78100";
164 break;
165 default:
166 dev = "UNKNOWN";
167 break;
168 }
169
170 printf("%s", dev);
171 if (*rev != '\0')
172 printf(" rev %s", rev);
173 printf(", TClock %dMHz\n", get_tclk() / 1000 / 1000);
174
175 /* TODO add info on currently set endianess */
176}
177
178int
179soc_decode_win(void)
180{
91 uint32_t ef = 0;
92
93 soc_id(&dev, &rev);
94 if (dev == MV_DEV_88F6281 || dev == MV_DEV_MV78100)
95 __asm __volatile("mrc p15, 1, %0, c15, c1, 0" : "=r" (ef));
96 else if (dev == MV_DEV_88F5182 || dev == MV_DEV_88F5281)
97 __asm __volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (ef));
98 else if (bootverbose)
99 printf("This ARM Core does not support any extra features\n");
100
101 return (ef);
102}
103
104uint32_t
105soc_power_ctrl_get(uint32_t mask)
106{
107
108 if (mask != CPU_PM_CTRL_NONE)
109 mask &= read_cpu_ctrl(CPU_PM_CTRL);
110
111 return (mask);
112}
113
114void
115soc_id(uint32_t *dev, uint32_t *rev)
116{
117
118 /*
119 * Notice: system identifiers are available in the registers range of
120 * PCIE controller, so using this function is only allowed (and
121 * possible) after the internal registers range has been mapped in via
122 * pmap_devmap_bootstrap().
123 */
124 *dev = bus_space_read_4(obio_tag, MV_PCIE_BASE, 0) >> 16;
125 *rev = bus_space_read_4(obio_tag, MV_PCIE_BASE, 8) & 0xff;
126}
127
128void
129soc_identify(void)
130{
131 uint32_t d, r;
132 const char *dev;
133 const char *rev;
134
135 soc_id(&d, &r);
136
137 printf("SOC: ");
138 if (bootverbose)
139 printf("(0x%4x:0x%02x) ", d, r);
140
141 rev = "";
142 switch (d) {
143 case MV_DEV_88F5181:
144 dev = "Marvell 88F5181";
145 if (r == 3)
146 rev = "B1";
147 break;
148 case MV_DEV_88F5182:
149 dev = "Marvell 88F5182";
150 if (r == 2)
151 rev = "A2";
152 break;
153 case MV_DEV_88F5281:
154 dev = "Marvell 88F5281";
155 if (r == 4)
156 rev = "D0";
157 else if (r == 5)
158 rev = "D1";
159 else if (r == 6)
160 rev = "D2";
161 break;
162 case MV_DEV_88F6281:
163 dev = "Marvell 88F6281";
164 if (r == 0)
165 rev = "Z0";
166 else if (r == 2)
167 rev = "A0";
168 break;
169 case MV_DEV_MV78100:
170 dev = "Marvell MV78100";
171 break;
172 default:
173 dev = "UNKNOWN";
174 break;
175 }
176
177 printf("%s", dev);
178 if (*rev != '\0')
179 printf(" rev %s", rev);
180 printf(", TClock %dMHz\n", get_tclk() / 1000 / 1000);
181
182 /* TODO add info on currently set endianess */
183}
184
185int
186soc_decode_win(void)
187{
188 uint32_t dev, rev;
181
182 /* Retrieve our ID: some windows facilities vary between SoC models */
183 soc_id(&dev, &rev);
184
185 if (decode_win_cpu_valid() != 1 || decode_win_usb_valid() != 1 ||
186 decode_win_eth_valid() != 1 || decode_win_idma_valid() != 1 ||
189
190 /* Retrieve our ID: some windows facilities vary between SoC models */
191 soc_id(&dev, &rev);
192
193 if (decode_win_cpu_valid() != 1 || decode_win_usb_valid() != 1 ||
194 decode_win_eth_valid() != 1 || decode_win_idma_valid() != 1 ||
187 decode_win_pcie_valid() != 1)
195 decode_win_pcie_valid() != 1 || decode_win_sata_valid() != 1 ||
196 decode_win_cesa_valid() != 1)
188 return(-1);
189
190 decode_win_cpu_setup();
197 return(-1);
198
199 decode_win_cpu_setup();
191 decode_win_usb_setup(MV_USB0_BASE);
200 decode_win_usb_setup();
192 decode_win_eth_setup(MV_ETH0_BASE);
193 if (dev == MV_DEV_MV78100)
194 decode_win_eth_setup(MV_ETH1_BASE);
201 decode_win_eth_setup(MV_ETH0_BASE);
202 if (dev == MV_DEV_MV78100)
203 decode_win_eth_setup(MV_ETH1_BASE);
204 if (dev == MV_DEV_88F6281 || dev == MV_DEV_MV78100)
205 decode_win_cesa_setup();
195
196 decode_win_idma_setup();
206
207 decode_win_idma_setup();
208 decode_win_xor_setup();
197
198 if (dev == MV_DEV_MV78100) {
199 decode_win_pcie_setup(MV_PCIE00_BASE);
200 decode_win_pcie_setup(MV_PCIE01_BASE);
201 decode_win_pcie_setup(MV_PCIE02_BASE);
202 decode_win_pcie_setup(MV_PCIE03_BASE);
203 decode_win_pcie_setup(MV_PCIE10_BASE);
204 decode_win_pcie_setup(MV_PCIE11_BASE);
205 decode_win_pcie_setup(MV_PCIE12_BASE);
206 decode_win_pcie_setup(MV_PCIE13_BASE);
207 } else
208 decode_win_pcie_setup(MV_PCIE_BASE);
209
209
210 if (dev == MV_DEV_MV78100) {
211 decode_win_pcie_setup(MV_PCIE00_BASE);
212 decode_win_pcie_setup(MV_PCIE01_BASE);
213 decode_win_pcie_setup(MV_PCIE02_BASE);
214 decode_win_pcie_setup(MV_PCIE03_BASE);
215 decode_win_pcie_setup(MV_PCIE10_BASE);
216 decode_win_pcie_setup(MV_PCIE11_BASE);
217 decode_win_pcie_setup(MV_PCIE12_BASE);
218 decode_win_pcie_setup(MV_PCIE13_BASE);
219 } else
220 decode_win_pcie_setup(MV_PCIE_BASE);
221
210 /* TODO set up decode wins for SATA */
222 if (dev != MV_DEV_88F5281)
223 decode_win_sata_setup();
211
212 return (0);
213}
214
215/**************************************************************************
216 * Decode windows registers accessors
217 **************************************************************************/
218WIN_REG_IDX_RD(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
219WIN_REG_IDX_RD(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
220WIN_REG_IDX_RD(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
221WIN_REG_IDX_RD(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
222WIN_REG_IDX_WR(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
223WIN_REG_IDX_WR(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
224WIN_REG_IDX_WR(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
225WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
226
227WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
228WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
229
224
225 return (0);
226}
227
228/**************************************************************************
229 * Decode windows registers accessors
230 **************************************************************************/
231WIN_REG_IDX_RD(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
232WIN_REG_IDX_RD(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
233WIN_REG_IDX_RD(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
234WIN_REG_IDX_RD(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
235WIN_REG_IDX_WR(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE)
236WIN_REG_IDX_WR(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE)
237WIN_REG_IDX_WR(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE)
238WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE)
239
240WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE)
241WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE)
242
230WIN_REG_IDX_RD(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
231WIN_REG_IDX_RD(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
232WIN_REG_IDX_WR(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
233WIN_REG_IDX_WR(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
243WIN_REG_IDX_RD2(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
244WIN_REG_IDX_RD2(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
245WIN_REG_IDX_WR2(win_usb, cr, MV_WIN_USB_CTRL, MV_USB_AWR_BASE)
246WIN_REG_IDX_WR2(win_usb, br, MV_WIN_USB_BASE, MV_USB_AWR_BASE)
234
247
248WIN_REG_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL, MV_CESA_BASE)
249WIN_REG_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE, MV_CESA_BASE)
250WIN_REG_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL, MV_CESA_BASE)
251WIN_REG_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE, MV_CESA_BASE)
252
235WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
236WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
237WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
238WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
239WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
240WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
253WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE)
254WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE)
255WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP)
256WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE)
257WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE)
258WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP)
259
260WIN_REG_IDX_RD2(win_xor, br, MV_WIN_XOR_BASE, MV_XOR_BASE)
261WIN_REG_IDX_RD2(win_xor, sz, MV_WIN_XOR_SIZE, MV_XOR_BASE)
262WIN_REG_IDX_RD2(win_xor, har, MV_WIN_XOR_REMAP, MV_XOR_BASE)
263WIN_REG_IDX_RD2(win_xor, ctrl, MV_WIN_XOR_CTRL, MV_XOR_BASE)
264WIN_REG_IDX_WR2(win_xor, br, MV_WIN_XOR_BASE, MV_XOR_BASE)
265WIN_REG_IDX_WR2(win_xor, sz, MV_WIN_XOR_SIZE, MV_XOR_BASE)
266WIN_REG_IDX_WR2(win_xor, har, MV_WIN_XOR_REMAP, MV_XOR_BASE)
267WIN_REG_IDX_WR2(win_xor, ctrl, MV_WIN_XOR_CTRL, MV_XOR_BASE)
268
241WIN_REG_BASE_RD(win_eth, bare, 0x290)
242WIN_REG_BASE_RD(win_eth, epap, 0x294)
243WIN_REG_BASE_WR(win_eth, bare, 0x290)
244WIN_REG_BASE_WR(win_eth, epap, 0x294)
245
246WIN_REG_BASE_IDX_RD(win_pcie, cr, MV_WIN_PCIE_CTRL);
247WIN_REG_BASE_IDX_RD(win_pcie, br, MV_WIN_PCIE_BASE);
248WIN_REG_BASE_IDX_RD(win_pcie, remap, MV_WIN_PCIE_REMAP);
249WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL);
250WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE);
251WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP);
252WIN_REG_BASE_IDX_WR(pcie, bar, MV_PCIE_BAR);
253
254WIN_REG_IDX_RD(win_idma, br, MV_WIN_IDMA_BASE, MV_IDMA_BASE)
255WIN_REG_IDX_RD(win_idma, sz, MV_WIN_IDMA_SIZE, MV_IDMA_BASE)
256WIN_REG_IDX_RD(win_idma, har, MV_WIN_IDMA_REMAP, MV_IDMA_BASE)
257WIN_REG_IDX_RD(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
258WIN_REG_IDX_WR(win_idma, br, MV_WIN_IDMA_BASE, MV_IDMA_BASE)
259WIN_REG_IDX_WR(win_idma, sz, MV_WIN_IDMA_SIZE, MV_IDMA_BASE)
260WIN_REG_IDX_WR(win_idma, har, MV_WIN_IDMA_REMAP, MV_IDMA_BASE)
261WIN_REG_IDX_WR(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
262WIN_REG_RD(win_idma, bare, 0xa80, MV_IDMA_BASE)
263WIN_REG_WR(win_idma, bare, 0xa80, MV_IDMA_BASE)
264
269WIN_REG_BASE_RD(win_eth, bare, 0x290)
270WIN_REG_BASE_RD(win_eth, epap, 0x294)
271WIN_REG_BASE_WR(win_eth, bare, 0x290)
272WIN_REG_BASE_WR(win_eth, epap, 0x294)
273
274WIN_REG_BASE_IDX_RD(win_pcie, cr, MV_WIN_PCIE_CTRL);
275WIN_REG_BASE_IDX_RD(win_pcie, br, MV_WIN_PCIE_BASE);
276WIN_REG_BASE_IDX_RD(win_pcie, remap, MV_WIN_PCIE_REMAP);
277WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL);
278WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE);
279WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP);
280WIN_REG_BASE_IDX_WR(pcie, bar, MV_PCIE_BAR);
281
282WIN_REG_IDX_RD(win_idma, br, MV_WIN_IDMA_BASE, MV_IDMA_BASE)
283WIN_REG_IDX_RD(win_idma, sz, MV_WIN_IDMA_SIZE, MV_IDMA_BASE)
284WIN_REG_IDX_RD(win_idma, har, MV_WIN_IDMA_REMAP, MV_IDMA_BASE)
285WIN_REG_IDX_RD(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
286WIN_REG_IDX_WR(win_idma, br, MV_WIN_IDMA_BASE, MV_IDMA_BASE)
287WIN_REG_IDX_WR(win_idma, sz, MV_WIN_IDMA_SIZE, MV_IDMA_BASE)
288WIN_REG_IDX_WR(win_idma, har, MV_WIN_IDMA_REMAP, MV_IDMA_BASE)
289WIN_REG_IDX_WR(win_idma, cap, MV_WIN_IDMA_CAP, MV_IDMA_BASE)
290WIN_REG_RD(win_idma, bare, 0xa80, MV_IDMA_BASE)
291WIN_REG_WR(win_idma, bare, 0xa80, MV_IDMA_BASE)
292
293WIN_REG_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL, MV_SATAHC_BASE);
294WIN_REG_IDX_RD(win_sata, br, MV_WIN_SATA_BASE, MV_SATAHC_BASE);
295WIN_REG_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL, MV_SATAHC_BASE);
296WIN_REG_IDX_WR(win_sata, br, MV_WIN_SATA_BASE, MV_SATAHC_BASE);
297
265/**************************************************************************
266 * Decode windows helper routines
267 **************************************************************************/
268void
269soc_dump_decode_win(void)
270{
298/**************************************************************************
299 * Decode windows helper routines
300 **************************************************************************/
301void
302soc_dump_decode_win(void)
303{
304 uint32_t dev, rev;
271 int i;
272
273 soc_id(&dev, &rev);
274
275 for (i = 0; i < MV_WIN_CPU_MAX; i++) {
276 printf("CPU window#%d: c 0x%08x, b 0x%08x", i,
277 win_cpu_cr_read(i),
278 win_cpu_br_read(i));
279
280 if (win_cpu_can_remap(i))
281 printf(", rl 0x%08x, rh 0x%08x",
282 win_cpu_remap_l_read(i),
283 win_cpu_remap_h_read(i));
284
285 printf("\n");
286 }
287 printf("Internal regs base: 0x%08x\n",
288 bus_space_read_4(obio_tag, MV_INTREGS_BASE, 0));
289
290 for (i = 0; i < MV_WIN_DDR_MAX; i++)
291 printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
292 ddr_br_read(i), ddr_sz_read(i));
305 int i;
306
307 soc_id(&dev, &rev);
308
309 for (i = 0; i < MV_WIN_CPU_MAX; i++) {
310 printf("CPU window#%d: c 0x%08x, b 0x%08x", i,
311 win_cpu_cr_read(i),
312 win_cpu_br_read(i));
313
314 if (win_cpu_can_remap(i))
315 printf(", rl 0x%08x, rh 0x%08x",
316 win_cpu_remap_l_read(i),
317 win_cpu_remap_h_read(i));
318
319 printf("\n");
320 }
321 printf("Internal regs base: 0x%08x\n",
322 bus_space_read_4(obio_tag, MV_INTREGS_BASE, 0));
323
324 for (i = 0; i < MV_WIN_DDR_MAX; i++)
325 printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i,
326 ddr_br_read(i), ddr_sz_read(i));
293
294 for (i = 0; i < MV_WIN_USB_MAX; i++)
295 printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
296 win_usb_cr_read(i), win_usb_br_read(i));
297
298 for (i = 0; i < MV_WIN_ETH_MAX; i++) {
299 printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
300 win_eth_br_read(MV_ETH0_BASE, i),
301 win_eth_sz_read(MV_ETH0_BASE, i));
302
303 if (win_eth_can_remap(i))
304 printf(", ha 0x%08x",
305 win_eth_har_read(MV_ETH0_BASE, i));
306
307 printf("\n");
308 }
309 printf("ETH windows: bare 0x%08x, epap 0x%08x\n",
310 win_eth_bare_read(MV_ETH0_BASE),
311 win_eth_epap_read(MV_ETH0_BASE));
312
313 decode_win_idma_dump();
327
328 for (i = 0; i < MV_WIN_ETH_MAX; i++) {
329 printf("ETH window#%d: b 0x%08x, s 0x%08x", i,
330 win_eth_br_read(MV_ETH0_BASE, i),
331 win_eth_sz_read(MV_ETH0_BASE, i));
332
333 if (win_eth_can_remap(i))
334 printf(", ha 0x%08x",
335 win_eth_har_read(MV_ETH0_BASE, i));
336
337 printf("\n");
338 }
339 printf("ETH windows: bare 0x%08x, epap 0x%08x\n",
340 win_eth_bare_read(MV_ETH0_BASE),
341 win_eth_epap_read(MV_ETH0_BASE));
342
343 decode_win_idma_dump();
344 decode_win_cesa_dump();
345 decode_win_usb_dump();
314 printf("\n");
315}
316
317/**************************************************************************
318 * CPU windows routines
319 **************************************************************************/
320int
321win_cpu_can_remap(int i)
322{
346 printf("\n");
347}
348
349/**************************************************************************
350 * CPU windows routines
351 **************************************************************************/
352int
353win_cpu_can_remap(int i)
354{
355 uint32_t dev, rev;
323
356
357 soc_id(&dev, &rev);
358
324 /* Depending on the SoC certain windows have remap capability */
325 if ((dev == MV_DEV_88F5182 && i < 2) ||
326 (dev == MV_DEV_88F5281 && i < 4) ||
327 (dev == MV_DEV_88F6281 && i < 4) ||
328 (dev == MV_DEV_MV78100 && i < 8))
329 return (1);
330
331 return (0);
332}
333
334/* XXX This should check for overlapping remap fields too.. */
335int
336decode_win_overlap(int win, int win_no, const struct decode_win *wintab)
337{
338 const struct decode_win *tab;
339 int i;
340
341 tab = wintab;
342
343 for (i = 0; i < win_no; i++, tab++) {
344 if (i == win)
345 /* Skip self */
346 continue;
347
348 if ((tab->base + tab->size - 1) < (wintab + win)->base)
349 continue;
350
351 else if (((wintab + win)->base + (wintab + win)->size - 1) <
352 tab->base)
353 continue;
354 else
355 return (i);
356 }
357
358 return (-1);
359}
360
361static int
362decode_win_cpu_valid(void)
363{
364 int i, j, rv;
365 uint32_t b, e, s;
366
367 if (cpu_wins_no > MV_WIN_CPU_MAX) {
368 printf("CPU windows: too many entries: %d\n", cpu_wins_no);
369 return (-1);
370 }
371
372 rv = 1;
373 for (i = 0; i < cpu_wins_no; i++) {
374
375 if (cpu_wins[i].target == 0) {
376 printf("CPU window#%d: DDR target window is not "
377 "supposed to be reprogrammed!\n", i);
378 rv = 0;
379 }
380
381 if (cpu_wins[i].remap >= 0 && win_cpu_can_remap(i) != 1) {
382 printf("CPU window#%d: not capable of remapping, but "
383 "val 0x%08x defined\n", i, cpu_wins[i].remap);
384 rv = 0;
385 }
386
387 s = cpu_wins[i].size;
388 b = cpu_wins[i].base;
389 e = b + s - 1;
390 if (s > (0xFFFFFFFF - b + 1)) {
391 /*
392 * XXX this boundary check should account for 64bit
393 * and remapping..
394 */
395 printf("CPU window#%d: no space for size 0x%08x at "
396 "0x%08x\n", i, s, b);
397 rv = 0;
398 continue;
399 }
400
401 j = decode_win_overlap(i, cpu_wins_no, &cpu_wins[0]);
402 if (j >= 0) {
403 printf("CPU window#%d: (0x%08x - 0x%08x) overlaps "
404 "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
405 cpu_wins[j].base,
406 cpu_wins[j].base + cpu_wins[j].size - 1);
407 rv = 0;
408 }
409 }
410
411 return (rv);
412}
413
414int
415decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
416 int remap)
417{
418 uint32_t br, cr;
419 int win;
420
421 if (used_cpu_wins >= MV_WIN_CPU_MAX)
422 return (-1);
423
424 win = used_cpu_wins++;
425
426 br = base & 0xffff0000;
427 win_cpu_br_write(win, br);
428
429 if (win_cpu_can_remap(win)) {
430 if (remap >= 0) {
431 win_cpu_remap_l_write(win, remap & 0xffff0000);
432 win_cpu_remap_h_write(win, 0);
433 } else {
434 /*
435 * Remap function is not used for a given window
436 * (capable of remapping) - set remap field with the
437 * same value as base.
438 */
439 win_cpu_remap_l_write(win, base & 0xffff0000);
440 win_cpu_remap_h_write(win, 0);
441 }
442 }
443
444 cr = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
445 win_cpu_cr_write(win, cr);
446
447 return (0);
448}
449
450static void
451decode_win_cpu_setup(void)
452{
453 int i;
454
455 used_cpu_wins = 0;
456
457 /* Disable all CPU windows */
458 for (i = 0; i < MV_WIN_CPU_MAX; i++) {
459 win_cpu_cr_write(i, 0);
460 win_cpu_br_write(i, 0);
461 if (win_cpu_can_remap(i)) {
462 win_cpu_remap_l_write(i, 0);
463 win_cpu_remap_h_write(i, 0);
464 }
465 }
466
467 for (i = 0; i < cpu_wins_no; i++)
468 if (cpu_wins[i].target > 0)
469 decode_win_cpu_set(cpu_wins[i].target,
470 cpu_wins[i].attr, cpu_wins[i].base,
471 cpu_wins[i].size, cpu_wins[i].remap);
472
473}
474
475/*
476 * Check if we're able to cover all active DDR banks.
477 */
478static int
479decode_win_can_cover_ddr(int max)
480{
481 int i, c;
482
483 c = 0;
484 for (i = 0; i < MV_WIN_DDR_MAX; i++)
485 if (ddr_is_active(i))
486 c++;
487
488 if (c > max) {
489 printf("Unable to cover all active DDR banks: "
490 "%d, available windows: %d\n", c, max);
491 return (0);
492 }
493
494 return (1);
495}
496
497/**************************************************************************
498 * DDR windows routines
499 **************************************************************************/
500int
501ddr_is_active(int i)
502{
503
504 if (ddr_sz_read(i) & 0x1)
505 return (1);
506
507 return (0);
508}
509
510uint32_t
511ddr_base(int i)
512{
513
514 return (ddr_br_read(i) & 0xff000000);
515}
516
517uint32_t
518ddr_size(int i)
519{
520
521 return ((ddr_sz_read(i) | 0x00ffffff) + 1);
522}
523
524uint32_t
525ddr_attr(int i)
526{
527
528 return (i == 0 ? 0xe :
529 (i == 1 ? 0xd :
530 (i == 2 ? 0xb :
531 (i == 3 ? 0x7 : 0xff))));
532}
533
534uint32_t
535ddr_target(int i)
536{
537
538 /* Mbus unit ID is 0x0 for DDR SDRAM controller */
539 return (0);
540}
541
542/**************************************************************************
543 * USB windows routines
544 **************************************************************************/
545static int
546decode_win_usb_valid(void)
547{
548
549 return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
550}
551
359 /* Depending on the SoC certain windows have remap capability */
360 if ((dev == MV_DEV_88F5182 && i < 2) ||
361 (dev == MV_DEV_88F5281 && i < 4) ||
362 (dev == MV_DEV_88F6281 && i < 4) ||
363 (dev == MV_DEV_MV78100 && i < 8))
364 return (1);
365
366 return (0);
367}
368
369/* XXX This should check for overlapping remap fields too.. */
370int
371decode_win_overlap(int win, int win_no, const struct decode_win *wintab)
372{
373 const struct decode_win *tab;
374 int i;
375
376 tab = wintab;
377
378 for (i = 0; i < win_no; i++, tab++) {
379 if (i == win)
380 /* Skip self */
381 continue;
382
383 if ((tab->base + tab->size - 1) < (wintab + win)->base)
384 continue;
385
386 else if (((wintab + win)->base + (wintab + win)->size - 1) <
387 tab->base)
388 continue;
389 else
390 return (i);
391 }
392
393 return (-1);
394}
395
396static int
397decode_win_cpu_valid(void)
398{
399 int i, j, rv;
400 uint32_t b, e, s;
401
402 if (cpu_wins_no > MV_WIN_CPU_MAX) {
403 printf("CPU windows: too many entries: %d\n", cpu_wins_no);
404 return (-1);
405 }
406
407 rv = 1;
408 for (i = 0; i < cpu_wins_no; i++) {
409
410 if (cpu_wins[i].target == 0) {
411 printf("CPU window#%d: DDR target window is not "
412 "supposed to be reprogrammed!\n", i);
413 rv = 0;
414 }
415
416 if (cpu_wins[i].remap >= 0 && win_cpu_can_remap(i) != 1) {
417 printf("CPU window#%d: not capable of remapping, but "
418 "val 0x%08x defined\n", i, cpu_wins[i].remap);
419 rv = 0;
420 }
421
422 s = cpu_wins[i].size;
423 b = cpu_wins[i].base;
424 e = b + s - 1;
425 if (s > (0xFFFFFFFF - b + 1)) {
426 /*
427 * XXX this boundary check should account for 64bit
428 * and remapping..
429 */
430 printf("CPU window#%d: no space for size 0x%08x at "
431 "0x%08x\n", i, s, b);
432 rv = 0;
433 continue;
434 }
435
436 j = decode_win_overlap(i, cpu_wins_no, &cpu_wins[0]);
437 if (j >= 0) {
438 printf("CPU window#%d: (0x%08x - 0x%08x) overlaps "
439 "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
440 cpu_wins[j].base,
441 cpu_wins[j].base + cpu_wins[j].size - 1);
442 rv = 0;
443 }
444 }
445
446 return (rv);
447}
448
449int
450decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size,
451 int remap)
452{
453 uint32_t br, cr;
454 int win;
455
456 if (used_cpu_wins >= MV_WIN_CPU_MAX)
457 return (-1);
458
459 win = used_cpu_wins++;
460
461 br = base & 0xffff0000;
462 win_cpu_br_write(win, br);
463
464 if (win_cpu_can_remap(win)) {
465 if (remap >= 0) {
466 win_cpu_remap_l_write(win, remap & 0xffff0000);
467 win_cpu_remap_h_write(win, 0);
468 } else {
469 /*
470 * Remap function is not used for a given window
471 * (capable of remapping) - set remap field with the
472 * same value as base.
473 */
474 win_cpu_remap_l_write(win, base & 0xffff0000);
475 win_cpu_remap_h_write(win, 0);
476 }
477 }
478
479 cr = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1;
480 win_cpu_cr_write(win, cr);
481
482 return (0);
483}
484
485static void
486decode_win_cpu_setup(void)
487{
488 int i;
489
490 used_cpu_wins = 0;
491
492 /* Disable all CPU windows */
493 for (i = 0; i < MV_WIN_CPU_MAX; i++) {
494 win_cpu_cr_write(i, 0);
495 win_cpu_br_write(i, 0);
496 if (win_cpu_can_remap(i)) {
497 win_cpu_remap_l_write(i, 0);
498 win_cpu_remap_h_write(i, 0);
499 }
500 }
501
502 for (i = 0; i < cpu_wins_no; i++)
503 if (cpu_wins[i].target > 0)
504 decode_win_cpu_set(cpu_wins[i].target,
505 cpu_wins[i].attr, cpu_wins[i].base,
506 cpu_wins[i].size, cpu_wins[i].remap);
507
508}
509
510/*
511 * Check if we're able to cover all active DDR banks.
512 */
513static int
514decode_win_can_cover_ddr(int max)
515{
516 int i, c;
517
518 c = 0;
519 for (i = 0; i < MV_WIN_DDR_MAX; i++)
520 if (ddr_is_active(i))
521 c++;
522
523 if (c > max) {
524 printf("Unable to cover all active DDR banks: "
525 "%d, available windows: %d\n", c, max);
526 return (0);
527 }
528
529 return (1);
530}
531
532/**************************************************************************
533 * DDR windows routines
534 **************************************************************************/
535int
536ddr_is_active(int i)
537{
538
539 if (ddr_sz_read(i) & 0x1)
540 return (1);
541
542 return (0);
543}
544
545uint32_t
546ddr_base(int i)
547{
548
549 return (ddr_br_read(i) & 0xff000000);
550}
551
552uint32_t
553ddr_size(int i)
554{
555
556 return ((ddr_sz_read(i) | 0x00ffffff) + 1);
557}
558
559uint32_t
560ddr_attr(int i)
561{
562
563 return (i == 0 ? 0xe :
564 (i == 1 ? 0xd :
565 (i == 2 ? 0xb :
566 (i == 3 ? 0x7 : 0xff))));
567}
568
569uint32_t
570ddr_target(int i)
571{
572
573 /* Mbus unit ID is 0x0 for DDR SDRAM controller */
574 return (0);
575}
576
577/**************************************************************************
578 * USB windows routines
579 **************************************************************************/
580static int
581decode_win_usb_valid(void)
582{
583
584 return (decode_win_can_cover_ddr(MV_WIN_USB_MAX));
585}
586
587static __inline int
588usb_max_ports(void)
589{
590 uint32_t dev, rev;
591
592 soc_id(&dev, &rev);
593 return (dev == MV_DEV_MV78100 ? 3 : 1);
594}
595
596static void
597decode_win_usb_dump(void)
598{
599 int i, p, m;
600
601 m = usb_max_ports();
602 for (p = 0; p < m; p++)
603 for (i = 0; i < MV_WIN_USB_MAX; i++)
604 printf("USB window#%d: c 0x%08x, b 0x%08x\n", i,
605 win_usb_cr_read(i, p), win_usb_br_read(i, p));
606}
607
552/*
553 * Set USB decode windows.
554 */
555static void
608/*
609 * Set USB decode windows.
610 */
611static void
556decode_win_usb_setup(uint32_t ctrl)
612decode_win_usb_setup(void)
557{
558 uint32_t br, cr;
613{
614 uint32_t br, cr;
559 int i, j;
615 int i, j, p, m;
560
616
561 /* Disable and clear all USB windows */
562 for (i = 0; i < MV_WIN_USB_MAX; i++) {
563 win_usb_cr_write(i, 0);
564 win_usb_br_write(i, 0);
565 }
617 /* Disable and clear all USB windows for all ports */
618 m = usb_max_ports();
619 for (p = 0; p < m; p++) {
566
620
567 /* Only access to active DRAM banks is required */
568 for (i = 0; i < MV_WIN_DDR_MAX; i++)
569 if (ddr_is_active(i)) {
570 br = ddr_base(i);
571 /*
572 * XXX for 6281 we should handle Mbus write burst limit
573 * field in the ctrl reg
574 */
575 cr = (((ddr_size(i) - 1) & 0xffff0000) |
576 (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1);
621 for (i = 0; i < MV_WIN_USB_MAX; i++) {
622 win_usb_cr_write(i, p, 0);
623 win_usb_br_write(i, p, 0);
624 }
577
625
578 /* Set the first free USB window */
579 for (j = 0; j < MV_WIN_USB_MAX; j++) {
580 if (win_usb_cr_read(j) & 0x1)
581 continue;
626 /* Only access to active DRAM banks is required */
627 for (i = 0; i < MV_WIN_DDR_MAX; i++) {
628 if (ddr_is_active(i)) {
629 br = ddr_base(i);
630 /*
631 * XXX for 6281 we should handle Mbus write
632 * burst limit field in the ctrl reg
633 */
634 cr = (((ddr_size(i) - 1) & 0xffff0000) |
635 (ddr_attr(i) << 8) |
636 (ddr_target(i) << 4) | 1);
582
637
583 win_usb_br_write(j, br);
584 win_usb_cr_write(j, cr);
585 break;
638 /* Set the first free USB window */
639 for (j = 0; j < MV_WIN_USB_MAX; j++) {
640 if (win_usb_cr_read(j, p) & 0x1)
641 continue;
642
643 win_usb_br_write(j, p, br);
644 win_usb_cr_write(j, p, cr);
645 break;
646 }
586 }
587 }
647 }
648 }
649 }
588}
589
590/**************************************************************************
591 * ETH windows routines
592 **************************************************************************/
593
594static int
595win_eth_can_remap(int i)
596{
597
598 /* ETH encode windows 0-3 have remap capability */
599 if (i < 4)
600 return (1);
601
602 return (0);
603}
604
605static int
606eth_bare_read(uint32_t base, int i)
607{
608 uint32_t v;
609
610 v = win_eth_bare_read(base);
611 v &= (1 << i);
612
613 return (v >> i);
614}
615
616static void
617eth_bare_write(uint32_t base, int i, int val)
618{
619 uint32_t v;
620
621 v = win_eth_bare_read(base);
622 v &= ~(1 << i);
623 v |= (val << i);
624 win_eth_bare_write(base, v);
625}
626
627static void
628eth_epap_write(uint32_t base, int i, int val)
629{
630 uint32_t v;
631
632 v = win_eth_epap_read(base);
633 v &= ~(0x3 << (i * 2));
634 v |= (val << (i * 2));
635 win_eth_epap_write(base, v);
636}
637
638static void
639decode_win_eth_setup(uint32_t base)
640{
641 uint32_t br, sz;
642 int i, j;
643
644 /* Disable, clear and revoke protection for all ETH windows */
645 for (i = 0; i < MV_WIN_ETH_MAX; i++) {
646
647 eth_bare_write(base, i, 1);
648 eth_epap_write(base, i, 0);
649 win_eth_br_write(base, i, 0);
650 win_eth_sz_write(base, i, 0);
651 if (win_eth_can_remap(i))
652 win_eth_har_write(base, i, 0);
653 }
654
655 /* Only access to active DRAM banks is required */
656 for (i = 0; i < MV_WIN_DDR_MAX; i++)
657 if (ddr_is_active(i)) {
658
659 br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
660 sz = ((ddr_size(i) - 1) & 0xffff0000);
661
662 /* Set the first free ETH window */
663 for (j = 0; j < MV_WIN_ETH_MAX; j++) {
664 if (eth_bare_read(base, j) == 0)
665 continue;
666
667 win_eth_br_write(base, j, br);
668 win_eth_sz_write(base, j, sz);
669
670 /* XXX remapping ETH windows not supported */
671
672 /* Set protection RW */
673 eth_epap_write(base, j, 0x3);
674
675 /* Enable window */
676 eth_bare_write(base, j, 0);
677 break;
678 }
679 }
680}
681
682static int
683decode_win_eth_valid(void)
684{
685
686 return (decode_win_can_cover_ddr(MV_WIN_ETH_MAX));
687}
688
689/**************************************************************************
690 * PCIE windows routines
691 **************************************************************************/
692
693static void
694decode_win_pcie_setup(uint32_t base)
695{
696 uint32_t size = 0;
697 uint32_t cr, br;
698 int i, j;
699
700 for (i = 0; i < MV_PCIE_BAR_MAX; i++)
701 pcie_bar_write(base, i, 0);
702
703 for (i = 0; i < MV_WIN_PCIE_MAX; i++) {
704 win_pcie_cr_write(base, i, 0);
705 win_pcie_br_write(base, i, 0);
706 win_pcie_remap_write(base, i, 0);
707 }
708
709 for (i = 0; i < MV_WIN_DDR_MAX; i++) {
710 if (ddr_is_active(i)) {
711 /* Map DDR to BAR 1 */
712 cr = (ddr_size(i) - 1) & 0xffff0000;
713 size += ddr_size(i) & 0xffff0000;
714 cr |= (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
715 br = ddr_base(i);
716
717 /* Use the first available PCIE window */
718 for (j = 0; j < MV_WIN_PCIE_MAX; j++) {
719 if (win_pcie_cr_read(base, j) != 0)
720 continue;
721
722 win_pcie_br_write(base, j, br);
723 win_pcie_cr_write(base, j, cr);
724 break;
725 }
726 }
727 }
728
729 /*
730 * Upper 16 bits in BAR register is interpreted as BAR size
731 * (in 64 kB units) plus 64kB, so substract 0x10000
732 * form value passed to register to get correct value.
733 */
734 size -= 0x10000;
735 pcie_bar_write(base, 0, size | 1);
736}
737
738static int
739decode_win_pcie_valid(void)
740{
741
742 return (decode_win_can_cover_ddr(MV_WIN_PCIE_MAX));
743}
744
745/**************************************************************************
746 * IDMA windows routines
747 **************************************************************************/
748#if defined(SOC_MV_ORION) || defined(SOC_MV_DISCOVERY)
749static int
750idma_bare_read(int i)
751{
752 uint32_t v;
753
754 v = win_idma_bare_read();
755 v &= (1 << i);
756
757 return (v >> i);
758}
759
760static void
761idma_bare_write(int i, int val)
762{
763 uint32_t v;
764
765 v = win_idma_bare_read();
766 v &= ~(1 << i);
767 v |= (val << i);
768 win_idma_bare_write(v);
769}
770
771/*
772 * Sets channel protection 'val' for window 'w' on channel 'c'
773 */
774static void
775idma_cap_write(int c, int w, int val)
776{
777 uint32_t v;
778
779 v = win_idma_cap_read(c);
780 v &= ~(0x3 << (w * 2));
781 v |= (val << (w * 2));
782 win_idma_cap_write(c, v);
783}
784
785/*
786 * Set protection 'val' on all channels for window 'w'
787 */
788static void
789idma_set_prot(int w, int val)
790{
791 int c;
792
793 for (c = 0; c < MV_IDMA_CHAN_MAX; c++)
794 idma_cap_write(c, w, val);
795}
796
797static int
798win_idma_can_remap(int i)
799{
800
801 /* IDMA decode windows 0-3 have remap capability */
802 if (i < 4)
803 return (1);
804
805 return (0);
806}
807
808void
809decode_win_idma_setup(void)
810{
811 uint32_t br, sz;
812 int i, j;
813
814 /*
815 * Disable and clear all IDMA windows, revoke protection for all channels
816 */
817 for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
818
819 idma_bare_write(i, 1);
820 win_idma_br_write(i, 0);
821 win_idma_sz_write(i, 0);
822 if (win_idma_can_remap(i) == 1)
823 win_idma_har_write(i, 0);
824 }
825 for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
826 win_idma_cap_write(i, 0);
827
828 /*
829 * Set up access to all active DRAM banks
830 */
831 for (i = 0; i < MV_WIN_DDR_MAX; i++)
832 if (ddr_is_active(i)) {
833 br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
834 sz = ((ddr_size(i) - 1) & 0xffff0000);
835
836 /* Place DDR entries in non-remapped windows */
837 for (j = 0; j < MV_WIN_IDMA_MAX; j++)
838 if (win_idma_can_remap(j) != 1 &&
839 idma_bare_read(j) == 1) {
840
841 /* Configure window */
842 win_idma_br_write(j, br);
843 win_idma_sz_write(j, sz);
844
845 /* Set protection RW on all channels */
846 idma_set_prot(j, 0x3);
847
848 /* Enable window */
849 idma_bare_write(j, 0);
850 break;
851 }
852 }
853
854 /*
855 * Remaining targets -- from statically defined table
856 */
857 for (i = 0; i < idma_wins_no; i++)
858 if (idma_wins[i].target > 0) {
859 br = (idma_wins[i].base & 0xffff0000) |
860 (idma_wins[i].attr << 8) | idma_wins[i].target;
861 sz = ((idma_wins[i].size - 1) & 0xffff0000);
862
863 /* Set the first free IDMA window */
864 for (j = 0; j < MV_WIN_IDMA_MAX; j++) {
865 if (idma_bare_read(j) == 0)
866 continue;
867
868 /* Configure window */
869 win_idma_br_write(j, br);
870 win_idma_sz_write(j, sz);
871 if (win_idma_can_remap(j) &&
872 idma_wins[j].remap >= 0)
873 win_idma_har_write(j, idma_wins[j].remap);
874
875 /* Set protection RW on all channels */
876 idma_set_prot(j, 0x3);
877
878 /* Enable window */
879 idma_bare_write(j, 0);
880 break;
881 }
882 }
883}
884
885int
886decode_win_idma_valid(void)
887{
888 const struct decode_win *wintab;
889 int c, i, j, rv;
890 uint32_t b, e, s;
891
892 if (idma_wins_no > MV_WIN_IDMA_MAX) {
893 printf("IDMA windows: too many entries: %d\n", idma_wins_no);
894 return (-1);
895 }
896 for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
897 if (ddr_is_active(i))
898 c++;
899
900 if (idma_wins_no > (MV_WIN_IDMA_MAX - c)) {
901 printf("IDMA windows: too many entries: %d, available: %d\n",
902 idma_wins_no, MV_WIN_IDMA_MAX - c);
903 return (-1);
904 }
905
906 wintab = idma_wins;
907 rv = 1;
908 for (i = 0; i < idma_wins_no; i++, wintab++) {
909
910 if (wintab->target == 0) {
911 printf("IDMA window#%d: DDR target window is not "
912 "supposed to be reprogrammed!\n", i);
913 rv = 0;
914 }
915
916 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
917 printf("IDMA window#%d: not capable of remapping, but "
918 "val 0x%08x defined\n", i, wintab->remap);
919 rv = 0;
920 }
921
922 s = wintab->size;
923 b = wintab->base;
924 e = b + s - 1;
925 if (s > (0xFFFFFFFF - b + 1)) {
926 /* XXX this boundary check should account for 64bit and
927 * remapping.. */
928 printf("IDMA window#%d: no space for size 0x%08x at "
929 "0x%08x\n", i, s, b);
930 rv = 0;
931 continue;
932 }
933
934 j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]);
935 if (j >= 0) {
936 printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps "
650}
651
652/**************************************************************************
653 * ETH windows routines
654 **************************************************************************/
655
656static int
657win_eth_can_remap(int i)
658{
659
660 /* ETH encode windows 0-3 have remap capability */
661 if (i < 4)
662 return (1);
663
664 return (0);
665}
666
667static int
668eth_bare_read(uint32_t base, int i)
669{
670 uint32_t v;
671
672 v = win_eth_bare_read(base);
673 v &= (1 << i);
674
675 return (v >> i);
676}
677
678static void
679eth_bare_write(uint32_t base, int i, int val)
680{
681 uint32_t v;
682
683 v = win_eth_bare_read(base);
684 v &= ~(1 << i);
685 v |= (val << i);
686 win_eth_bare_write(base, v);
687}
688
689static void
690eth_epap_write(uint32_t base, int i, int val)
691{
692 uint32_t v;
693
694 v = win_eth_epap_read(base);
695 v &= ~(0x3 << (i * 2));
696 v |= (val << (i * 2));
697 win_eth_epap_write(base, v);
698}
699
700static void
701decode_win_eth_setup(uint32_t base)
702{
703 uint32_t br, sz;
704 int i, j;
705
706 /* Disable, clear and revoke protection for all ETH windows */
707 for (i = 0; i < MV_WIN_ETH_MAX; i++) {
708
709 eth_bare_write(base, i, 1);
710 eth_epap_write(base, i, 0);
711 win_eth_br_write(base, i, 0);
712 win_eth_sz_write(base, i, 0);
713 if (win_eth_can_remap(i))
714 win_eth_har_write(base, i, 0);
715 }
716
717 /* Only access to active DRAM banks is required */
718 for (i = 0; i < MV_WIN_DDR_MAX; i++)
719 if (ddr_is_active(i)) {
720
721 br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
722 sz = ((ddr_size(i) - 1) & 0xffff0000);
723
724 /* Set the first free ETH window */
725 for (j = 0; j < MV_WIN_ETH_MAX; j++) {
726 if (eth_bare_read(base, j) == 0)
727 continue;
728
729 win_eth_br_write(base, j, br);
730 win_eth_sz_write(base, j, sz);
731
732 /* XXX remapping ETH windows not supported */
733
734 /* Set protection RW */
735 eth_epap_write(base, j, 0x3);
736
737 /* Enable window */
738 eth_bare_write(base, j, 0);
739 break;
740 }
741 }
742}
743
744static int
745decode_win_eth_valid(void)
746{
747
748 return (decode_win_can_cover_ddr(MV_WIN_ETH_MAX));
749}
750
751/**************************************************************************
752 * PCIE windows routines
753 **************************************************************************/
754
755static void
756decode_win_pcie_setup(uint32_t base)
757{
758 uint32_t size = 0;
759 uint32_t cr, br;
760 int i, j;
761
762 for (i = 0; i < MV_PCIE_BAR_MAX; i++)
763 pcie_bar_write(base, i, 0);
764
765 for (i = 0; i < MV_WIN_PCIE_MAX; i++) {
766 win_pcie_cr_write(base, i, 0);
767 win_pcie_br_write(base, i, 0);
768 win_pcie_remap_write(base, i, 0);
769 }
770
771 for (i = 0; i < MV_WIN_DDR_MAX; i++) {
772 if (ddr_is_active(i)) {
773 /* Map DDR to BAR 1 */
774 cr = (ddr_size(i) - 1) & 0xffff0000;
775 size += ddr_size(i) & 0xffff0000;
776 cr |= (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
777 br = ddr_base(i);
778
779 /* Use the first available PCIE window */
780 for (j = 0; j < MV_WIN_PCIE_MAX; j++) {
781 if (win_pcie_cr_read(base, j) != 0)
782 continue;
783
784 win_pcie_br_write(base, j, br);
785 win_pcie_cr_write(base, j, cr);
786 break;
787 }
788 }
789 }
790
791 /*
792 * Upper 16 bits in BAR register is interpreted as BAR size
793 * (in 64 kB units) plus 64kB, so substract 0x10000
794 * form value passed to register to get correct value.
795 */
796 size -= 0x10000;
797 pcie_bar_write(base, 0, size | 1);
798}
799
800static int
801decode_win_pcie_valid(void)
802{
803
804 return (decode_win_can_cover_ddr(MV_WIN_PCIE_MAX));
805}
806
807/**************************************************************************
808 * IDMA windows routines
809 **************************************************************************/
810#if defined(SOC_MV_ORION) || defined(SOC_MV_DISCOVERY)
811static int
812idma_bare_read(int i)
813{
814 uint32_t v;
815
816 v = win_idma_bare_read();
817 v &= (1 << i);
818
819 return (v >> i);
820}
821
822static void
823idma_bare_write(int i, int val)
824{
825 uint32_t v;
826
827 v = win_idma_bare_read();
828 v &= ~(1 << i);
829 v |= (val << i);
830 win_idma_bare_write(v);
831}
832
833/*
834 * Sets channel protection 'val' for window 'w' on channel 'c'
835 */
836static void
837idma_cap_write(int c, int w, int val)
838{
839 uint32_t v;
840
841 v = win_idma_cap_read(c);
842 v &= ~(0x3 << (w * 2));
843 v |= (val << (w * 2));
844 win_idma_cap_write(c, v);
845}
846
847/*
848 * Set protection 'val' on all channels for window 'w'
849 */
850static void
851idma_set_prot(int w, int val)
852{
853 int c;
854
855 for (c = 0; c < MV_IDMA_CHAN_MAX; c++)
856 idma_cap_write(c, w, val);
857}
858
859static int
860win_idma_can_remap(int i)
861{
862
863 /* IDMA decode windows 0-3 have remap capability */
864 if (i < 4)
865 return (1);
866
867 return (0);
868}
869
870void
871decode_win_idma_setup(void)
872{
873 uint32_t br, sz;
874 int i, j;
875
876 /*
877 * Disable and clear all IDMA windows, revoke protection for all channels
878 */
879 for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
880
881 idma_bare_write(i, 1);
882 win_idma_br_write(i, 0);
883 win_idma_sz_write(i, 0);
884 if (win_idma_can_remap(i) == 1)
885 win_idma_har_write(i, 0);
886 }
887 for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
888 win_idma_cap_write(i, 0);
889
890 /*
891 * Set up access to all active DRAM banks
892 */
893 for (i = 0; i < MV_WIN_DDR_MAX; i++)
894 if (ddr_is_active(i)) {
895 br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i);
896 sz = ((ddr_size(i) - 1) & 0xffff0000);
897
898 /* Place DDR entries in non-remapped windows */
899 for (j = 0; j < MV_WIN_IDMA_MAX; j++)
900 if (win_idma_can_remap(j) != 1 &&
901 idma_bare_read(j) == 1) {
902
903 /* Configure window */
904 win_idma_br_write(j, br);
905 win_idma_sz_write(j, sz);
906
907 /* Set protection RW on all channels */
908 idma_set_prot(j, 0x3);
909
910 /* Enable window */
911 idma_bare_write(j, 0);
912 break;
913 }
914 }
915
916 /*
917 * Remaining targets -- from statically defined table
918 */
919 for (i = 0; i < idma_wins_no; i++)
920 if (idma_wins[i].target > 0) {
921 br = (idma_wins[i].base & 0xffff0000) |
922 (idma_wins[i].attr << 8) | idma_wins[i].target;
923 sz = ((idma_wins[i].size - 1) & 0xffff0000);
924
925 /* Set the first free IDMA window */
926 for (j = 0; j < MV_WIN_IDMA_MAX; j++) {
927 if (idma_bare_read(j) == 0)
928 continue;
929
930 /* Configure window */
931 win_idma_br_write(j, br);
932 win_idma_sz_write(j, sz);
933 if (win_idma_can_remap(j) &&
934 idma_wins[j].remap >= 0)
935 win_idma_har_write(j, idma_wins[j].remap);
936
937 /* Set protection RW on all channels */
938 idma_set_prot(j, 0x3);
939
940 /* Enable window */
941 idma_bare_write(j, 0);
942 break;
943 }
944 }
945}
946
947int
948decode_win_idma_valid(void)
949{
950 const struct decode_win *wintab;
951 int c, i, j, rv;
952 uint32_t b, e, s;
953
954 if (idma_wins_no > MV_WIN_IDMA_MAX) {
955 printf("IDMA windows: too many entries: %d\n", idma_wins_no);
956 return (-1);
957 }
958 for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
959 if (ddr_is_active(i))
960 c++;
961
962 if (idma_wins_no > (MV_WIN_IDMA_MAX - c)) {
963 printf("IDMA windows: too many entries: %d, available: %d\n",
964 idma_wins_no, MV_WIN_IDMA_MAX - c);
965 return (-1);
966 }
967
968 wintab = idma_wins;
969 rv = 1;
970 for (i = 0; i < idma_wins_no; i++, wintab++) {
971
972 if (wintab->target == 0) {
973 printf("IDMA window#%d: DDR target window is not "
974 "supposed to be reprogrammed!\n", i);
975 rv = 0;
976 }
977
978 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
979 printf("IDMA window#%d: not capable of remapping, but "
980 "val 0x%08x defined\n", i, wintab->remap);
981 rv = 0;
982 }
983
984 s = wintab->size;
985 b = wintab->base;
986 e = b + s - 1;
987 if (s > (0xFFFFFFFF - b + 1)) {
988 /* XXX this boundary check should account for 64bit and
989 * remapping.. */
990 printf("IDMA window#%d: no space for size 0x%08x at "
991 "0x%08x\n", i, s, b);
992 rv = 0;
993 continue;
994 }
995
996 j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]);
997 if (j >= 0) {
998 printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps "
937 "with " "#%d (0x%08x - 0x%08x)\n", i, b, e, j,
999 "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
938 idma_wins[j].base,
939 idma_wins[j].base + idma_wins[j].size - 1);
940 rv = 0;
941 }
942 }
943
944 return (rv);
945}
946
947void
948decode_win_idma_dump(void)
949{
950 int i;
951
952 for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
953 printf("IDMA window#%d: b 0x%08x, s 0x%08x", i,
954 win_idma_br_read(i), win_idma_sz_read(i));
955
956 if (win_idma_can_remap(i))
957 printf(", ha 0x%08x", win_idma_har_read(i));
958
959 printf("\n");
960 }
961 for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
962 printf("IDMA channel#%d: ap 0x%08x\n", i,
963 win_idma_cap_read(i));
964 printf("IDMA windows: bare 0x%08x\n", win_idma_bare_read());
965}
966#else
967
968/* Provide dummy functions to satisfy the build for SoCs not equipped with IDMA */
969int
970decode_win_idma_valid(void)
971{
972
973 return (1);
974}
975
976void
977decode_win_idma_setup(void)
978{
979}
980
981void
982decode_win_idma_dump(void)
983{
984}
985#endif
1000 idma_wins[j].base,
1001 idma_wins[j].base + idma_wins[j].size - 1);
1002 rv = 0;
1003 }
1004 }
1005
1006 return (rv);
1007}
1008
1009void
1010decode_win_idma_dump(void)
1011{
1012 int i;
1013
1014 for (i = 0; i < MV_WIN_IDMA_MAX; i++) {
1015 printf("IDMA window#%d: b 0x%08x, s 0x%08x", i,
1016 win_idma_br_read(i), win_idma_sz_read(i));
1017
1018 if (win_idma_can_remap(i))
1019 printf(", ha 0x%08x", win_idma_har_read(i));
1020
1021 printf("\n");
1022 }
1023 for (i = 0; i < MV_IDMA_CHAN_MAX; i++)
1024 printf("IDMA channel#%d: ap 0x%08x\n", i,
1025 win_idma_cap_read(i));
1026 printf("IDMA windows: bare 0x%08x\n", win_idma_bare_read());
1027}
1028#else
1029
1030/* Provide dummy functions to satisfy the build for SoCs not equipped with IDMA */
1031int
1032decode_win_idma_valid(void)
1033{
1034
1035 return (1);
1036}
1037
1038void
1039decode_win_idma_setup(void)
1040{
1041}
1042
1043void
1044decode_win_idma_dump(void)
1045{
1046}
1047#endif
1048
1049/**************************************************************************
1050 * XOR windows routines
1051 **************************************************************************/
1052#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
1053static int
1054xor_ctrl_read(int i, int c, int e)
1055{
1056 uint32_t v;
1057 v = win_xor_ctrl_read(c, e);
1058 v &= (1 << i);
1059
1060 return (v >> i);
1061}
1062
1063static void
1064xor_ctrl_write(int i, int c, int e, int val)
1065{
1066 uint32_t v;
1067
1068 v = win_xor_ctrl_read(c, e);
1069 v &= ~(1 << i);
1070 v |= (val << i);
1071 win_xor_ctrl_write(c, e, v);
1072}
1073
1074/*
1075 * Set channel protection 'val' for window 'w' on channel 'c'
1076 */
1077
1078static void
1079xor_chan_write(int c, int e, int w, int val)
1080{
1081 uint32_t v;
1082
1083 v = win_xor_ctrl_read(c, e);
1084 v &= ~(0x3 << (w * 2 + 16));
1085 v |= (val << (w * 2 + 16));
1086 win_xor_ctrl_write(c, e, v);
1087}
1088
1089/*
1090 * Set protection 'val' on all channels for window 'w' on engine 'e'
1091 */
1092static void
1093xor_set_prot(int w, int e, int val)
1094{
1095 int c;
1096
1097 for (c = 0; c < MV_XOR_CHAN_MAX; c++)
1098 xor_chan_write(c, e, w, val);
1099}
1100
1101static int
1102win_xor_can_remap(int i)
1103{
1104
1105 /* XOR decode windows 0-3 have remap capability */
1106 if (i < 4)
1107 return (1);
1108
1109 return (0);
1110}
1111
1112static __inline int
1113xor_max_eng(void)
1114{
1115 uint32_t dev, rev;
1116
1117 soc_id(&dev, &rev);
1118 return ((dev == MV_DEV_88F6281) ? 2 :
1119 (dev == MV_DEV_MV78100) ? 1 : 0);
1120}
1121
1122static void
1123xor_active_dram(int c, int e, int *window)
1124{
1125 uint32_t br, sz;
1126 int i, m, w;
1127
1128 /*
1129 * Set up access to all active DRAM banks
1130 */
1131 m = xor_max_eng();
1132 for (i = 0; i < m; i++)
1133 if (ddr_is_active(i)) {
1134 br = ddr_base(i) | (ddr_attr(i) << 8) |
1135 ddr_target(i);
1136 sz = ((ddr_size(i) - 1) & 0xffff0000);
1137
1138 /* Place DDR entries in non-remapped windows */
1139 for (w = 0; w < MV_WIN_XOR_MAX; w++)
1140 if (win_xor_can_remap(w) != 1 &&
1141 (xor_ctrl_read(w, c, e) == 0) &&
1142 w > *window) {
1143 /* Configure window */
1144 win_xor_br_write(w, e, br);
1145 win_xor_sz_write(w, e, sz);
1146
1147 /* Set protection RW on all channels */
1148 xor_set_prot(w, e, 0x3);
1149
1150 /* Enable window */
1151 xor_ctrl_write(w, c, e, 1);
1152 (*window)++;
1153 break;
1154 }
1155 }
1156}
1157
1158void
1159decode_win_xor_setup(void)
1160{
1161 uint32_t br, sz;
1162 int i, j, z, e = 1, m, window;
1163
1164 /*
1165 * Disable and clear all XOR windows, revoke protection for all
1166 * channels
1167 */
1168 m = xor_max_eng();
1169 for (j = 0; j < m; j++, e--) {
1170
1171 /* Number of non-remaped windows */
1172 window = MV_XOR_NON_REMAP - 1;
1173
1174 for (i = 0; i < MV_WIN_XOR_MAX; i++) {
1175 win_xor_br_write(i, e, 0);
1176 win_xor_sz_write(i, e, 0);
1177 }
1178
1179 if (win_xor_can_remap(i) == 1)
1180 win_xor_har_write(i, e, 0);
1181
1182 for (i = 0; i < MV_XOR_CHAN_MAX; i++) {
1183 win_xor_ctrl_write(i, e, 0);
1184 xor_active_dram(i, e, &window);
1185 }
1186
1187 /*
1188 * Remaining targets -- from a statically defined table
1189 */
1190 for (i = 0; i < xor_wins_no; i++)
1191 if (xor_wins[i].target > 0) {
1192 br = (xor_wins[i].base & 0xffff0000) |
1193 (xor_wins[i].attr << 8) |
1194 xor_wins[i].target;
1195 sz = ((xor_wins[i].size - 1) & 0xffff0000);
1196
1197 /* Set the first free XOR window */
1198 for (z = 0; z < MV_WIN_XOR_MAX; z++) {
1199 if (xor_ctrl_read(z, 0, e) &&
1200 xor_ctrl_read(z, 1, e))
1201 continue;
1202
1203 /* Configure window */
1204 win_xor_br_write(z, e, br);
1205 win_xor_sz_write(z, e, sz);
1206 if (win_xor_can_remap(z) &&
1207 xor_wins[z].remap >= 0)
1208 win_xor_har_write(z, e,
1209 xor_wins[z].remap);
1210
1211 /* Set protection RW on all channels */
1212 xor_set_prot(z, e, 0x3);
1213
1214 /* Enable window */
1215 xor_ctrl_write(z, 0, e, 1);
1216 xor_ctrl_write(z, 1, e, 1);
1217 break;
1218 }
1219 }
1220 }
1221}
1222
1223int
1224decode_win_xor_valid(void)
1225{
1226 const struct decode_win *wintab;
1227 int c, i, j, rv;
1228 uint32_t b, e, s;
1229
1230 if (xor_wins_no > MV_WIN_XOR_MAX) {
1231 printf("XOR windows: too many entries: %d\n", xor_wins_no);
1232 return (-1);
1233 }
1234 for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++)
1235 if (ddr_is_active(i))
1236 c++;
1237
1238 if (xor_wins_no > (MV_WIN_XOR_MAX - c)) {
1239 printf("XOR windows: too many entries: %d, available: %d\n",
1240 xor_wins_no, MV_WIN_IDMA_MAX - c);
1241 return (-1);
1242 }
1243
1244 wintab = xor_wins;
1245 rv = 1;
1246 for (i = 0; i < xor_wins_no; i++, wintab++) {
1247
1248 if (wintab->target == 0) {
1249 printf("XOR window#%d: DDR target window is not "
1250 "supposed to be reprogrammed!\n", i);
1251 rv = 0;
1252 }
1253
1254 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) {
1255 printf("XOR window#%d: not capable of remapping, but "
1256 "val 0x%08x defined\n", i, wintab->remap);
1257 rv = 0;
1258 }
1259
1260 s = wintab->size;
1261 b = wintab->base;
1262 e = b + s - 1;
1263 if (s > (0xFFFFFFFF - b + 1)) {
1264 /*
1265 * XXX this boundary check should account for 64bit
1266 * and remapping..
1267 */
1268 printf("XOR window#%d: no space for size 0x%08x at "
1269 "0x%08x\n", i, s, b);
1270 rv = 0;
1271 continue;
1272 }
1273
1274 j = decode_win_overlap(i, xor_wins_no, &xor_wins[0]);
1275 if (j >= 0) {
1276 printf("XOR window#%d: (0x%08x - 0x%08x) overlaps "
1277 "with #%d (0x%08x - 0x%08x)\n", i, b, e, j,
1278 xor_wins[j].base,
1279 xor_wins[j].base + xor_wins[j].size - 1);
1280 rv = 0;
1281 }
1282 }
1283
1284 return (rv);
1285}
1286
1287void
1288decode_win_xor_dump(void)
1289{
1290 int i, j;
1291 int e = 1;
1292
1293 for (j = 0; j < xor_max_eng(); j++, e--) {
1294 for (i = 0; i < MV_WIN_XOR_MAX; i++) {
1295 printf("XOR window#%d: b 0x%08x, s 0x%08x", i,
1296 win_xor_br_read(i, e), win_xor_sz_read(i, e));
1297
1298 if (win_xor_can_remap(i))
1299 printf(", ha 0x%08x", win_xor_har_read(i, e));
1300
1301 printf("\n");
1302 }
1303 for (i = 0; i < MV_XOR_CHAN_MAX; i++)
1304 printf("XOR control#%d: 0x%08x\n", i,
1305 win_xor_ctrl_read(i, e));
1306 }
1307}
1308
1309#else
1310/* Provide dummy functions to satisfy the build for SoCs not equipped with XOR */
1311int
1312decode_win_xor_valid(void)
1313{
1314
1315 return (1);
1316}
1317
1318void
1319decode_win_xor_setup(void)
1320{
1321}
1322
1323void
1324decode_win_xor_dump(void)
1325{
1326}
1327#endif
1328
1329/**************************************************************************
1330 * CESA TDMA windows routines
1331 **************************************************************************/
1332#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY)
1333/*
1334 * Dump CESA TDMA decode windows.
1335 */
1336static void
1337decode_win_cesa_dump(void)
1338{
1339 int i;
1340
1341 for (i = 0; i < MV_WIN_CESA_MAX; i++)
1342 printf("CESA window#%d: c 0x%08x, b 0x%08x\n", i,
1343 win_cesa_cr_read(i), win_cesa_br_read(i));
1344}
1345
1346
1347/*
1348 * Set CESA TDMA decode windows.
1349 */
1350static void
1351decode_win_cesa_setup(void)
1352{
1353 uint32_t br, cr;
1354 int i, j;
1355
1356 /* Disable and clear all CESA windows */
1357 for (i = 0; i < MV_WIN_CESA_MAX; i++) {
1358 win_cesa_cr_write(i, 0);
1359 win_cesa_br_write(i, 0);
1360 }
1361
1362 /* Only access to active DRAM banks is required. */
1363 for (i = 0; i < MV_WIN_DDR_MAX; i++)
1364 if (ddr_is_active(i)) {
1365 br = ddr_base(i);
1366 cr = (((ddr_size(i) - 1) & 0xffff0000) |
1367 (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1);
1368
1369 /* Set the first available CESA window */
1370 for (j = 0; j < MV_WIN_CESA_MAX; j++) {
1371 if (win_cesa_cr_read(j) & 0x1)
1372 continue;
1373
1374 win_cesa_br_write(j, br);
1375 win_cesa_cr_write(j, cr);
1376 break;
1377 }
1378 }
1379}
1380
1381/*
1382 * Check CESA TDMA decode windows.
1383 */
1384static int
1385decode_win_cesa_valid(void)
1386{
1387
1388 return (decode_win_can_cover_ddr(MV_WIN_CESA_MAX));
1389}
1390#else
1391
1392/*
1393 * Provide dummy functions to satisfy the build for SoCs not equipped with
1394 * CESA
1395 */
1396
1397int
1398decode_win_cesa_valid(void)
1399{
1400
1401 return (1);
1402}
1403
1404void
1405decode_win_cesa_setup(void)
1406{
1407}
1408
1409void
1410decode_win_cesa_dump(void)
1411{
1412}
1413#endif
1414
1415/**************************************************************************
1416 * SATA windows routines
1417 **************************************************************************/
1418static void
1419decode_win_sata_setup(void)
1420{
1421 uint32_t cr, br;
1422 int i, j;
1423
1424 for (i = 0; i < MV_WIN_SATA_MAX; i++) {
1425 win_sata_cr_write(i, 0);
1426 win_sata_br_write(i, 0);
1427 }
1428
1429 for (i = 0; i < MV_WIN_DDR_MAX; i++)
1430 if (ddr_is_active(i)) {
1431 cr = ((ddr_size(i) - 1) & 0xffff0000) |
1432 (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1;
1433 br = ddr_base(i);
1434
1435 /* Use the first available SATA window */
1436 for (j = 0; j < MV_WIN_SATA_MAX; j++) {
1437 if ((win_sata_cr_read(j) & 1) != 0)
1438 continue;
1439
1440 win_sata_br_write(j, br);
1441 win_sata_cr_write(j, cr);
1442 break;
1443 }
1444 }
1445}
1446
1447static int
1448decode_win_sata_valid(void)
1449{
1450 uint32_t dev, rev;
1451
1452 soc_id(&dev, &rev);
1453 if (dev == MV_DEV_88F5281)
1454 return (1);
1455
1456 return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX));
1457}