linux/drivers/soc/mediatek/mtk-svs.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2022 MediaTek Inc.
 * Copyright (C) 2022 Collabora Ltd.
 *                    AngeloGioacchino Del Regno <[email protected]>
 */

#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/cpu.h>
#include <linux/cpuidle.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/kthread.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/nvmem-consumer.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_opp.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/thermal.h>

/* svs bank mode support */
#define SVSB_MODE_ALL_DISABLE
#define SVSB_MODE_INIT01
#define SVSB_MODE_INIT02
#define SVSB_MODE_MON

/* svs bank volt flags */
#define SVSB_INIT01_PD_REQ
#define SVSB_INIT01_VOLT_IGNORE
#define SVSB_INIT01_VOLT_INC_ONLY
#define SVSB_MON_VOLT_IGNORE
#define SVSB_REMOVE_DVTFIXED_VOLT

/* svs bank register fields and common configuration */
#define SVSB_PTPCONFIG_DETMAX
#define SVSB_DET_MAX
#define SVSB_DET_WINDOW

/* DESCHAR */
#define SVSB_DESCHAR_FLD_MDES
#define SVSB_DESCHAR_FLD_BDES

/* TEMPCHAR */
#define SVSB_TEMPCHAR_FLD_DVT_FIXED
#define SVSB_TEMPCHAR_FLD_MTDES
#define SVSB_TEMPCHAR_FLD_VCO

/* DETCHAR */
#define SVSB_DETCHAR_FLD_DCMDET
#define SVSB_DETCHAR_FLD_DCBDET

/* SVSEN (PTPEN) */
#define SVSB_PTPEN_INIT01
#define SVSB_PTPEN_MON
#define SVSB_PTPEN_INIT02
#define SVSB_PTPEN_OFF

/* FREQPCTS */
#define SVSB_FREQPCTS_FLD_PCT0_4
#define SVSB_FREQPCTS_FLD_PCT1_5
#define SVSB_FREQPCTS_FLD_PCT2_6
#define SVSB_FREQPCTS_FLD_PCT3_7

/* INTSTS */
#define SVSB_INTSTS_VAL_CLEAN
#define SVSB_INTSTS_F0_COMPLETE
#define SVSB_INTSTS_FLD_MONVOP
#define SVSB_RUNCONFIG_DEFAULT

/* LIMITVALS */
#define SVSB_LIMITVALS_FLD_DTLO
#define SVSB_LIMITVALS_FLD_DTHI
#define SVSB_LIMITVALS_FLD_VMIN
#define SVSB_LIMITVALS_FLD_VMAX
#define SVSB_VAL_DTHI
#define SVSB_VAL_DTLO

/* INTEN */
#define SVSB_INTEN_F0EN
#define SVSB_INTEN_DACK0UPEN
#define SVSB_INTEN_DC0EN
#define SVSB_INTEN_DC1EN
#define SVSB_INTEN_DACK0LOEN
#define SVSB_INTEN_INITPROD_OVF_EN
#define SVSB_INTEN_INITSUM_OVF_EN
#define SVSB_INTEN_MONVOPEN
#define SVSB_INTEN_INIT0x

/* TSCALCS */
#define SVSB_TSCALCS_FLD_MTS
#define SVSB_TSCALCS_FLD_BTS

/* INIT2VALS */
#define SVSB_INIT2VALS_FLD_DCVOFFSETIN
#define SVSB_INIT2VALS_FLD_AGEVOFFSETIN

/* VOPS */
#define SVSB_VOPS_FLD_VOP0_4
#define SVSB_VOPS_FLD_VOP1_5
#define SVSB_VOPS_FLD_VOP2_6
#define SVSB_VOPS_FLD_VOP3_7

/* SVS Thermal Coefficients */
#define SVSB_TS_COEFF_MT8195
#define SVSB_TS_COEFF_MT8186

/* Algo helpers */
#define FUSE_DATA_NOT_VALID

