clk: tegra: Changes for v4.18-rc1
Contains a proper implementation of the CDEV1/2 clocks on Tegra20. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEiOrDCAFJzPfAjcif3SOs138+s6EFAlr+4IcTHHRyZWRpbmdA bnZpZGlhLmNvbQAKCRDdI6zXfz6zoQzFD/9DHQQoF4bnRiYysWBUrM7aQrj8J8oe FsFmCcNzusD0qoodUqr1Y+IiIy+DLL1LObG6ofjsUh78kRQbiFY4AlovSqkf4FLj G5Oi98CZm1BcJ0EyX5P4eDPsznCtvOtnPLf7LmFwYklme50B9FiUlbHrGgWHMJHZ yNqRZkJ7hqAH1MXb+N7zbs1xhnbIq4wDKHpTtN/mnhmsOtSaPERksXXa09t7Fkry hp9X6Uo7tzAKH5Tnxh4eisfCahrDg1WfA00ChJhWEYdAd6aJWT9jCRBCtDz7oNxW 1+V9r3jS/m1/zDM2sMIWANubSGoeTfQRbJyNzEzyxPKvyrsifcKtH6Matfvjc2Eq 7cvvRalLJMaT5p0J/Aj2YIqA/sGovqaGRseCAGD09wGk5lRu83Bw/aXAjpWKFWgs cm68XE3H+gSgpCrO0O1/CiimRlBfsMGAC9ju8dFEJjt630/FHIOsFL89+s3aenBG m0f+Xm6N04nx01eb7NCSn7/Qyl073oT1GZhWD+u0BqWj4ignRJev9NeAA0Li3zIc 3IcoYIPdkPeZKxy+i5CPNWePTH/qPezvEswx4dnPxdL28XrL+ai2QcxuRxcmodBf XRVAZKPJaWODBZSJ45nmBH9udxIAYtokcvzMgCwNwYWLonM4lGS+BQ3eu9QSXJyY /iBAdDNWryrjBA== =hrV+ -----END PGP SIGNATURE----- Merge tag 'tegra-for-4.18-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into clk-tegra Pull Tegra clk driver updates from Thierry Reding: - proper implementation of the CDEV1/2 clocks on Tegra20 * tag 'tegra-for-4.18-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: clk: tegra: Add quirk for getting CDEV1/2 clocks on Tegra20 clk: tegra20: Correct parents of CDEV1/2 clocks clk: tegra20: Add DEV1/DEV2 OSC dividers
This commit is contained in:
commit
70b7e55a19
|
@ -1367,7 +1367,7 @@ static void __init tegra114_clock_init(struct device_node *np)
|
|||
tegra_super_clk_gen4_init(clk_base, pmc_base, tegra114_clks,
|
||||
&pll_x_params);
|
||||
|
||||
tegra_add_of_provider(np);
|
||||
tegra_add_of_provider(np, of_clk_src_onecell_get);
|
||||
tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
|
||||
|
||||
tegra_clk_apply_init_table = tegra114_clock_apply_init_table;
|
||||
|
|
|
@ -1479,7 +1479,7 @@ static void __init tegra124_132_clock_init_post(struct device_node *np)
|
|||
&pll_x_params);
|
||||
tegra_init_special_resets(1, tegra124_reset_assert,
|
||||
tegra124_reset_deassert);
|
||||
tegra_add_of_provider(np);
|
||||
tegra_add_of_provider(np, of_clk_src_onecell_get);
|
||||
|
||||
clks[TEGRA124_CLK_EMC] = tegra_clk_register_emc(clk_base, np,
|
||||
&emc_lock);
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
#include "clk.h"
|
||||
#include "clk-id.h"
|
||||
|
||||
#define MISC_CLK_ENB 0x48
|
||||
|
||||
#define OSC_CTRL 0x50
|
||||
#define OSC_CTRL_OSC_FREQ_MASK (3<<30)
|
||||
#define OSC_CTRL_OSC_FREQ_13MHZ (0<<30)
|
||||
|
@ -831,15 +833,25 @@ static void __init tegra20_periph_clk_init(void)
|
|||
periph_clk_enb_refcnt);
|
||||
clks[TEGRA20_CLK_PEX] = clk;
|
||||
|
||||
/* dev1 OSC divider */
|
||||
clk_register_divider(NULL, "dev1_osc_div", "clk_m",
|
||||
0, clk_base + MISC_CLK_ENB, 22, 2,
|
||||
CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_READ_ONLY,
|
||||
NULL);
|
||||
|
||||
/* dev2 OSC divider */
|
||||
clk_register_divider(NULL, "dev2_osc_div", "clk_m",
|
||||
0, clk_base + MISC_CLK_ENB, 20, 2,
|
||||
CLK_DIVIDER_POWER_OF_TWO | CLK_DIVIDER_READ_ONLY,
|
||||
NULL);
|
||||
|
||||
/* cdev1 */
|
||||
clk = clk_register_fixed_rate(NULL, "cdev1_fixed", NULL, 0, 26000000);
|
||||
clk = tegra_clk_register_periph_gate("cdev1", "cdev1_fixed", 0,
|
||||
clk = tegra_clk_register_periph_gate("cdev1", "cdev1_mux", 0,
|
||||
clk_base, 0, 94, periph_clk_enb_refcnt);
|
||||
clks[TEGRA20_CLK_CDEV1] = clk;
|
||||
|
||||
/* cdev2 */
|
||||
clk = clk_register_fixed_rate(NULL, "cdev2_fixed", NULL, 0, 26000000);
|
||||
clk = tegra_clk_register_periph_gate("cdev2", "cdev2_fixed", 0,
|
||||
clk = tegra_clk_register_periph_gate("cdev2", "cdev2_mux", 0,
|
||||
clk_base, 0, 93, periph_clk_enb_refcnt);
|
||||
clks[TEGRA20_CLK_CDEV2] = clk;
|
||||
|
||||
|
@ -1077,6 +1089,36 @@ static const struct of_device_id pmc_match[] __initconst = {
|
|||
{ },
|
||||
};
|
||||
|
||||
static struct clk *tegra20_clk_src_onecell_get(struct of_phandle_args *clkspec,
|
||||
void *data)
|
||||
{
|
||||
struct clk_hw *parent_hw;
|
||||
struct clk_hw *hw;
|
||||
struct clk *clk;
|
||||
|
||||
clk = of_clk_src_onecell_get(clkspec, data);
|
||||
if (IS_ERR(clk))
|
||||
return clk;
|
||||
|
||||
/*
|
||||
* Tegra20 CDEV1 and CDEV2 clocks are a bit special case, their parent
|
||||
* clock is created by the pinctrl driver. It is possible for clk user
|
||||
* to request these clocks before pinctrl driver got probed and hence
|
||||
* user will get an orphaned clock. That might be undesirable because
|
||||
* user may expect parent clock to be enabled by the child.
|
||||
*/
|
||||
if (clkspec->args[0] == TEGRA20_CLK_CDEV1 ||
|
||||
clkspec->args[0] == TEGRA20_CLK_CDEV2) {
|
||||
hw = __clk_get_hw(clk);
|
||||
|
||||
parent_hw = clk_hw_get_parent(hw);
|
||||
if (!parent_hw)
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
}
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
static void __init tegra20_clock_init(struct device_node *np)
|
||||
{
|
||||
struct device_node *node;
|
||||
|
@ -1115,7 +1157,7 @@ static void __init tegra20_clock_init(struct device_node *np)
|
|||
|
||||
tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA20_CLK_CLK_MAX);
|
||||
|
||||
tegra_add_of_provider(np);
|
||||
tegra_add_of_provider(np, tegra20_clk_src_onecell_get);
|
||||
tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
|
||||
|
||||
tegra_clk_apply_init_table = tegra20_clock_apply_init_table;
|
||||
|
|
|
@ -3567,7 +3567,7 @@ static void __init tegra210_clock_init(struct device_node *np)
|
|||
tegra_init_special_resets(2, tegra210_reset_assert,
|
||||
tegra210_reset_deassert);
|
||||
|
||||
tegra_add_of_provider(np);
|
||||
tegra_add_of_provider(np, of_clk_src_onecell_get);
|
||||
tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
|
||||
|
||||
tegra210_mbist_clk_init();
|
||||
|
|
|
@ -1349,7 +1349,7 @@ static void __init tegra30_clock_init(struct device_node *np)
|
|||
|
||||
tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX);
|
||||
|
||||
tegra_add_of_provider(np);
|
||||
tegra_add_of_provider(np, of_clk_src_onecell_get);
|
||||
tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
|
||||
|
||||
tegra_clk_apply_init_table = tegra30_clock_apply_init_table;
|
||||
|
|
|
@ -298,7 +298,8 @@ static struct reset_controller_dev rst_ctlr = {
|
|||
.of_reset_n_cells = 1,
|
||||
};
|
||||
|
||||
void __init tegra_add_of_provider(struct device_node *np)
|
||||
void __init tegra_add_of_provider(struct device_node *np,
|
||||
void *clk_src_onecell_get)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -314,7 +315,7 @@ void __init tegra_add_of_provider(struct device_node *np)
|
|||
|
||||
clk_data.clks = clks;
|
||||
clk_data.clk_num = clk_num;
|
||||
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||
of_clk_add_provider(np, clk_src_onecell_get, &clk_data);
|
||||
|
||||
rst_ctlr.of_node = np;
|
||||
rst_ctlr.nr_resets = periph_banks * 32 + num_special_reset;
|
||||
|
|
|
@ -763,7 +763,7 @@ struct clk **tegra_clk_init(void __iomem *clk_base, int num, int periph_banks);
|
|||
|
||||
struct clk **tegra_lookup_dt_id(int clk_id, struct tegra_clk *tegra_clk);
|
||||
|
||||
void tegra_add_of_provider(struct device_node *np);
|
||||
void tegra_add_of_provider(struct device_node *np, void *clk_src_onecell_get);
|
||||
void tegra_register_devclks(struct tegra_devclk *dev_clks, int num);
|
||||
|
||||
void tegra_audio_clk_init(void __iomem *clk_base,
|
||||
|
|
Loading…
Reference in New Issue