1/* SPDX-License-Identifier: GPL-2.0-only */
2/*
3 * Copyright (c) 2017 Chen-Yu Tsai. All rights reserved.
4 */
5
6#ifndef _CCU_SDM_H
7#define _CCU_SDM_H
8
9#include <linux/clk-provider.h>
10
11#include "ccu_common.h"
12
13struct ccu_sdm_setting {
14	unsigned long	rate;
15
16	/*
17	 * XXX We don't know what the step and bottom register fields
18	 * mean. Just copy the whole register value from the vendor
19	 * kernel for now.
20	 */
21	u32		pattern;
22
23	/*
24	 * M and N factors here should be the values used in
25	 * calculation, not the raw values written to registers
26	 */
27	u32		m;
28	u32		n;
29};
30
31struct ccu_sdm_internal {
32	struct ccu_sdm_setting	*table;
33	u32		table_size;
34	/* early SoCs don't have the SDM enable bit in the PLL register */
35	u32		enable;
36	/* second enable bit in tuning register */
37	u32		tuning_enable;
38	u16		tuning_reg;
39};
40
41#define _SUNXI_CCU_SDM(_table, _enable,			\
42		       _reg, _reg_enable)		\
43	{						\
44		.table		= _table,		\
45		.table_size	= ARRAY_SIZE(_table),	\
46		.enable		= _enable,		\
47		.tuning_enable	= _reg_enable,		\
48		.tuning_reg	= _reg,			\
49	}
50
51bool ccu_sdm_helper_is_enabled(struct ccu_common *common,
52			       struct ccu_sdm_internal *sdm);
53void ccu_sdm_helper_enable(struct ccu_common *common,
54			   struct ccu_sdm_internal *sdm,
55			   unsigned long rate);
56void ccu_sdm_helper_disable(struct ccu_common *common,
57			    struct ccu_sdm_internal *sdm);
58
59bool ccu_sdm_helper_has_rate(struct ccu_common *common,
60			     struct ccu_sdm_internal *sdm,
61			     unsigned long rate);
62
63unsigned long ccu_sdm_helper_read_rate(struct ccu_common *common,
64				       struct ccu_sdm_internal *sdm,
65				       u32 m, u32 n);
66
67int ccu_sdm_helper_get_factors(struct ccu_common *common,
68			       struct ccu_sdm_internal *sdm,
69			       unsigned long rate,
70			       unsigned long *m, unsigned long *n);
71
72#endif
73