From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756670AbcFGUqA (ORCPT ); Tue, 7 Jun 2016 16:46:00 -0400 Received: from down.free-electrons.com ([37.187.137.238]:52944 "EHLO mail.free-electrons.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753717AbcFGUmM (ORCPT ); Tue, 7 Jun 2016 16:42:12 -0400 From: Maxime Ripard To: Mike Turquette , Stephen Boyd , Chen-Yu Tsai Cc: linux-clk@vger.kernel.org, Hans de Goede , Andre Przywara , Rob Herring , Vishnu Patekar , linux-arm-kernel@lists.infradead.org, Boris Brezillon , Jean-Francois Moine , linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Maxime Ripard Subject: [PATCH v2 04/15] clk: sunxi-ng: Add fixed factor clock support Date: Tue, 7 Jun 2016 22:41:43 +0200 Message-Id: <20160607204154.31967-5-maxime.ripard@free-electrons.com> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20160607204154.31967-1-maxime.ripard@free-electrons.com> References: <20160607204154.31967-1-maxime.ripard@free-electrons.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Some clocks in the Allwinner SoCs clock units are direct, fixed, multipliers or dividers from their parent. Add support for such clocks. Signed-off-by: Maxime Ripard --- drivers/clk/sunxi-ng/Makefile | 2 ++ drivers/clk/sunxi-ng/ccu_fixed_factor.c | 50 +++++++++++++++++++++++++++++++++ drivers/clk/sunxi-ng/ccu_fixed_factor.h | 50 +++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 drivers/clk/sunxi-ng/ccu_fixed_factor.c create mode 100644 drivers/clk/sunxi-ng/ccu_fixed_factor.h diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile index 4585443b3771..c59cf2ea509b 100644 --- a/drivers/clk/sunxi-ng/Makefile +++ b/drivers/clk/sunxi-ng/Makefile @@ -2,3 +2,5 @@ obj-y += ccu_common.o obj-y += ccu_reset.o obj-y += ccu_frac.o + +obj-y += ccu_fixed_factor.o diff --git a/drivers/clk/sunxi-ng/ccu_fixed_factor.c b/drivers/clk/sunxi-ng/ccu_fixed_factor.c new file mode 100644 index 000000000000..0498dc5340ea --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu_fixed_factor.c @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2016 Maxime Ripard + * Maxime Ripard + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + */ + +#include + +#include "ccu_fixed_factor.h" + +static unsigned long ccu_fixed_factor_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct ccu_fixed_factor *fix = hw_to_ccu_fixed_factor(hw); + + return parent_rate / fix->div * fix->mult; +} + +static long ccu_fixed_factor_round_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long *parent_rate) +{ + struct ccu_fixed_factor *fix = hw_to_ccu_fixed_factor(hw); + + if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) { + unsigned long best_parent; + + best_parent = (rate / fix->mult) * fix->div; + *parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), + best_parent); + } + + return *parent_rate / fix->div * fix->mult; +} + +static int ccu_fixed_factor_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + return 0; +} + +const struct clk_ops ccu_fixed_factor_ops = { + .recalc_rate = ccu_fixed_factor_recalc_rate, + .round_rate = ccu_fixed_factor_round_rate, + .set_rate = ccu_fixed_factor_set_rate, +}; diff --git a/drivers/clk/sunxi-ng/ccu_fixed_factor.h b/drivers/clk/sunxi-ng/ccu_fixed_factor.h new file mode 100644 index 000000000000..4e53dbc9d10b --- /dev/null +++ b/drivers/clk/sunxi-ng/ccu_fixed_factor.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2016 Maxime Ripard. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _CCU_FIXED_FACTOR_H_ +#define _CCU_FIXED_FACTOR_H_ + +#include + +#include "ccu_common.h" + +struct ccu_fixed_factor { + u16 div; + u16 mult; + + struct ccu_common common; +}; + +#define SUNXI_CCU_FIXED_FACTOR(_struct, _name, _parent, \ + _div, _mult, _flags) \ + struct ccu_fixed_factor _struct = { \ + .div = _div, \ + .mult = _mult, \ + .common = { \ + .hw.init = SUNXI_HW_INIT(_name, \ + _parent, \ + &ccu_fixed_factor_ops, \ + _flags), \ + }, \ + } + +static inline struct ccu_fixed_factor *hw_to_ccu_fixed_factor(struct clk_hw *hw) +{ + struct ccu_common *common = hw_to_ccu_common(hw); + + return container_of(common, struct ccu_fixed_factor, common); +} + +extern const struct clk_ops ccu_fixed_factor_ops; + +#endif /* _CCU_FIXED_FACTOR_H_ */ -- 2.8.3