Commit 16320d7f authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'tegra-for-5.13-clk' of...

Merge tag 'tegra-for-5.13-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into arm/drivers

clk: tegra: Changes for v5.13-rc1

This adds PLLE HW sequencer support which is necessary for USB sleepwalk
functionality.

* tag 'tegra-for-5.13-clk' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux:
  clk: tegra: Don't enable PLLE HW sequencer at init
  clk: tegra: Add PLLE HW power sequencer control

Link: https://lore.kernel.org/r/20210401172622.3352990-2-thierry.reding@gmail.com


Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 62c93360 0c7ea2b1
Loading
Loading
Loading
Loading
+0 −12
Original line number Diff line number Diff line
@@ -2515,18 +2515,6 @@ static int clk_plle_tegra210_enable(struct clk_hw *hw)
	pll_writel(val, PLLE_SS_CTRL, pll);
	udelay(1);

	val = pll_readl_misc(pll);
	val &= ~PLLE_MISC_IDDQ_SW_CTRL;
	pll_writel_misc(val, pll);

	val = pll_readl(pll->params->aux_reg, pll);
	val |= (PLLE_AUX_USE_LOCKDET | PLLE_AUX_SS_SEQ_INCLUDE);
	val &= ~(PLLE_AUX_ENABLE_SWCTL | PLLE_AUX_SS_SWCTL);
	pll_writel(val, pll->params->aux_reg, pll);
	udelay(1);
	val |= PLLE_AUX_SEQ_ENABLE;
	pll_writel(val, pll->params->aux_reg, pll);

out:
	if (pll->lock)
		spin_unlock_irqrestore(pll->lock, flags);
+52 −1
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2012-2014 NVIDIA CORPORATION.  All rights reserved.
 * Copyright (c) 2012-2020 NVIDIA CORPORATION.  All rights reserved.
 */

#include <linux/io.h>
@@ -403,6 +403,14 @@ static unsigned long tegra210_input_freq[] = {
#define PLLRE_BASE_DEFAULT_MASK		0x1c000000
#define PLLRE_MISC0_WRITE_MASK		0x67ffffff

/* PLLE */
#define PLLE_MISC_IDDQ_SW_CTRL		(1 << 14)
#define PLLE_AUX_USE_LOCKDET		(1 << 3)
#define PLLE_AUX_SS_SEQ_INCLUDE		(1 << 31)
#define PLLE_AUX_ENABLE_SWCTL		(1 << 4)
#define PLLE_AUX_SS_SWCTL		(1 << 6)
#define PLLE_AUX_SEQ_ENABLE		(1 << 24)

/* PLLX */
#define PLLX_USE_DYN_RAMP		1
#define PLLX_BASE_LOCK			(1 << 27)
@@ -489,6 +497,49 @@ static unsigned long tegra210_input_freq[] = {
#define PLLU_MISC0_WRITE_MASK		0xbfffffff
#define PLLU_MISC1_WRITE_MASK		0x00000007

bool tegra210_plle_hw_sequence_is_enabled(void)
{
	u32 value;

	value = readl_relaxed(clk_base + PLLE_AUX);
	if (value & PLLE_AUX_SEQ_ENABLE)
		return true;

	return false;
}
EXPORT_SYMBOL_GPL(tegra210_plle_hw_sequence_is_enabled);

int tegra210_plle_hw_sequence_start(void)
{
	u32 value;

	if (tegra210_plle_hw_sequence_is_enabled())
		return 0;

	/* skip if PLLE is not enabled yet */
	value = readl_relaxed(clk_base + PLLE_MISC0);
	if (!(value & PLLE_MISC_LOCK))
		return -EIO;

	value &= ~PLLE_MISC_IDDQ_SW_CTRL;
	writel_relaxed(value, clk_base + PLLE_MISC0);

	value = readl_relaxed(clk_base + PLLE_AUX);
	value |= (PLLE_AUX_USE_LOCKDET | PLLE_AUX_SS_SEQ_INCLUDE);
	value &= ~(PLLE_AUX_ENABLE_SWCTL | PLLE_AUX_SS_SWCTL);
	writel_relaxed(value, clk_base + PLLE_AUX);

	fence_udelay(1, clk_base);

	value |= PLLE_AUX_SEQ_ENABLE;
	writel_relaxed(value, clk_base + PLLE_AUX);

	fence_udelay(1, clk_base);

	return 0;
}
EXPORT_SYMBOL_GPL(tegra210_plle_hw_sequence_start);

void tegra210_xusb_pll_hw_control_enable(void)
{
	u32 val;
+3 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
 * Copyright (c) 2012-2020, NVIDIA CORPORATION.  All rights reserved.
 */

#ifndef __LINUX_CLK_TEGRA_H_
@@ -123,6 +123,8 @@ static inline void tegra_cpu_clock_resume(void)
}
#endif

extern int tegra210_plle_hw_sequence_start(void);
extern bool tegra210_plle_hw_sequence_is_enabled(void);
extern void tegra210_xusb_pll_hw_control_enable(void);
extern void tegra210_xusb_pll_hw_sequence_start(void);
extern void tegra210_sata_pll_hw_control_enable(void);