aboutsummaryrefslogtreecommitdiff
path: root/drivers/misc/mediatek/spm/mt6735/mt_spm_internal.h
blob: a26bbb34d6007f47ea2e42e32072a37e30f39f66 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
#ifndef _MT_SPM_INTERNAL_
#define _MT_SPM_INTERNAL_

#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/atomic.h>
#include <linux/io.h>
#include <linux/aee.h>

#include <mach/mt_spm.h>
#include <mach/mt_lpae.h>
#include <mach/mt_gpio.h>
#include <mach/mt_vcore_dvfs.h>

/**************************************
 * Config and Parameter
 **************************************/
#ifdef MTK_FORCE_CLUSTER1
#define SPM_CTRL_BIG_CPU	1
#else
#define SPM_CTRL_BIG_CPU	0
#endif

#define POWER_ON_VAL1_DEF	0x60015830//mt6735
#define PCM_FSM_STA_DEF		0x48490

#define PCM_WDT_TIMEOUT		(30 * 32768)	/* 30s */
#define PCM_TIMER_MAX		(0xffffffff - PCM_WDT_TIMEOUT)


/**************************************
 * Define and Declare
 **************************************/
#define CON0_PCM_KICK		(1U << 0)
#define CON0_IM_KICK		(1U << 1)
#define CON0_IM_SLEEP_DVS	(1U << 3)
#define CON0_PCM_SW_RESET	(1U << 15)
#define CON0_CFG_KEY		(SPM_PROJECT_CODE << 16)

#define CON1_IM_SLAVE		(1U << 0)
#define CON1_MIF_APBEN		(1U << 3)
#define CON1_PCM_TIMER_EN	(1U << 5)
#define CON1_IM_NONRP_EN	(1U << 6)
#define CON1_PCM_WDT_EN		(1U << 8)
#define CON1_PCM_WDT_WAKE_MODE	(1U << 9)
#define CON1_SPM_SRAM_SLP_B	(1U << 10)
#define CON1_SPM_SRAM_ISO_B	(1U << 11)
#define CON1_EVENT_LOCK_EN	(1U << 12)
#define CON1_SRCCLKEN_FAST_RESP	  (1U << 13)
#define CON1_MD32_APB_INTERNAL_EN (1U << 14)
#define CON1_CFG_KEY		(SPM_PROJECT_CODE << 16)

#define PCM_PWRIO_EN_R0		(1U << 0)
#define PCM_PWRIO_EN_R7		(1U << 7)
#define PCM_RF_SYNC_R0		(1U << 16)
#define PCM_RF_SYNC_R2		(1U << 18)
#define PCM_RF_SYNC_R6		(1U << 22)
#define PCM_RF_SYNC_R7		(1U << 23)

#define R7_AP_MDSRC_REQ		(1U << 17)

#define R13_EXT_SRCLKENA_0	(1U << 0)
#define R13_EXT_SRCLKENA_1	(1U << 1)
#define R13_MD1_SRCLKENA	(1U << 3)
#define R13_MD1_APSRC_REQ	(1U << 4)
#define R13_AP_MD1SRC_ACK	(1U << 5)
#define R13_MD2_SRCLKENA	(1U << 6)
#define R13_MD2_APSRC_REQ	(1U << 7)
#define R13_AP_MD2SRC_ACK	(1U << 8)
#define R13_MD_DDR_EN		(1U << 12)
#define R13_CONN_SRCLKENA	(1U << 14)
#define R13_CONN_APSRC_REQ	(1U << 15)

#define PCM_SW_INT0		(1U << 0)
#define PCM_SW_INT1		(1U << 1)
#define PCM_SW_INT2		(1U << 2)
#define PCM_SW_INT3		(1U << 3)
#define PCM_SW_INT4		(1U << 4)
#define PCM_SW_INT5		(1U << 5)
#define PCM_SW_INT6		(1U << 6)
#define PCM_SW_INT7		(1U << 7)
#define PCM_SW_INT_ALL		(PCM_SW_INT7 | PCM_SW_INT6 | PCM_SW_INT5 |	\
				 PCM_SW_INT4 | PCM_SW_INT3 | PCM_SW_INT2 |	\
				 PCM_SW_INT1 | PCM_SW_INT0)

#define CC_SYSCLK0_EN_0		(1U << 0)
#define CC_SYSCLK0_EN_1		(1U << 1)
#define CC_SYSCLK1_EN_0		(1U << 2)
#define CC_SYSCLK1_EN_1		(1U << 3)
#define CC_SYSSETTLE_SEL	(1U << 4)
#define CC_LOCK_INFRA_DCM	(1U << 5)
#define CC_SRCLKENA_MASK_0	(1U << 6)
#define CC_CXO32K_RM_EN_MD1	(1U << 9)
#define CC_CXO32K_RM_EN_MD2	(1U << 10)
#define CC_CLKSQ1_SEL		(1U << 12)
#define CC_DISABLE_DORM_PWR	(1U << 14)
#define CC_MD32_DCM_EN		(1U << 18)

