On Mon, Jan 03, 2022 at 08:44:22PM +0100, Mark Kettenis wrote: > > Date: Mon, 3 Jan 2022 16:31:29 +0000 > > From: Visa Hankala <v...@hankala.org> > > > > This adds an initial driver for the PolarFire SoC MSS clock controller. > > > > The driver also provides a reset function for the SoC. The soft reset > > register is in the same region that covers the clock control registers. > > > > OK? > > None of the other clock drivers use a mutex to protect themselves from > multiple clients simultanously enabling/disabling clocks. And I don't > really see the need for that in the foreseeable future.
I think it is wiser to keep the mutex in case some driver will toggle clocks at runtime. Handling the serialization within the driver is less prone to errors. Only the clock driver knows that the state updates have to go through common registers. > Other than that: > > ok kettenis@ > > > Index: share/man/man4/man4.riscv64/Makefile > > =================================================================== > > RCS file: src/share/man/man4/man4.riscv64/Makefile,v > > retrieving revision 1.3 > > diff -u -p -r1.3 Makefile > > --- share/man/man4/man4.riscv64/Makefile 6 Aug 2021 06:35:13 -0000 > > 1.3 > > +++ share/man/man4/man4.riscv64/Makefile 3 Jan 2022 16:26:48 -0000 > > @@ -1,6 +1,6 @@ > > # $OpenBSD: Makefile,v 1.3 2021/08/06 06:35:13 jsg Exp $ > > > > -MAN= intro.4 plic.4 sfcc.4 sfclock.4 sfuart.4 > > +MAN= intro.4 mpfclock.4 plic.4 sfcc.4 sfclock.4 sfuart.4 > > > > MANSUBDIR=riscv64 > > > > Index: share/man/man4/man4.riscv64/mpfclock.4 > > =================================================================== > > RCS file: share/man/man4/man4.riscv64/mpfclock.4 > > diff -N share/man/man4/man4.riscv64/mpfclock.4 > > --- /dev/null 1 Jan 1970 00:00:00 -0000 > > +++ share/man/man4/man4.riscv64/mpfclock.4 3 Jan 2022 16:26:48 -0000 > > @@ -0,0 +1,37 @@ > > +.\" $OpenBSD$ > > +.\" > > +.\" Copyright (c) 2022 Visa Hankala > > +.\" > > +.\" 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. > > +.\" > > +.Dd $Mdocdate$ > > +.Dt MPFCLOCK 4 riscv64 > > +.Os > > +.Sh NAME > > +.Nm mpfclock > > +.Nd Microchip PolarFire SoC MSS clock controller > > +.Sh SYNOPSIS > > +.Cd "mpfclock* at fdt?" > > +.Sh DESCRIPTION > > +The > > +.Nm > > +driver controls the clock signals for the integrated components > > +of PolarFire SoCs. > > +The driver also provides system reset functionality. > > +.Sh SEE ALSO > > +.Xr intro 4 > > +.Sh HISTORY > > +The > > +.Nm > > +driver first appeared in > > +.Ox 7.1 . > > Index: sys/arch/riscv64/conf/GENERIC > > =================================================================== > > RCS file: src/sys/arch/riscv64/conf/GENERIC,v > > retrieving revision 1.31 > > diff -u -p -r1.31 GENERIC > > --- sys/arch/riscv64/conf/GENERIC 3 Jan 2022 15:50:16 -0000 1.31 > > +++ sys/arch/riscv64/conf/GENERIC 3 Jan 2022 16:26:48 -0000 > > @@ -44,6 +44,9 @@ intc0 at cpu0 > > # NS16550 compatible serial ports > > com* at fdt? > > > > +# PolarFire SoCs > > +mpfclock* at fdt? early 1 > > + > > # SiFive SoCs > > sfclock* at fdt? early 1 # PRCI > > sfcc* at fdt? early 1 # L2 Cache Controller > > Index: sys/arch/riscv64/conf/RAMDISK > > =================================================================== > > RCS file: src/sys/arch/riscv64/conf/RAMDISK,v > > retrieving revision 1.27 > > diff -u -p -r1.27 RAMDISK > > --- sys/arch/riscv64/conf/RAMDISK 3 Jan 2022 15:50:16 -0000 1.27 > > +++ sys/arch/riscv64/conf/RAMDISK 3 Jan 2022 16:26:48 -0000 > > @@ -35,6 +35,9 @@ intc0 at cpu0 > > # NS16550 compatible serial ports > > com* at fdt? > > > > +# PolarFire SoCs > > +mpfclock* at fdt? early 1 > > + > > # SiFive SoCs > > sfclock* at fdt? early 1 # PRCI > > sfcc* at fdt? early 1 # L2 Cache Controller > > Index: sys/arch/riscv64/conf/files.riscv64 > > =================================================================== > > RCS file: src/sys/arch/riscv64/conf/files.riscv64,v > > retrieving revision 1.17 > > diff -u -p -r1.17 files.riscv64 > > --- sys/arch/riscv64/conf/files.riscv64 5 Oct 2021 18:32:27 -0000 > > 1.17 > > +++ sys/arch/riscv64/conf/files.riscv64 3 Jan 2022 16:26:48 -0000 > > @@ -84,6 +84,11 @@ device plic > > attach plic at fdt > > file arch/riscv64/dev/plic.c plic > > > > +# PolarFire SoC MSS clock controller > > +device mpfclock > > +attach mpfclock at fdt > > +file arch/riscv64/dev/mpfclock.c mpfclock > > + > > # L2 cache controller > > device sfcc > > attach sfcc at fdt > > Index: sys/arch/riscv64/dev/mpfclock.c > > =================================================================== > > RCS file: sys/arch/riscv64/dev/mpfclock.c > > diff -N sys/arch/riscv64/dev/mpfclock.c > > --- /dev/null 1 Jan 1970 00:00:00 -0000 > > +++ sys/arch/riscv64/dev/mpfclock.c 3 Jan 2022 16:26:48 -0000 > > @@ -0,0 +1,235 @@ > > +/* $OpenBSD$ */ > > + > > +/* > > + * Copyright (c) 2022 Visa Hankala > > + * > > + * Permission to use, copy, modify, and/or 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. > > + */ > > + > > +/* > > + * Driver for PolarFire SoC MSS clock controller. > > + */ > > + > > +#include <sys/param.h> > > +#include <sys/systm.h> > > +#include <sys/device.h> > > +#include <sys/mutex.h> > > + > > +#include <machine/bus.h> > > +#include <machine/fdt.h> > > + > > +#include <dev/ofw/fdt.h> > > +#include <dev/ofw/openfirm.h> > > +#include <dev/ofw/ofw_clock.h> > > + > > +extern void (*cpuresetfn)(void); > > + > > +#define CLOCK_CONFIG_CR 0x0008 > > +#define CLOCK_CONFIG_CR_AHB_DIV_SHIFT 4 > > +#define CLOCK_CONFIG_CR_AXI_DIV_SHIFT 2 > > +#define CLOCK_CONFIG_CR_CPU_DIV_SHIFT 0 > > +#define CLOCK_CONFIG_CR_DIV_MASK 0x3 > > +#define MSS_RESET_CR 0x0018 > > +#define SUBBLK_CLOCK_CR 0x0084 > > +#define SUBBLK_RESET_CR 0x0088 > > + > > +#define CLK_CPU 0 > > +#define CLK_AXI 1 > > +#define CLK_AHB 2 > > +#define CLK_ENVM 3 > > +#define CLK_MAC0 4 > > +#define CLK_MAC1 5 > > +#define CLK_MMC 6 > > +#define CLK_TIMER 7 > > +#define CLK_MMUART0 8 > > +#define CLK_MMUART1 9 > > +#define CLK_MMUART2 10 > > +#define CLK_MMUART3 11 > > +#define CLK_MMUART4 12 > > +#define CLK_SPI0 13 > > +#define CLK_SPI1 14 > > +#define CLK_I2C0 15 > > +#define CLK_I2C1 16 > > +#define CLK_CAN0 17 > > +#define CLK_CAN1 18 > > +#define CLK_USB 19 > > +#define CLK_RESERVED 20 /* FPGA in > > SUBBLK_RESET_CR */ > > +#define CLK_RTC 21 > > +#define CLK_QSPI 22 > > +#define CLK_GPIO0 23 > > +#define CLK_GPIO1 24 > > +#define CLK_GPIO2 25 > > +#define CLK_DDRC 26 > > +#define CLK_FIC0 27 > > +#define CLK_FIC1 28 > > +#define CLK_FIC2 29 > > +#define CLK_FIC3 30 > > +#define CLK_ATHENA 31 > > +#define CLK_CFM 32 > > + > > +struct mpfclock_softc { > > + struct device sc_dev; > > + bus_space_tag_t sc_iot; > > + bus_space_handle_t sc_ioh; > > + uint32_t sc_clkcfg; > > + uint32_t sc_refclk; > > + > > + struct clock_device sc_cd; > > +}; > > + > > +#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)) > > + > > +int mpfclock_match(struct device *, void *, void *); > > +void mpfclock_attach(struct device *, struct device *, void *); > > + > > +void mpfclock_enable(void *, uint32_t *, int); > > +uint32_t mpfclock_get_frequency(void *, uint32_t *); > > +int mpfclock_set_frequency(void *, uint32_t *, uint32_t); > > + > > +void mpfclock_cpureset(void); > > + > > +const struct cfattach mpfclock_ca = { > > + sizeof(struct mpfclock_softc), mpfclock_match, mpfclock_attach > > +}; > > + > > +struct cfdriver mpfclock_cd = { > > + NULL, "mpfclock", DV_DULL > > +}; > > + > > +struct mutex mpfclock_mtx = MUTEX_INITIALIZER(IPL_HIGH); > > +struct mpfclock_softc *mpfclock_sc; > > + > > +int > > +mpfclock_match(struct device *parent, void *match, void *aux) > > +{ > > + struct fdt_attach_args *faa = aux; > > + > > + if (faa->fa_nreg < 1) > > + return 0; > > + return OF_is_compatible(faa->fa_node, "microchip,mpfs-clkcfg"); > > +} > > + > > +void > > +mpfclock_attach(struct device *parent, struct device *self, void *aux) > > +{ > > + struct fdt_attach_args *faa = aux; > > + struct mpfclock_softc *sc = (struct mpfclock_softc *)self; > > + > > + sc->sc_refclk = clock_get_frequency_idx(faa->fa_node, 0); > > + if (sc->sc_refclk == 0) { > > + printf(": can't get refclk frequency\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) != 0) { > > + printf(": can't map registers\n"); > > + return; > > + } > > + > > + sc->sc_clkcfg = HREAD4(sc, CLOCK_CONFIG_CR); > > + > > + printf(": %u MHz ref clock\n", (sc->sc_refclk + 500000) / 1000000); > > + > > + sc->sc_cd.cd_node = faa->fa_node; > > + sc->sc_cd.cd_cookie = sc; > > + sc->sc_cd.cd_enable = mpfclock_enable; > > + sc->sc_cd.cd_get_frequency = mpfclock_get_frequency; > > + sc->sc_cd.cd_set_frequency = mpfclock_set_frequency; > > + clock_register(&sc->sc_cd); > > + > > + mpfclock_sc = sc; > > + cpuresetfn = mpfclock_cpureset; > > +} > > + > > +uint32_t > > +mpfclock_get_frequency(void *cookie, uint32_t *cells) > > +{ > > + struct mpfclock_softc *sc = cookie; > > + uint32_t div, shift; > > + uint32_t idx = cells[0]; > > + > > + if (idx == CLK_MMC) > > + return 200000000; > > + > > + if (idx > CLK_AHB) > > + idx = CLK_AHB; > > + > > + switch (idx) { > > + case CLK_CPU: > > + shift = CLOCK_CONFIG_CR_CPU_DIV_SHIFT; > > + break; > > + case CLK_AXI: > > + shift = CLOCK_CONFIG_CR_AXI_DIV_SHIFT; > > + break; > > + case CLK_AHB: > > + shift = CLOCK_CONFIG_CR_AHB_DIV_SHIFT; > > + break; > > + default: > > + panic("%s: invalid idx %u\n", __func__, idx); > > + } > > + > > + div = 1U << ((sc->sc_clkcfg >> shift) & CLOCK_CONFIG_CR_DIV_MASK); > > + > > + return sc->sc_refclk / div; > > +} > > + > > +int > > +mpfclock_set_frequency(void *cookie, uint32_t *cells, uint32_t freq) > > +{ > > + return -1; > > +} > > + > > +void > > +mpfclock_enable(void *cookie, uint32_t *cells, int on) > > +{ > > + struct mpfclock_softc *sc = cookie; > > + uint32_t idx = cells[0]; > > + uint32_t bit, val; > > + > > + if (idx < CLK_ENVM || idx - CLK_ENVM > 31) > > + return; > > + bit = 1U << (idx - CLK_ENVM); > > + > > + mtx_enter(&mpfclock_mtx); > > + if (on) { > > + val = HREAD4(sc, SUBBLK_CLOCK_CR); > > + val |= bit; > > + HWRITE4(sc, SUBBLK_CLOCK_CR, val); > > + > > + val = HREAD4(sc, SUBBLK_RESET_CR); > > + val &= ~bit; > > + HWRITE4(sc, SUBBLK_RESET_CR, val); > > + } else { > > + val = HREAD4(sc, SUBBLK_RESET_CR); > > + val |= bit; > > + HWRITE4(sc, SUBBLK_RESET_CR, val); > > + > > + val = HREAD4(sc, SUBBLK_CLOCK_CR); > > + val &= ~bit; > > + HWRITE4(sc, SUBBLK_CLOCK_CR, val); > > + } > > + mtx_leave(&mpfclock_mtx); > > +} > > + > > +void > > +mpfclock_cpureset(void) > > +{ > > + struct mpfclock_softc *sc = mpfclock_sc; > > + > > + HWRITE4(sc, MSS_RESET_CR, 0xdead); > > +} > > > > >