/* svs bank related setting */
#define BITS8
#define MAX_OPP_ENTRIES
#define REG_BYTES
#define SVSB_DC_SIGNED_BIT
#define SVSB_DET_CLK_EN
#define SVSB_TEMP_LOWER_BOUND
#define SVSB_TEMP_UPPER_BOUND

static DEFINE_SPINLOCK(svs_lock);

#ifdef CONFIG_DEBUG_FS
#define debug_fops_ro(name)

#define debug_fops_rw(name)

#define svs_dentry_data(name)
#endif

/**
 * enum svsb_sw_id - SVS Bank Software ID
 * @SVSB_SWID_CPU_LITTLE: CPU little cluster Bank
 * @SVSB_SWID_CPU_BIG:    CPU big cluster Bank
 * @SVSB_SWID_CCI:        Cache Coherent Interconnect Bank
 * @SVSB_SWID_GPU:        GPU Bank
 * @SVSB_SWID_MAX:        Total number of Banks
 */
enum svsb_sw_id {};

/**
 * enum svsb_type - SVS Bank 2-line: Type and Role
 * @SVSB_TYPE_NONE: One-line type Bank - Global role
 * @SVSB_TYPE_LOW:  Two-line type Bank - Low bank role
 * @SVSB_TYPE_HIGH: Two-line type Bank - High bank role
 * @SVSB_TYPE_MAX:  Total number of bank types
 */
enum svsb_type {};

/**
 * enum svsb_phase - svs bank phase enumeration
 * @SVSB_PHASE_ERROR: svs bank encounters unexpected condition
 * @SVSB_PHASE_INIT01: svs bank basic init for data calibration
 * @SVSB_PHASE_INIT02: svs bank can provide voltages to opp table
 * @SVSB_PHASE_MON: svs bank can provide voltages with thermal effect
 * @SVSB_PHASE_MAX: total number of svs bank phase (debug purpose)
 *
 * Each svs bank has its own independent phase and we enable each svs bank by
 * running their phase orderly. However, when svs bank encounters unexpected
 * condition, it will fire an irq (PHASE_ERROR) to inform svs software.
 *
 * svs bank general phase-enabled order:
 * SVSB_PHASE_INIT01 -> SVSB_PHASE_INIT02 -> SVSB_PHASE_MON
 */
enum svsb_phase {};

enum svs_reg_index {};

static const u32 svs_regs_v2[] =;

static const char * const svs_swid_names[SVSB_SWID_MAX] =;

static const char * const svs_type_names[SVSB_TYPE_MAX] =;

enum svs_fusemap_dev {};

enum svs_fusemap_glb {};

struct svs_fusemap {};

/**
 * struct svs_platform - svs platform control
 * @base: svs platform register base
 * @dev: svs platform device
 * @main_clk: main clock for svs bank
 * @banks: svs banks that svs platform supports
 * @rst: svs platform reset control
 * @efuse_max: total number of svs efuse
 * @tefuse_max: total number of thermal efuse
 * @regs: svs platform registers map
 * @efuse: svs efuse data received from NVMEM framework
 * @tefuse: thermal efuse data received from NVMEM framework
 * @ts_coeff: thermal sensors coefficient
 * @bank_max: total number of svs banks
 */
struct svs_platform {};

struct svs_platform_data {};

/**
 * struct svs_bank_pdata - SVS Bank immutable config parameters
 * @dev_fuse_map: Bank fuse map data
 * @buck_name: Regulator name
 * @tzone_name: Thermal zone name
 * @age_config: Bank age configuration
 * @ctl0: TS-x selection
 * @dc_config: Bank dc configuration
 * @int_st: Bank interrupt identification
 * @turn_freq_base: Reference frequency for 2-line turn point
 * @tzone_htemp: Thermal zone high temperature threshold
 * @tzone_ltemp: Thermal zone low temperature threshold
 * @volt_step: Bank voltage step
 * @volt_base: Bank voltage base
 * @tzone_htemp_voffset: Thermal zone high temperature voltage offset
 * @tzone_ltemp_voffset: Thermal zone low temperature voltage offset
 * @chk_shift: Bank chicken shift
 * @cpu_id: CPU core ID for SVS CPU bank use only
 * @opp_count: Bank opp count
 * @vboot: Voltage request for bank init01 only
 * @vco: Bank VCO value
 * @sw_id: Bank software identification
 * @type: SVS Bank Type (1 or 2-line) and Role (high/low)
 * @set_freq_pct: function pointer to set bank frequency percent table
 * @get_volts: function pointer to get bank voltages
 */
