ti_comp_clock.c revision 1.1
11.1Sskrll/* $NetBSD: ti_comp_clock.c,v 1.1 2025/12/16 12:20:22 skrll Exp $ */ 21.1Sskrll 31.1Sskrll/*- 41.1Sskrll * Copyright (c) 2025 Rui-Xiang Guo 51.1Sskrll * Copyright (c) 2019 Jared McNeill <jmcneill@invisible.ca> 61.1Sskrll * All rights reserved. 71.1Sskrll * 81.1Sskrll * Redistribution and use in source and binary forms, with or without 91.1Sskrll * modification, are permitted provided that the following conditions 101.1Sskrll * are met: 111.1Sskrll * 1. Redistributions of source code must retain the above copyright 121.1Sskrll * notice, this list of conditions and the following disclaimer. 131.1Sskrll * 2. Redistributions in binary form must reproduce the above copyright 141.1Sskrll * notice, this list of conditions and the following disclaimer in the 151.1Sskrll * documentation and/or other materials provided with the distribution. 161.1Sskrll * 171.1Sskrll * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 181.1Sskrll * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 191.1Sskrll * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 201.1Sskrll * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 211.1Sskrll * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 221.1Sskrll * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 231.1Sskrll * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 241.1Sskrll * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 251.1Sskrll * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261.1Sskrll * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271.1Sskrll * SUCH DAMAGE. 281.1Sskrll */ 291.1Sskrll 301.1Sskrll#include <sys/cdefs.h> 311.1Sskrll__KERNEL_RCSID(0, "$NetBSD: ti_comp_clock.c,v 1.1 2025/12/16 12:20:22 skrll Exp $"); 321.1Sskrll 331.1Sskrll#include <sys/param.h> 341.1Sskrll#include <sys/systm.h> 351.1Sskrll#include <sys/device.h> 361.1Sskrll#include <sys/kmem.h> 371.1Sskrll#include <sys/bus.h> 381.1Sskrll 391.1Sskrll#include <dev/clk/clk_backend.h> 401.1Sskrll 411.1Sskrll#include <dev/fdt/fdtvar.h> 421.1Sskrll 431.1Sskrllstatic int ti_comp_clock_match(device_t, cfdata_t, void *); 441.1Sskrllstatic void ti_comp_clock_attach(device_t, device_t, void *); 451.1Sskrll 461.1Sskrllstatic struct clk *ti_comp_clock_decode(device_t, int, const void *, size_t); 471.1Sskrll 481.1Sskrllstatic const struct fdtbus_clock_controller_func ti_comp_clock_fdt_funcs = { 491.1Sskrll .decode = ti_comp_clock_decode 501.1Sskrll}; 511.1Sskrll 521.1Sskrllstatic struct clk *ti_comp_clock_get(void *, const char *); 531.1Sskrllstatic void ti_comp_clock_put(void *, struct clk *); 541.1Sskrllstatic u_int ti_comp_clock_get_rate(void *, struct clk *); 551.1Sskrllstatic int ti_comp_clock_enable(void *, struct clk *); 561.1Sskrllstatic int ti_comp_clock_disable(void *, struct clk *); 571.1Sskrllstatic struct clk *ti_comp_clock_get_parent(void *, struct clk *); 581.1Sskrllstatic int ti_comp_clock_set_parent(void *, struct clk *, struct clk *); 591.1Sskrll 601.1Sskrllstatic const struct clk_funcs ti_comp_clock_clk_funcs = { 611.1Sskrll .get = ti_comp_clock_get, 621.1Sskrll .put = ti_comp_clock_put, 631.1Sskrll .get_rate = ti_comp_clock_get_rate, 641.1Sskrll .enable = ti_comp_clock_enable, 651.1Sskrll .disable = ti_comp_clock_disable, 661.1Sskrll .get_parent = ti_comp_clock_get_parent, 671.1Sskrll .set_parent = ti_comp_clock_set_parent, 681.1Sskrll}; 691.1Sskrll 701.1Sskrllstruct ti_comp_clock_softc { 711.1Sskrll device_t sc_dev; 721.1Sskrll int sc_phandle; 731.1Sskrll 741.1Sskrll struct clk_domain sc_clkdom; 751.1Sskrll struct clk sc_clk; 761.1Sskrll}; 771.1Sskrll 781.1Sskrll#define RD4(sc, reg) \ 791.1Sskrll bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 801.1Sskrll#define WR4(sc, reg, val) \ 811.1Sskrll bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 821.1Sskrll 831.1SskrllCFATTACH_DECL_NEW(ti_comp_clock, sizeof(struct ti_comp_clock_softc), 841.1Sskrll ti_comp_clock_match, ti_comp_clock_attach, NULL, NULL); 851.1Sskrll 861.1Sskrllstatic const struct device_compatible_entry compat_data[] = { 871.1Sskrll { .compat = "ti,composite-clock" }, 881.1Sskrll DEVICE_COMPAT_EOL 891.1Sskrll}; 901.1Sskrll 911.1Sskrllstatic int 921.1Sskrllti_comp_clock_match(device_t parent, cfdata_t cf, void *aux) 931.1Sskrll{ 941.1Sskrll const struct fdt_attach_args *faa = aux; 951.1Sskrll 961.1Sskrll return of_compatible_match(faa->faa_phandle, compat_data); 971.1Sskrll} 981.1Sskrll 991.1Sskrllstatic void 1001.1Sskrllti_comp_clock_attach(device_t parent, device_t self, void *aux) 1011.1Sskrll{ 1021.1Sskrll struct ti_comp_clock_softc * const sc = device_private(self); 1031.1Sskrll const struct fdt_attach_args *faa = aux; 1041.1Sskrll const int phandle = faa->faa_phandle; 1051.1Sskrll 1061.1Sskrll sc->sc_dev = self; 1071.1Sskrll sc->sc_phandle = phandle; 1081.1Sskrll 1091.1Sskrll sc->sc_clkdom.name = device_xname(self); 1101.1Sskrll sc->sc_clkdom.funcs = &ti_comp_clock_clk_funcs; 1111.1Sskrll sc->sc_clkdom.priv = sc; 1121.1Sskrll 1131.1Sskrll sc->sc_clk.domain = &sc->sc_clkdom; 1141.1Sskrll sc->sc_clk.name = kmem_asprintf("%s", faa->faa_name); 1151.1Sskrll clk_attach(&sc->sc_clk); 1161.1Sskrll 1171.1Sskrll aprint_naive("\n"); 1181.1Sskrll aprint_normal(": TI composite clock (%s)\n", sc->sc_clk.name); 1191.1Sskrll 1201.1Sskrll fdtbus_register_clock_controller(self, phandle, &ti_comp_clock_fdt_funcs); 1211.1Sskrll} 1221.1Sskrll 1231.1Sskrllstatic struct clk * 1241.1Sskrllti_comp_clock_decode(device_t dev, int cc_phandle, const void *data, 1251.1Sskrll size_t len) 1261.1Sskrll{ 1271.1Sskrll struct ti_comp_clock_softc * const sc = device_private(dev); 1281.1Sskrll 1291.1Sskrll return &sc->sc_clk; 1301.1Sskrll} 1311.1Sskrll 1321.1Sskrllstatic struct clk * 1331.1Sskrllti_comp_clock_get(void *priv, const char *name) 1341.1Sskrll{ 1351.1Sskrll struct ti_comp_clock_softc * const sc = priv; 1361.1Sskrll 1371.1Sskrll return &sc->sc_clk; 1381.1Sskrll} 1391.1Sskrll 1401.1Sskrllstatic void 1411.1Sskrllti_comp_clock_put(void *priv, struct clk *clk) 1421.1Sskrll{ 1431.1Sskrll} 1441.1Sskrll 1451.1Sskrllstatic u_int 1461.1Sskrllti_comp_clock_get_rate(void *priv, struct clk *clk) 1471.1Sskrll{ 1481.1Sskrll struct clk *clk_parent = clk_get_parent(clk); 1491.1Sskrll 1501.1Sskrll if (clk_parent == NULL) 1511.1Sskrll return 0; 1521.1Sskrll 1531.1Sskrll return clk_get_rate(clk_parent); 1541.1Sskrll} 1551.1Sskrll 1561.1Sskrllstatic int 1571.1Sskrllti_comp_clock_enable(void *priv, struct clk *clk) 1581.1Sskrll{ 1591.1Sskrll struct ti_comp_clock_softc * const sc = priv; 1601.1Sskrll struct clk *clk_gate = fdtbus_clock_get_index(sc->sc_phandle, 0); 1611.1Sskrll 1621.1Sskrll return clk_enable(clk_gate); 1631.1Sskrll} 1641.1Sskrll 1651.1Sskrllstatic int 1661.1Sskrllti_comp_clock_disable(void *priv, struct clk *clk) 1671.1Sskrll{ 1681.1Sskrll struct ti_comp_clock_softc * const sc = priv; 1691.1Sskrll struct clk *clk_gate = fdtbus_clock_get_index(sc->sc_phandle, 0); 1701.1Sskrll 1711.1Sskrll return clk_disable(clk_gate); 1721.1Sskrll} 1731.1Sskrll 1741.1Sskrllstatic struct clk * 1751.1Sskrllti_comp_clock_get_parent(void *priv, struct clk *clk) 1761.1Sskrll{ 1771.1Sskrll struct ti_comp_clock_softc * const sc = priv; 1781.1Sskrll 1791.1Sskrll return fdtbus_clock_get_index(sc->sc_phandle, 1); 1801.1Sskrll} 1811.1Sskrll 1821.1Sskrllstatic int 1831.1Sskrllti_comp_clock_set_parent(void *priv, struct clk *clk, struct clk *parent_clk) 1841.1Sskrll{ 1851.1Sskrll return clk_set_parent(clk, parent_clk); 1861.1Sskrll} 187