18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (c) 2017 Chen-Yu Tsai. All rights reserved.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#ifndef _CCU_SDM_H
78c2ecf20Sopenharmony_ci#define _CCU_SDM_H
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <linux/clk-provider.h>
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include "ccu_common.h"
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_cistruct ccu_sdm_setting {
148c2ecf20Sopenharmony_ci	unsigned long	rate;
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci	/*
178c2ecf20Sopenharmony_ci	 * XXX We don't know what the step and bottom register fields
188c2ecf20Sopenharmony_ci	 * mean. Just copy the whole register value from the vendor
198c2ecf20Sopenharmony_ci	 * kernel for now.
208c2ecf20Sopenharmony_ci	 */
218c2ecf20Sopenharmony_ci	u32		pattern;
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci	/*
248c2ecf20Sopenharmony_ci	 * M and N factors here should be the values used in
258c2ecf20Sopenharmony_ci	 * calculation, not the raw values written to registers
268c2ecf20Sopenharmony_ci	 */
278c2ecf20Sopenharmony_ci	u32		m;
288c2ecf20Sopenharmony_ci	u32		n;
298c2ecf20Sopenharmony_ci};
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistruct ccu_sdm_internal {
328c2ecf20Sopenharmony_ci	struct ccu_sdm_setting	*table;
338c2ecf20Sopenharmony_ci	u32		table_size;
348c2ecf20Sopenharmony_ci	/* early SoCs don't have the SDM enable bit in the PLL register */
358c2ecf20Sopenharmony_ci	u32		enable;
368c2ecf20Sopenharmony_ci	/* second enable bit in tuning register */
378c2ecf20Sopenharmony_ci	u32		tuning_enable;
388c2ecf20Sopenharmony_ci	u16		tuning_reg;
398c2ecf20Sopenharmony_ci};
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci#define _SUNXI_CCU_SDM(_table, _enable,			\
428c2ecf20Sopenharmony_ci		       _reg, _reg_enable)		\
438c2ecf20Sopenharmony_ci	{						\
448c2ecf20Sopenharmony_ci		.table		= _table,		\
458c2ecf20Sopenharmony_ci		.table_size	= ARRAY_SIZE(_table),	\
468c2ecf20Sopenharmony_ci		.enable		= _enable,		\
478c2ecf20Sopenharmony_ci		.tuning_enable	= _reg_enable,		\
488c2ecf20Sopenharmony_ci		.tuning_reg	= _reg,			\
498c2ecf20Sopenharmony_ci	}
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_cibool ccu_sdm_helper_is_enabled(struct ccu_common *common,
528c2ecf20Sopenharmony_ci			       struct ccu_sdm_internal *sdm);
538c2ecf20Sopenharmony_civoid ccu_sdm_helper_enable(struct ccu_common *common,
548c2ecf20Sopenharmony_ci			   struct ccu_sdm_internal *sdm,
558c2ecf20Sopenharmony_ci			   unsigned long rate);
568c2ecf20Sopenharmony_civoid ccu_sdm_helper_disable(struct ccu_common *common,
578c2ecf20Sopenharmony_ci			    struct ccu_sdm_internal *sdm);
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_cibool ccu_sdm_helper_has_rate(struct ccu_common *common,
608c2ecf20Sopenharmony_ci			     struct ccu_sdm_internal *sdm,
618c2ecf20Sopenharmony_ci			     unsigned long rate);
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ciunsigned long ccu_sdm_helper_read_rate(struct ccu_common *common,
648c2ecf20Sopenharmony_ci				       struct ccu_sdm_internal *sdm,
658c2ecf20Sopenharmony_ci				       u32 m, u32 n);
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ciint ccu_sdm_helper_get_factors(struct ccu_common *common,
688c2ecf20Sopenharmony_ci			       struct ccu_sdm_internal *sdm,
698c2ecf20Sopenharmony_ci			       unsigned long rate,
708c2ecf20Sopenharmony_ci			       unsigned long *m, unsigned long *n);
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci#endif
73