/* SPDX-License-Identifier: GPL-2.0+ */
/*
 * clock.h
 *
 * clock header
 *
 * Copyright (C) 2011, Texas Instruments Incorporated - https://www.ti.com/
 */

#ifndef _CLOCKS_H_
#define _CLOCKS_H_

#include <asm/arch/clocks_am33xx.h>
#include <asm/arch/hardware.h>
#include <asm/ti-common/omap_clock.h>

#define LDELAY 1000000

/* CM_CLKMODE_DPLL */
#define CM_CLKMODE_DPLL_SSC_EN_SHIFT		12
#define CM_CLKMODE_DPLL_SSC_EN_MASK		(1 << 12)
#define CM_CLKMODE_DPLL_SSC_ACK_MASK		(1 << 13)
#define CM_CLKMODE_DPLL_SSC_DOWNSPREAD_MASK	(1 << 14)
#define CM_CLKMODE_DPLL_SSC_TYPE_MASK		(1 << 15)
#define CM_CLKMODE_DPLL_REGM4XEN_SHIFT		11
#define CM_CLKMODE_DPLL_REGM4XEN_MASK		(1 << 11)
#define CM_CLKMODE_DPLL_LPMODE_EN_SHIFT		10
#define CM_CLKMODE_DPLL_LPMODE_EN_MASK		(1 << 10)
#define CM_CLKMODE_DPLL_RELOCK_RAMP_EN_SHIFT	9
#define CM_CLKMODE_DPLL_RELOCK_RAMP_EN_MASK	(1 << 9)
#define CM_CLKMODE_DPLL_DRIFTGUARD_EN_SHIFT	8
#define CM_CLKMODE_DPLL_DRIFTGUARD_EN_MASK	(1 << 8)
#define CM_CLKMODE_DPLL_RAMP_RATE_SHIFT		5
#define CM_CLKMODE_DPLL_RAMP_RATE_MASK		(0x7 << 5)

/* CM_SSC_DELTAM_DPLL */
#define CM_SSC_DELTAM_DPLL_FRAC_SHIFT		0
#define CM_SSC_DELTAM_DPLL_FRAC_MASK		GENMASK(17, 0)
#define CM_SSC_DELTAM_DPLL_INT_SHIFT		18
#define CM_SSC_DELTAM_DPLL_INT_MASK		GENMASK(19, 18)

/* CM_SSC_MODFREQ_DPLL */
#define CM_SSC_MODFREQ_DPLL_MANT_SHIFT		0
#define CM_SSC_MODFREQ_DPLL_MANT_MASK		GENMASK(6, 0)
#define CM_SSC_MODFREQ_DPLL_EXP_SHIFT		7
#define CM_SSC_MODFREQ_DPLL_EXP_MASK		GENMASK(10, 8)

struct dpll_params {
	u32 m;
	u32 n;
	s8 m2;
	s8 m3;
	s8 m4;
	s8 m5;
	s8 m6;
};

struct dpll_regs {
	u32 cm_clkmode_dpll;
	u32 cm_idlest_dpll;
	u32 cm_autoidle_dpll;
	u32 cm_clksel_dpll;
	u32 cm_div_m2_dpll;
	u32 cm_div_m3_dpll;
	u32 cm_div_m4_dpll;
	u32 cm_div_m5_dpll;
	u32 cm_div_m6_dpll;
};

extern const struct dpll_regs dpll_mpu_regs;
extern const struct dpll_regs dpll_core_regs;
extern const struct dpll_regs dpll_per_regs;
extern const struct dpll_regs dpll_ddr_regs;
extern const struct dpll_regs dpll_disp_regs;
extern const struct dpll_params dpll_mpu_opp[NUM_CRYSTAL_FREQ][NUM_OPPS];
extern const struct dpll_params dpll_core_1000MHz[NUM_CRYSTAL_FREQ];
extern const struct dpll_params dpll_per_192MHz[NUM_CRYSTAL_FREQ];
extern const struct dpll_params dpll_ddr2_266MHz[NUM_CRYSTAL_FREQ];
extern const struct dpll_params dpll_ddr3_303MHz[NUM_CRYSTAL_FREQ];
extern const struct dpll_params dpll_ddr3_400MHz[NUM_CRYSTAL_FREQ];

extern struct cm_wkuppll *const cmwkup;

const struct dpll_params *get_dpll_mpu_params(void);
const struct dpll_params *get_dpll_core_params(void);
const struct dpll_params *get_dpll_per_params(void);
const struct dpll_params *get_dpll_ddr_params(void);
void scale_vcores(void);
void do_setup_dpll(const struct dpll_regs *, const struct dpll_params *);
void prcm_init(void);
void enable_basic_clocks(void);

void rtc_only_update_board_type(u32 btype);
u32 rtc_only_get_board_type(void);
void rtc_only_prcm_init(void);
void rtc_only_enable_basic_clocks(void);

void do_enable_clocks(u32 *const *, u32 *const *, u8);
void do_disable_clocks(u32 *const *, u32 *const *, u8);

void set_mpu_spreadspectrum(int permille);
#endif
