Path: blob/main/sys/arm64/qoriq/clk/ls1088a_clkgen.c
39536 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2021 Alstom Group.4* Copyright (c) 2021 Semihalf.5* Copyright (c) 2022 Bjoern A. Zeeb6*7* Redistribution and use in source and binary forms, with or without8* modification, are permitted provided that the following conditions9* are met:10* 1. Redistributions of source code must retain the above copyright11* notice, this list of conditions and the following disclaimer.12* 2. Redistributions in binary form must reproduce the above copyright13* notice, this list of conditions and the following disclaimer in the14* documentation and/or other materials provided with the distribution.15*16* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND17* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE18* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE19* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE20* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL21* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS22* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)23* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT24* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY25* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF26* SUCH DAMAGE.27*/28/*29* Based on QorIQ LS1088A Reference Manual, Rev. 1, 11/2020.30* [LS1088ARM.pdf]31*/3233#include <sys/param.h>34#include <sys/bus.h>35#include <sys/kernel.h>36#include <sys/module.h>37#include <sys/mutex.h>38#include <sys/rman.h>39#include <machine/bus.h>4041#include <dev/fdt/simplebus.h>4243#include <dev/ofw/ofw_bus.h>44#include <dev/ofw/ofw_bus_subr.h>4546#include <dev/clk/clk_fixed.h>4748#include <arm64/qoriq/clk/qoriq_clkgen.h>4950static uint8_t ls1088a_pltfrm_pll_divs[] = {511, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 052};5354static struct qoriq_clk_pll_def ls1088a_pltfrm_pll = {55.clkdef = {56.name = "ls1088a_platform_pll",57.id = QORIQ_CLK_ID(QORIQ_TYPE_PLATFORM_PLL, 0),58.flags = 059},60.offset = 0x60080,61.shift = 1,62.mask = 0xFE,63.dividers = ls1088a_pltfrm_pll_divs,64.flags = QORIQ_CLK_PLL_HAS_KILL_BIT65};6667static const uint8_t ls1088a_cga_pll_divs[] = {682, 3, 4, 069};7071static struct qoriq_clk_pll_def ls1088a_cga_pll1 = {72.clkdef = {73.name = "ls1088a_cga_pll1",74.id = QORIQ_CLK_ID(QORIQ_TYPE_INTERNAL, 0),75.flags = 076},77.offset = 0x80,78.shift = 1,79.mask = 0xFE,80.dividers = ls1088a_cga_pll_divs,81.flags = QORIQ_CLK_PLL_HAS_KILL_BIT82};8384static struct qoriq_clk_pll_def ls1088a_cga_pll2 = {85.clkdef = {86.name = "ls1088a_cga_pll2",87.id = QORIQ_CLK_ID(QORIQ_TYPE_INTERNAL, 20),88.flags = 089},90.offset = 0xA0,91.shift = 1,92.mask = 0xFE,93.dividers = ls1088a_cga_pll_divs,94.flags = QORIQ_CLK_PLL_HAS_KILL_BIT95};9697static struct qoriq_clk_pll_def *ls1088a_cga_plls[] = {98&ls1088a_cga_pll1,99&ls1088a_cga_pll2100};101102103/* 4.7.2 Core Cluster a Clock Control/Status Register (CLKC1CSR - CLKC2CSR) */104static const char *ls1088a_cmux0_parent_names[] = {105"ls1088a_cga_pll1",106"ls1088a_cga_pll1_div2",107"ls1088a_cga_pll1_div4",108NULL,109"ls1088a_cga_pll2",110"ls1088a_cga_pll2_div2",111"ls1088a_cga_pll2_div4"112};113114static struct clk_mux_def ls1088a_cmux0 = {115.clkdef = {116.name = "ls1088a_cmux0",117.id = QORIQ_CLK_ID(QORIQ_TYPE_CMUX, 0),118.parent_names = ls1088a_cmux0_parent_names,119.parent_cnt = nitems(ls1088a_cmux0_parent_names),120.flags = 0121},122.offset = 0x70000,123.shift = 27,124.width = 4,125.mux_flags = 0126};127128static struct clk_mux_def ls1088a_cmux1 = {129.clkdef = {130.name = "ls1088a_cmux1",131.id = QORIQ_CLK_ID(QORIQ_TYPE_CMUX, 1),132.parent_names = ls1088a_cmux0_parent_names,133.parent_cnt = nitems(ls1088a_cmux0_parent_names),134.flags = 0135},136.offset = 0x70020,137.shift = 27,138.width = 4,139.mux_flags = 0140};141142/* 4.4.2 HWAaCSR (HWA1CSR - HWA3CSR) */143static const char *ls1088a_hwaccel1_parent_names[] = {144"ls1088a_platform_pll",145"ls1088a_cga_pll1",146"ls1088a_cga_pll1_div2",147"ls1088a_cga_pll1_div3",148"ls1088a_cga_pll1_div4",149NULL, /* HWAMUX1 External Clock Source */150"ls1088a_cga_pll2_div2",151"ls1088a_cga_pll2_div3"152};153154static const char *ls1088a_hwaccel2_parent_names[] = {155"ls1088a_platform_pll",156"ls1088a_cga_pll2",157"ls1088a_cga_pll2_div2",158"ls1088a_cga_pll2_div3",159"ls1088a_cga_pll2_div4",160NULL, /* HWAMUX2 External Clock Source */161"ls1088a_cga_pll1_div2",162"ls1088a_cga_pll1_div3"163};164165static const char *ls1088a_hwaccel3_parent_names[] = {166"ls1088a_platform_pll",167NULL,168NULL,169NULL,170NULL,171NULL, /* HWAMUX3 External Clock Source */172"ls1088a_cga_pll2_div2",173"ls1088a_cga_pll2_div3"174};175176static struct clk_mux_def ls1088a_hwaccel1 = {177.clkdef = {178.name = "ls1088a_hwaccel1",179.id = QORIQ_CLK_ID(QORIQ_TYPE_HWACCEL, 0),180.parent_names = ls1088a_hwaccel1_parent_names,181.parent_cnt = nitems(ls1088a_hwaccel1_parent_names),182.flags = 0183},184.offset = 0x10,185.shift = 27,186.width = 4,187.mux_flags = 0188};189190static struct clk_mux_def ls1088a_hwaccel2 = {191.clkdef = {192.name = "ls1088a_hwaccel2",193.id = QORIQ_CLK_ID(QORIQ_TYPE_HWACCEL, 1),194.parent_names = ls1088a_hwaccel2_parent_names,195.parent_cnt = nitems(ls1088a_hwaccel2_parent_names),196.flags = 0197},198.offset = 0x30,199.shift = 27,200.width = 4,201.mux_flags = 0202};203204static struct clk_mux_def ls1088a_hwaccel3 = {205.clkdef = {206.name = "ls1088a_hwaccel3",207.id = QORIQ_CLK_ID(QORIQ_TYPE_HWACCEL, 2),208.parent_names = ls1088a_hwaccel3_parent_names,209.parent_cnt = nitems(ls1088a_hwaccel3_parent_names),210.flags = 0211},212.offset = 0x50,213.shift = 27,214.width = 4,215.mux_flags = 0216};217218219static struct clk_mux_def *ls1088a_mux_nodes[] = {220&ls1088a_cmux0,221&ls1088a_cmux1,222&ls1088a_hwaccel1,223&ls1088a_hwaccel2,224&ls1088a_hwaccel3225};226227static int228ls1088a_clkgen_probe(device_t dev)229{230231if (!ofw_bus_status_okay(dev))232return (ENXIO);233234if(!ofw_bus_is_compatible(dev, "fsl,ls1088a-clockgen"))235return (ENXIO);236237device_set_desc(dev, "LS1088A clockgen");238return (BUS_PROBE_DEFAULT);239}240241static int242ls1088a_clkgen_attach(device_t dev)243{244struct qoriq_clkgen_softc *sc;245246sc = device_get_softc(dev);247248sc->pltfrm_pll_def = &ls1088a_pltfrm_pll;249sc->cga_pll = ls1088a_cga_plls;250sc->cga_pll_num = nitems(ls1088a_cga_plls);251sc->mux = ls1088a_mux_nodes;252sc->mux_num = nitems(ls1088a_mux_nodes);253sc->flags = QORIQ_LITTLE_ENDIAN;254255return (qoriq_clkgen_attach(dev));256}257258static device_method_t ls1088a_clkgen_methods[] = {259DEVMETHOD(device_probe, ls1088a_clkgen_probe),260DEVMETHOD(device_attach, ls1088a_clkgen_attach),261262DEVMETHOD_END263};264265DEFINE_CLASS_1(ls1088a_clkgen, ls1088a_clkgen_driver, ls1088a_clkgen_methods,266sizeof(struct qoriq_clkgen_softc), qoriq_clkgen_driver);267268EARLY_DRIVER_MODULE(ls1088a_clkgen, simplebus, ls1088a_clkgen_driver, 0, 0,269BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);270271272