Commit 097064b8 authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge tag 'tegra-for-5.5-clk-v2' of...

Merge tag 'tegra-for-5.5-clk-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into clk-tegra

Pull Tegra clk driver updates from Thierry Reding:

The bulk of these changes implement suspend/resume support for Tegra210.
In addition, some of the SOR clocks on earlier Tegra generations are
reimplemented to more closely match the implementation on later chips,
which in turn makes it possible to handle HDMI and DP support in a more
unified way.

* tag 'tegra-for-5.5-clk-v2' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: (21 commits)
  clk: tegra: Fix build error without CONFIG_PM_SLEEP
  clk: tegra: Add missing stubs for the case of !CONFIG_PM_SLEEP
  clk: tegra: Optimize PLLX restore on Tegra20/30
  clk: tegra: Add suspend and resume support on Tegra210
  clk: tegra: Share clk and rst register defines with Tegra clock driver
  clk: tegra: Use fence_udelay() during PLLU init
  clk: tegra: clk-dfll: Add suspend and resume support
  clk: tegra: clk-super: Add restore-context support
  clk: tegra: clk-super: Fix to enable PLLP branches to CPU
  clk: tegra: periph: Add restore_context support
  clk: tegra: Support for OSC context save and restore
  clk: tegra: pll: Save and restore pll context
  clk: tegra: pllout: Save and restore pllout context
  clk: tegra: divider: Save and restore divider rate
  clk: tegra: Reimplement SOR clocks on Tegra210
  clk: tegra: Reimplement SOR clock on Tegra124
  clk: tegra: Rename sor0_lvds to sor0_out
  clk: tegra: Move SOR0 implementation to Tegra124
  clk: tegra: Remove last remains of TEGRA210_CLK_SOR1_SRC
  clk: tegra: Add Tegra20/30 EMC clock implementation
  ...
parents 55ae8a11 07b293c5
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -17,7 +17,9 @@ obj-y += clk-tegra-fixed.o
obj-y					+= clk-tegra-super-gen4.o
obj-$(CONFIG_TEGRA_CLK_EMC)		+= clk-emc.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC)         += clk-tegra20.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC)		+= clk-tegra20-emc.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC)         += clk-tegra30.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC)		+= clk-tegra20-emc.o
obj-$(CONFIG_ARCH_TEGRA_114_SOC)	+= clk-tegra114.o
obj-$(CONFIG_ARCH_TEGRA_124_SOC)	+= clk-tegra124.o
obj-$(CONFIG_TEGRA_CLK_DFLL)		+= clk-tegra124-dfll-fcpu.o
+56 −0
Original line number Diff line number Diff line
@@ -1487,6 +1487,7 @@ static int dfll_init(struct tegra_dfll *td)
	td->last_unrounded_rate = 0;

	pm_runtime_enable(td->dev);
	pm_runtime_irq_safe(td->dev);
	pm_runtime_get_sync(td->dev);

	dfll_set_mode(td, DFLL_DISABLED);
@@ -1513,6 +1514,61 @@ static int dfll_init(struct tegra_dfll *td)
	return ret;
}

/**
 * tegra_dfll_suspend - check DFLL is disabled
 * @dev: DFLL device *
 *
 * DFLL clock should be disabled by the CPUFreq driver. So, make
 * sure it is disabled and disable all clocks needed by the DFLL.
 */
int tegra_dfll_suspend(struct device *dev)
{
	struct tegra_dfll *td = dev_get_drvdata(dev);

	if (dfll_is_running(td)) {
		dev_err(td->dev, "DFLL still enabled while suspending\n");
		return -EBUSY;
	}

	reset_control_assert(td->dvco_rst);

	return 0;
}
EXPORT_SYMBOL(tegra_dfll_suspend);

/**
 * tegra_dfll_resume - reinitialize DFLL on resume
 * @dev: DFLL instance
 *
 * DFLL is disabled and reset during suspend and resume.
 * So, reinitialize the DFLL IP block back for use.
 * DFLL clock is enabled later in closed loop mode by CPUFreq
 * driver before switching its clock source to DFLL output.
 */
int tegra_dfll_resume(struct device *dev)
{
	struct tegra_dfll *td = dev_get_drvdata(dev);

	reset_control_deassert(td->dvco_rst);

	pm_runtime_get_sync(td->dev);

	dfll_set_mode(td, DFLL_DISABLED);
	dfll_set_default_params(td);

	if (td->soc->init_clock_trimmers)
		td->soc->init_clock_trimmers();

	dfll_set_open_loop_config(td);

	dfll_init_out_if(td);

	pm_runtime_put_sync(td->dev);

	return 0;
}
EXPORT_SYMBOL(tegra_dfll_resume);

/*
 * DT data fetch
 */
+2 −0
Original line number Diff line number Diff line
@@ -42,5 +42,7 @@ int tegra_dfll_register(struct platform_device *pdev,
struct tegra_dfll_soc_data *tegra_dfll_unregister(struct platform_device *pdev);
int tegra_dfll_runtime_suspend(struct device *dev);
int tegra_dfll_runtime_resume(struct device *dev);
int tegra_dfll_suspend(struct device *dev);
int tegra_dfll_resume(struct device *dev);

#endif /* __DRIVERS_CLK_TEGRA_CLK_DFLL_H */
+11 −0
Original line number Diff line number Diff line
@@ -109,10 +109,21 @@ static int clk_frac_div_set_rate(struct clk_hw *hw, unsigned long rate,
	return 0;
}

static void clk_divider_restore_context(struct clk_hw *hw)
{
	struct clk_hw *parent = clk_hw_get_parent(hw);
	unsigned long parent_rate = clk_hw_get_rate(parent);
	unsigned long rate = clk_hw_get_rate(hw);

	if (clk_frac_div_set_rate(hw, rate, parent_rate) < 0)
		WARN_ON(1);
}

const struct clk_ops tegra_clk_frac_div_ops = {
	.recalc_rate = clk_frac_div_recalc_rate,
	.set_rate = clk_frac_div_set_rate,
	.round_rate = clk_frac_div_round_rate,
	.restore_context = clk_divider_restore_context,
};

struct clk *tegra_clk_register_divider(const char *name,
+2 −2
Original line number Diff line number Diff line
@@ -236,9 +236,9 @@ enum clk_id {
	tegra_clk_soc_therm,
	tegra_clk_soc_therm_8,
	tegra_clk_sor0,
	tegra_clk_sor0_lvds,
	tegra_clk_sor0_out,
	tegra_clk_sor1,
	tegra_clk_sor1_src,
	tegra_clk_sor1_out,
	tegra_clk_spdif,
	tegra_clk_spdif_2x,
	tegra_clk_spdif_in,
Loading