Home | History | Annotate | Line # | Download | only in imx
      1 /* $NetBSD: imx23_digctl.c,v 1.8 2026/09/29 20:04:27 yurix Exp $ */
      2 
      3 /*
      4 * Copyright (c) 2013 The NetBSD Foundation, Inc.
      5 * All rights reserved.
      6 *
      7 * This code is derived from software contributed to The NetBSD Foundation
      8 * by Petri Laakso.
      9 *
     10 * Redistribution and use in source and binary forms, with or without
     11 * modification, are permitted provided that the following conditions
     12 * are met:
     13 * 1. Redistributions of source code must retain the above copyright
     14 *    notice, this list of conditions and the following disclaimer.
     15 * 2. Redistributions in binary form must reproduce the above copyright
     16 *    notice, this list of conditions and the following disclaimer in the
     17 *    documentation and/or other materials provided with the distribution.
     18 *
     19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29 * POSSIBILITY OF SUCH DAMAGE.
     30 */
     31 
     32 #include <sys/param.h>
     33 #include <sys/types.h>
     34 #include <sys/bus.h>
     35 #include <sys/cdefs.h>
     36 #include <sys/device.h>
     37 #include <sys/errno.h>
     38 #include <sys/timetc.h>
     39 
     40 #include <dev/fdt/fdtvar.h>
     41 
     42 #include <arm/imx/imx23_digctlreg.h>
     43 #include <arm/imx/imx23var.h>
     44 
     45 struct imx23_digctl_softc {
     46 	bus_space_tag_t sc_iot;
     47 	bus_space_handle_t sc_hdl;
     48 	struct timecounter sc_tc;
     49 };
     50 
     51 static int	imx23_digctl_match(device_t, cfdata_t, void *);
     52 static void	imx23_digctl_attach(device_t, device_t, void *);
     53 
     54 /* timecounter. */
     55 static u_int imx23_digctl_tc_get_timecount(struct timecounter *);
     56 
     57 CFATTACH_DECL_NEW(imx23digctl, sizeof(struct imx23_digctl_softc),
     58 		  imx23_digctl_match, imx23_digctl_attach, NULL, NULL);
     59 
     60 #define DCTL_RD(sc, reg)                                                 \
     61         bus_space_read_4(sc->sc_iot, sc->sc_hdl, (reg))
     62 #define DCTL_WR(sc, reg, val)                                            \
     63         bus_space_write_4(sc->sc_iot, sc->sc_hdl, (reg), (val))
     64 
     65 static const struct device_compatible_entry compat_data[] = {
     66 	{ .compat = "fsl,imx23-digctl" },
     67 	DEVICE_COMPAT_EOL
     68 };
     69 
     70 static int
     71 imx23_digctl_match(device_t parent, cfdata_t match, void *aux)
     72 {
     73 	struct fdt_attach_args * const faa = aux;
     74 
     75 	return of_compatible_match(faa->faa_phandle, compat_data);
     76 }
     77 
     78 static void
     79 imx23_digctl_attach(device_t parent, device_t self, void *aux)
     80 {
     81 	struct imx23_digctl_softc * const sc = device_private(self);
     82 	struct fdt_attach_args * const faa = aux;
     83 	const int phandle = faa->faa_phandle;
     84 
     85 	sc->sc_iot = faa->faa_bst;
     86 
     87 	bus_addr_t addr;
     88 	bus_size_t size;
     89 	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
     90 		aprint_error(": couldn't get register address\n");
     91 		return;
     92 	}
     93 	if (bus_space_map(faa->faa_bst, addr, size, 0, &sc->sc_hdl)) {
     94 		aprint_error(": couldn't map registers\n");
     95 		return;
     96 	}
     97 
     98 	aprint_naive("\n");
     99 	aprint_normal("\n");
    100 
    101 	/*
    102 	 * Setup timecounter to use digctl microseconds counter.
    103 	 */
    104 	sc->sc_tc.tc_get_timecount = imx23_digctl_tc_get_timecount;
    105 	sc->sc_tc.tc_poll_pps = NULL;
    106 	sc->sc_tc.tc_counter_mask = 0xffffffff; /* 32bit counter. */
    107 	sc->sc_tc.tc_frequency = 1000000;       /* @ 1MHz */
    108 	sc->sc_tc.tc_name = "digctl";
    109 	sc->sc_tc.tc_quality = 100;
    110 	sc->sc_tc.tc_priv = sc;
    111 
    112 	/* Enable counter. */
    113 	DCTL_WR(sc, HW_DIGCTL_CTRL_CLR, HW_DIGCTL_CTRL_XTAL24M_GATE);
    114 
    115 	tc_init(&sc->sc_tc);
    116 
    117 	/* Enable USB clocks */
    118 	DCTL_WR(sc, HW_DIGCTL_CTRL_CLR, HW_DIGCTL_CTRL_USB_CLKGATE);
    119 }
    120 
    121 /*
    122  *
    123  */
    124 static u_int
    125 imx23_digctl_tc_get_timecount(struct timecounter *tc)
    126 {
    127 	struct imx23_digctl_softc * const sc = tc->tc_priv;
    128 	return DCTL_RD(sc, HW_DIGCTL_MICROSECONDS);
    129 }
    130