xref: /netbsd-src/sys/arch/arm/imx/imx23_clkctrl.c (revision c56890eeefdfd43071f47d01e82d01208239d6b0)
1*c56890eeSmsaitoh /* $Id: imx23_clkctrl.c,v 1.3 2019/10/18 04:09:01 msaitoh Exp $ */
294de0730Smatt 
394de0730Smatt /*
494de0730Smatt * Copyright (c) 2013 The NetBSD Foundation, Inc.
594de0730Smatt * All rights reserved.
694de0730Smatt *
794de0730Smatt * This code is derived from software contributed to The NetBSD Foundation
894de0730Smatt * by Petri Laakso.
994de0730Smatt *
1094de0730Smatt * Redistribution and use in source and binary forms, with or without
1194de0730Smatt * modification, are permitted provided that the following conditions
1294de0730Smatt * are met:
1394de0730Smatt * 1. Redistributions of source code must retain the above copyright
1494de0730Smatt *    notice, this list of conditions and the following disclaimer.
1594de0730Smatt * 2. Redistributions in binary form must reproduce the above copyright
1694de0730Smatt *    notice, this list of conditions and the following disclaimer in the
1794de0730Smatt *    documentation and/or other materials provided with the distribution.
1894de0730Smatt *
1994de0730Smatt * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2094de0730Smatt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2194de0730Smatt * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2294de0730Smatt * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2394de0730Smatt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2494de0730Smatt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2594de0730Smatt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2694de0730Smatt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2794de0730Smatt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2894de0730Smatt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2994de0730Smatt * POSSIBILITY OF SUCH DAMAGE.
3094de0730Smatt */
3194de0730Smatt 
3294de0730Smatt #include <sys/param.h>
3394de0730Smatt #include <sys/types.h>
3494de0730Smatt #include <sys/bus.h>
3594de0730Smatt #include <sys/cdefs.h>
3694de0730Smatt #include <sys/device.h>
3794de0730Smatt #include <sys/errno.h>
3894de0730Smatt 
3994de0730Smatt #include <arm/imx/imx23_clkctrlreg.h>
4094de0730Smatt #include <arm/imx/imx23_clkctrlvar.h>
4194de0730Smatt #include <arm/imx/imx23var.h>
4294de0730Smatt 
4394de0730Smatt typedef struct clkctrl_softc {
4494de0730Smatt 	device_t sc_dev;
4594de0730Smatt 	bus_space_tag_t sc_iot;
4694de0730Smatt 	bus_space_handle_t sc_hdl;
4794de0730Smatt } *clkctrl_softc_t;
4894de0730Smatt 
4994de0730Smatt static int	clkctrl_match(device_t, cfdata_t, void *);
5094de0730Smatt static void	clkctrl_attach(device_t, device_t, void *);
5194de0730Smatt static int	clkctrl_activate(device_t, enum devact);
5294de0730Smatt 
5394de0730Smatt static void     clkctrl_init(struct clkctrl_softc *);
5494de0730Smatt 
5594de0730Smatt static clkctrl_softc_t _sc = NULL;
5694de0730Smatt 
5794de0730Smatt CFATTACH_DECL3_NEW(clkctrl,
5894de0730Smatt         sizeof(struct clkctrl_softc),
5994de0730Smatt         clkctrl_match,
6094de0730Smatt         clkctrl_attach,
6194de0730Smatt         NULL,
6294de0730Smatt         clkctrl_activate,
6394de0730Smatt         NULL,
6494de0730Smatt         NULL,
6594de0730Smatt         0
6694de0730Smatt );
6794de0730Smatt 
6894de0730Smatt #define CLKCTRL_RD(sc, reg)                                                 \
6994de0730Smatt         bus_space_read_4(sc->sc_iot, sc->sc_hdl, (reg))
7094de0730Smatt #define CLKCTRL_WR(sc, reg, val)                                            \
7194de0730Smatt         bus_space_write_4(sc->sc_iot, sc->sc_hdl, (reg), (val))
7294de0730Smatt 
7394de0730Smatt #define CLKCTRL_SOFT_RST_LOOP 455 /* At least 1 us ... */
7494de0730Smatt 
7594de0730Smatt static int
clkctrl_match(device_t parent,cfdata_t match,void * aux)7694de0730Smatt clkctrl_match(device_t parent, cfdata_t match, void *aux)
7794de0730Smatt {
7894de0730Smatt 	struct apb_attach_args *aa = aux;
7994de0730Smatt 
8094de0730Smatt 	if ((aa->aa_addr == HW_CLKCTRL_BASE) &&
8194de0730Smatt 	    (aa->aa_size == HW_CLKCTRL_SIZE))
8294de0730Smatt 		return 1;
8394de0730Smatt 
8494de0730Smatt 	return 0;
8594de0730Smatt }
8694de0730Smatt 
8794de0730Smatt static void
clkctrl_attach(device_t parent,device_t self,void * aux)8894de0730Smatt clkctrl_attach(device_t parent, device_t self, void *aux)
8994de0730Smatt {
9094de0730Smatt 	struct clkctrl_softc *sc = device_private(self);
9194de0730Smatt 	struct apb_attach_args *aa = aux;
9294de0730Smatt 	static int clkctrl_attached = 0;
9394de0730Smatt 
9494de0730Smatt 	sc->sc_dev = self;
9594de0730Smatt 	sc->sc_iot = aa->aa_iot;
9694de0730Smatt 
9794de0730Smatt 	if (clkctrl_attached) {
9894de0730Smatt 		aprint_error_dev(sc->sc_dev, "already attached\n");
9994de0730Smatt 		return;
10094de0730Smatt 	}
10194de0730Smatt 
10294de0730Smatt 	if (bus_space_map(sc->sc_iot, aa->aa_addr, aa->aa_size, 0,
10394de0730Smatt 	    &sc->sc_hdl))
10494de0730Smatt 	{
10594de0730Smatt 		aprint_error_dev(sc->sc_dev, "Unable to map bus space\n");
10694de0730Smatt 		return;
10794de0730Smatt 	}
10894de0730Smatt 
10994de0730Smatt 
11094de0730Smatt 	clkctrl_init(sc);
11194de0730Smatt 
11294de0730Smatt 	aprint_normal("\n");
11394de0730Smatt 
11494de0730Smatt 	clkctrl_attached = 1;
11594de0730Smatt 
11694de0730Smatt 	return;
11794de0730Smatt }
11894de0730Smatt 
11994de0730Smatt static int
clkctrl_activate(device_t self,enum devact act)12094de0730Smatt clkctrl_activate(device_t self, enum devact act)
12194de0730Smatt {
12294de0730Smatt 
12394de0730Smatt 	return EOPNOTSUPP;
12494de0730Smatt }
12594de0730Smatt 
12694de0730Smatt static void
clkctrl_init(struct clkctrl_softc * sc)12794de0730Smatt clkctrl_init(struct clkctrl_softc *sc)
12894de0730Smatt {
12994de0730Smatt 	_sc = sc;
13094de0730Smatt 	return;
13194de0730Smatt }
13294de0730Smatt 
13394de0730Smatt /*
13494de0730Smatt  * Power up 8-phase PLL outputs for USB PHY
13594de0730Smatt  *
13694de0730Smatt  */
13794de0730Smatt void
clkctrl_en_usb(void)13894de0730Smatt clkctrl_en_usb(void)
13994de0730Smatt {
14094de0730Smatt 	struct clkctrl_softc *sc = _sc;
14194de0730Smatt 
14294de0730Smatt         if (sc == NULL) {
143*c56890eeSmsaitoh                 aprint_error("clkctrl is not initialized");
14494de0730Smatt                 return;
14594de0730Smatt         }
14694de0730Smatt 
14794de0730Smatt 	CLKCTRL_WR(sc, HW_CLKCTRL_PLLCTRL0_SET,
14894de0730Smatt 	    HW_CLKCTRL_PLLCTRL0_EN_USB_CLKS);
14994de0730Smatt 
15094de0730Smatt 	return;
15194de0730Smatt }
15292f2c674Sjmcneill 
15392f2c674Sjmcneill /*
15492f2c674Sjmcneill  * Enable 24MHz clock for the Digital Filter.
15592f2c674Sjmcneill  *
15692f2c674Sjmcneill  */
15792f2c674Sjmcneill void
clkctrl_en_filtclk(void)15892f2c674Sjmcneill clkctrl_en_filtclk(void)
15992f2c674Sjmcneill {
16092f2c674Sjmcneill 	struct clkctrl_softc *sc = _sc;
16192f2c674Sjmcneill 
16292f2c674Sjmcneill 	if (sc == NULL) {
163*c56890eeSmsaitoh 		aprint_error("clkctrl is not initialized");
16492f2c674Sjmcneill 		return;
16592f2c674Sjmcneill 	}
16692f2c674Sjmcneill 
16792f2c674Sjmcneill 	CLKCTRL_WR(sc, HW_CLKCTRL_XTAL_CLR, HW_CLKCTRL_XTAL_FILT_CLK24M_GATE);
16892f2c674Sjmcneill 
16992f2c674Sjmcneill 	return;
17092f2c674Sjmcneill }
171