#define ASC_MD_DDR_EN_SEL	(1U << 22)
#define ASC_SRCCLKENI_MASK      (1U << 25) 

#define WFI_OP_AND		1
#define WFI_OP_OR		0
#define SEL_MD_DDR_EN		1
#define SEL_MD_APSRC_REQ	0

#define TWAM_CON_EN		(1U << 0)
#define TWAM_CON_SPEED_EN	(1U << 1)

#define TWAM_MON_TYPE_RISE 0
#define TWAM_MON_TYPE_FALL 1
#define TWAM_MON_TYPE_HIGH 2
#define TWAM_MON_TYPE_LOW 3

#define PCM_MD32_IRQ_SEL	(1U << 4)

#define ISRM_TWAM		(1U << 2)
#define ISRM_PCM_RETURN		(1U << 3)
#define ISRM_RET_IRQ0		(1U << 8)
#define ISRM_RET_IRQ1		(1U << 9)
#define ISRM_RET_IRQ2		(1U << 10)
#define ISRM_RET_IRQ3		(1U << 11)
#define ISRM_RET_IRQ4		(1U << 12)
#define ISRM_RET_IRQ5		(1U << 13)
#define ISRM_RET_IRQ6		(1U << 14)
#define ISRM_RET_IRQ7		(1U << 15)

#define ISRM_RET_IRQ_AUX	(ISRM_RET_IRQ7 | ISRM_RET_IRQ6 |	\
				 ISRM_RET_IRQ5 | ISRM_RET_IRQ4 |	\
				 ISRM_RET_IRQ3 | ISRM_RET_IRQ2 |	\
				 ISRM_RET_IRQ1)
#define ISRM_ALL_EXC_TWAM	(ISRM_RET_IRQ_AUX | ISRM_RET_IRQ0 | ISRM_PCM_RETURN)
#define ISRM_ALL		(ISRM_ALL_EXC_TWAM | ISRM_TWAM)

#define ISRS_TWAM		(1U << 2)
#define ISRS_PCM_RETURN		(1U << 3)
#define ISRS_SW_INT0		(1U << 4)

#define ISRC_TWAM		ISRS_TWAM
#define ISRC_ALL_EXC_TWAM	ISRS_PCM_RETURN
#define ISRC_ALL		(ISRC_ALL_EXC_TWAM | ISRC_TWAM)

#define WAKE_MISC_TWAM		(1U << 16)
#define WAKE_MISC_PCM_TIMER	(1U << 17)
#define WAKE_MISC_CPU_WAKE	(1U << 18)

#define SR_PCM_APSRC_REQ	(1U << 0)
#define SR_PCM_F26M_REQ	        (1U << 1)
#define SR_CCIF0_TO_MD_MASK_B	(1U << 2)
#define SR_CCIF0_TO_AP_MASK_B	(1U << 3)
#define SR_CCIF1_TO_MD_MASK_B	(1U << 4)
#define SR_CCIF1_TO_AP_MASK_B	(1U << 5)

#ifndef CONFIG_MTK_FPGA
#if defined(CONFIG_ARCH_MT6735) || defined(CONFIG_ARCH_MT6735M) || defined(CONFIG_ARCH_MT6753)
#define SPM_VCORE_EN
#endif
#endif

#define SPM_SLEEP_DVFS_STA	SPM_MFG_ASYNC_PWR_CON
#define VCORE_STA_0		(1U << 0)
#define VCORE_STA_1		(1U << 1)
#define VRF18_0_STA		(1U << 8)
#define HPM_REQ_STA		(1U << 9)
#define UHPM_REQ_STA		(1U << 10)

#if defined (CONFIG_OF)
extern void __iomem *i2c4_base;
#endif

struct pcm_desc {
	const char *version;	/* PCM code version */
	const u32 *base;	/* binary array base */
	const u16 size;		/* binary array size */
	const u8 sess;		/* session number */
	const u8 replace;	/* replace mode */

	u32 vec0;		/* event vector 0 config */
	u32 vec1;		/* event vector 1 config */
	u32 vec2;		/* event vector 2 config */
	u32 vec3;		/* event vector 3 config */
	u32 vec4;		/* event vector 4 config */
	u32 vec5;		/* event vector 5 config */
	u32 vec6;		/* event vector 6 config */
	u32 vec7;		/* event vector 7 config */
};

