18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci *  linux/arch/arm/mach-omap2/clock.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci *  Copyright (C) 2005-2008 Texas Instruments, Inc.
68c2ecf20Sopenharmony_ci *  Copyright (C) 2004-2010 Nokia Corporation
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci *  Contacts:
98c2ecf20Sopenharmony_ci *  Richard Woodruff <r-woodruff2@ti.com>
108c2ecf20Sopenharmony_ci *  Paul Walmsley
118c2ecf20Sopenharmony_ci */
128c2ecf20Sopenharmony_ci#undef DEBUG
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <linux/kernel.h>
158c2ecf20Sopenharmony_ci#include <linux/export.h>
168c2ecf20Sopenharmony_ci#include <linux/list.h>
178c2ecf20Sopenharmony_ci#include <linux/errno.h>
188c2ecf20Sopenharmony_ci#include <linux/err.h>
198c2ecf20Sopenharmony_ci#include <linux/delay.h>
208c2ecf20Sopenharmony_ci#include <linux/clk.h>
218c2ecf20Sopenharmony_ci#include <linux/clk-provider.h>
228c2ecf20Sopenharmony_ci#include <linux/io.h>
238c2ecf20Sopenharmony_ci#include <linux/bitops.h>
248c2ecf20Sopenharmony_ci#include <linux/of_address.h>
258c2ecf20Sopenharmony_ci#include <asm/cpu.h>
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#include <trace/events/power.h>
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#include "soc.h"
308c2ecf20Sopenharmony_ci#include "clockdomain.h"
318c2ecf20Sopenharmony_ci#include "clock.h"
328c2ecf20Sopenharmony_ci#include "cm.h"
338c2ecf20Sopenharmony_ci#include "cm2xxx.h"
348c2ecf20Sopenharmony_ci#include "cm3xxx.h"
358c2ecf20Sopenharmony_ci#include "cm-regbits-24xx.h"
368c2ecf20Sopenharmony_ci#include "cm-regbits-34xx.h"
378c2ecf20Sopenharmony_ci#include "common.h"
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ciu16 cpu_mask;
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci/* DPLL valid Fint frequency band limits - from 34xx TRM Section 4.7.6.2 */
428c2ecf20Sopenharmony_ci#define OMAP3430_DPLL_FINT_BAND1_MIN	750000
438c2ecf20Sopenharmony_ci#define OMAP3430_DPLL_FINT_BAND1_MAX	2100000
448c2ecf20Sopenharmony_ci#define OMAP3430_DPLL_FINT_BAND2_MIN	7500000
458c2ecf20Sopenharmony_ci#define OMAP3430_DPLL_FINT_BAND2_MAX	21000000
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci/*
488c2ecf20Sopenharmony_ci * DPLL valid Fint frequency range for OMAP36xx and OMAP4xxx.
498c2ecf20Sopenharmony_ci * From device data manual section 4.3 "DPLL and DLL Specifications".
508c2ecf20Sopenharmony_ci */
518c2ecf20Sopenharmony_ci#define OMAP3PLUS_DPLL_FINT_MIN		32000
528c2ecf20Sopenharmony_ci#define OMAP3PLUS_DPLL_FINT_MAX		52000000
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_cistruct ti_clk_ll_ops omap_clk_ll_ops = {
558c2ecf20Sopenharmony_ci	.clkdm_clk_enable = clkdm_clk_enable,
568c2ecf20Sopenharmony_ci	.clkdm_clk_disable = clkdm_clk_disable,
578c2ecf20Sopenharmony_ci	.clkdm_lookup = clkdm_lookup,
588c2ecf20Sopenharmony_ci	.cm_wait_module_ready = omap_cm_wait_module_ready,
598c2ecf20Sopenharmony_ci	.cm_split_idlest_reg = cm_split_idlest_reg,
608c2ecf20Sopenharmony_ci};
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci/**
638c2ecf20Sopenharmony_ci * omap2_clk_setup_ll_ops - setup clock driver low-level ops
648c2ecf20Sopenharmony_ci *
658c2ecf20Sopenharmony_ci * Sets up clock driver low-level platform ops. These are needed
668c2ecf20Sopenharmony_ci * for register accesses and various other misc platform operations.
678c2ecf20Sopenharmony_ci * Returns 0 on success, -EBUSY if low level ops have been registered
688c2ecf20Sopenharmony_ci * already.
698c2ecf20Sopenharmony_ci */
708c2ecf20Sopenharmony_ciint __init omap2_clk_setup_ll_ops(void)
718c2ecf20Sopenharmony_ci{
728c2ecf20Sopenharmony_ci	return ti_clk_setup_ll_ops(&omap_clk_ll_ops);
738c2ecf20Sopenharmony_ci}
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci/*
768c2ecf20Sopenharmony_ci * OMAP2+ specific clock functions
778c2ecf20Sopenharmony_ci */
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ci/**
808c2ecf20Sopenharmony_ci * ti_clk_init_features - init clock features struct for the SoC
818c2ecf20Sopenharmony_ci *
828c2ecf20Sopenharmony_ci * Initializes the clock features struct based on the SoC type.
838c2ecf20Sopenharmony_ci */
848c2ecf20Sopenharmony_civoid __init ti_clk_init_features(void)
858c2ecf20Sopenharmony_ci{
868c2ecf20Sopenharmony_ci	struct ti_clk_features features = { 0 };
878c2ecf20Sopenharmony_ci	/* Fint setup for DPLLs */
888c2ecf20Sopenharmony_ci	if (cpu_is_omap3430()) {
898c2ecf20Sopenharmony_ci		features.fint_min = OMAP3430_DPLL_FINT_BAND1_MIN;
908c2ecf20Sopenharmony_ci		features.fint_max = OMAP3430_DPLL_FINT_BAND2_MAX;
918c2ecf20Sopenharmony_ci		features.fint_band1_max = OMAP3430_DPLL_FINT_BAND1_MAX;
928c2ecf20Sopenharmony_ci		features.fint_band2_min = OMAP3430_DPLL_FINT_BAND2_MIN;
938c2ecf20Sopenharmony_ci	} else {
948c2ecf20Sopenharmony_ci		features.fint_min = OMAP3PLUS_DPLL_FINT_MIN;
958c2ecf20Sopenharmony_ci		features.fint_max = OMAP3PLUS_DPLL_FINT_MAX;
968c2ecf20Sopenharmony_ci	}
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	/* Bypass value setup for DPLLs */
998c2ecf20Sopenharmony_ci	if (cpu_is_omap24xx()) {
1008c2ecf20Sopenharmony_ci		features.dpll_bypass_vals |=
1018c2ecf20Sopenharmony_ci			(1 << OMAP2XXX_EN_DPLL_LPBYPASS) |
1028c2ecf20Sopenharmony_ci			(1 << OMAP2XXX_EN_DPLL_FRBYPASS);
1038c2ecf20Sopenharmony_ci	} else if (cpu_is_omap34xx()) {
1048c2ecf20Sopenharmony_ci		features.dpll_bypass_vals |=
1058c2ecf20Sopenharmony_ci			(1 << OMAP3XXX_EN_DPLL_LPBYPASS) |
1068c2ecf20Sopenharmony_ci			(1 << OMAP3XXX_EN_DPLL_FRBYPASS);
1078c2ecf20Sopenharmony_ci	} else if (soc_is_am33xx() || cpu_is_omap44xx() || soc_is_am43xx() ||
1088c2ecf20Sopenharmony_ci		   soc_is_omap54xx() || soc_is_dra7xx()) {
1098c2ecf20Sopenharmony_ci		features.dpll_bypass_vals |=
1108c2ecf20Sopenharmony_ci			(1 << OMAP4XXX_EN_DPLL_LPBYPASS) |
1118c2ecf20Sopenharmony_ci			(1 << OMAP4XXX_EN_DPLL_FRBYPASS) |
1128c2ecf20Sopenharmony_ci			(1 << OMAP4XXX_EN_DPLL_MNBYPASS);
1138c2ecf20Sopenharmony_ci	}
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	/* Jitter correction only available on OMAP343X */
1168c2ecf20Sopenharmony_ci	if (cpu_is_omap343x())
1178c2ecf20Sopenharmony_ci		features.flags |= TI_CLK_DPLL_HAS_FREQSEL;
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	if (omap_type() == OMAP2_DEVICE_TYPE_GP)
1208c2ecf20Sopenharmony_ci		features.flags |= TI_CLK_DEVICE_TYPE_GP;
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci	/* Idlest value for interface clocks.
1238c2ecf20Sopenharmony_ci	 * 24xx uses 0 to indicate not ready, and 1 to indicate ready.
1248c2ecf20Sopenharmony_ci	 * 34xx reverses this, just to keep us on our toes
1258c2ecf20Sopenharmony_ci	 * AM35xx uses both, depending on the module.
1268c2ecf20Sopenharmony_ci	 */
1278c2ecf20Sopenharmony_ci	if (cpu_is_omap24xx())
1288c2ecf20Sopenharmony_ci		features.cm_idlest_val = OMAP24XX_CM_IDLEST_VAL;
1298c2ecf20Sopenharmony_ci	else if (cpu_is_omap34xx())
1308c2ecf20Sopenharmony_ci		features.cm_idlest_val = OMAP34XX_CM_IDLEST_VAL;
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci	/* On OMAP3430 ES1.0, DPLL4 can't be re-programmed */
1338c2ecf20Sopenharmony_ci	if (omap_rev() == OMAP3430_REV_ES1_0)
1348c2ecf20Sopenharmony_ci		features.flags |= TI_CLK_DPLL4_DENY_REPROGRAM;
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci	/* Errata I810 for omap5 / dra7 */
1378c2ecf20Sopenharmony_ci	if (soc_is_omap54xx() || soc_is_dra7xx())
1388c2ecf20Sopenharmony_ci		features.flags |= TI_CLK_ERRATA_I810;
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	ti_clk_setup_features(&features);
1418c2ecf20Sopenharmony_ci}
142