1f9dca0f0SNishanth Menon /* SPDX-License-Identifier: GPL-2.0 */
2b86aeafcSJean Pihet /*
3b86aeafcSJean Pihet * OMAP Smartreflex Defines and Routines
4b86aeafcSJean Pihet *
5b86aeafcSJean Pihet * Author: Thara Gopinath <[email protected]>
6b86aeafcSJean Pihet *
7b86aeafcSJean Pihet * Copyright (C) 2010 Texas Instruments, Inc.
8b86aeafcSJean Pihet * Thara Gopinath <[email protected]>
9b86aeafcSJean Pihet *
10b86aeafcSJean Pihet * Copyright (C) 2008 Nokia Corporation
11b86aeafcSJean Pihet * Kalle Jokiniemi
12b86aeafcSJean Pihet *
13b86aeafcSJean Pihet * Copyright (C) 2007 Texas Instruments, Inc.
14b86aeafcSJean Pihet * Lesly A M <[email protected]>
15b86aeafcSJean Pihet */
16b86aeafcSJean Pihet
17b86aeafcSJean Pihet #ifndef __POWER_SMARTREFLEX_H
18b86aeafcSJean Pihet #define __POWER_SMARTREFLEX_H
19b86aeafcSJean Pihet
20b86aeafcSJean Pihet #include <linux/types.h>
21b86aeafcSJean Pihet #include <linux/platform_device.h>
2250e4a7d0SJean Pihet #include <linux/delay.h>
232203747cSArnd Bergmann #include <linux/platform_data/voltage-omap.h>
24b86aeafcSJean Pihet
25b86aeafcSJean Pihet /*
26b86aeafcSJean Pihet * Different Smartreflex IPs version. The v1 is the 65nm version used in
27b86aeafcSJean Pihet * OMAP3430. The v2 is the update for the 45nm version of the IP
28b86aeafcSJean Pihet * used in OMAP3630 and OMAP4430
29b86aeafcSJean Pihet */
30b86aeafcSJean Pihet #define SR_TYPE_V1 1
31b86aeafcSJean Pihet #define SR_TYPE_V2 2
32b86aeafcSJean Pihet
33b86aeafcSJean Pihet /* SMART REFLEX REG ADDRESS OFFSET */
34b86aeafcSJean Pihet #define SRCONFIG 0x00
35b86aeafcSJean Pihet #define SRSTATUS 0x04
36b86aeafcSJean Pihet #define SENVAL 0x08
37b86aeafcSJean Pihet #define SENMIN 0x0C
38b86aeafcSJean Pihet #define SENMAX 0x10
39b86aeafcSJean Pihet #define SENAVG 0x14
40b86aeafcSJean Pihet #define AVGWEIGHT 0x18
41b86aeafcSJean Pihet #define NVALUERECIPROCAL 0x1c
42b86aeafcSJean Pihet #define SENERROR_V1 0x20
43b86aeafcSJean Pihet #define ERRCONFIG_V1 0x24
44b86aeafcSJean Pihet #define IRQ_EOI 0x20
45b86aeafcSJean Pihet #define IRQSTATUS_RAW 0x24
46b86aeafcSJean Pihet #define IRQSTATUS 0x28
47b86aeafcSJean Pihet #define IRQENABLE_SET 0x2C
48b86aeafcSJean Pihet #define IRQENABLE_CLR 0x30
49b86aeafcSJean Pihet #define SENERROR_V2 0x34
50b86aeafcSJean Pihet #define ERRCONFIG_V2 0x38
51b86aeafcSJean Pihet
52b86aeafcSJean Pihet /* Bit/Shift Positions */
53b86aeafcSJean Pihet
54b86aeafcSJean Pihet /* SRCONFIG */
55b86aeafcSJean Pihet #define SRCONFIG_ACCUMDATA_SHIFT 22
56b86aeafcSJean Pihet #define SRCONFIG_SRCLKLENGTH_SHIFT 12
57b86aeafcSJean Pihet #define SRCONFIG_SENNENABLE_V1_SHIFT 5
58b86aeafcSJean Pihet #define SRCONFIG_SENPENABLE_V1_SHIFT 3
59b86aeafcSJean Pihet #define SRCONFIG_SENNENABLE_V2_SHIFT 1
60b86aeafcSJean Pihet #define SRCONFIG_SENPENABLE_V2_SHIFT 0
61b86aeafcSJean Pihet #define SRCONFIG_CLKCTRL_SHIFT 0
62b86aeafcSJean Pihet
63b86aeafcSJean Pihet #define SRCONFIG_ACCUMDATA_MASK (0x3ff << 22)
64b86aeafcSJean Pihet
65b86aeafcSJean Pihet #define SRCONFIG_SRENABLE BIT(11)
66b86aeafcSJean Pihet #define SRCONFIG_SENENABLE BIT(10)
67b86aeafcSJean Pihet #define SRCONFIG_ERRGEN_EN BIT(9)
68b86aeafcSJean Pihet #define SRCONFIG_MINMAXAVG_EN BIT(8)
69b86aeafcSJean Pihet #define SRCONFIG_DELAYCTRL BIT(2)
70b86aeafcSJean Pihet
71b86aeafcSJean Pihet /* AVGWEIGHT */
72b86aeafcSJean Pihet #define AVGWEIGHT_SENPAVGWEIGHT_SHIFT 2
73b86aeafcSJean Pihet #define AVGWEIGHT_SENNAVGWEIGHT_SHIFT 0
74b86aeafcSJean Pihet
75b86aeafcSJean Pihet /* NVALUERECIPROCAL */
76b86aeafcSJean Pihet #define NVALUERECIPROCAL_SENPGAIN_SHIFT 20
77b86aeafcSJean Pihet #define NVALUERECIPROCAL_SENNGAIN_SHIFT 16
78b86aeafcSJean Pihet #define NVALUERECIPROCAL_RNSENP_SHIFT 8
79b86aeafcSJean Pihet #define NVALUERECIPROCAL_RNSENN_SHIFT 0
80b86aeafcSJean Pihet
81b86aeafcSJean Pihet /* ERRCONFIG */
82b86aeafcSJean Pihet #define ERRCONFIG_ERRWEIGHT_SHIFT 16
83b86aeafcSJean Pihet #define ERRCONFIG_ERRMAXLIMIT_SHIFT 8
84b86aeafcSJean Pihet #define ERRCONFIG_ERRMINLIMIT_SHIFT 0
85b86aeafcSJean Pihet
86b86aeafcSJean Pihet #define SR_ERRWEIGHT_MASK (0x07 << 16)
87b86aeafcSJean Pihet #define SR_ERRMAXLIMIT_MASK (0xff << 8)
88b86aeafcSJean Pihet #define SR_ERRMINLIMIT_MASK (0xff << 0)
89b86aeafcSJean Pihet
90b86aeafcSJean Pihet #define ERRCONFIG_VPBOUNDINTEN_V1 BIT(31)
91b86aeafcSJean Pihet #define ERRCONFIG_VPBOUNDINTST_V1 BIT(30)
92b86aeafcSJean Pihet #define ERRCONFIG_MCUACCUMINTEN BIT(29)
93b86aeafcSJean Pihet #define ERRCONFIG_MCUACCUMINTST BIT(28)
94b86aeafcSJean Pihet #define ERRCONFIG_MCUVALIDINTEN BIT(27)
95b86aeafcSJean Pihet #define ERRCONFIG_MCUVALIDINTST BIT(26)
96b86aeafcSJean Pihet #define ERRCONFIG_MCUBOUNDINTEN BIT(25)
97b86aeafcSJean Pihet #define ERRCONFIG_MCUBOUNDINTST BIT(24)
98b86aeafcSJean Pihet #define ERRCONFIG_MCUDISACKINTEN BIT(23)
99b86aeafcSJean Pihet #define ERRCONFIG_VPBOUNDINTST_V2 BIT(23)
100b86aeafcSJean Pihet #define ERRCONFIG_MCUDISACKINTST BIT(22)
101b86aeafcSJean Pihet #define ERRCONFIG_VPBOUNDINTEN_V2 BIT(22)
102b86aeafcSJean Pihet
103b86aeafcSJean Pihet #define ERRCONFIG_STATUS_V1_MASK (ERRCONFIG_VPBOUNDINTST_V1 | \
104b86aeafcSJean Pihet ERRCONFIG_MCUACCUMINTST | \
105b86aeafcSJean Pihet ERRCONFIG_MCUVALIDINTST | \
106b86aeafcSJean Pihet ERRCONFIG_MCUBOUNDINTST | \
107b86aeafcSJean Pihet ERRCONFIG_MCUDISACKINTST)
108b86aeafcSJean Pihet /* IRQSTATUS */
109b86aeafcSJean Pihet #define IRQSTATUS_MCUACCUMINT BIT(3)
110b86aeafcSJean Pihet #define IRQSTATUS_MCVALIDINT BIT(2)
111b86aeafcSJean Pihet #define IRQSTATUS_MCBOUNDSINT BIT(1)
112b86aeafcSJean Pihet #define IRQSTATUS_MCUDISABLEACKINT BIT(0)
113b86aeafcSJean Pihet
114b86aeafcSJean Pihet /* IRQENABLE_SET and IRQENABLE_CLEAR */
115b86aeafcSJean Pihet #define IRQENABLE_MCUACCUMINT BIT(3)
116b86aeafcSJean Pihet #define IRQENABLE_MCUVALIDINT BIT(2)
117b86aeafcSJean Pihet #define IRQENABLE_MCUBOUNDSINT BIT(1)
118b86aeafcSJean Pihet #define IRQENABLE_MCUDISABLEACKINT BIT(0)
119b86aeafcSJean Pihet
120b86aeafcSJean Pihet /* Common Bit values */
121b86aeafcSJean Pihet
122b86aeafcSJean Pihet #define SRCLKLENGTH_12MHZ_SYSCLK 0x3c
123b86aeafcSJean Pihet #define SRCLKLENGTH_13MHZ_SYSCLK 0x41
124b86aeafcSJean Pihet #define SRCLKLENGTH_19MHZ_SYSCLK 0x60
125b86aeafcSJean Pihet #define SRCLKLENGTH_26MHZ_SYSCLK 0x82
126b86aeafcSJean Pihet #define SRCLKLENGTH_38MHZ_SYSCLK 0xC0
127b86aeafcSJean Pihet
128b86aeafcSJean Pihet /*
129b86aeafcSJean Pihet * 3430 specific values. Maybe these should be passed from board file or
130b86aeafcSJean Pihet * pmic structures.
131b86aeafcSJean Pihet */
132b86aeafcSJean Pihet #define OMAP3430_SR_ACCUMDATA 0x1f4
133b86aeafcSJean Pihet
134b86aeafcSJean Pihet #define OMAP3430_SR1_SENPAVGWEIGHT 0x03
135b86aeafcSJean Pihet #define OMAP3430_SR1_SENNAVGWEIGHT 0x03
136b86aeafcSJean Pihet
137b86aeafcSJean Pihet #define OMAP3430_SR2_SENPAVGWEIGHT 0x01
138b86aeafcSJean Pihet #define OMAP3430_SR2_SENNAVGWEIGHT 0x01
139b86aeafcSJean Pihet
140b86aeafcSJean Pihet #define OMAP3430_SR_ERRWEIGHT 0x04
141b86aeafcSJean Pihet #define OMAP3430_SR_ERRMAXLIMIT 0x02
142b86aeafcSJean Pihet
143d060b405STony Lindgren enum sr_instance {
144d060b405STony Lindgren OMAP_SR_MPU, /* shared with iva on omap3 */
145d060b405STony Lindgren OMAP_SR_CORE,
146d060b405STony Lindgren OMAP_SR_IVA,
147d060b405STony Lindgren OMAP_SR_NR,
148d060b405STony Lindgren };
149d060b405STony Lindgren
15080821c9cSJean Pihet struct omap_sr {
1518b765d72SJean Pihet char *name;
15280821c9cSJean Pihet struct list_head node;
15380821c9cSJean Pihet struct platform_device *pdev;
15480821c9cSJean Pihet struct omap_sr_nvalue_table *nvalue_table;
15580821c9cSJean Pihet struct voltagedomain *voltdm;
15680821c9cSJean Pihet struct dentry *dbg_dir;
15780821c9cSJean Pihet unsigned int irq;
158*ed4520d6STony Lindgren struct clk *fck;
15980821c9cSJean Pihet int srid;
16080821c9cSJean Pihet int ip_type;
16180821c9cSJean Pihet int nvalue_count;
16280821c9cSJean Pihet bool autocomp_active;
16380821c9cSJean Pihet u32 clk_length;
16480821c9cSJean Pihet u32 err_weight;
16580821c9cSJean Pihet u32 err_minlimit;
16680821c9cSJean Pihet u32 err_maxlimit;
16780821c9cSJean Pihet u32 accum_data;
16880821c9cSJean Pihet u32 senn_avgweight;
16980821c9cSJean Pihet u32 senp_avgweight;
17080821c9cSJean Pihet u32 senp_mod;
17180821c9cSJean Pihet u32 senn_mod;
17280821c9cSJean Pihet void __iomem *base;
173*ed4520d6STony Lindgren unsigned long enabled:1;
17480821c9cSJean Pihet };
17580821c9cSJean Pihet
176b86aeafcSJean Pihet /**
17750e4a7d0SJean Pihet * test_cond_timeout - busy-loop, testing a condition
17850e4a7d0SJean Pihet * @cond: condition to test until it evaluates to true
17950e4a7d0SJean Pihet * @timeout: maximum number of microseconds in the timeout
18050e4a7d0SJean Pihet * @index: loop index (integer)
18150e4a7d0SJean Pihet *
18250e4a7d0SJean Pihet * Loop waiting for @cond to become true or until at least @timeout
18350e4a7d0SJean Pihet * microseconds have passed. To use, define some integer @index in the
18450e4a7d0SJean Pihet * calling code. After running, if @index == @timeout, then the loop has
18550e4a7d0SJean Pihet * timed out.
18650e4a7d0SJean Pihet *
18750e4a7d0SJean Pihet * Copied from omap_test_timeout */
18850e4a7d0SJean Pihet #define sr_test_cond_timeout(cond, timeout, index) \
18950e4a7d0SJean Pihet ({ \
19050e4a7d0SJean Pihet for (index = 0; index < timeout; index++) { \
19150e4a7d0SJean Pihet if (cond) \
19250e4a7d0SJean Pihet break; \
19350e4a7d0SJean Pihet udelay(1); \
19450e4a7d0SJean Pihet } \
19550e4a7d0SJean Pihet })
19650e4a7d0SJean Pihet
19750e4a7d0SJean Pihet /**
198b86aeafcSJean Pihet * struct omap_sr_pmic_data - Strucutre to be populated by pmic code to pass
199b86aeafcSJean Pihet * pmic specific info to smartreflex driver
200b86aeafcSJean Pihet *
201b86aeafcSJean Pihet * @sr_pmic_init: API to initialize smartreflex on the PMIC side.
202b86aeafcSJean Pihet */
203b86aeafcSJean Pihet struct omap_sr_pmic_data {
204b86aeafcSJean Pihet void (*sr_pmic_init) (void);
205b86aeafcSJean Pihet };
206b86aeafcSJean Pihet
207b86aeafcSJean Pihet /**
208b86aeafcSJean Pihet * struct omap_smartreflex_dev_attr - Smartreflex Device attribute.
209b86aeafcSJean Pihet *
210b86aeafcSJean Pihet * @sensor_voltdm_name: Name of voltdomain of SR instance
211b86aeafcSJean Pihet */
212b86aeafcSJean Pihet struct omap_smartreflex_dev_attr {
213b86aeafcSJean Pihet const char *sensor_voltdm_name;
214b86aeafcSJean Pihet };
215b86aeafcSJean Pihet
216b86aeafcSJean Pihet /*
217b86aeafcSJean Pihet * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR.
218b86aeafcSJean Pihet * The smartreflex class driver should pass the class type.
219b86aeafcSJean Pihet * Should be used to populate the class_type field of the
220b86aeafcSJean Pihet * omap_smartreflex_class_data structure.
221b86aeafcSJean Pihet */
222b86aeafcSJean Pihet #define SR_CLASS1 0x1
223b86aeafcSJean Pihet #define SR_CLASS2 0x2
224b86aeafcSJean Pihet #define SR_CLASS3 0x3
225b86aeafcSJean Pihet
226b86aeafcSJean Pihet /**
227b86aeafcSJean Pihet * struct omap_sr_class_data - Smartreflex class driver info
228b86aeafcSJean Pihet *
229b86aeafcSJean Pihet * @enable: API to enable a particular class smaartreflex.
230b86aeafcSJean Pihet * @disable: API to disable a particular class smartreflex.
231b86aeafcSJean Pihet * @configure: API to configure a particular class smartreflex.
232b86aeafcSJean Pihet * @notify: API to notify the class driver about an event in SR.
233b86aeafcSJean Pihet * Not needed for class3.
234b86aeafcSJean Pihet * @notify_flags: specify the events to be notified to the class driver
235b86aeafcSJean Pihet * @class_type: specify which smartreflex class.
236b86aeafcSJean Pihet * Can be used by the SR driver to take any class
237b86aeafcSJean Pihet * based decisions.
238b86aeafcSJean Pihet */
239b86aeafcSJean Pihet struct omap_sr_class_data {
24080821c9cSJean Pihet int (*enable)(struct omap_sr *sr);
24180821c9cSJean Pihet int (*disable)(struct omap_sr *sr, int is_volt_reset);
24280821c9cSJean Pihet int (*configure)(struct omap_sr *sr);
24380821c9cSJean Pihet int (*notify)(struct omap_sr *sr, u32 status);
244b86aeafcSJean Pihet u8 notify_flags;
245b86aeafcSJean Pihet u8 class_type;
246b86aeafcSJean Pihet };
247b86aeafcSJean Pihet
248b86aeafcSJean Pihet /**
249b86aeafcSJean Pihet * struct omap_sr_nvalue_table - Smartreflex n-target value info
250b86aeafcSJean Pihet *
251b86aeafcSJean Pihet * @efuse_offs: The offset of the efuse where n-target values are stored.
252b86aeafcSJean Pihet * @nvalue: The n-target value.
2535e7f2e12SJean Pihet * @errminlimit: The value of the ERRMINLIMIT bitfield for this n-target
2545e7f2e12SJean Pihet * @volt_nominal: microvolts DC that the VDD is initially programmed to
255b86aeafcSJean Pihet */
256b86aeafcSJean Pihet struct omap_sr_nvalue_table {
257b86aeafcSJean Pihet u32 efuse_offs;
258b86aeafcSJean Pihet u32 nvalue;
2595e7f2e12SJean Pihet u32 errminlimit;
2605e7f2e12SJean Pihet unsigned long volt_nominal;
261b86aeafcSJean Pihet };
262b86aeafcSJean Pihet
263b86aeafcSJean Pihet /**
264b86aeafcSJean Pihet * struct omap_sr_data - Smartreflex platform data.
265b86aeafcSJean Pihet *
2668b765d72SJean Pihet * @name: instance name
267b86aeafcSJean Pihet * @ip_type: Smartreflex IP type.
26898aed08eSJean Pihet * @senp_mod: SENPENABLE value of the sr CONFIG register
26998aed08eSJean Pihet * @senn_mod: SENNENABLE value for sr CONFIG register
27098aed08eSJean Pihet * @err_weight ERRWEIGHT value of the sr ERRCONFIG register
27198aed08eSJean Pihet * @err_maxlimit ERRMAXLIMIT value of the sr ERRCONFIG register
27298aed08eSJean Pihet * @accum_data ACCUMDATA value of the sr CONFIG register
27398aed08eSJean Pihet * @senn_avgweight SENNAVGWEIGHT value of the sr AVGWEIGHT register
27498aed08eSJean Pihet * @senp_avgweight SENPAVGWEIGHT value of the sr AVGWEIGHT register
275b86aeafcSJean Pihet * @nvalue_count: Number of distinct nvalues in the nvalue table
276b86aeafcSJean Pihet * @nvalue_table: table containing the efuse offsets and nvalues
277b86aeafcSJean Pihet * corresponding to them.
278b86aeafcSJean Pihet * @voltdm: Pointer to the voltage domain associated with the SR
279b86aeafcSJean Pihet */
280b86aeafcSJean Pihet struct omap_sr_data {
2818b765d72SJean Pihet const char *name;
282b86aeafcSJean Pihet int ip_type;
283b86aeafcSJean Pihet u32 senp_mod;
284b86aeafcSJean Pihet u32 senn_mod;
28598aed08eSJean Pihet u32 err_weight;
28698aed08eSJean Pihet u32 err_maxlimit;
28798aed08eSJean Pihet u32 accum_data;
28898aed08eSJean Pihet u32 senn_avgweight;
28998aed08eSJean Pihet u32 senp_avgweight;
290b86aeafcSJean Pihet int nvalue_count;
291b86aeafcSJean Pihet struct omap_sr_nvalue_table *nvalue_table;
292b86aeafcSJean Pihet struct voltagedomain *voltdm;
293b86aeafcSJean Pihet };
294b86aeafcSJean Pihet
2952079fe6eSBen Dooks
2962079fe6eSBen Dooks extern struct omap_sr_data omap_sr_pdata[OMAP_SR_NR];
2972079fe6eSBen Dooks
298d060b405STony Lindgren #ifdef CONFIG_POWER_AVS_OMAP
299d060b405STony Lindgren
300b86aeafcSJean Pihet /* Smartreflex module enable/disable interface */
301b86aeafcSJean Pihet void omap_sr_enable(struct voltagedomain *voltdm);
302b86aeafcSJean Pihet void omap_sr_disable(struct voltagedomain *voltdm);
303b86aeafcSJean Pihet void omap_sr_disable_reset_volt(struct voltagedomain *voltdm);
304b86aeafcSJean Pihet
305b86aeafcSJean Pihet /* Smartreflex driver hooks to be called from Smartreflex class driver */
306299066bbSAndrii Tseglytskyi int sr_enable(struct omap_sr *sr, unsigned long volt);
307299066bbSAndrii Tseglytskyi void sr_disable(struct omap_sr *sr);
3083dfc35ffSAndrii Tseglytskyi int sr_configure_errgen(struct omap_sr *sr);
3093dfc35ffSAndrii Tseglytskyi int sr_disable_errgen(struct omap_sr *sr);
3106c805734SAndrii Tseglytskyi int sr_configure_minmax(struct omap_sr *sr);
311b86aeafcSJean Pihet
312b86aeafcSJean Pihet /* API to register the smartreflex class driver with the smartreflex driver */
313b86aeafcSJean Pihet int sr_register_class(struct omap_sr_class_data *class_data);
314b86aeafcSJean Pihet #else
omap_sr_enable(struct voltagedomain * voltdm)315b86aeafcSJean Pihet static inline void omap_sr_enable(struct voltagedomain *voltdm) {}
omap_sr_disable(struct voltagedomain * voltdm)316b86aeafcSJean Pihet static inline void omap_sr_disable(struct voltagedomain *voltdm) {}
omap_sr_disable_reset_volt(struct voltagedomain * voltdm)317b86aeafcSJean Pihet static inline void omap_sr_disable_reset_volt(
318b86aeafcSJean Pihet struct voltagedomain *voltdm) {}
319b86aeafcSJean Pihet #endif
320b86aeafcSJean Pihet #endif
321