xref: /freebsd/sys/arm/mv/clk/a37x0_xtal.c (revision 62e8ccc3a489434af379c7f47da71545bc1e14ee)
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