107c5be33SAlbert Jakieła /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 307c5be33SAlbert Jakieła * 407c5be33SAlbert Jakieła * Copyright (c) 2022 Semihalf. 507c5be33SAlbert Jakieła * 607c5be33SAlbert Jakieła * Redistribution and use in source and binary forms, with or without 707c5be33SAlbert Jakieła * modification, are permitted provided that the following conditions 807c5be33SAlbert Jakieła * are met: 907c5be33SAlbert Jakieła * 1. Redistributions of source code must retain the above copyright 1007c5be33SAlbert Jakieła * notice, this list of conditions and the following disclaimer. 1107c5be33SAlbert Jakieła * 2. Redistributions in binary form must reproduce the above copyright 1207c5be33SAlbert Jakieła * notice, this list of conditions and the following disclaimer in the 1307c5be33SAlbert Jakieła * documentation and/or other materials provided with the distribution. 1407c5be33SAlbert Jakieła * 1507c5be33SAlbert Jakieła * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1607c5be33SAlbert Jakieła * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1707c5be33SAlbert Jakieła * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1807c5be33SAlbert Jakieła * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1907c5be33SAlbert Jakieła * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2007c5be33SAlbert Jakieła * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2107c5be33SAlbert Jakieła * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2207c5be33SAlbert Jakieła * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2307c5be33SAlbert Jakieła * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2407c5be33SAlbert Jakieła * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2507c5be33SAlbert Jakieła */ 2607c5be33SAlbert Jakieła 2707c5be33SAlbert Jakieła #include <sys/cdefs.h> 2807c5be33SAlbert Jakieła __FBSDID("$FreeBSD$"); 2907c5be33SAlbert Jakieła 3007c5be33SAlbert Jakieła #include <sys/param.h> 3107c5be33SAlbert Jakieła #include <sys/systm.h> 3207c5be33SAlbert Jakieła #include <sys/bus.h> 3307c5be33SAlbert Jakieła 3407c5be33SAlbert Jakieła #include <machine/bus.h> 3507c5be33SAlbert Jakieła 3607c5be33SAlbert Jakieła #include <dev/extres/clk/clk.h> 3707c5be33SAlbert Jakieła 3807c5be33SAlbert Jakieła #include <arm/mv/clk/armada38x_gen.h> 3907c5be33SAlbert Jakieła 4007c5be33SAlbert Jakieła #include "clkdev_if.h" 4107c5be33SAlbert Jakieła 4207c5be33SAlbert Jakieła #define SAR_A38X_TCLK_FREQ_SHIFT 15 4307c5be33SAlbert Jakieła #define SAR_A38X_TCLK_FREQ_MASK 0x00008000 4407c5be33SAlbert Jakieła 4507c5be33SAlbert Jakieła #define TCLK_250MHZ 250 * 1000 * 1000 4607c5be33SAlbert Jakieła #define TCLK_200MHZ 200 * 1000 * 1000 4707c5be33SAlbert Jakieła 4807c5be33SAlbert Jakieła #define WR4(_clk, offset, val) \ 4907c5be33SAlbert Jakieła CLKDEV_WRITE_4(clknode_get_device(_clk), offset, val) 5007c5be33SAlbert Jakieła #define RD4(_clk, offset, val) \ 5107c5be33SAlbert Jakieła CLKDEV_READ_4(clknode_get_device(_clk), offset, val) 5207c5be33SAlbert Jakieła #define DEVICE_LOCK(_clk) \ 5307c5be33SAlbert Jakieła CLKDEV_DEVICE_LOCK(clknode_get_device(_clk)) 5407c5be33SAlbert Jakieła #define DEVICE_UNLOCK(_clk) \ 5507c5be33SAlbert Jakieła CLKDEV_DEVICE_UNLOCK(clknode_get_device(_clk)) 5607c5be33SAlbert Jakieła 5707c5be33SAlbert Jakieła static int 5807c5be33SAlbert Jakieła armada38x_gen_recalc(struct clknode *clk, uint64_t *freq) 5907c5be33SAlbert Jakieła { 6007c5be33SAlbert Jakieła uint32_t reg; 6107c5be33SAlbert Jakieła 6207c5be33SAlbert Jakieła DEVICE_LOCK(clk); 6307c5be33SAlbert Jakieła RD4(clk, 0, ®); 6407c5be33SAlbert Jakieła DEVICE_UNLOCK(clk); 6507c5be33SAlbert Jakieła 6607c5be33SAlbert Jakieła reg = (reg & SAR_A38X_TCLK_FREQ_MASK) >> SAR_A38X_TCLK_FREQ_SHIFT; 6707c5be33SAlbert Jakieła *freq = reg ? TCLK_200MHZ : TCLK_250MHZ; 6807c5be33SAlbert Jakieła 6907c5be33SAlbert Jakieła return (0); 7007c5be33SAlbert Jakieła } 7107c5be33SAlbert Jakieła 7207c5be33SAlbert Jakieła static int 7307c5be33SAlbert Jakieła armada38x_gen_init(struct clknode *clk, device_t dev) 7407c5be33SAlbert Jakieła { 7507c5be33SAlbert Jakieła return (0); 7607c5be33SAlbert Jakieła } 7707c5be33SAlbert Jakieła 7807c5be33SAlbert Jakieła static clknode_method_t armada38x_gen_clknode_methods[] = { 7907c5be33SAlbert Jakieła /* Device interface */ 8007c5be33SAlbert Jakieła CLKNODEMETHOD(clknode_init, armada38x_gen_init), 8107c5be33SAlbert Jakieła CLKNODEMETHOD(clknode_recalc_freq, armada38x_gen_recalc), 8207c5be33SAlbert Jakieła CLKNODEMETHOD_END 8307c5be33SAlbert Jakieła }; 8407c5be33SAlbert Jakieła 8507c5be33SAlbert Jakieła DEFINE_CLASS_1(armada38x_gen_clknode, armada38x_gen_clknode_class, 8607c5be33SAlbert Jakieła armada38x_gen_clknode_methods, 0, clknode_class); 8707c5be33SAlbert Jakieła 8807c5be33SAlbert Jakieła int 8907c5be33SAlbert Jakieła armada38x_gen_register(struct clkdom *clkdom, const struct armada38x_gen_clknode_def *clkdef) 9007c5be33SAlbert Jakieła { 9107c5be33SAlbert Jakieła struct clknode *clk; 9207c5be33SAlbert Jakieła 9307c5be33SAlbert Jakieła clk = clknode_create(clkdom, &armada38x_gen_clknode_class, &clkdef->def); 9407c5be33SAlbert Jakieła if (clk == NULL) 9507c5be33SAlbert Jakieła return (1); 9607c5be33SAlbert Jakieła 9707c5be33SAlbert Jakieła clknode_register(clkdom, clk); 9807c5be33SAlbert Jakieła 9907c5be33SAlbert Jakieła return(0); 10007c5be33SAlbert Jakieła } 101