struct pwr_ctrl {
	/* for SPM */
	u32 pcm_flags;
	u32 pcm_flags_cust;	/* can override pcm_flags */
	u32 pcm_reserve;
	u32 timer_val;		/* @ 1T 32K */
	u32 timer_val_cust;	/* @ 1T 32K, can override timer_val */
	u32 wake_src;
	u32 wake_src_cust;	/* can override wake_src */
	u32 wake_src_md32;
	u8 r0_ctrl_en;
	u8 r7_ctrl_en;
	u8 infra_dcm_lock;
	u8 pcm_apsrc_req;
	u8 pcm_f26m_req;

	/* for AP */
	u8 mcusys_idle_mask;
	u8 ca15top_idle_mask;
	u8 ca7top_idle_mask;
	u8 wfi_op;		/* 1:WFI_OP_AND, 0:WFI_OP_OR */
	u8 ca15_wfi0_en;
	u8 ca15_wfi1_en;
	u8 ca15_wfi2_en;
	u8 ca15_wfi3_en;
	u8 ca7_wfi0_en;
	u8 ca7_wfi1_en;
	u8 ca7_wfi2_en;
	u8 ca7_wfi3_en;

	/* for MD */
	u8 md1_req_mask;
	u8 md2_req_mask;
	u8 md_apsrc_sel;	/* 1:SEL_MD_DDR_EN, 0:SEL_MD_APSRC_REQ */
        u8 md2_apsrc_sel;	/* 1:SEL_MD2_DDR_EN, 0:SEL_MD2_APSRC_REQ */
	u8 ccif0_to_ap_mask;
	u8 ccif0_to_md_mask;
	u8 ccif1_to_ap_mask;
	u8 ccif1_to_md_mask;
        u8 lte_mask;
        u8 ccifmd_md1_event_mask;
        u8 ccifmd_md2_event_mask;
	u8 md_vrf18_req_mask_b;

        /* for CONN */
        u8 conn_mask;

	/* for MM */
	u8 gce_req_mask;
	u8 disp_req_mask;
	u8 mfg_req_mask;
	u8 dsi0_ddr_en_mask;	/* E2 */
	u8 dsi1_ddr_en_mask;	/* E2 */
	u8 dpi_ddr_en_mask;	/* E2 */
	u8 isp0_ddr_en_mask;	/* E2 */
	u8 isp1_ddr_en_mask;	/* E2 */

	/* for other SYS */
	u8 md32_req_mask;
	u8 syspwreq_mask;	/* make 26M off when attach ICE */
	u8 srclkenai_mask;

	/* for scenario */
	u32 param1;
	u32 param2;
	u32 param3;
};

struct wake_status {
	u32 assert_pc;		/* PCM_REG_DATA_INI */
	u32 r12;		/* PCM_REG12_DATA */
	u32 raw_sta;		/* SLEEP_ISR_RAW_STA */
	u32 wake_misc;		/* SLEEP_WAKEUP_MISC */
	u32 timer_out;		/* PCM_TIMER_OUT */
	u32 r13;		/* PCM_REG13_DATA */
	u32 idle_sta;		/* SLEEP_SUBSYS_IDLE_STA */
	u32 debug_flag;		/* PCM_PASR_DPD_3 */
	u32 event_reg;		/* PCM_EVENT_REG_STA */
	u32 isr;		/* SLEEP_ISR_STATUS */
	u32 r9;		/* PCM_REG9_DATA */
    u32 log_index;
};

struct spm_lp_scen {
	struct pcm_desc *pcmdesc;
	struct pwr_ctrl *pwrctrl;
    struct wake_status *wakestatus;
};

extern spinlock_t __spm_lock;
extern atomic_t __spm_mainpll_req;

extern struct spm_lp_scen __spm_suspend;
extern struct spm_lp_scen __spm_dpidle;
extern struct spm_lp_scen __spm_sodi;
extern struct spm_lp_scen __spm_mcdi;
extern struct spm_lp_scen __spm_talking;
extern struct spm_lp_scen __spm_ddrdfs;
extern struct spm_lp_scen __spm_vcore_dvfs;

extern void __spm_reset_and_init_pcm(const struct pcm_desc *pcmdesc);
extern void __spm_kick_im_to_fetch(const struct pcm_desc *pcmdesc);

extern void __spm_init_pcm_register(void);	/* init r0 and r7 */
extern void __spm_init_event_vector(const struct pcm_desc *pcmdesc);
extern void __spm_set_power_control(const struct pwr_ctrl *pwrctrl);
extern void __spm_set_wakeup_event(const struct pwr_ctrl *pwrctrl);
extern void __spm_kick_pcm_to_run(const struct pwr_ctrl *pwrctrl);

