xref: /netbsd-src/sys/arch/arm/sunxi/sunxi_ccu_fixed_factor.c (revision aac640031a959069b5b3792247232bd2321cac59)
1*aac64003Sjmcneill /* $NetBSD: sunxi_ccu_fixed_factor.c,v 1.2 2018/05/08 22:05:25 jmcneill Exp $ */
2a5198ca0Sjmcneill 
3a5198ca0Sjmcneill /*-
4a5198ca0Sjmcneill  * Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca>
5a5198ca0Sjmcneill  * All rights reserved.
6a5198ca0Sjmcneill  *
7a5198ca0Sjmcneill  * Redistribution and use in source and binary forms, with or without
8a5198ca0Sjmcneill  * modification, are permitted provided that the following conditions
9a5198ca0Sjmcneill  * are met:
10a5198ca0Sjmcneill  * 1. Redistributions of source code must retain the above copyright
11a5198ca0Sjmcneill  *    notice, this list of conditions and the following disclaimer.
12a5198ca0Sjmcneill  * 2. Redistributions in binary form must reproduce the above copyright
13a5198ca0Sjmcneill  *    notice, this list of conditions and the following disclaimer in the
14a5198ca0Sjmcneill  *    documentation and/or other materials provided with the distribution.
15a5198ca0Sjmcneill  *
16a5198ca0Sjmcneill  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17a5198ca0Sjmcneill  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18a5198ca0Sjmcneill  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19a5198ca0Sjmcneill  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20a5198ca0Sjmcneill  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21a5198ca0Sjmcneill  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22a5198ca0Sjmcneill  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23a5198ca0Sjmcneill  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24a5198ca0Sjmcneill  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25a5198ca0Sjmcneill  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26a5198ca0Sjmcneill  * SUCH DAMAGE.
27a5198ca0Sjmcneill  */
28a5198ca0Sjmcneill 
29a5198ca0Sjmcneill #include <sys/cdefs.h>
30*aac64003Sjmcneill __KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_fixed_factor.c,v 1.2 2018/05/08 22:05:25 jmcneill Exp $");
31a5198ca0Sjmcneill 
32a5198ca0Sjmcneill #include <sys/param.h>
33a5198ca0Sjmcneill #include <sys/bus.h>
34a5198ca0Sjmcneill 
35a5198ca0Sjmcneill #include <dev/clk/clk_backend.h>
36a5198ca0Sjmcneill 
37a5198ca0Sjmcneill #include <arm/sunxi/sunxi_ccu.h>
38a5198ca0Sjmcneill 
39a5198ca0Sjmcneill static u_int
sunxi_ccu_fixed_factor_get_parent_rate(struct clk * clkp)40a5198ca0Sjmcneill sunxi_ccu_fixed_factor_get_parent_rate(struct clk *clkp)
41a5198ca0Sjmcneill {
42a5198ca0Sjmcneill 	struct clk *clkp_parent;
43a5198ca0Sjmcneill 
44a5198ca0Sjmcneill 	clkp_parent = clk_get_parent(clkp);
45a5198ca0Sjmcneill 	if (clkp_parent == NULL)
46a5198ca0Sjmcneill 		return 0;
47a5198ca0Sjmcneill 
48a5198ca0Sjmcneill 	return clk_get_rate(clkp_parent);
49a5198ca0Sjmcneill }
50a5198ca0Sjmcneill 
51a5198ca0Sjmcneill u_int
sunxi_ccu_fixed_factor_get_rate(struct sunxi_ccu_softc * sc,struct sunxi_ccu_clk * clk)52a5198ca0Sjmcneill sunxi_ccu_fixed_factor_get_rate(struct sunxi_ccu_softc *sc,
53a5198ca0Sjmcneill     struct sunxi_ccu_clk *clk)
54a5198ca0Sjmcneill {
55a5198ca0Sjmcneill 	struct sunxi_ccu_fixed_factor *fixed_factor = &clk->u.fixed_factor;
56a5198ca0Sjmcneill 	struct clk *clkp = &clk->base;
57a5198ca0Sjmcneill 
58a5198ca0Sjmcneill 	KASSERT(clk->type == SUNXI_CCU_FIXED_FACTOR);
59a5198ca0Sjmcneill 
60a5198ca0Sjmcneill 	const u_int p_rate = sunxi_ccu_fixed_factor_get_parent_rate(clkp);
61a5198ca0Sjmcneill 	if (p_rate == 0)
62a5198ca0Sjmcneill 		return 0;
63a5198ca0Sjmcneill 
64a5198ca0Sjmcneill 	return (u_int)(((uint64_t)p_rate * fixed_factor->mult) / fixed_factor->div);
65a5198ca0Sjmcneill }
66a5198ca0Sjmcneill 
67*aac64003Sjmcneill static int
sunxi_ccu_fixed_factor_set_parent_rate(struct clk * clkp,u_int rate)68*aac64003Sjmcneill sunxi_ccu_fixed_factor_set_parent_rate(struct clk *clkp, u_int rate)
69*aac64003Sjmcneill {
70*aac64003Sjmcneill 	struct clk *clkp_parent;
71*aac64003Sjmcneill 
72*aac64003Sjmcneill 	clkp_parent = clk_get_parent(clkp);
73*aac64003Sjmcneill 	if (clkp_parent == NULL)
74*aac64003Sjmcneill 		return ENXIO;
75*aac64003Sjmcneill 
76*aac64003Sjmcneill 	return clk_set_rate(clkp_parent, rate);
77*aac64003Sjmcneill }
78*aac64003Sjmcneill 
79*aac64003Sjmcneill int
sunxi_ccu_fixed_factor_set_rate(struct sunxi_ccu_softc * sc,struct sunxi_ccu_clk * clk,u_int rate)80*aac64003Sjmcneill sunxi_ccu_fixed_factor_set_rate(struct sunxi_ccu_softc *sc,
81*aac64003Sjmcneill     struct sunxi_ccu_clk *clk, u_int rate)
82*aac64003Sjmcneill {
83*aac64003Sjmcneill 	struct sunxi_ccu_fixed_factor *fixed_factor = &clk->u.fixed_factor;
84*aac64003Sjmcneill 	struct clk *clkp = &clk->base;
85*aac64003Sjmcneill 
86*aac64003Sjmcneill 	KASSERT(clk->type == SUNXI_CCU_FIXED_FACTOR);
87*aac64003Sjmcneill 
88*aac64003Sjmcneill 	rate *= fixed_factor->div;
89*aac64003Sjmcneill 	rate /= fixed_factor->mult;
90*aac64003Sjmcneill 
91*aac64003Sjmcneill 	return sunxi_ccu_fixed_factor_set_parent_rate(clkp, rate);
92*aac64003Sjmcneill }
93*aac64003Sjmcneill 
94a5198ca0Sjmcneill const char *
sunxi_ccu_fixed_factor_get_parent(struct sunxi_ccu_softc * sc,struct sunxi_ccu_clk * clk)95a5198ca0Sjmcneill sunxi_ccu_fixed_factor_get_parent(struct sunxi_ccu_softc *sc,
96a5198ca0Sjmcneill     struct sunxi_ccu_clk *clk)
97a5198ca0Sjmcneill {
98a5198ca0Sjmcneill 	struct sunxi_ccu_fixed_factor *fixed_factor = &clk->u.fixed_factor;
99a5198ca0Sjmcneill 
100a5198ca0Sjmcneill 	KASSERT(clk->type == SUNXI_CCU_FIXED_FACTOR);
101a5198ca0Sjmcneill 
102a5198ca0Sjmcneill 	return fixed_factor->parent;
103a5198ca0Sjmcneill }
104