Add pr_info-level logging across the SDHCI subsystem and the Tegra
SDMMC clock providers so clock rate calculation, rounding, assigned
clocks and parents are visible in dmesg without needing dynamic_debug.
- sdhci-tegra: log curr_clk_rate/max_clk/clock on set_clock entry and
after clk_get_rate(), the requested host_clk, the rounded
get_max_clock value, and dump regs before hw tuning.
- sdhci: promote the DBG() macro from pr_debug to pr_info and log
host->clock/max_clk/clock plus the computed divider/actual clock
in sdhci_calc_clk() and sdhci_set_clock().
- clk-sdmmc-mux / clk-divider / clk-utils: log div, mul, parent_rate,
rounded rate and recalc_rate results in round_rate/recalc_rate/
set_rate/div_frac_get so the full rate decision path is traceable.
- mmc core: log the requested speed in mmc_set_clock() and the
tuning entry/host-exec points in mmc_execute_tuning().
Change-Id: I4d569a01da8355db3319e82de942f1401dfac911
49 lines
996 B
C
49 lines
996 B
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
|
|
*/
|
|
|
|
#include <asm/div64.h>
|
|
|
|
#include "clk.h"
|
|
|
|
#define DRIVER_NAME "sdhci"
|
|
|
|
#define div_mask(w) ((1 << (w)) - 1)
|
|
|
|
int div_frac_get(unsigned long rate, unsigned parent_rate, u8 width,
|
|
u8 frac_width, u8 flags)
|
|
{
|
|
s64 divider_ux1 = parent_rate;
|
|
int mul;
|
|
|
|
if (!rate)
|
|
return div_mask(width);
|
|
|
|
mul = 1 << frac_width;
|
|
|
|
if (!(flags & TEGRA_DIVIDER_INT))
|
|
divider_ux1 *= mul;
|
|
|
|
if (flags & TEGRA_DIVIDER_ROUND_UP)
|
|
divider_ux1 += rate - 1;
|
|
|
|
do_div(divider_ux1, rate);
|
|
|
|
if (flags & TEGRA_DIVIDER_INT)
|
|
divider_ux1 *= mul;
|
|
|
|
divider_ux1 -= mul;
|
|
|
|
if (divider_ux1 > div_mask(width))
|
|
return div_mask(width);
|
|
|
|
if (div1_5_not_allowed && (divider_ux1 > 0) && (divider_ux1 < mul))
|
|
divider_ux1 = (flags & TEGRA_DIVIDER_ROUND_UP) ? mul : 0;
|
|
|
|
pr_info("(" DRIVER_NAME ") div_frac_get: rate=%lu parent_rate=%u div=%lld mul=%d\n",
|
|
rate, parent_rate, divider_ux1, mul);
|
|
|
|
return divider_ux1;
|
|
}
|