Path: blob/main/sys/arm/mv/clk/periph_clk_mux_gate.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_div.h>39#include <dev/clk/clk_fixed.h>40#include <dev/clk/clk_gate.h>41#include <dev/clk/clk_mux.h>4243#include <dev/ofw/ofw_bus.h>44#include <dev/ofw/ofw_bus_subr.h>4546#include "clkdev_if.h"47#include "periph.h"4849#define PARENT_CNT 250#define TBG_A_S_OFW_INDEX 05152/*53* Register chain: fixed (freq/2) -> mux (choose fixed or parent frequency) ->54* gate (enable or disable clock).55*/5657int58a37x0_periph_register_mux_gate(struct clkdom *clkdom,59struct a37x0_periph_clknode_def *device_def)60{61const char *parent_names[PARENT_CNT];62struct clk_fixed_def fixed;63struct clk_gate_def *gate;64struct clk_mux_def *mux;65int error, dev_id;6667dev_id = device_def->common_def.device_id;68mux = &device_def->clk_def.mux_gate.mux;69gate = &device_def->clk_def.mux_gate.gate;70fixed = device_def->clk_def.fixed.fixed;7172fixed.clkdef.id = A37x0_INTERNAL_CLK_ID(dev_id, FIXED1_POS);73fixed.clkdef.parent_names = &device_def->common_def.pname;74fixed.clkdef.parent_cnt = 1;75fixed.clkdef.flags = 0x0;76fixed.mult = 1;77fixed.div = 2;78fixed.freq = 0;7980error = clknode_fixed_register(clkdom, &fixed);81if (error)82goto fail;8384parent_names[0] = device_def->common_def.pname;85parent_names[1] = fixed.clkdef.name;8687a37x0_periph_set_props(&mux->clkdef, parent_names, PARENT_CNT);88error = a37x0_periph_create_mux(clkdom, mux,89A37x0_INTERNAL_CLK_ID(dev_id, MUX_POS));90if (error)91goto fail;9293a37x0_periph_set_props(&gate->clkdef, &mux->clkdef.name, 1);94error = a37x0_periph_create_gate(clkdom, gate,95dev_id);96if (error)97goto fail;9899fail:100101return (error);102}103104/*105* Register chain: fixed1 (freq/2) -> mux (fixed1 or TBG-A-S frequency) ->106* gate -> fixed2 (freq/2).107*/108109int110a37x0_periph_register_mux_gate_fixed(struct clkdom * clkdom,111struct a37x0_periph_clknode_def *device_def)112{113struct clk_fixed_def *fixed1, *fixed2;114const char *parent_names[PARENT_CNT];115struct clk_gate_def *gate;116struct clk_mux_def *mux;117int error, dev_id;118119dev_id = device_def->common_def.device_id;120mux = &device_def->clk_def.mux_gate_fixed.mux;121gate = &device_def->clk_def.mux_gate_fixed.gate;122fixed1 = &device_def->clk_def.mux_gate_fixed.fixed1;123fixed2 = &device_def->clk_def.mux_gate_fixed.fixed2;124125fixed1->clkdef.parent_names = &device_def->common_def.pname;126fixed1->clkdef.id = A37x0_INTERNAL_CLK_ID(dev_id, FIXED1_POS);127fixed1->clkdef.flags = 0x0;128fixed1->mult = 1;129fixed1->div = 2;130fixed1->freq = 0;131132error = clknode_fixed_register(clkdom, fixed1);133if (error)134goto fail;135136parent_names[0] = device_def->common_def.tbgs[TBG_A_S_OFW_INDEX];137parent_names[1] = fixed1->clkdef.name;138139a37x0_periph_set_props(&mux->clkdef, parent_names, PARENT_CNT);140error = a37x0_periph_create_mux(clkdom, mux,141A37x0_INTERNAL_CLK_ID(dev_id, MUX_POS));142if (error)143goto fail;144145a37x0_periph_set_props(&gate->clkdef, &mux->clkdef.name, 1);146error = a37x0_periph_create_gate(clkdom, gate,147A37x0_INTERNAL_CLK_ID(dev_id, GATE_POS));148if (error)149goto fail;150151fixed2->clkdef.parent_names = &gate->clkdef.name;152fixed2->clkdef.parent_cnt = 1;153fixed2->clkdef.id = dev_id;154155error = clknode_fixed_register(clkdom, fixed2);156if (error)157goto fail;158159fail:160161return (error);162}163164165