162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright 2014 Google, Inc
462306a36Sopenharmony_ci * Author: Alexandru M Stan <amstan@chromium.org>
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/slab.h>
862306a36Sopenharmony_ci#include <linux/clk.h>
962306a36Sopenharmony_ci#include <linux/clk-provider.h>
1062306a36Sopenharmony_ci#include <linux/io.h>
1162306a36Sopenharmony_ci#include <linux/kernel.h>
1262306a36Sopenharmony_ci#include "clk.h"
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_cistruct rockchip_mmc_clock {
1562306a36Sopenharmony_ci	struct clk_hw	hw;
1662306a36Sopenharmony_ci	void __iomem	*reg;
1762306a36Sopenharmony_ci	int		id;
1862306a36Sopenharmony_ci	int		shift;
1962306a36Sopenharmony_ci	int		cached_phase;
2062306a36Sopenharmony_ci	struct notifier_block clk_rate_change_nb;
2162306a36Sopenharmony_ci};
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci#define to_mmc_clock(_hw) container_of(_hw, struct rockchip_mmc_clock, hw)
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#define RK3288_MMC_CLKGEN_DIV 2
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_cistatic unsigned long rockchip_mmc_recalc(struct clk_hw *hw,
2862306a36Sopenharmony_ci					 unsigned long parent_rate)
2962306a36Sopenharmony_ci{
3062306a36Sopenharmony_ci	return parent_rate / RK3288_MMC_CLKGEN_DIV;
3162306a36Sopenharmony_ci}
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#define ROCKCHIP_MMC_DELAY_SEL BIT(10)
3462306a36Sopenharmony_ci#define ROCKCHIP_MMC_DEGREE_MASK 0x3
3562306a36Sopenharmony_ci#define ROCKCHIP_MMC_DELAYNUM_OFFSET 2
3662306a36Sopenharmony_ci#define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#define PSECS_PER_SEC 1000000000000LL
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci/*
4162306a36Sopenharmony_ci * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
4262306a36Sopenharmony_ci * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
4362306a36Sopenharmony_ci */
4462306a36Sopenharmony_ci#define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic int rockchip_mmc_get_phase(struct clk_hw *hw)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw);
4962306a36Sopenharmony_ci	unsigned long rate = clk_hw_get_rate(hw);
5062306a36Sopenharmony_ci	u32 raw_value;
5162306a36Sopenharmony_ci	u16 degrees;
5262306a36Sopenharmony_ci	u32 delay_num = 0;
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci	/* Constant signal, no measurable phase shift */
5562306a36Sopenharmony_ci	if (!rate)
5662306a36Sopenharmony_ci		return 0;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift);
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	if (raw_value & ROCKCHIP_MMC_DELAY_SEL) {
6362306a36Sopenharmony_ci		/* degrees/delaynum * 1000000 */
6462306a36Sopenharmony_ci		unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
6562306a36Sopenharmony_ci					36 * (rate / 10000);
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci		delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
6862306a36Sopenharmony_ci		delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
6962306a36Sopenharmony_ci		degrees += DIV_ROUND_CLOSEST(delay_num * factor, 1000000);
7062306a36Sopenharmony_ci	}
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	return degrees % 360;
7362306a36Sopenharmony_ci}
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_cistatic int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees)
7662306a36Sopenharmony_ci{
7762306a36Sopenharmony_ci	struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw);
7862306a36Sopenharmony_ci	unsigned long rate = clk_hw_get_rate(hw);
7962306a36Sopenharmony_ci	u8 nineties, remainder;
8062306a36Sopenharmony_ci	u8 delay_num;
8162306a36Sopenharmony_ci	u32 raw_value;
8262306a36Sopenharmony_ci	u32 delay;
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	/*
8562306a36Sopenharmony_ci	 * The below calculation is based on the output clock from
8662306a36Sopenharmony_ci	 * MMC host to the card, which expects the phase clock inherits
8762306a36Sopenharmony_ci	 * the clock rate from its parent, namely the output clock
8862306a36Sopenharmony_ci	 * provider of MMC host. However, things may go wrong if
8962306a36Sopenharmony_ci	 * (1) It is orphan.
9062306a36Sopenharmony_ci	 * (2) It is assigned to the wrong parent.
9162306a36Sopenharmony_ci	 *
9262306a36Sopenharmony_ci	 * This check help debug the case (1), which seems to be the
9362306a36Sopenharmony_ci	 * most likely problem we often face and which makes it difficult
9462306a36Sopenharmony_ci	 * for people to debug unstable mmc tuning results.
9562306a36Sopenharmony_ci	 */
9662306a36Sopenharmony_ci	if (!rate) {
9762306a36Sopenharmony_ci		pr_err("%s: invalid clk rate\n", __func__);
9862306a36Sopenharmony_ci		return -EINVAL;
9962306a36Sopenharmony_ci	}
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci	nineties = degrees / 90;
10262306a36Sopenharmony_ci	remainder = (degrees % 90);
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	/*
10562306a36Sopenharmony_ci	 * Due to the inexact nature of the "fine" delay, we might
10662306a36Sopenharmony_ci	 * actually go non-monotonic.  We don't go _too_ monotonic
10762306a36Sopenharmony_ci	 * though, so we should be OK.  Here are options of how we may
10862306a36Sopenharmony_ci	 * work:
10962306a36Sopenharmony_ci	 *
11062306a36Sopenharmony_ci	 * Ideally we end up with:
11162306a36Sopenharmony_ci	 *   1.0, 2.0, ..., 69.0, 70.0, ...,  89.0, 90.0
11262306a36Sopenharmony_ci	 *
11362306a36Sopenharmony_ci	 * On one extreme (if delay is actually 44ps):
11462306a36Sopenharmony_ci	 *   .73, 1.5, ..., 50.6, 51.3, ...,  65.3, 90.0
11562306a36Sopenharmony_ci	 * The other (if delay is actually 77ps):
11662306a36Sopenharmony_ci	 *   1.3, 2.6, ..., 88.6. 89.8, ..., 114.0, 90
11762306a36Sopenharmony_ci	 *
11862306a36Sopenharmony_ci	 * It's possible we might make a delay that is up to 25
11962306a36Sopenharmony_ci	 * degrees off from what we think we're making.  That's OK
12062306a36Sopenharmony_ci	 * though because we should be REALLY far from any bad range.
12162306a36Sopenharmony_ci	 */
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci	/*
12462306a36Sopenharmony_ci	 * Convert to delay; do a little extra work to make sure we
12562306a36Sopenharmony_ci	 * don't overflow 32-bit / 64-bit numbers.
12662306a36Sopenharmony_ci	 */
12762306a36Sopenharmony_ci	delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
12862306a36Sopenharmony_ci	delay *= remainder;
12962306a36Sopenharmony_ci	delay = DIV_ROUND_CLOSEST(delay,
13062306a36Sopenharmony_ci			(rate / 1000) * 36 *
13162306a36Sopenharmony_ci				(ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci	delay_num = (u8) min_t(u32, delay, 255);
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci	raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
13662306a36Sopenharmony_ci	raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
13762306a36Sopenharmony_ci	raw_value |= nineties;
13862306a36Sopenharmony_ci	writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift),
13962306a36Sopenharmony_ci	       mmc_clock->reg);
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci	pr_debug("%s->set_phase(%d) delay_nums=%u reg[0x%p]=0x%03x actual_degrees=%d\n",
14262306a36Sopenharmony_ci		clk_hw_get_name(hw), degrees, delay_num,
14362306a36Sopenharmony_ci		mmc_clock->reg, raw_value>>(mmc_clock->shift),
14462306a36Sopenharmony_ci		rockchip_mmc_get_phase(hw)
14562306a36Sopenharmony_ci	);
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	return 0;
14862306a36Sopenharmony_ci}
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_cistatic const struct clk_ops rockchip_mmc_clk_ops = {
15162306a36Sopenharmony_ci	.recalc_rate	= rockchip_mmc_recalc,
15262306a36Sopenharmony_ci	.get_phase	= rockchip_mmc_get_phase,
15362306a36Sopenharmony_ci	.set_phase	= rockchip_mmc_set_phase,
15462306a36Sopenharmony_ci};
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci#define to_rockchip_mmc_clock(x) \
15762306a36Sopenharmony_ci	container_of(x, struct rockchip_mmc_clock, clk_rate_change_nb)
15862306a36Sopenharmony_cistatic int rockchip_mmc_clk_rate_notify(struct notifier_block *nb,
15962306a36Sopenharmony_ci					unsigned long event, void *data)
16062306a36Sopenharmony_ci{
16162306a36Sopenharmony_ci	struct rockchip_mmc_clock *mmc_clock = to_rockchip_mmc_clock(nb);
16262306a36Sopenharmony_ci	struct clk_notifier_data *ndata = data;
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci	/*
16562306a36Sopenharmony_ci	 * rockchip_mmc_clk is mostly used by mmc controllers to sample
16662306a36Sopenharmony_ci	 * the intput data, which expects the fixed phase after the tuning
16762306a36Sopenharmony_ci	 * process. However if the clock rate is changed, the phase is stale
16862306a36Sopenharmony_ci	 * and may break the data sampling. So here we try to restore the phase
16962306a36Sopenharmony_ci	 * for that case, except that
17062306a36Sopenharmony_ci	 * (1) cached_phase is invaild since we inevitably cached it when the
17162306a36Sopenharmony_ci	 * clock provider be reparented from orphan to its real parent in the
17262306a36Sopenharmony_ci	 * first place. Otherwise we may mess up the initialization of MMC cards
17362306a36Sopenharmony_ci	 * since we only set the default sample phase and drive phase later on.
17462306a36Sopenharmony_ci	 * (2) the new coming rate is higher than the older one since mmc driver
17562306a36Sopenharmony_ci	 * set the max-frequency to match the boards' ability but we can't go
17662306a36Sopenharmony_ci	 * over the heads of that, otherwise the tests smoke out the issue.
17762306a36Sopenharmony_ci	 */
17862306a36Sopenharmony_ci	if (ndata->old_rate <= ndata->new_rate)
17962306a36Sopenharmony_ci		return NOTIFY_DONE;
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci	if (event == PRE_RATE_CHANGE)
18262306a36Sopenharmony_ci		mmc_clock->cached_phase =
18362306a36Sopenharmony_ci			rockchip_mmc_get_phase(&mmc_clock->hw);
18462306a36Sopenharmony_ci	else if (mmc_clock->cached_phase != -EINVAL &&
18562306a36Sopenharmony_ci		 event == POST_RATE_CHANGE)
18662306a36Sopenharmony_ci		rockchip_mmc_set_phase(&mmc_clock->hw, mmc_clock->cached_phase);
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	return NOTIFY_DONE;
18962306a36Sopenharmony_ci}
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_cistruct clk *rockchip_clk_register_mmc(const char *name,
19262306a36Sopenharmony_ci				const char *const *parent_names, u8 num_parents,
19362306a36Sopenharmony_ci				void __iomem *reg, int shift)
19462306a36Sopenharmony_ci{
19562306a36Sopenharmony_ci	struct clk_init_data init;
19662306a36Sopenharmony_ci	struct rockchip_mmc_clock *mmc_clock;
19762306a36Sopenharmony_ci	struct clk *clk;
19862306a36Sopenharmony_ci	int ret;
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci	mmc_clock = kmalloc(sizeof(*mmc_clock), GFP_KERNEL);
20162306a36Sopenharmony_ci	if (!mmc_clock)
20262306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	init.name = name;
20562306a36Sopenharmony_ci	init.flags = 0;
20662306a36Sopenharmony_ci	init.num_parents = num_parents;
20762306a36Sopenharmony_ci	init.parent_names = parent_names;
20862306a36Sopenharmony_ci	init.ops = &rockchip_mmc_clk_ops;
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci	mmc_clock->hw.init = &init;
21162306a36Sopenharmony_ci	mmc_clock->reg = reg;
21262306a36Sopenharmony_ci	mmc_clock->shift = shift;
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci	clk = clk_register(NULL, &mmc_clock->hw);
21562306a36Sopenharmony_ci	if (IS_ERR(clk)) {
21662306a36Sopenharmony_ci		ret = PTR_ERR(clk);
21762306a36Sopenharmony_ci		goto err_register;
21862306a36Sopenharmony_ci	}
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci	mmc_clock->clk_rate_change_nb.notifier_call =
22162306a36Sopenharmony_ci				&rockchip_mmc_clk_rate_notify;
22262306a36Sopenharmony_ci	ret = clk_notifier_register(clk, &mmc_clock->clk_rate_change_nb);
22362306a36Sopenharmony_ci	if (ret)
22462306a36Sopenharmony_ci		goto err_notifier;
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci	return clk;
22762306a36Sopenharmony_cierr_notifier:
22862306a36Sopenharmony_ci	clk_unregister(clk);
22962306a36Sopenharmony_cierr_register:
23062306a36Sopenharmony_ci	kfree(mmc_clock);
23162306a36Sopenharmony_ci	return ERR_PTR(ret);
23262306a36Sopenharmony_ci}
233