struct svs_bank_pdata {};

/**
 * struct svs_bank - svs bank representation
 * @pdata: SVS Bank immutable config parameters
 * @dev: bank device
 * @opp_dev: device for opp table/buck control
 * @init_completion: the timeout completion for bank init
 * @buck: regulator used by opp_dev
 * @tzd: thermal zone device for getting temperature
 * @lock: mutex lock to protect voltage update process
 * @name: bank name
 * @phase: bank current phase
 * @volt_od: bank voltage overdrive
 * @reg_data: bank register data in different phase for debug purpose
 * @pm_runtime_enabled_count: bank pm runtime enabled count
 * @mode_support: bank mode support
 * @freq_base: reference frequency for bank init
 * @opp_dfreq: default opp frequency table
 * @opp_dvolt: default opp voltage table
 * @freq_pct: frequency percent table for bank init
 * @volt: bank voltage table
 * @volt_flags: bank voltage flags
 * @vmax: bank voltage maximum
 * @vmin: bank voltage minimum
 * @age_voffset_in: bank age voltage offset
 * @dc_voffset_in: bank dc voltage offset
 * @dvt_fixed: bank dvt fixed value
 * @core_sel: bank selection
 * @temp: bank temperature
 * @bts: svs efuse data
 * @mts: svs efuse data
 * @bdes: svs efuse data
 * @mdes: svs efuse data
 * @mtdes: svs efuse data
 * @dcbdet: svs efuse data
 * @dcmdet: svs efuse data
 * @turn_pt: 2-line turn point tells which opp_volt calculated by high/low bank
 * @vbin_turn_pt: voltage bin turn point helps know which svsb_volt should be overridden
 *
 * Svs bank will generate suitable voltages by below general math equation
 * and provide these voltages to opp voltage table.
 *
 * opp_volt[i] = (volt[i] * volt_step) + volt_base;
 */
struct svs_bank {};

static u32 percent(u32 numerator, u32 denominator)
{}

static u32 svs_readl_relaxed(struct svs_platform *svsp, enum svs_reg_index rg_i)
{}

static void svs_writel_relaxed(struct svs_platform *svsp, u32 val,
			       enum svs_reg_index rg_i)
{}

static void svs_switch_bank(struct svs_platform *svsp, struct svs_bank *svsb)
{}

static u32 svs_bank_volt_to_opp_volt(u32 svsb_volt, u32 svsb_volt_step,
				     u32 svsb_volt_base)
{}

static u32 svs_opp_volt_to_bank_volt(u32 opp_u_volt, u32 svsb_volt_step,
				     u32 svsb_volt_base)
{}

static int svs_sync_bank_volts_from_opp(struct svs_bank *svsb)
{}

static int svs_adjust_pm_opp_volts(struct svs_bank *svsb)
{}

static void svs_bank_disable_and_restore_default_volts(struct svs_platform *svsp,
						       struct svs_bank *svsb)
{}

#ifdef CONFIG_DEBUG_FS
static int svs_dump_debug_show(struct seq_file *m, void *p)
{}

debug_fops_ro();

static int svs_enable_debug_show(struct seq_file *m, void *v)
{}

static ssize_t svs_enable_debug_write(struct file *filp,
				      const char __user *buffer,
				      size_t count, loff_t *pos)
{}

debug_fops_rw();

static int svs_status_debug_show(struct seq_file *m, void *v)
{}

debug_fops_ro();

static int svs_create_debug_cmds(struct svs_platform *svsp)
{}
#endif /* CONFIG_DEBUG_FS */

