Path: blob/main/sys/arm/mv/clk/a37x0_periph_clk_driver.c
39536 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2021 Semihalf.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8* 1. Redistributions of source code must retain the above copyright9* notice, this list of conditions and the following disclaimer.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND15* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE16* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE17* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE18* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL19* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS20* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)21* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT22* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY23* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF24* SUCH DAMAGE.25*/2627#include <sys/param.h>28#include <sys/bus.h>29#include <sys/kernel.h>30#include <sys/module.h>31#include <sys/mutex.h>32#include <sys/rman.h>33#include <machine/bus.h>3435#include <dev/fdt/simplebus.h>3637#include <dev/clk/clk.h>38#include <dev/clk/clk_fixed.h>3940#include <dev/ofw/ofw_bus.h>41#include <dev/ofw/ofw_bus_subr.h>4243#include "clkdev_if.h"44#include "periph.h"4546#define TBG_COUNT 447#define XTAL_OFW_INDEX 44849static struct resource_spec a37x0_periph_clk_spec[] = {50{ SYS_RES_MEMORY, 0, RF_ACTIVE },51{ -1, 0 }52};5354int55a37x0_periph_clk_attach(device_t dev)56{57struct a37x0_periph_clknode_def *dev_defs;58struct a37x0_periph_clk_softc *sc;59const char *tbg_clocks[5];60const char *xtal_clock;61phandle_t node;62int error, i;63clk_t clock;6465sc = device_get_softc(dev);66node = ofw_bus_get_node(dev);67sc->dev = dev;6869mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);7071if (bus_alloc_resources(dev, a37x0_periph_clk_spec, &sc->res) != 0) {72device_printf(dev, "Cannot allocate resources\n");73return (ENXIO);74}7576sc->clkdom = clkdom_create(dev);77if (sc->clkdom == NULL) {78device_printf(dev, "Cannot create clock domain\n");79return (ENXIO);80}8182for (i = 0; i < TBG_COUNT; i++){83error = clk_get_by_ofw_index(dev, node, i, &clock);84if (error)85goto fail;86tbg_clocks[i] = clk_get_name(clock);87}8889error = clk_get_by_ofw_index(dev, node, XTAL_OFW_INDEX, &clock);90if (error)91goto fail;92xtal_clock = clk_get_name(clock);9394dev_defs = sc->devices;9596for (i = 0; i< sc->device_count; i++) {97dev_defs[i].common_def.tbgs = tbg_clocks;98dev_defs[i].common_def.xtal = xtal_clock;99dev_defs[i].common_def.tbg_cnt = TBG_COUNT;100switch (dev_defs[i].type) {101case CLK_FULL_DD:102error = a37x0_periph_d_register_full_clk_dd(103sc->clkdom, &dev_defs[i]);104if (error)105goto fail;106break;107108case CLK_FULL:109error = a37x0_periph_d_register_full_clk(110sc->clkdom, &dev_defs[i]);111if (error)112goto fail;113break;114115case CLK_GATE:116error = a37x0_periph_gate_register_gate(117sc->clkdom, &dev_defs[i]);118if (error)119goto fail;120break;121122case CLK_MUX_GATE:123error = a37x0_periph_register_mux_gate(124sc->clkdom, &dev_defs[i]);125if (error)126goto fail;127break;128129case CLK_FIXED:130error = a37x0_periph_fixed_register_fixed(131sc->clkdom, &dev_defs[i]);132if (error)133goto fail;134break;135136case CLK_CPU:137error = a37x0_periph_d_register_periph_cpu(138sc->clkdom, &dev_defs[i]);139if (error)140goto fail;141break;142143case CLK_MDD:144error = a37x0_periph_d_register_mdd(145sc->clkdom, &dev_defs[i]);146if (error)147goto fail;148break;149150case CLK_MUX_GATE_FIXED:151error = a37x0_periph_register_mux_gate_fixed(152sc->clkdom, &dev_defs[i]);153if (error)154goto fail;155break;156157default:158return (ENXIO);159}160}161162error = clkdom_finit(sc->clkdom);163if (error)164goto fail;165166if (bootverbose)167clkdom_dump(sc->clkdom);168169return (0);170171fail:172bus_release_resources(dev, a37x0_periph_clk_spec, &sc->res);173174return (error);175176}177178int179a37x0_periph_clk_read_4(device_t dev, bus_addr_t addr, uint32_t *val)180{181struct a37x0_periph_clk_softc *sc;182183sc = device_get_softc(dev);184*val = bus_read_4(sc->res, addr);185186return (0);187}188189void190a37x0_periph_clk_device_lock(device_t dev)191{192struct a37x0_periph_clk_softc *sc;193194sc = device_get_softc(dev);195mtx_lock(&sc->mtx);196}197198void199a37x0_periph_clk_device_unlock(device_t dev)200{201struct a37x0_periph_clk_softc *sc;202203sc = device_get_softc(dev);204mtx_unlock(&sc->mtx);205}206207int208a37x0_periph_clk_detach(device_t dev)209{210211return (EBUSY);212}213214215