git: be9fefafc280 - main - imx_ccm: Rearrange clock control module driver
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 13 Sep 2024 08:20:17 UTC
The branch main has been updated by thj: URL: https://cgit.FreeBSD.org/src/commit/?id=be9fefafc2801ef449a0f3205c9397ba35425323 commit be9fefafc2801ef449a0f3205c9397ba35425323 Author: Tom Jones <thj@FreeBSD.org> AuthorDate: 2024-09-11 12:51:10 +0000 Commit: Tom Jones <thj@FreeBSD.org> CommitDate: 2024-09-13 08:15:19 +0000 imx_ccm: Rearrange clock control module driver Rearrange the IMX clock control module driver so it is more straight forward to support clock trees from other SOCs in the family. Move the existing imx8mq_ccm driver to a more generic imx_ccm (based on rk_cru) and update the previous driver to sub class imx_ccm. Reviewed by: manu Sponsored by: The FreeBSD Foundations Differential Revision: https://reviews.freebsd.org/D46641 --- sys/arm64/freescale/imx/imx8mq_ccm.c | 197 ++--------------- sys/arm64/freescale/imx/imx_ccm.c | 237 +++++++++++++++++++++ .../freescale/imx/{imx_ccm_clk.h => imx_ccm.h} | 20 +- sys/conf/files.arm64 | 1 + 4 files changed, 272 insertions(+), 183 deletions(-) diff --git a/sys/arm64/freescale/imx/imx8mq_ccm.c b/sys/arm64/freescale/imx/imx8mq_ccm.c index e89300c19d51..17bea24e9b39 100644 --- a/sys/arm64/freescale/imx/imx8mq_ccm.c +++ b/sys/arm64/freescale/imx/imx8mq_ccm.c @@ -27,7 +27,7 @@ #include <sys/cdefs.h> /* - * Clocks driver for Freescale i.MX8MQ SoC + * Clocks driver for Freescale i.MX 8M Quad SoC. */ #include <sys/param.h> @@ -43,7 +43,7 @@ #include <machine/bus.h> -#include <arm64/freescale/imx/imx_ccm_clk.h> +#include <arm64/freescale/imx/imx_ccm.h> #include <arm64/freescale/imx/imx8mq_ccm.h> #include <arm64/freescale/imx/clk/imx_clk_gate.h> #include <arm64/freescale/imx/clk/imx_clk_mux.h> @@ -118,7 +118,7 @@ static const char *ahb_p[] = { "sys3_pll_out", "audio_pll1_out", "video_pll1_out" }; -static struct imx_clk imx_clks[] = { +static struct imx_clk imx8mq_clks[] = { FIXED(IMX8MQ_CLK_DUMMY, "dummy", 0), LINK(IMX8MQ_CLK_32K, "ckil"), @@ -275,119 +275,22 @@ struct ccm_softc { int nclks; }; -static inline uint32_t -CCU_READ4(struct ccm_softc *sc, bus_size_t off) -{ - - return (bus_read_4(sc->mem_res, off)); -} - -static inline void -CCU_WRITE4(struct ccm_softc *sc, bus_size_t off, uint32_t val) -{ - - bus_write_4(sc->mem_res, off, val); -} - static int -ccm_detach(device_t dev) +imx8mq_ccm_attach(device_t dev) { - struct ccm_softc *sc; + struct imx_ccm_softc *sc; sc = device_get_softc(dev); + sc->dev = dev; - if (sc->mem_res != NULL) - bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res); - - return (0); -} - -static int -ccm_attach(device_t dev) -{ - struct ccm_softc *sc; - int err, rid; - phandle_t node; - int i; + sc->clks = imx8mq_clks; + sc->nclks = nitems(imx8mq_clks); - sc = device_get_softc(dev); - err = 0; - - /* Allocate bus_space resources. */ - rid = 0; - sc->clks = imx_clks; - sc->nclks = nitems(imx_clks); - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (sc->mem_res == NULL) { - device_printf(dev, "Cannot allocate memory resources\n"); - err = ENXIO; - goto out; - } - - mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF); - - sc->clkdom = clkdom_create(dev); - if (sc->clkdom == NULL) - panic("Cannot create clkdom\n"); - - for (i = 0; i < sc->nclks; i++) { - switch (sc->clks[i].type) { - case IMX_CLK_UNDEFINED: - break; - case IMX_CLK_LINK: - clknode_link_register(sc->clkdom, - sc->clks[i].clk.link); - break; - case IMX_CLK_FIXED: - clknode_fixed_register(sc->clkdom, - sc->clks[i].clk.fixed); - break; - case IMX_CLK_MUX: - imx_clk_mux_register(sc->clkdom, sc->clks[i].clk.mux); - break; - case IMX_CLK_GATE: - imx_clk_gate_register(sc->clkdom, sc->clks[i].clk.gate); - break; - case IMX_CLK_COMPOSITE: - imx_clk_composite_register(sc->clkdom, sc->clks[i].clk.composite); - break; - case IMX_CLK_SSCG_PLL: - imx_clk_sscg_pll_register(sc->clkdom, sc->clks[i].clk.sscg_pll); - break; - case IMX_CLK_FRAC_PLL: - imx_clk_frac_pll_register(sc->clkdom, sc->clks[i].clk.frac_pll); - break; - case IMX_CLK_DIV: - clknode_div_register(sc->clkdom, sc->clks[i].clk.div); - break; - default: - device_printf(dev, "Unknown clock type %d\n", sc->clks[i].type); - return (ENXIO); - } - } - - if (clkdom_finit(sc->clkdom) != 0) - panic("cannot finalize clkdom initialization\n"); - - if (bootverbose) - clkdom_dump(sc->clkdom); - - node = ofw_bus_get_node(dev); - clk_set_assigned(dev, node); - - err = 0; - -out: - - if (err != 0) - ccm_detach(dev); - - return (err); + return (imx_ccm_attach(dev)); } static int -ccm_probe(device_t dev) +imx8mq_ccm_probe(device_t dev) { if (!ofw_bus_status_okay(dev)) @@ -396,87 +299,21 @@ ccm_probe(device_t dev) if (ofw_bus_is_compatible(dev, "fsl,imx8mq-ccm") == 0) return (ENXIO); - device_set_desc(dev, "Freescale i.MX8 Clock Control Module"); + device_set_desc(dev, "Freescale i.MX 8M Quad Clock Control Module"); return (BUS_PROBE_DEFAULT); } -static int -imx_ccm_write_4(device_t dev, bus_addr_t addr, uint32_t val) -{ - struct ccm_softc *sc; - - sc = device_get_softc(dev); - CCU_WRITE4(sc, addr, val); - return (0); -} - -static int -imx_ccm_read_4(device_t dev, bus_addr_t addr, uint32_t *val) -{ - struct ccm_softc *sc; - - sc = device_get_softc(dev); - - *val = CCU_READ4(sc, addr); - return (0); -} - -static int -imx_ccm_modify_4(device_t dev, bus_addr_t addr, uint32_t clr, uint32_t set) -{ - struct ccm_softc *sc; - uint32_t reg; - - sc = device_get_softc(dev); - - reg = CCU_READ4(sc, addr); - reg &= ~clr; - reg |= set; - CCU_WRITE4(sc, addr, reg); - - return (0); -} - -static void -imx_ccm_device_lock(device_t dev) -{ - struct ccm_softc *sc; - - sc = device_get_softc(dev); - mtx_lock(&sc->mtx); -} - -static void -imx_ccm_device_unlock(device_t dev) -{ - struct ccm_softc *sc; - - sc = device_get_softc(dev); - mtx_unlock(&sc->mtx); -} - -static device_method_t ccm_methods[] = { +static device_method_t imx8mq_ccm_methods[] = { /* Device interface */ - DEVMETHOD(device_probe, ccm_probe), - DEVMETHOD(device_attach, ccm_attach), - DEVMETHOD(device_detach, ccm_detach), - - /* clkdev interface */ - DEVMETHOD(clkdev_write_4, imx_ccm_write_4), - DEVMETHOD(clkdev_read_4, imx_ccm_read_4), - DEVMETHOD(clkdev_modify_4, imx_ccm_modify_4), - DEVMETHOD(clkdev_device_lock, imx_ccm_device_lock), - DEVMETHOD(clkdev_device_unlock, imx_ccm_device_unlock), + DEVMETHOD(device_probe, imx8mq_ccm_probe), + DEVMETHOD(device_attach, imx8mq_ccm_attach), DEVMETHOD_END }; -static driver_t ccm_driver = { - "ccm", - ccm_methods, - sizeof(struct ccm_softc) -}; +DEFINE_CLASS_1(imx8mq_ccm, imx8mq_ccm_driver, imx8mq_ccm_methods, + sizeof(struct imx_ccm_softc), imx_ccm_driver); -EARLY_DRIVER_MODULE(ccm, simplebus, ccm_driver, 0, 0, +EARLY_DRIVER_MODULE(imx8mq_ccm, simplebus, imx8mq_ccm_driver, 0, 0, BUS_PASS_CPU + BUS_PASS_ORDER_EARLY); diff --git a/sys/arm64/freescale/imx/imx_ccm.c b/sys/arm64/freescale/imx/imx_ccm.c new file mode 100644 index 000000000000..a5660c5d0a5d --- /dev/null +++ b/sys/arm64/freescale/imx/imx_ccm.c @@ -0,0 +1,237 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 Oleksandr Tymoshenko <gonzo@FreeBSD.org> + * Copyright (c) 2024 The FreeBSD Foundation + * + * Portions of this software were developed by Tom Jones <thj@freebsd.org> + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> + +/* + * Clock Control Module driver for Freescale i.MX 8M SoC family. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/mutex.h> +#include <sys/bus.h> +#include <sys/rman.h> + +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> + +#include <machine/bus.h> + +#include <arm64/freescale/imx/imx_ccm.h> +#include <arm64/freescale/imx/clk/imx_clk_gate.h> +#include <arm64/freescale/imx/clk/imx_clk_mux.h> +#include <arm64/freescale/imx/clk/imx_clk_composite.h> +#include <arm64/freescale/imx/clk/imx_clk_sscg_pll.h> +#include <arm64/freescale/imx/clk/imx_clk_frac_pll.h> + +#include "clkdev_if.h" + +static inline uint32_t +CCU_READ4(struct imx_ccm_softc *sc, bus_size_t off) +{ + + return (bus_read_4(sc->mem_res, off)); +} + +static inline void +CCU_WRITE4(struct imx_ccm_softc *sc, bus_size_t off, uint32_t val) +{ + + bus_write_4(sc->mem_res, off, val); +} + +int +imx_ccm_detach(device_t dev) +{ + struct imx_ccm_softc *sc; + + sc = device_get_softc(dev); + + if (sc->mem_res != NULL) + bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res); + + return (0); +} + +int +imx_ccm_attach(device_t dev) +{ + struct imx_ccm_softc *sc; + int err, rid; + phandle_t node; + int i; + + sc = device_get_softc(dev); + sc->dev = dev; + err = 0; + + /* Allocate bus_space resources. */ + rid = 0; + sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->mem_res == NULL) { + device_printf(dev, "Cannot allocate memory resources\n"); + err = ENXIO; + goto out; + } + + mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF); + + sc->clkdom = clkdom_create(dev); + if (sc->clkdom == NULL) + panic("Cannot create clkdom\n"); + + for (i = 0; i < sc->nclks; i++) { + switch (sc->clks[i].type) { + case IMX_CLK_UNDEFINED: + break; + case IMX_CLK_LINK: + clknode_link_register(sc->clkdom, + sc->clks[i].clk.link); + break; + case IMX_CLK_FIXED: + clknode_fixed_register(sc->clkdom, + sc->clks[i].clk.fixed); + break; + case IMX_CLK_MUX: + imx_clk_mux_register(sc->clkdom, sc->clks[i].clk.mux); + break; + case IMX_CLK_GATE: + imx_clk_gate_register(sc->clkdom, sc->clks[i].clk.gate); + break; + case IMX_CLK_COMPOSITE: + imx_clk_composite_register(sc->clkdom, sc->clks[i].clk.composite); + break; + case IMX_CLK_SSCG_PLL: + imx_clk_sscg_pll_register(sc->clkdom, sc->clks[i].clk.sscg_pll); + break; + case IMX_CLK_FRAC_PLL: + imx_clk_frac_pll_register(sc->clkdom, sc->clks[i].clk.frac_pll); + break; + case IMX_CLK_DIV: + clknode_div_register(sc->clkdom, sc->clks[i].clk.div); + break; + default: + device_printf(dev, "Unknown clock type %d\n", sc->clks[i].type); + return (ENXIO); + } + } + + if (clkdom_finit(sc->clkdom) != 0) + panic("cannot finalize clkdom initialization\n"); + + if (bootverbose) + clkdom_dump(sc->clkdom); + + node = ofw_bus_get_node(dev); + clk_set_assigned(dev, node); + + err = 0; + +out: + + if (err != 0) + imx_ccm_detach(dev); + + return (err); +} + +static int +imx_ccm_write_4(device_t dev, bus_addr_t addr, uint32_t val) +{ + struct imx_ccm_softc *sc; + + sc = device_get_softc(dev); + CCU_WRITE4(sc, addr, val); + return (0); +} + +static int +imx_ccm_read_4(device_t dev, bus_addr_t addr, uint32_t *val) +{ + struct imx_ccm_softc *sc; + + sc = device_get_softc(dev); + + *val = CCU_READ4(sc, addr); + return (0); +} + +static int +imx_ccm_modify_4(device_t dev, bus_addr_t addr, uint32_t clr, uint32_t set) +{ + struct imx_ccm_softc *sc; + uint32_t reg; + + sc = device_get_softc(dev); + + reg = CCU_READ4(sc, addr); + reg &= ~clr; + reg |= set; + CCU_WRITE4(sc, addr, reg); + + return (0); +} + +static void +imx_ccm_device_lock(device_t dev) +{ + struct imx_ccm_softc *sc; + + sc = device_get_softc(dev); + mtx_lock(&sc->mtx); +} + +static void +imx_ccm_device_unlock(device_t dev) +{ + struct imx_ccm_softc *sc; + + sc = device_get_softc(dev); + mtx_unlock(&sc->mtx); +} + +static device_method_t imx_ccm_methods[] = { + /* clkdev interface */ + DEVMETHOD(clkdev_write_4, imx_ccm_write_4), + DEVMETHOD(clkdev_read_4, imx_ccm_read_4), + DEVMETHOD(clkdev_modify_4, imx_ccm_modify_4), + DEVMETHOD(clkdev_device_lock, imx_ccm_device_lock), + DEVMETHOD(clkdev_device_unlock, imx_ccm_device_unlock), + + DEVMETHOD_END +}; + +DEFINE_CLASS_0(imx_ccm, imx_ccm_driver, imx_ccm_methods, + sizeof(struct imx_ccm_softc)); diff --git a/sys/arm64/freescale/imx/imx_ccm_clk.h b/sys/arm64/freescale/imx/imx_ccm.h similarity index 95% rename from sys/arm64/freescale/imx/imx_ccm_clk.h rename to sys/arm64/freescale/imx/imx_ccm.h index 4c16fa00fe6b..9c34789a648e 100644 --- a/sys/arm64/freescale/imx/imx_ccm_clk.h +++ b/sys/arm64/freescale/imx/imx_ccm.h @@ -25,8 +25,8 @@ * SUCH DAMAGE. */ -#ifndef IMX6_CCM_CLK_H -#define IMX6_CCM_CLK_H +#ifndef IMX8_CCM_H +#define IMX8_CCM_H #include <dev/clk/clk.h> #include <dev/clk/clk_div.h> @@ -34,6 +34,20 @@ #include <dev/clk/clk_gate.h> #include <dev/clk/clk_link.h> +int imx_ccm_attach(device_t); +int imx_ccm_detach(device_t); + +struct imx_ccm_softc { + device_t dev; + struct resource *mem_res; + struct clkdom *clkdom; + struct mtx mtx; + struct imx_clk *clks; + int nclks; +}; + +DECLARE_CLASS(imx_ccm_driver); + enum imx_clk_type { IMX_CLK_UNDEFINED = 0, IMX_CLK_FIXED, @@ -207,4 +221,4 @@ struct imx_clk { }, \ } -#endif +#endif /* IMX8_CCM_H */ diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index cd161a18500f..fe1259669059 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -590,6 +590,7 @@ arm64/cavium/thunder_pcie_pem_fdt.c optional soc_cavm_thunderx pci fdt arm64/cavium/thunder_pcie_common.c optional soc_cavm_thunderx pci # i.MX8 Clock support +arm64/freescale/imx/imx_ccm.c optional fdt soc_freescale_imx8 arm64/freescale/imx/imx8mq_ccm.c optional fdt soc_freescale_imx8 arm64/freescale/imx/clk/imx_clk_gate.c optional fdt soc_freescale_imx8 arm64/freescale/imx/clk/imx_clk_mux.c optional fdt soc_freescale_imx8