static u32 interpolate(u32 f0, u32 f1, u32 v0, u32 v1, u32 fx)
{}

static void svs_get_bank_volts_v3(struct svs_platform *svsp, struct svs_bank *svsb)
{}

static void svs_set_bank_freq_pct_v3(struct svs_platform *svsp, struct svs_bank *svsb)
{}

static void svs_get_bank_volts_v2(struct svs_platform *svsp, struct svs_bank *svsb)
{}

static void svs_set_bank_freq_pct_v2(struct svs_platform *svsp, struct svs_bank *svsb)
{}

static void svs_set_bank_phase(struct svs_platform *svsp,
			       unsigned int bank_idx,
			       enum svsb_phase target_phase)
{}

static inline void svs_save_bank_register_data(struct svs_platform *svsp,
					       unsigned short bank_idx,
					       enum svsb_phase phase)
{}

static inline void svs_error_isr_handler(struct svs_platform *svsp,
					 unsigned short bank_idx)
{}

static inline void svs_init01_isr_handler(struct svs_platform *svsp,
					  unsigned short bank_idx)
{}

static inline void svs_init02_isr_handler(struct svs_platform *svsp,
					  unsigned short bank_idx)
{}

static inline void svs_mon_mode_isr_handler(struct svs_platform *svsp,
					    unsigned short bank_idx)
{}

static irqreturn_t svs_isr(int irq, void *data)
{}

static bool svs_mode_available(struct svs_platform *svsp, u8 mode)
{}

static int svs_init01(struct svs_platform *svsp)
{}

static int svs_init02(struct svs_platform *svsp)
{}

static void svs_mon_mode(struct svs_platform *svsp)
{}

static int svs_start(struct svs_platform *svsp)
{}

static int svs_suspend(struct device *dev)
{}

static int svs_resume(struct device *dev)
{}

static int svs_bank_resource_setup(struct svs_platform *svsp)
{}

static int svs_get_efuse_data(struct svs_platform *svsp,
			      const char *nvmem_cell_name,
			      u32 **svsp_efuse, size_t *svsp_efuse_max)
{}

static u32 svs_get_fuse_val(u32 *fuse_array, const struct svs_fusemap *fmap, u8 nbits)
{}

static bool svs_is_available(struct svs_platform *svsp)
{}

static bool svs_common_parse_efuse(struct svs_platform *svsp,
				   const struct svs_platform_data *pdata)
{}

static bool svs_mt8183_efuse_parsing(struct svs_platform *svsp,
				     const struct svs_platform_data *pdata)
{}

static struct device *svs_get_subsys_device(struct svs_platform *svsp,
					    const char *node_name)
{}

static struct device *svs_add_device_link(struct svs_platform *svsp,
					  const char *node_name)
{}

static int svs_mt8192_platform_probe(struct svs_platform *svsp)
{}

static int svs_mt8183_platform_probe(struct svs_platform *svsp)
{}

static struct svs_bank svs_mt8195_banks[] =;

static struct svs_bank svs_mt8192_banks[] =;

static struct svs_bank svs_mt8188_banks[] =;

static struct svs_bank svs_mt8186_banks[] =;

static struct svs_bank svs_mt8183_banks[] =;

static const struct svs_platform_data svs_mt8195_platform_data =;

static const struct svs_platform_data svs_mt8192_platform_data =;

static const struct svs_platform_data svs_mt8188_platform_data =;

static const struct svs_platform_data svs_mt8186_platform_data =;

static const struct svs_platform_data svs_mt8183_platform_data =;

static const struct of_device_id svs_of_match[] =;
MODULE_DEVICE_TABLE(of, svs_of_match);

static int svs_probe(struct platform_device *pdev)
{}

static DEFINE_SIMPLE_DEV_PM_OPS(svs_pm_ops, svs_suspend, svs_resume);

static struct platform_driver svs_driver =;

module_platform_driver();

MODULE_AUTHOR();
MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();