101b9c59fSHubert Mazur /*-
24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
301b9c59fSHubert Mazur *
401b9c59fSHubert Mazur * Copyright (c) 2021 Semihalf.
501b9c59fSHubert Mazur *
601b9c59fSHubert Mazur * Redistribution and use in source and binary forms, with or without
701b9c59fSHubert Mazur * modification, are permitted provided that the following conditions
801b9c59fSHubert Mazur * are met:
901b9c59fSHubert Mazur * 1. Redistributions of source code must retain the above copyright
1001b9c59fSHubert Mazur * notice, this list of conditions and the following disclaimer.
1101b9c59fSHubert Mazur * 2. Redistributions in binary form must reproduce the above copyright
1201b9c59fSHubert Mazur * notice, this list of conditions and the following disclaimer in the
1301b9c59fSHubert Mazur * documentation and/or other materials provided with the distribution.
1401b9c59fSHubert Mazur *
1501b9c59fSHubert Mazur * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1601b9c59fSHubert Mazur * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1701b9c59fSHubert Mazur * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1801b9c59fSHubert Mazur * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1901b9c59fSHubert Mazur * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2001b9c59fSHubert Mazur * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2101b9c59fSHubert Mazur * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2201b9c59fSHubert Mazur * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2301b9c59fSHubert Mazur * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2401b9c59fSHubert Mazur * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2501b9c59fSHubert Mazur * SUCH DAMAGE.
2601b9c59fSHubert Mazur */
2701b9c59fSHubert Mazur
2801b9c59fSHubert Mazur #include <sys/param.h>
2901b9c59fSHubert Mazur #include <sys/bus.h>
3001b9c59fSHubert Mazur #include <sys/kernel.h>
3101b9c59fSHubert Mazur #include <sys/module.h>
3201b9c59fSHubert Mazur #include <sys/mutex.h>
3301b9c59fSHubert Mazur #include <sys/rman.h>
3401b9c59fSHubert Mazur #include <machine/bus.h>
3501b9c59fSHubert Mazur
3601b9c59fSHubert Mazur #include <dev/fdt/simplebus.h>
3701b9c59fSHubert Mazur
38be82b3a0SEmmanuel Vadot #include <dev/clk/clk.h>
39be82b3a0SEmmanuel Vadot #include <dev/clk/clk_fixed.h>
40*62e8ccc3SEmmanuel Vadot #include <dev/syscon/syscon.h>
4101b9c59fSHubert Mazur
4201b9c59fSHubert Mazur #include <dev/ofw/ofw_bus.h>
4301b9c59fSHubert Mazur #include <dev/ofw/ofw_bus_subr.h>
4401b9c59fSHubert Mazur
4501b9c59fSHubert Mazur #include "syscon_if.h"
4601b9c59fSHubert Mazur
4701b9c59fSHubert Mazur #define BIT(x) (1 << (x))
4801b9c59fSHubert Mazur
4901b9c59fSHubert Mazur #define NB_GPIO1_PIN_LT_L 0x8
5001b9c59fSHubert Mazur #define NB_GPIO1_MPP1_9 BIT(9)
5101b9c59fSHubert Mazur
5201b9c59fSHubert Mazur struct a37x0_xtal_softc {
5301b9c59fSHubert Mazur device_t dev;
5401b9c59fSHubert Mazur struct clkdom *clkdom;
5501b9c59fSHubert Mazur };
5601b9c59fSHubert Mazur
5701b9c59fSHubert Mazur static int a37x0_xtal_attach(device_t dev);
5801b9c59fSHubert Mazur static int a37x0_xtal_detach(device_t dev);
5901b9c59fSHubert Mazur static int a37x0_xtal_probe(device_t dev);
6001b9c59fSHubert Mazur
6101b9c59fSHubert Mazur static device_method_t a37x0_xtal_methods [] = {
6201b9c59fSHubert Mazur DEVMETHOD(device_probe, a37x0_xtal_probe),
6301b9c59fSHubert Mazur DEVMETHOD(device_attach, a37x0_xtal_attach),
6401b9c59fSHubert Mazur DEVMETHOD(device_detach, a37x0_xtal_detach),
6501b9c59fSHubert Mazur DEVMETHOD_END
6601b9c59fSHubert Mazur };
6701b9c59fSHubert Mazur
6801b9c59fSHubert Mazur static driver_t a37x0_xtal_driver = {
6901b9c59fSHubert Mazur "a37x0-xtal",
7001b9c59fSHubert Mazur a37x0_xtal_methods,
7101b9c59fSHubert Mazur sizeof(struct a37x0_xtal_softc)
7201b9c59fSHubert Mazur };
7301b9c59fSHubert Mazur
74a3b866cbSJohn Baldwin EARLY_DRIVER_MODULE(a37x0_xtal, simplebus, a37x0_xtal_driver, 0, 0,
75a3b866cbSJohn Baldwin BUS_PASS_TIMER + BUS_PASS_ORDER_EARLY);
7601b9c59fSHubert Mazur
7701b9c59fSHubert Mazur static int
a37x0_xtal_attach(device_t dev)7801b9c59fSHubert Mazur a37x0_xtal_attach(device_t dev)
7901b9c59fSHubert Mazur {
8001b9c59fSHubert Mazur struct a37x0_xtal_softc *sc;
8101b9c59fSHubert Mazur struct clk_fixed_def def;
8201b9c59fSHubert Mazur struct syscon *syscon;
8301b9c59fSHubert Mazur uint32_t reg;
8401b9c59fSHubert Mazur int error;
8501b9c59fSHubert Mazur
8601b9c59fSHubert Mazur sc = device_get_softc(dev);
8701b9c59fSHubert Mazur
8801b9c59fSHubert Mazur def.clkdef.name = "armada-3700-xtal";
8901b9c59fSHubert Mazur def.clkdef.parent_names = NULL;
9001b9c59fSHubert Mazur def.clkdef.parent_cnt = 0;
9101b9c59fSHubert Mazur def.clkdef.id = 1;
9201b9c59fSHubert Mazur def.mult = 0;
9301b9c59fSHubert Mazur def.div = 0;
9401b9c59fSHubert Mazur
9501b9c59fSHubert Mazur if (SYSCON_GET_HANDLE(dev, &syscon) != 0 || syscon == NULL){
9601b9c59fSHubert Mazur device_printf(dev, "Cannot get syscon driver handle\n");
9701b9c59fSHubert Mazur return (ENXIO);
9801b9c59fSHubert Mazur }
9901b9c59fSHubert Mazur
10001b9c59fSHubert Mazur reg = SYSCON_READ_4(syscon, NB_GPIO1_PIN_LT_L);
10101b9c59fSHubert Mazur if (reg & NB_GPIO1_MPP1_9)
10201b9c59fSHubert Mazur def.freq = 40000000;
10301b9c59fSHubert Mazur else
10401b9c59fSHubert Mazur def.freq = 25000000;
10501b9c59fSHubert Mazur
10601b9c59fSHubert Mazur sc->clkdom = clkdom_create(dev);
10701b9c59fSHubert Mazur error = clknode_fixed_register(sc->clkdom, &def);
10801b9c59fSHubert Mazur if (error){
10901b9c59fSHubert Mazur device_printf(dev, "Cannot register clock node\n");
11001b9c59fSHubert Mazur return (ENXIO);
11101b9c59fSHubert Mazur }
11201b9c59fSHubert Mazur
11301b9c59fSHubert Mazur error = clkdom_finit(sc->clkdom);
11401b9c59fSHubert Mazur if (error){
11501b9c59fSHubert Mazur device_printf(dev, "Cannot finalize clock domain initialization\n");
11601b9c59fSHubert Mazur return (ENXIO);
11701b9c59fSHubert Mazur }
11801b9c59fSHubert Mazur
11901b9c59fSHubert Mazur if (bootverbose)
12001b9c59fSHubert Mazur clkdom_dump(sc->clkdom);
12101b9c59fSHubert Mazur
12201b9c59fSHubert Mazur return (0);
12301b9c59fSHubert Mazur }
12401b9c59fSHubert Mazur
12501b9c59fSHubert Mazur static int
a37x0_xtal_probe(device_t dev)12601b9c59fSHubert Mazur a37x0_xtal_probe(device_t dev)
12701b9c59fSHubert Mazur {
12801b9c59fSHubert Mazur
12901b9c59fSHubert Mazur if (!ofw_bus_status_okay(dev))
13001b9c59fSHubert Mazur return (ENXIO);
13101b9c59fSHubert Mazur
13201b9c59fSHubert Mazur if (!ofw_bus_is_compatible(dev, "marvell,armada-3700-xtal-clock"))
13301b9c59fSHubert Mazur return (ENXIO);
13401b9c59fSHubert Mazur
13501b9c59fSHubert Mazur device_set_desc(dev, "Marvell Armada 3700 Oscillator");
13601b9c59fSHubert Mazur return (BUS_PROBE_DEFAULT);
13701b9c59fSHubert Mazur }
13801b9c59fSHubert Mazur
13901b9c59fSHubert Mazur static int
a37x0_xtal_detach(device_t dev)14001b9c59fSHubert Mazur a37x0_xtal_detach(device_t dev)
14101b9c59fSHubert Mazur {
14201b9c59fSHubert Mazur
14301b9c59fSHubert Mazur return (EBUSY);
14401b9c59fSHubert Mazur }
145