18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright 2014 Google, Inc 48c2ecf20Sopenharmony_ci * Author: Alexandru M Stan <amstan@chromium.org> 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/slab.h> 88c2ecf20Sopenharmony_ci#include <linux/clk.h> 98c2ecf20Sopenharmony_ci#include <linux/clk-provider.h> 108c2ecf20Sopenharmony_ci#include <linux/io.h> 118c2ecf20Sopenharmony_ci#include <linux/kernel.h> 128c2ecf20Sopenharmony_ci#include "clk.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistruct rockchip_mmc_clock { 158c2ecf20Sopenharmony_ci struct clk_hw hw; 168c2ecf20Sopenharmony_ci void __iomem *reg; 178c2ecf20Sopenharmony_ci int id; 188c2ecf20Sopenharmony_ci int shift; 198c2ecf20Sopenharmony_ci int cached_phase; 208c2ecf20Sopenharmony_ci struct notifier_block clk_rate_change_nb; 218c2ecf20Sopenharmony_ci}; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#define to_mmc_clock(_hw) container_of(_hw, struct rockchip_mmc_clock, hw) 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci#define RK3288_MMC_CLKGEN_DIV 2 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cistatic unsigned long rockchip_mmc_recalc(struct clk_hw *hw, 288c2ecf20Sopenharmony_ci unsigned long parent_rate) 298c2ecf20Sopenharmony_ci{ 308c2ecf20Sopenharmony_ci return parent_rate / RK3288_MMC_CLKGEN_DIV; 318c2ecf20Sopenharmony_ci} 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#define ROCKCHIP_MMC_DELAY_SEL BIT(10) 348c2ecf20Sopenharmony_ci#define ROCKCHIP_MMC_DEGREE_MASK 0x3 358c2ecf20Sopenharmony_ci#define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 368c2ecf20Sopenharmony_ci#define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci#define PSECS_PER_SEC 1000000000000LL 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci/* 418c2ecf20Sopenharmony_ci * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to 428c2ecf20Sopenharmony_ci * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg. 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_ci#define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic int rockchip_mmc_get_phase(struct clk_hw *hw) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw); 498c2ecf20Sopenharmony_ci unsigned long rate = clk_hw_get_rate(hw); 508c2ecf20Sopenharmony_ci u32 raw_value; 518c2ecf20Sopenharmony_ci u16 degrees; 528c2ecf20Sopenharmony_ci u32 delay_num = 0; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci /* Constant signal, no measurable phase shift */ 558c2ecf20Sopenharmony_ci if (!rate) 568c2ecf20Sopenharmony_ci return 0; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift); 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { 638c2ecf20Sopenharmony_ci /* degrees/delaynum * 1000000 */ 648c2ecf20Sopenharmony_ci unsigned long factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 658c2ecf20Sopenharmony_ci 36 * (rate / 10000); 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); 688c2ecf20Sopenharmony_ci delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; 698c2ecf20Sopenharmony_ci degrees += DIV_ROUND_CLOSEST(delay_num * factor, 1000000); 708c2ecf20Sopenharmony_ci } 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci return degrees % 360; 738c2ecf20Sopenharmony_ci} 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_cistatic int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees) 768c2ecf20Sopenharmony_ci{ 778c2ecf20Sopenharmony_ci struct rockchip_mmc_clock *mmc_clock = to_mmc_clock(hw); 788c2ecf20Sopenharmony_ci unsigned long rate = clk_hw_get_rate(hw); 798c2ecf20Sopenharmony_ci u8 nineties, remainder; 808c2ecf20Sopenharmony_ci u8 delay_num; 818c2ecf20Sopenharmony_ci u32 raw_value; 828c2ecf20Sopenharmony_ci u32 delay; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci /* 858c2ecf20Sopenharmony_ci * The below calculation is based on the output clock from 868c2ecf20Sopenharmony_ci * MMC host to the card, which expects the phase clock inherits 878c2ecf20Sopenharmony_ci * the clock rate from its parent, namely the output clock 888c2ecf20Sopenharmony_ci * provider of MMC host. However, things may go wrong if 898c2ecf20Sopenharmony_ci * (1) It is orphan. 908c2ecf20Sopenharmony_ci * (2) It is assigned to the wrong parent. 918c2ecf20Sopenharmony_ci * 928c2ecf20Sopenharmony_ci * This check help debug the case (1), which seems to be the 938c2ecf20Sopenharmony_ci * most likely problem we often face and which makes it difficult 948c2ecf20Sopenharmony_ci * for people to debug unstable mmc tuning results. 958c2ecf20Sopenharmony_ci */ 968c2ecf20Sopenharmony_ci if (!rate) { 978c2ecf20Sopenharmony_ci pr_err("%s: invalid clk rate\n", __func__); 988c2ecf20Sopenharmony_ci return -EINVAL; 998c2ecf20Sopenharmony_ci } 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci nineties = degrees / 90; 1028c2ecf20Sopenharmony_ci remainder = (degrees % 90); 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci /* 1058c2ecf20Sopenharmony_ci * Due to the inexact nature of the "fine" delay, we might 1068c2ecf20Sopenharmony_ci * actually go non-monotonic. We don't go _too_ monotonic 1078c2ecf20Sopenharmony_ci * though, so we should be OK. Here are options of how we may 1088c2ecf20Sopenharmony_ci * work: 1098c2ecf20Sopenharmony_ci * 1108c2ecf20Sopenharmony_ci * Ideally we end up with: 1118c2ecf20Sopenharmony_ci * 1.0, 2.0, ..., 69.0, 70.0, ..., 89.0, 90.0 1128c2ecf20Sopenharmony_ci * 1138c2ecf20Sopenharmony_ci * On one extreme (if delay is actually 44ps): 1148c2ecf20Sopenharmony_ci * .73, 1.5, ..., 50.6, 51.3, ..., 65.3, 90.0 1158c2ecf20Sopenharmony_ci * The other (if delay is actually 77ps): 1168c2ecf20Sopenharmony_ci * 1.3, 2.6, ..., 88.6. 89.8, ..., 114.0, 90 1178c2ecf20Sopenharmony_ci * 1188c2ecf20Sopenharmony_ci * It's possible we might make a delay that is up to 25 1198c2ecf20Sopenharmony_ci * degrees off from what we think we're making. That's OK 1208c2ecf20Sopenharmony_ci * though because we should be REALLY far from any bad range. 1218c2ecf20Sopenharmony_ci */ 1228c2ecf20Sopenharmony_ci 1238c2ecf20Sopenharmony_ci /* 1248c2ecf20Sopenharmony_ci * Convert to delay; do a little extra work to make sure we 1258c2ecf20Sopenharmony_ci * don't overflow 32-bit / 64-bit numbers. 1268c2ecf20Sopenharmony_ci */ 1278c2ecf20Sopenharmony_ci delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ 1288c2ecf20Sopenharmony_ci delay *= remainder; 1298c2ecf20Sopenharmony_ci delay = DIV_ROUND_CLOSEST(delay, 1308c2ecf20Sopenharmony_ci (rate / 1000) * 36 * 1318c2ecf20Sopenharmony_ci (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci delay_num = (u8) min_t(u32, delay, 255); 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; 1368c2ecf20Sopenharmony_ci raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; 1378c2ecf20Sopenharmony_ci raw_value |= nineties; 1388c2ecf20Sopenharmony_ci writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift), 1398c2ecf20Sopenharmony_ci mmc_clock->reg); 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci pr_debug("%s->set_phase(%d) delay_nums=%u reg[0x%p]=0x%03x actual_degrees=%d\n", 1428c2ecf20Sopenharmony_ci clk_hw_get_name(hw), degrees, delay_num, 1438c2ecf20Sopenharmony_ci mmc_clock->reg, raw_value>>(mmc_clock->shift), 1448c2ecf20Sopenharmony_ci rockchip_mmc_get_phase(hw) 1458c2ecf20Sopenharmony_ci ); 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci return 0; 1488c2ecf20Sopenharmony_ci} 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_cistatic const struct clk_ops rockchip_mmc_clk_ops = { 1518c2ecf20Sopenharmony_ci .recalc_rate = rockchip_mmc_recalc, 1528c2ecf20Sopenharmony_ci .get_phase = rockchip_mmc_get_phase, 1538c2ecf20Sopenharmony_ci .set_phase = rockchip_mmc_set_phase, 1548c2ecf20Sopenharmony_ci}; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci#define to_rockchip_mmc_clock(x) \ 1578c2ecf20Sopenharmony_ci container_of(x, struct rockchip_mmc_clock, clk_rate_change_nb) 1588c2ecf20Sopenharmony_cistatic int rockchip_mmc_clk_rate_notify(struct notifier_block *nb, 1598c2ecf20Sopenharmony_ci unsigned long event, void *data) 1608c2ecf20Sopenharmony_ci{ 1618c2ecf20Sopenharmony_ci struct rockchip_mmc_clock *mmc_clock = to_rockchip_mmc_clock(nb); 1628c2ecf20Sopenharmony_ci struct clk_notifier_data *ndata = data; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci /* 1658c2ecf20Sopenharmony_ci * rockchip_mmc_clk is mostly used by mmc controllers to sample 1668c2ecf20Sopenharmony_ci * the intput data, which expects the fixed phase after the tuning 1678c2ecf20Sopenharmony_ci * process. However if the clock rate is changed, the phase is stale 1688c2ecf20Sopenharmony_ci * and may break the data sampling. So here we try to restore the phase 1698c2ecf20Sopenharmony_ci * for that case, except that 1708c2ecf20Sopenharmony_ci * (1) cached_phase is invaild since we inevitably cached it when the 1718c2ecf20Sopenharmony_ci * clock provider be reparented from orphan to its real parent in the 1728c2ecf20Sopenharmony_ci * first place. Otherwise we may mess up the initialization of MMC cards 1738c2ecf20Sopenharmony_ci * since we only set the default sample phase and drive phase later on. 1748c2ecf20Sopenharmony_ci * (2) the new coming rate is higher than the older one since mmc driver 1758c2ecf20Sopenharmony_ci * set the max-frequency to match the boards' ability but we can't go 1768c2ecf20Sopenharmony_ci * over the heads of that, otherwise the tests smoke out the issue. 1778c2ecf20Sopenharmony_ci */ 1788c2ecf20Sopenharmony_ci if (ndata->old_rate <= ndata->new_rate) 1798c2ecf20Sopenharmony_ci return NOTIFY_DONE; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci if (event == PRE_RATE_CHANGE) 1828c2ecf20Sopenharmony_ci mmc_clock->cached_phase = 1838c2ecf20Sopenharmony_ci rockchip_mmc_get_phase(&mmc_clock->hw); 1848c2ecf20Sopenharmony_ci else if (mmc_clock->cached_phase != -EINVAL && 1858c2ecf20Sopenharmony_ci event == POST_RATE_CHANGE) 1868c2ecf20Sopenharmony_ci rockchip_mmc_set_phase(&mmc_clock->hw, mmc_clock->cached_phase); 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_ci return NOTIFY_DONE; 1898c2ecf20Sopenharmony_ci} 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_cistruct clk *rockchip_clk_register_mmc(const char *name, 1928c2ecf20Sopenharmony_ci const char *const *parent_names, u8 num_parents, 1938c2ecf20Sopenharmony_ci void __iomem *reg, int shift) 1948c2ecf20Sopenharmony_ci{ 1958c2ecf20Sopenharmony_ci struct clk_init_data init; 1968c2ecf20Sopenharmony_ci struct rockchip_mmc_clock *mmc_clock; 1978c2ecf20Sopenharmony_ci struct clk *clk; 1988c2ecf20Sopenharmony_ci int ret; 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci mmc_clock = kmalloc(sizeof(*mmc_clock), GFP_KERNEL); 2018c2ecf20Sopenharmony_ci if (!mmc_clock) 2028c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci init.name = name; 2058c2ecf20Sopenharmony_ci init.flags = 0; 2068c2ecf20Sopenharmony_ci init.num_parents = num_parents; 2078c2ecf20Sopenharmony_ci init.parent_names = parent_names; 2088c2ecf20Sopenharmony_ci init.ops = &rockchip_mmc_clk_ops; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci mmc_clock->hw.init = &init; 2118c2ecf20Sopenharmony_ci mmc_clock->reg = reg; 2128c2ecf20Sopenharmony_ci mmc_clock->shift = shift; 2138c2ecf20Sopenharmony_ci 2148c2ecf20Sopenharmony_ci clk = clk_register(NULL, &mmc_clock->hw); 2158c2ecf20Sopenharmony_ci if (IS_ERR(clk)) { 2168c2ecf20Sopenharmony_ci ret = PTR_ERR(clk); 2178c2ecf20Sopenharmony_ci goto err_register; 2188c2ecf20Sopenharmony_ci } 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci mmc_clock->clk_rate_change_nb.notifier_call = 2218c2ecf20Sopenharmony_ci &rockchip_mmc_clk_rate_notify; 2228c2ecf20Sopenharmony_ci ret = clk_notifier_register(clk, &mmc_clock->clk_rate_change_nb); 2238c2ecf20Sopenharmony_ci if (ret) 2248c2ecf20Sopenharmony_ci goto err_notifier; 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci return clk; 2278c2ecf20Sopenharmony_cierr_notifier: 2288c2ecf20Sopenharmony_ci clk_unregister(clk); 2298c2ecf20Sopenharmony_cierr_register: 2308c2ecf20Sopenharmony_ci kfree(mmc_clock); 2318c2ecf20Sopenharmony_ci return ERR_PTR(ret); 2328c2ecf20Sopenharmony_ci} 233