extern void __spm_get_wakeup_status(struct wake_status *wakesta);
extern void __spm_clean_after_wakeup(void);
extern wake_reason_t __spm_output_wake_reason(const struct wake_status *wakesta,
					      const struct pcm_desc *pcmdesc,
					      bool suspend);

extern void __spm_dbgout_md_ddr_en(bool enable);
extern u32 __spm_dpidle_sodi_set_pmic_setting(void);
extern void __spm_dpidle_sodi_restore_pmic_setting(u32 vsram_vosel_on_lb);

extern int spm_fs_init(void);
#ifndef CONFIG_MTK_FPGA
extern int is_ext_buck_exist(void);
#endif
extern int spm_golden_setting_cmp(bool en);
extern bool spm_set_pcm_init_flag(void);
extern void spm_set_dram_bank_info_pcm_flag(u32 *pcm_flags);
/*
 * if in talking, modify @spm_flags based on @lpscen and return __spm_talking,
 * otherwise, do nothing and return @lpscen
 */
extern struct spm_lp_scen *spm_check_talking_get_lpscen(struct spm_lp_scen *lpscen,
							u32 *spm_flags);

extern void __spm_enable_i2c4_clk(void);
extern void __spm_disable_i2c4_clk(void);

/**************************************
 * Macro and Inline
 **************************************/
#define EVENT_VEC(event, resume, imme, pc)	\
	(((pc) << 16) |				\
	 (!!(imme) << 6) |			\
	 (!!(resume) << 5) |			\
	 ((event) & 0x1f))

#define spm_emerg(fmt, args...)		pr_emerg("[SPM] " fmt, ##args)
#define spm_alert(fmt, args...)		pr_alert("[SPM] " fmt, ##args)
#define spm_crit(fmt, args...)		pr_crit("[SPM] " fmt, ##args)
#define spm_err(fmt, args...)		pr_err("[SPM] " fmt, ##args)
#define spm_warn(fmt, args...)		pr_warn("[SPM] " fmt, ##args)
#define spm_notice(fmt, args...)	pr_notice("[SPM] " fmt, ##args)
#define spm_info(fmt, args...)		pr_info("[SPM] " fmt, ##args)
#define spm_debug(fmt, args...)		pr_info("[SPM] " fmt, ##args)	/* pr_debug show nothing */

/* just use in suspend flow for important log due to console suspend */
#define spm_crit2(fmt, args...)		\
do {					\
	aee_sram_printk(fmt, ##args);	\
	spm_crit(fmt, ##args);		\
} while (0)

#define wfi_with_sync()					\
do {							\
	isb();						\
	dsb();						\
	__asm__ __volatile__("wfi" : : : "memory");	\
} while (0)

static inline u32 base_va_to_pa(const u32 *base)
{
	phys_addr_t pa = virt_to_phys(base);
	MAPPING_DRAM_ACCESS_ADDR(pa);	/* for 4GB mode */
	return (u32)pa;
}

static inline void set_pwrctrl_pcm_flags(struct pwr_ctrl *pwrctrl, u32 flags)
{
#ifndef CONFIG_MTK_FPGA
   #if defined(CONFIG_ARCH_MT6735)
   #elif defined(CONFIG_ARCH_MT6735M)	
   #elif defined(CONFIG_ARCH_MT6753)
   //~~~Do something in D3
      if(is_ext_buck_exist())
         flags |= SPM_BUCK_SEL;
	    else		
	    	flags &= ~SPM_BUCK_SEL;// D3 change to bit26  
   #else
   //ERROR
   #endif
#endif
	spm_set_dram_bank_info_pcm_flag(&flags);

#ifdef SPM_VCORE_EN
	if (is_vcorefs_can_work())
		flags |= SPM_VCORE_DVFS_EN;
#endif

	if (pwrctrl->pcm_flags_cust == 0)
		pwrctrl->pcm_flags = flags;
	else
		pwrctrl->pcm_flags = pwrctrl->pcm_flags_cust;
}

static inline void set_pwrctrl_pcm_data(struct pwr_ctrl *pwrctrl, u32 data)
{
	pwrctrl->pcm_reserve = data;
}

static inline void set_flags_for_mainpll(u32 *flags)
{
	#if 0 /* mt6735 pcm flag bit 8 changed */ 
	if (atomic_read(&__spm_mainpll_req) != 0)
		*flags |= SPM_MAINPLL_PDN_DIS;
	else
		*flags &= ~SPM_MAINPLL_PDN_DIS;
	#endif
}

#endif