/*
 * Copyright (C) 2016 Maxime Ripard
 * Maxime Ripard <maxime.ripard@free-electrons.com>
 *
 * 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 <linux/clk-provider.h>

#include "ccu_gate.h"
#include "ccu_div.h"

static unsigned long ccu_div_round_rate(struct ccu_mux_internal *mux,
					unsigned long parent_rate,
					unsigned long rate,
					void *data)
{
	struct ccu_div *cd = data;
	unsigned long val;

	/*
	 * We can't use divider_round_rate that assumes that there's
	 * several parents, while we might be called to evaluate
	 * several different parents.
	 */
	val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width,
			      cd->div.flags);

	return divider_recalc_rate(&cd->common.hw, parent_rate, val,
				   cd->div.table, cd->div.flags);
}

static void ccu_div_disable(struct clk_hw *hw)
{
	struct ccu_div *cd = hw_to_ccu_div(hw);

	return ccu_gate_helper_disable(&cd->common, cd->enable);
}

static int ccu_div_enable(struct clk_hw *hw)
{
	struct ccu_div *cd = hw_to_ccu_div(hw);

	return ccu_gate_helper_enable(&cd->common, cd->enable);
}

static int ccu_div_is_enabled(struct clk_hw *hw)
{
	struct ccu_div *cd = hw_to_ccu_div(hw);

	return ccu_gate_helper_is_enabled(&cd->common, cd->enable);
}

static unsigned long ccu_div_recalc_rate(struct clk_hw *hw,
					unsigned long parent_rate)
{
	struct ccu_div *cd = hw_to_ccu_div(hw);
	unsigned long val;
	u32 reg;

	reg = readl(cd->common.base + cd->common.reg);
	val = reg >> cd->div.shift;
	val &= (1 << cd->div.width) - 1;

	ccu_mux_helper_adjust_parent_for_prediv(&cd->common, &cd->mux, -1,
						&parent_rate);

	return divider_recalc_rate(hw, parent_rate, val, cd->div.table,
				   cd->div.flags);
}

static int ccu_div_determine_rate(struct clk_hw *hw,
				struct clk_rate_request *req)
{
	struct ccu_div *cd = hw_to_ccu_div(hw);

	return ccu_mux_helper_determine_rate(&cd->common, &cd->mux,
					     req, ccu_div_round_rate, cd);
}

static int ccu_div_set_rate(struct clk_hw *hw, unsigned long rate,
			   unsigned long parent_rate)
{
	struct ccu_div *cd = hw_to_ccu_div(hw);
	unsigned long flags;
	unsigned long val;
	u32 reg;

	ccu_mux_helper_adjust_parent_for_prediv(&cd->common, &cd->mux, -1,
						&parent_rate);

	val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width,
			      cd->div.flags);

	spin_lock_irqsave(cd->common.lock, flags);

	reg = readl(cd->common.base + cd->common.reg);
	reg &= ~GENMASK(cd->div.width + cd->div.shift - 1, cd->div.shift);

	writel(reg | (val << cd->div.shift),
	       cd->common.base + cd->common.reg);

	spin_unlock_irqrestore(cd->common.lock, flags);

	return 0;
}

static u8 ccu_div_get_parent(struct clk_hw *hw)
{
	struct ccu_div *cd = hw_to_ccu_div(hw);

	return ccu_mux_helper_get_parent(&cd->common, &cd->mux);
}

static int ccu_div_set_parent(struct clk_hw *hw, u8 index)
{
	struct ccu_div *cd = hw_to_ccu_div(hw);

	return ccu_mux_helper_set_parent(&cd->common, &cd->mux, index);
}

const struct clk_ops ccu_div_ops = {
	.disable	= ccu_div_disable,
	.enable		= ccu_div_enable,
	.is_enabled	= ccu_div_is_enabled,

	.get_parent	= ccu_div_get_parent,
	.set_parent	= ccu_div_set_parent,

	.determine_rate	= ccu_div_determine_rate,
	.recalc_rate	= ccu_div_recalc_rate,
	.set_rate	= ccu_div_set_rate,
};
