On Fri, Dec 15, 2017 at 10:58:22PM +0100, Mark Kettenis wrote: > Some of the Allwinner SoCs have a so-called Reduces Serial Bus that is > used to communicate with peripheral chips (mostly power management > ICs). The diff below adds a driver for the RSB conntroller, named > sxirsb(4), and a driver for the RTC component of the X-Powers AC100 > audio codec. I deliberately cose not to abstract the RSB bus itself > as that is a unecessary as long as we only have a single RSB > controller implementation. But the code is written such that this can > be easily changed if the need arises. Shows up in dmesg as: > > sxirsb0 at simplebus0 > "x-powers,axp809" at sxirsb0 addr 0x3a3 not configured > "x-powers,axp806" at sxirsb0 addr 0x745 not configured > acrtc0 at sxirsb0 addr 0xe89 > > The sxirsb(4) driver attaches early since its children are often used > for power management. > > ok? >
Looks better than what i've had in my branches, as faking i2c-controller turned out to be messy. Besides my personal preference not to mention/compare to linux even in comments , only change i came up w/reading the diff was the obvious typo in the name Reduces=Reduced. -Artturi > > Index: arch/armv7/conf/GENERIC > =================================================================== > RCS file: /cvs/src/sys/arch/armv7/conf/GENERIC,v > retrieving revision 1.99 > diff -u -p -r1.99 GENERIC > --- arch/armv7/conf/GENERIC 24 Oct 2017 17:00:34 -0000 1.99 > +++ arch/armv7/conf/GENERIC 15 Dec 2017 21:53:54 -0000 > @@ -91,6 +91,8 @@ sxipio* at fdt? early 1 # GPIO pins fo > gpio* at sxipio? > sxiccmu* at fdt? early 1 # Clock Control Module/Unit > sxitimer* at fdt? early 1 > +sxirsb* at fdt? early 1 # Reduces Serial Bus typo here ----------------------------------------^ > +acrtc* at sxirsb? > sxidog* at fdt? # watchdog timer > sxirtc* at fdt? # Real Time Clock > sxie* at fdt? > Index: arch/armv7/conf/RAMDISK > =================================================================== > RCS file: /cvs/src/sys/arch/armv7/conf/RAMDISK,v > retrieving revision 1.92 > diff -u -p -r1.92 RAMDISK > --- arch/armv7/conf/RAMDISK 24 Oct 2017 17:00:34 -0000 1.92 > +++ arch/armv7/conf/RAMDISK 15 Dec 2017 21:53:54 -0000 > @@ -87,6 +87,8 @@ sxipio* at fdt? early 1 # GPIO pins fo > gpio* at sxipio? > sxiccmu* at fdt? early 1 # Clock Control Module/Unit > sxitimer* at fdt? early 1 > +sxirsb* at fdt? early 1 # Reduces Serial Bus typo here ----------------------------------------^ > +acrtc* at sxirsb? > sxidog* at fdt? # watchdog timer > sxirtc* at fdt? # Real Time Clock > sxie* at fdt? > Index: dev/fdt/acrtc.c > =================================================================== > RCS file: dev/fdt/acrtc.c > diff -N dev/fdt/acrtc.c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ dev/fdt/acrtc.c 15 Dec 2017 21:53:55 -0000 > @@ -0,0 +1,186 @@ > +/* $OpenBSD$ */ > +/* > + * Copyright (c) 2017 Mark Kettenis <[email protected]> > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include <sys/param.h> > +#include <sys/systm.h> > +#include <sys/device.h> > +#include <sys/malloc.h> > + > +#include <dev/fdt/rsbvar.h> > + > +#include <dev/ofw/openfirm.h> > +#include <dev/ofw/fdt.h> > + > +#include <dev/clock_subr.h> > + > +#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) > + > +extern todr_chip_handle_t todr_handle; > + > +#define RTC_CTRL 0xc7 > +#define RTC_CTRL_12H_24H_MODE (1 << 0) > +#define RTC_SEC 0xc8 > +#define RTC_MIN 0xc9 > +#define RTC_HOU 0xca > +#define RTC_WEE 0xcb > +#define RTC_DAY 0xcc > +#define RTC_MON 0xcd > +#define RTC_YEA 0xce > +#define RTC_YEA_LEAP_YEAR (1 << 15) > +#define RTC_UPD_TRIG 0xcf > +#define RTC_UPD_TRIG_UPDATE (1 << 15) > + > +struct acrtc_softc { > + struct device sc_dev; > + void *sc_cookie; > + uint16_t sc_rta; > + > + struct todr_chip_handle sc_todr; > +}; > + > +int acrtc_match(struct device *, void *, void *); > +void acrtc_attach(struct device *, struct device *, void *); > + > +struct cfattach acrtc_ca = { > + sizeof(struct acrtc_softc), acrtc_match, acrtc_attach > +}; > + > +struct cfdriver acrtc_cd = { > + NULL, "acrtc", DV_DULL > +}; > + > +int acrtc_clock_read(struct acrtc_softc *, struct clock_ymdhms *); > +int acrtc_clock_write(struct acrtc_softc *, struct clock_ymdhms *); > +int acrtc_gettime(struct todr_chip_handle *, struct timeval *); > +int acrtc_settime(struct todr_chip_handle *, struct timeval *); > + > +int > +acrtc_match(struct device *parent, void *match, void *aux) > +{ > + struct rsb_attach_args *ra = aux; > + > + if (strcmp(ra->ra_name, "x-powers,ac100") == 0) > + return 1; > + return 0; > +} > + > +void > +acrtc_attach(struct device *parent, struct device *self, void *aux) > +{ > + struct acrtc_softc *sc = (struct acrtc_softc *)self; > + struct rsb_attach_args *ra = aux; > + > + sc->sc_cookie = ra->ra_cookie; > + sc->sc_rta = ra->ra_rta; > + > + printf("\n"); > + > + sc->sc_todr.cookie = sc; > + sc->sc_todr.todr_gettime = acrtc_gettime; > + sc->sc_todr.todr_settime = acrtc_settime; > + todr_handle = &sc->sc_todr; > +} > + > +inline uint16_t > +acrtc_read_reg(struct acrtc_softc *sc, uint8_t reg) > +{ > + return rsb_read_2(sc->sc_cookie, sc->sc_rta, reg); > +} > + > +inline void > +acrtc_write_reg(struct acrtc_softc *sc, uint8_t reg, uint16_t value) > +{ > + rsb_write_2(sc->sc_cookie, sc->sc_rta, reg, value); > +} > + > +int > +acrtc_gettime(struct todr_chip_handle *handle, struct timeval *tv) > +{ > + struct acrtc_softc *sc = handle->cookie; > + struct clock_ymdhms dt; > + int error; > + > + error = acrtc_clock_read(sc, &dt); > + if (error) > + return error; > + > + if (dt.dt_sec > 59 || dt.dt_min > 59 || dt.dt_hour > 23 || > + dt.dt_day > 31 || dt.dt_day == 0 || > + dt.dt_mon > 12 || dt.dt_mon == 0 || > + dt.dt_year < POSIX_BASE_YEAR) > + return EINVAL; > + > + tv->tv_sec = clock_ymdhms_to_secs(&dt); > + tv->tv_usec = 0; > + return 0; > +} > + > +int > +acrtc_settime(struct todr_chip_handle *handle, struct timeval *tv) > +{ > + struct acrtc_softc *sc = handle->cookie; > + struct clock_ymdhms dt; > + > + clock_secs_to_ymdhms(tv->tv_sec, &dt); > + > + return acrtc_clock_write(sc, &dt); > +} > + > +int > +acrtc_clock_read(struct acrtc_softc *sc, struct clock_ymdhms *dt) > +{ > + uint16_t ctrl; > + > + dt->dt_sec = FROMBCD(acrtc_read_reg(sc, RTC_SEC)); > + dt->dt_min = FROMBCD(acrtc_read_reg(sc, RTC_MIN)); > + dt->dt_hour = FROMBCD(acrtc_read_reg(sc, RTC_HOU)); > + dt->dt_day = FROMBCD(acrtc_read_reg(sc, RTC_DAY)); > + dt->dt_mon = FROMBCD(acrtc_read_reg(sc, RTC_MON)); > + dt->dt_year = FROMBCD(acrtc_read_reg(sc, RTC_YEA)) + 2000; > + > +#ifdef DEBUG > + printf("%02d/%02d/%04d %02d:%02d:%0d\n", dt->dt_day, dt->dt_mon, > + dt->dt_year, dt->dt_hour, dt->dt_min, dt->dt_sec); > +#endif > + > + /* Consider the time to be invalid if the clock is in 12H mode. */ > + ctrl = acrtc_read_reg(sc, RTC_CTRL); > + if ((ctrl & RTC_CTRL_12H_24H_MODE) == 0) > + return EINVAL; > + > + return 0; > +} > + > +int > +acrtc_clock_write(struct acrtc_softc *sc, struct clock_ymdhms *dt) > +{ > + uint16_t leap = isleap(dt->dt_year) ? RTC_YEA_LEAP_YEAR : 0; > + > + acrtc_write_reg(sc, RTC_SEC, TOBCD(dt->dt_sec)); > + acrtc_write_reg(sc, RTC_MIN, TOBCD(dt->dt_min)); > + acrtc_write_reg(sc, RTC_HOU, TOBCD(dt->dt_hour)); > + acrtc_write_reg(sc, RTC_WEE, TOBCD(dt->dt_wday)); > + acrtc_write_reg(sc, RTC_DAY, TOBCD(dt->dt_day)); > + acrtc_write_reg(sc, RTC_MON, TOBCD(dt->dt_mon)); > + acrtc_write_reg(sc, RTC_YEA, TOBCD(dt->dt_year - 2000) | leap); > + acrtc_write_reg(sc, RTC_UPD_TRIG, RTC_UPD_TRIG_UPDATE); > + > + /* Switch to 24H mode to indicate the time is now valid. */ > + acrtc_write_reg(sc, RTC_CTRL, RTC_CTRL_12H_24H_MODE); > + > + return 0; > +} > Index: dev/fdt/files.fdt > =================================================================== > RCS file: /cvs/src/sys/dev/fdt/files.fdt,v > retrieving revision 1.27 > diff -u -p -r1.27 files.fdt > --- dev/fdt/files.fdt 21 Sep 2017 12:01:52 -0000 1.27 > +++ dev/fdt/files.fdt 15 Dec 2017 21:53:55 -0000 > @@ -15,6 +15,11 @@ device sxipio {}: gpiobus > attach sxipio at fdt > file dev/fdt/sxipio.c sxipio > > +define rsb > +device sxirsb {}: rsb > +attach sxirsb at fdt > +file dev/fdt/sxirsb.c sxirsb > + > device sxirtc > attach sxirtc at fdt > file dev/fdt/sxirtc.c sxirtc > @@ -131,3 +136,7 @@ file dev/fdt/if_mvneta.c mvneta > device dwxe: ether, ifnet, mii, ifmedia > attach dwxe at fdt > file dev/fdt/if_dwxe.c dwxe > + > +device acrtc > +attach acrtc at sxirsb > +file dev/fdt/acrtc.c acrtc > \ No newline at end of file > Index: dev/fdt/rsbvar.h > =================================================================== > RCS file: dev/fdt/rsbvar.h > diff -N dev/fdt/rsbvar.h > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ dev/fdt/rsbvar.h 15 Dec 2017 21:53:55 -0000 > @@ -0,0 +1,29 @@ > +/* $OpenBSD$ */ > +/* > + * Copyright (c) 2017 Mark kettenis <[email protected]> > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +struct rsb_attach_args { > + void *ra_cookie; > + uint16_t ra_da; > + uint8_t ra_rta; > + char *ra_name; > + int ra_node; > +}; > + > +int rsb_print(void *, const char *); > + > +uint16_t rsb_read_2(void *, uint8_t, uint8_t); > +void rsb_write_2(void *, uint8_t, uint8_t, uint16_t); > Index: dev/fdt/sxirsb.c > =================================================================== > RCS file: dev/fdt/sxirsb.c > diff -N dev/fdt/sxirsb.c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ dev/fdt/sxirsb.c 15 Dec 2017 21:53:55 -0000 > @@ -0,0 +1,302 @@ > +/* $OpenBSD$ */ > +/* > + * Copyright (c) 2017 Mark kettenis <[email protected]> > + * > + * Permission to use, copy, modify, and distribute this software for any > + * purpose with or without fee is hereby granted, provided that the above > + * copyright notice and this permission notice appear in all copies. > + * > + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES > + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF > + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR > + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES > + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN > + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF > + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. > + */ > + > +#include <sys/param.h> > +#include <sys/systm.h> > +#include <sys/device.h> > + > +#include <machine/bus.h> > +#include <machine/fdt.h> > + > +#include <dev/fdt/rsbvar.h> > + > +#include <dev/ofw/openfirm.h> > +#include <dev/ofw/ofw_clock.h> > +#include <dev/ofw/ofw_pinctrl.h> > +#include <dev/ofw/fdt.h> > + > +#define RSB_CTRL 0x0000 > +#define RSB_CTRL_START_TRANS (1 << 7) > +#define RSB_CTRL_ABORT_TRANS (1 << 6) > +#define RSB_CTRL_GLOBAL_INT_ENB (1 << 1) > +#define RSB_CTRL_SOFT_RESET (1 << 0) > +#define RSB_CCR 0x0004 > +#define RSB_CCR_CD_ODLY_SHIFT 8 > +#define RSB_CCR_CD_ODLY_MAX 0x7 > +#define RSB_CCR_CK_DIV_SHIFT 0 > +#define RSB_CCR_CK_DIV_MAX 0xff > +#define RSB_STAT 0x000c > +#define RSB_STAT_TRANS_OVER (1 << 0) > +#define RSB_AR 0x0010 > +#define RSB_DATA 0x001c > +#define RSB_DMCR 0x0028 > +#define RSB_DMCR_DEVICE_MODE_START (1U << 31) > +#define RSB_DMCR_DEVICE_MODE_DATA 0x7e3e00 > +#define RSB_CMD 0x002c > +#define RSB_DAR 0x0030 > + > +#define SRTA 0xe8 > +#define RD8 0x8b > +#define RD16 0x9c > +#define RD32 0xa6 > +#define WR8 0x4e > +#define WR16 0x59 > +#define WR32 0x63 > + > +#define HREAD4(sc, reg) > \ > + (bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))) > +#define HWRITE4(sc, reg, val) > \ > + bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) > +#define HSET4(sc, reg, bits) \ > + HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits)) > +#define HCLR4(sc, reg, bits) \ > + HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits)) > + > +struct sxirsb_softc { > + struct device sc_dev; > + bus_space_tag_t sc_iot; > + bus_space_handle_t sc_ioh; > + > + int sc_addr; > +}; > + > +int sxirsb_match(struct device *, void *, void *); > +void sxirsb_attach(struct device *, struct device *, void *); > + > +struct cfattach sxirsb_ca = { > + sizeof(struct sxirsb_softc), sxirsb_match, sxirsb_attach > +}; > + > +struct cfdriver sxirsb_cd = { > + NULL, "sxirsb", DV_DULL > +}; > + > +uint8_t sxirsb_rta(uint16_t); > + > +int > +sxirsb_match(struct device *parent, void *match, void *aux) > +{ > + struct fdt_attach_args *faa = aux; > + > + return OF_is_compatible(faa->fa_node, "allwinner,sun8i-a23-rsb"); > +} > + > +void > +sxirsb_attach(struct device *parent, struct device *self, void *aux) > +{ > + struct sxirsb_softc *sc = (struct sxirsb_softc *)self; > + struct fdt_attach_args *faa = aux; > + uint32_t freq, parent_freq, div, odly; > + struct rsb_attach_args ra; > + char name[32]; > + uint32_t reg; > + uint8_t rta; > + int node; > + int timo; > + > + if (faa->fa_nreg < 1) { > + printf(": no registers\n"); > + return; > + } > + > + sc->sc_iot = faa->fa_iot; > + if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, > + faa->fa_reg[0].size, 0, &sc->sc_ioh)) { > + printf(": can't map registers\n"); > + return; > + } > + > + pinctrl_byname(faa->fa_node, "default"); > + > + clock_enable_all(faa->fa_node); > + reset_deassert_all(faa->fa_node); > + > + HWRITE4(sc, RSB_CTRL, RSB_CTRL_SOFT_RESET); > + for (timo = 1000; timo > 0; timo--) { > + if ((HREAD4(sc, RSB_CTRL) & RSB_CTRL_SOFT_RESET) == 0) > + break; > + delay(100); > + } > + if (timo == 0) { > + printf(": reset failed\n"); > + return; > + } > + > + freq = OF_getpropint(faa->fa_node, "clock-frequency", 3000000); > + parent_freq = clock_get_frequency_idx(faa->fa_node, 0); > + div = parent_freq / freq / 2; > + if (div == 0) > + div = 1; > + if (div > (RSB_CCR_CK_DIV_MAX + 1)) > + div = (RSB_CCR_CK_DIV_MAX + 1); > + odly = div >> 1; > + if (odly == 0) > + odly = 1; > + if (odly > RSB_CCR_CD_ODLY_MAX) > + odly = RSB_CCR_CD_ODLY_MAX; > + HWRITE4(sc, RSB_CCR, (odly << RSB_CCR_CD_ODLY_SHIFT) | > + ((div - 1) << RSB_CCR_CK_DIV_SHIFT)); > + > + HWRITE4(sc, RSB_DMCR, RSB_DMCR_DEVICE_MODE_START | > + RSB_DMCR_DEVICE_MODE_DATA); > + for (timo = 1000; timo > 0; timo--) { > + if ((HREAD4(sc, RSB_DMCR) & RSB_DMCR_DEVICE_MODE_START) == 0) > + break; > + delay(100); > + } > + if (timo == 0) { > + printf(": mode switch failed\n"); > + return; > + } > + > + for (node = OF_child(faa->fa_node); node; node = OF_peer(node)) { > + reg = OF_getpropint(node, "reg", 0); > + if (reg == 0) > + continue; > + > + rta = sxirsb_rta(reg); > + HWRITE4(sc, RSB_CMD, SRTA); > + HWRITE4(sc, RSB_DAR, (rta << 16 | reg)); > + > + HSET4(sc, RSB_CTRL, RSB_CTRL_START_TRANS); > + for (timo = 1000; timo > 0; timo--) { > + if ((HREAD4(sc, RSB_CTRL) & RSB_CTRL_START_TRANS) == 0) > + break; > + delay(10); > + } > + if (timo == 0) { > + printf(": SRTA failed for device 0x%03x\n", reg); > + return; > + } > + } > + > + printf("\n"); > + > + for (node = OF_child(faa->fa_node); node; node = OF_peer(node)) { > + reg = OF_getpropint(node, "reg", 0); > + if (reg == 0) > + continue; > + > + memset(name, 0, sizeof(name)); > + if (OF_getprop(node, "compatible", name, sizeof(name)) == -1) > + continue; > + if (name[0] == '\0') > + continue; > + > + memset(&ra, 0, sizeof(ra)); > + ra.ra_cookie = sc; > + ra.ra_da = reg; > + ra.ra_rta = sxirsb_rta(reg); > + ra.ra_name = name; > + ra.ra_node = node; > + config_found(self, &ra, rsb_print); > + } > +} > + > +/* > + * Use a fixed device address to run-time address mapping. This keeps > + * things simple and matches what Linux does. > + */ > + > +struct rsb_addr_map { > + uint16_t da; > + uint8_t rta; > +}; > + > +struct rsb_addr_map rsb_addr_map[] = { > + { 0x3a3, 0x2d }, > + { 0x745, 0x3a }, > + { 0xe89, 0x4e } > +}; > + > +uint8_t > +sxirsb_rta(uint16_t da) > +{ > + int i; > + > + for (i = 0; i < nitems(rsb_addr_map); i++) { > + if (rsb_addr_map[i].da == da) > + return rsb_addr_map[i].rta; > + } > + > + return 0; > +} > + > +uint16_t > +rsb_read_2(void *cookie, uint8_t rta, uint8_t addr) > +{ > + struct sxirsb_softc *sc = cookie; > + uint16_t stat; > + int timo; > + > + HWRITE4(sc, RSB_CMD, RD16); > + HWRITE4(sc, RSB_DAR, rta << 16); > + HWRITE4(sc, RSB_AR, addr); > + > + HSET4(sc, RSB_CTRL, RSB_CTRL_START_TRANS); > + for (timo = 1000; timo > 0; timo--) { > + if ((HREAD4(sc, RSB_CTRL) & RSB_CTRL_START_TRANS) == 0) > + break; > + delay(10); > + } > + stat = HREAD4(sc, RSB_STAT); > + HWRITE4(sc, RSB_STAT, stat); > + if (timo == 0 || stat != RSB_STAT_TRANS_OVER) { > + printf(": RD16 failed for run-time address 0x%02x\n", rta); > + return 0xff; > + } > + > + return HREAD4(sc, RSB_DATA); > +} > + > +void > +rsb_write_2(void *cookie, uint8_t rta, uint8_t addr, uint16_t data) > +{ > + struct sxirsb_softc *sc = cookie; > + uint16_t stat; > + int timo; > + > + HWRITE4(sc, RSB_CMD, WR16); > + HWRITE4(sc, RSB_DAR, rta << 16); > + HWRITE4(sc, RSB_AR, addr); > + HWRITE4(sc, RSB_DATA, data); > + > + HSET4(sc, RSB_CTRL, RSB_CTRL_START_TRANS); > + for (timo = 1000; timo > 0; timo--) { > + if ((HREAD4(sc, RSB_CTRL) & RSB_CTRL_START_TRANS) == 0) > + break; > + delay(10); > + } > + stat = HREAD4(sc, RSB_STAT); > + HWRITE4(sc, RSB_STAT, stat); > + if (timo == 0 || stat != RSB_STAT_TRANS_OVER) { > + printf(": WR16 failed for run-time address 0x%02x\n", rta); > + return; > + } > +} > + > +int > +rsb_print(void *aux, const char *pnp) > +{ > + struct rsb_attach_args *ra = aux; > + > + if (pnp != NULL) > + printf("\"%s\" at %s", ra->ra_name, pnp); > + printf(" addr 0x%x", ra->ra_da); > + > + return (UNCONF); > +} >
