Sun Mar 11 00:17:29 2018 UTC ()
Outsource setting the backplane window into a specific function so it
can be called and reused in different places.

From OpenBSD.


(khorben)
diff -r1.1 -r1.2 src/sys/dev/sdmmc/if_bwfm_sdio.c

cvs diff -r1.1 -r1.2 src/sys/dev/sdmmc/if_bwfm_sdio.c (expand / switch to unified diff)

--- src/sys/dev/sdmmc/if_bwfm_sdio.c 2017/11/07 16:30:32 1.1
+++ src/sys/dev/sdmmc/if_bwfm_sdio.c 2018/03/11 00:17:28 1.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_bwfm_sdio.c,v 1.1 2017/11/07 16:30:32 khorben Exp $ */ 1/* $NetBSD: if_bwfm_sdio.c,v 1.2 2018/03/11 00:17:28 khorben Exp $ */
2/* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */ 2/* $OpenBSD: if_bwfm_sdio.c,v 1.1 2017/10/11 17:19:50 patrick Exp $ */
3/* 3/*
4 * Copyright (c) 2010-2016 Broadcom Corporation 4 * Copyright (c) 2010-2016 Broadcom Corporation
5 * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se> 5 * Copyright (c) 2016,2017 Patrick Wildt <patrick@blueri.se>
6 * 6 *
7 * Permission to use, copy, modify, and/or distribute this software for any 7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
@@ -63,26 +63,27 @@ static int bwfm_debug = 2; @@ -63,26 +63,27 @@ static int bwfm_debug = 2;
63 63
64#define DEVNAME(sc) device_xname((sc)->sc_sc.sc_dev) 64#define DEVNAME(sc) device_xname((sc)->sc_sc.sc_dev)
65 65
66struct bwfm_sdio_softc { 66struct bwfm_sdio_softc {
67 struct bwfm_softc sc_sc; 67 struct bwfm_softc sc_sc;
68 struct sdmmc_function **sc_sf; 68 struct sdmmc_function **sc_sf;
69 uint32_t sc_bar0; 69 uint32_t sc_bar0;
70}; 70};
71 71
72int bwfm_sdio_match(device_t, cfdata_t, void *); 72int bwfm_sdio_match(device_t, cfdata_t, void *);
73void bwfm_sdio_attach(device_t, struct device *, void *); 73void bwfm_sdio_attach(device_t, struct device *, void *);
74int bwfm_sdio_detach(device_t, int); 74int bwfm_sdio_detach(device_t, int);
75 75
 76void bwfm_sdio_backplane(struct bwfm_sdio_softc *, uint32_t);
76uint8_t bwfm_sdio_read_1(struct bwfm_sdio_softc *, uint32_t); 77uint8_t bwfm_sdio_read_1(struct bwfm_sdio_softc *, uint32_t);
77uint32_t bwfm_sdio_read_4(struct bwfm_sdio_softc *, uint32_t); 78uint32_t bwfm_sdio_read_4(struct bwfm_sdio_softc *, uint32_t);
78void bwfm_sdio_write_1(struct bwfm_sdio_softc *, uint32_t, 79void bwfm_sdio_write_1(struct bwfm_sdio_softc *, uint32_t,
79 uint8_t); 80 uint8_t);
80void bwfm_sdio_write_4(struct bwfm_sdio_softc *, uint32_t, 81void bwfm_sdio_write_4(struct bwfm_sdio_softc *, uint32_t,
81 uint32_t); 82 uint32_t);
82 83
83uint32_t bwfm_sdio_buscore_read(struct bwfm_softc *, uint32_t); 84uint32_t bwfm_sdio_buscore_read(struct bwfm_softc *, uint32_t);
84void bwfm_sdio_buscore_write(struct bwfm_softc *, uint32_t, 85void bwfm_sdio_buscore_write(struct bwfm_softc *, uint32_t,
85 uint32_t); 86 uint32_t);
86int bwfm_sdio_buscore_prepare(struct bwfm_softc *); 87int bwfm_sdio_buscore_prepare(struct bwfm_softc *);
87void bwfm_sdio_buscore_activate(struct bwfm_softc *, uint32_t); 88void bwfm_sdio_buscore_activate(struct bwfm_softc *, uint32_t);
88 89
@@ -208,26 +209,41 @@ err: @@ -208,26 +209,41 @@ err:
208 209
209int 210int
210bwfm_sdio_detach(struct device *self, int flags) 211bwfm_sdio_detach(struct device *self, int flags)
211{ 212{
212 struct bwfm_sdio_softc *sc = (struct bwfm_sdio_softc *)self; 213 struct bwfm_sdio_softc *sc = (struct bwfm_sdio_softc *)self;
213 214
214 bwfm_detach(&sc->sc_sc, flags); 215 bwfm_detach(&sc->sc_sc, flags);
215 216
216 free(sc->sc_sf, M_DEVBUF); 217 free(sc->sc_sf, M_DEVBUF);
217 218
218 return 0; 219 return 0;
219} 220}
220 221
 222void
 223bwfm_sdio_backplane(struct bwfm_sdio_softc *sc, uint32_t bar0)
 224{
 225 if (sc->sc_bar0 == bar0)
 226 return;
 227
 228 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRLOW,
 229 (bar0 >> 8) & 0x80);
 230 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRMID,
 231 (bar0 >> 16) & 0xff);
 232 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRHIGH,
 233 (bar0 >> 24) & 0xff);
 234 sc->sc_bar0 = bar0;
 235}
 236
221uint8_t 237uint8_t
222bwfm_sdio_read_1(struct bwfm_sdio_softc *sc, uint32_t addr) 238bwfm_sdio_read_1(struct bwfm_sdio_softc *sc, uint32_t addr)
223{ 239{
224 struct sdmmc_function *sf; 240 struct sdmmc_function *sf;
225 uint8_t rv; 241 uint8_t rv;
226 242
227 /* 243 /*
228 * figure out how to read the register based on address range 244 * figure out how to read the register based on address range
229 * 0x00 ~ 0x7FF: function 0 CCCR and FBR 245 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
230 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers 246 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
231 * The rest: function 1 silicon backplane core registers 247 * The rest: function 1 silicon backplane core registers
232 */ 248 */
233 if ((addr & ~0x7ff) == 0) 249 if ((addr & ~0x7ff) == 0)
@@ -236,35 +252,27 @@ bwfm_sdio_read_1(struct bwfm_sdio_softc  @@ -236,35 +252,27 @@ bwfm_sdio_read_1(struct bwfm_sdio_softc
236 sf = sc->sc_sf[1]; 252 sf = sc->sc_sf[1];
237 253
238 rv = sdmmc_io_read_1(sf, addr); 254 rv = sdmmc_io_read_1(sf, addr);
239 return rv; 255 return rv;
240} 256}
241 257
242uint32_t 258uint32_t
243bwfm_sdio_read_4(struct bwfm_sdio_softc *sc, uint32_t addr) 259bwfm_sdio_read_4(struct bwfm_sdio_softc *sc, uint32_t addr)
244{ 260{
245 struct sdmmc_function *sf; 261 struct sdmmc_function *sf;
246 uint32_t bar0 = addr & ~BWFM_SDIO_SB_OFT_ADDR_MASK; 262 uint32_t bar0 = addr & ~BWFM_SDIO_SB_OFT_ADDR_MASK;
247 uint32_t rv; 263 uint32_t rv;
248 264
249 if (sc->sc_bar0 != bar0) { 265 bwfm_sdio_backplane(sc, bar0);
250 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRLOW, 
251 (bar0 >> 8) & 0x80); 
252 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRMID, 
253 (bar0 >> 16) & 0xff); 
254 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRHIGH, 
255 (bar0 >> 24) & 0xff); 
256 sc->sc_bar0 = bar0; 
257 } 
258 266
259 addr &= BWFM_SDIO_SB_OFT_ADDR_MASK; 267 addr &= BWFM_SDIO_SB_OFT_ADDR_MASK;
260 addr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG; 268 addr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG;
261 269
262 /* 270 /*
263 * figure out how to read the register based on address range 271 * figure out how to read the register based on address range
264 * 0x00 ~ 0x7FF: function 0 CCCR and FBR 272 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
265 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers 273 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
266 * The rest: function 1 silicon backplane core registers 274 * The rest: function 1 silicon backplane core registers
267 */ 275 */
268 if ((addr & ~0x7ff) == 0) 276 if ((addr & ~0x7ff) == 0)
269 sf = sc->sc_sf[0]; 277 sf = sc->sc_sf[0];
270 else 278 else
@@ -289,35 +297,27 @@ bwfm_sdio_write_1(struct bwfm_sdio_softc @@ -289,35 +297,27 @@ bwfm_sdio_write_1(struct bwfm_sdio_softc
289 sf = sc->sc_sf[0]; 297 sf = sc->sc_sf[0];
290 else 298 else
291 sf = sc->sc_sf[1]; 299 sf = sc->sc_sf[1];
292 300
293 sdmmc_io_write_1(sf, addr, data); 301 sdmmc_io_write_1(sf, addr, data);
294} 302}
295 303
296void 304void
297bwfm_sdio_write_4(struct bwfm_sdio_softc *sc, uint32_t addr, uint32_t data) 305bwfm_sdio_write_4(struct bwfm_sdio_softc *sc, uint32_t addr, uint32_t data)
298{ 306{
299 struct sdmmc_function *sf; 307 struct sdmmc_function *sf;
300 uint32_t bar0 = addr & ~BWFM_SDIO_SB_OFT_ADDR_MASK; 308 uint32_t bar0 = addr & ~BWFM_SDIO_SB_OFT_ADDR_MASK;
301 309
302 if (sc->sc_bar0 != bar0) { 310 bwfm_sdio_backplane(sc, bar0);
303 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRLOW, 
304 (bar0 >> 8) & 0x80); 
305 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRMID, 
306 (bar0 >> 16) & 0xff); 
307 bwfm_sdio_write_1(sc, BWFM_SDIO_FUNC1_SBADDRHIGH, 
308 (bar0 >> 24) & 0xff); 
309 sc->sc_bar0 = bar0; 
310 } 
311 311
312 addr &= BWFM_SDIO_SB_OFT_ADDR_MASK; 312 addr &= BWFM_SDIO_SB_OFT_ADDR_MASK;
313 addr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG; 313 addr |= BWFM_SDIO_SB_ACCESS_2_4B_FLAG;
314 314
315 /* 315 /*
316 * figure out how to read the register based on address range 316 * figure out how to read the register based on address range
317 * 0x00 ~ 0x7FF: function 0 CCCR and FBR 317 * 0x00 ~ 0x7FF: function 0 CCCR and FBR
318 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers 318 * 0x10000 ~ 0x1FFFF: function 1 miscellaneous registers
319 * The rest: function 1 silicon backplane core registers 319 * The rest: function 1 silicon backplane core registers
320 */ 320 */
321 if ((addr & ~0x7ff) == 0) 321 if ((addr & ~0x7ff) == 0)
322 sf = sc->sc_sf[0]; 322 sf = sc->sc_sf[0];
323 else 323 else