162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2019 Samsung Electronics Co., Ltd.
462306a36Sopenharmony_ci *	      http://www.samsung.com/
562306a36Sopenharmony_ci * Author: Sylwester Nawrocki <s.nawrocki@samsung.com>
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Samsung Exynos SoC Adaptive Supply Voltage support
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci#ifndef __LINUX_SOC_EXYNOS_ASV_H
1062306a36Sopenharmony_ci#define __LINUX_SOC_EXYNOS_ASV_H
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_cistruct regmap;
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci/* HPM, IDS values to select target group */
1562306a36Sopenharmony_cistruct asv_limit_entry {
1662306a36Sopenharmony_ci	unsigned int hpm;
1762306a36Sopenharmony_ci	unsigned int ids;
1862306a36Sopenharmony_ci};
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_cistruct exynos_asv_table {
2162306a36Sopenharmony_ci	unsigned int num_rows;
2262306a36Sopenharmony_ci	unsigned int num_cols;
2362306a36Sopenharmony_ci	u32 *buf;
2462306a36Sopenharmony_ci};
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_cistruct exynos_asv_subsys {
2762306a36Sopenharmony_ci	struct exynos_asv *asv;
2862306a36Sopenharmony_ci	const char *cpu_dt_compat;
2962306a36Sopenharmony_ci	int id;
3062306a36Sopenharmony_ci	struct exynos_asv_table table;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	unsigned int base_volt;
3362306a36Sopenharmony_ci	unsigned int offset_volt_h;
3462306a36Sopenharmony_ci	unsigned int offset_volt_l;
3562306a36Sopenharmony_ci};
3662306a36Sopenharmony_ci
3762306a36Sopenharmony_cistruct exynos_asv {
3862306a36Sopenharmony_ci	struct device *dev;
3962306a36Sopenharmony_ci	struct regmap *chipid_regmap;
4062306a36Sopenharmony_ci	struct exynos_asv_subsys subsys[2];
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	int (*opp_get_voltage)(const struct exynos_asv_subsys *subs,
4362306a36Sopenharmony_ci			       int level, unsigned int voltage);
4462306a36Sopenharmony_ci	unsigned int group;
4562306a36Sopenharmony_ci	unsigned int table;
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci	/* True if SG fields from PKG_ID register should be used */
4862306a36Sopenharmony_ci	bool use_sg;
4962306a36Sopenharmony_ci	/* ASV bin read from DT */
5062306a36Sopenharmony_ci	int of_bin;
5162306a36Sopenharmony_ci};
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cistatic inline u32 __asv_get_table_entry(const struct exynos_asv_table *table,
5462306a36Sopenharmony_ci					unsigned int row, unsigned int col)
5562306a36Sopenharmony_ci{
5662306a36Sopenharmony_ci	return table->buf[row * (table->num_cols) + col];
5762306a36Sopenharmony_ci}
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_cistatic inline u32 exynos_asv_opp_get_voltage(const struct exynos_asv_subsys *subsys,
6062306a36Sopenharmony_ci					unsigned int level, unsigned int group)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	return __asv_get_table_entry(&subsys->table, level, group + 1);
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_cistatic inline u32 exynos_asv_opp_get_frequency(const struct exynos_asv_subsys *subsys,
6662306a36Sopenharmony_ci					unsigned int level)
6762306a36Sopenharmony_ci{
6862306a36Sopenharmony_ci	return __asv_get_table_entry(&subsys->table, level, 0);
6962306a36Sopenharmony_ci}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ciint exynos_asv_init(struct device *dev, struct regmap *regmap);
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci#endif /* __LINUX_SOC_EXYNOS_ASV_H */
74