1 /*
2  * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <common/debug.h>
8 #include <lib/mmio.h>
9 
10 #include "dram_sub_func.h"
11 #include "rcar_def.h"
12 
13 #if RCAR_SYSTEM_SUSPEND
14 /* Local defines */
15 #define DRAM_BACKUP_GPIO_USE		0
16 #include "iic_dvfs.h"
17 #if PMIC_ROHM_BD9571
18 #define	PMIC_SLAVE_ADDR			0x30U
19 #define	PMIC_BKUP_MODE_CNT		0x20U
20 #define	PMIC_QLLM_CNT			0x27U
21 #define	BIT_BKUP_CTRL_OUT		BIT(4)
22 #define	BIT_QLLM_DDR0_EN		BIT(0)
23 #define	BIT_QLLM_DDR1_EN		BIT(1)
24 #endif
25 
26 #define GPIO_BKUP_REQB_SHIFT_SALVATOR	9U	/* GP1_9 (BKUP_REQB) */
27 #define GPIO_BKUP_TRG_SHIFT_SALVATOR	8U	/* GP1_8 (BKUP_TRG) */
28 #define GPIO_BKUP_REQB_SHIFT_EBISU	14U	/* GP6_14(BKUP_REQB) */
29 #define GPIO_BKUP_TRG_SHIFT_EBISU	13U	/* GP6_13(BKUP_TRG) */
30 #define GPIO_BKUP_REQB_SHIFT_CONDOR	1U	/* GP3_1 (BKUP_REQB) */
31 #define GPIO_BKUP_TRG_SHIFT_CONDOR	0U	/* GP3_0 (BKUP_TRG) */
32 
33 #define DRAM_BKUP_TRG_LOOP_CNT		1000U
34 #endif
35 
rcar_dram_get_boot_status(uint32_t * status)36 void rcar_dram_get_boot_status(uint32_t *status)
37 {
38 #if RCAR_SYSTEM_SUSPEND
39 	uint32_t reg_data;
40 	uint32_t product;
41 	uint32_t shift;
42 	uint32_t gpio;
43 
44 	product = mmio_read_32(PRR) & PRR_PRODUCT_MASK;
45 	if (product == PRR_PRODUCT_V3H) {
46 		shift = GPIO_BKUP_TRG_SHIFT_CONDOR;
47 		gpio = GPIO_INDT3;
48 	} else if (product == PRR_PRODUCT_E3) {
49 		shift = GPIO_BKUP_TRG_SHIFT_EBISU;
50 		gpio = GPIO_INDT6;
51 	} else {
52 		shift = GPIO_BKUP_TRG_SHIFT_SALVATOR;
53 		gpio = GPIO_INDT1;
54 	}
55 
56 	reg_data = mmio_read_32(gpio);
57 	if (reg_data & BIT(shift))
58 		*status = DRAM_BOOT_STATUS_WARM;
59 	else
60 		*status = DRAM_BOOT_STATUS_COLD;
61 #else	/* RCAR_SYSTEM_SUSPEND */
62 	*status = DRAM_BOOT_STATUS_COLD;
63 #endif	/* RCAR_SYSTEM_SUSPEND */
64 }
65 
rcar_dram_update_boot_status(uint32_t status)66 int32_t rcar_dram_update_boot_status(uint32_t status)
67 {
68 	int32_t ret = 0;
69 #if RCAR_SYSTEM_SUSPEND
70 	uint32_t reg_data;
71 #if PMIC_ROHM_BD9571
72 #if DRAM_BACKUP_GPIO_USE == 0
73 	uint8_t bkup_mode_cnt = 0U;
74 #else
75 	uint32_t reqb, outd;
76 #endif
77 	uint8_t qllm_cnt = 0U;
78 	int32_t i2c_dvfs_ret = -1;
79 #endif
80 	uint32_t loop_count;
81 	uint32_t product;
82 	uint32_t trg;
83 	uint32_t gpio;
84 
85 	product = mmio_read_32(PRR) & PRR_PRODUCT_MASK;
86 	if (product == PRR_PRODUCT_V3H) {
87 #if DRAM_BACKUP_GPIO_USE == 1
88 		reqb = GPIO_BKUP_REQB_SHIFT_CONDOR;
89 		outd = GPIO_OUTDT3;
90 #endif
91 		trg = GPIO_BKUP_TRG_SHIFT_CONDOR;
92 		gpio = GPIO_INDT3;
93 	} else if (product == PRR_PRODUCT_E3) {
94 #if DRAM_BACKUP_GPIO_USE == 1
95 		reqb = GPIO_BKUP_REQB_SHIFT_EBISU;
96 		outd = GPIO_OUTDT6;
97 #endif
98 		trg = GPIO_BKUP_TRG_SHIFT_EBISU;
99 		gpio = GPIO_INDT6;
100 	} else {
101 #if DRAM_BACKUP_GPIO_USE == 1
102 		reqb = GPIO_BKUP_REQB_SHIFT_SALVATOR;
103 		outd = GPIO_OUTDT1;
104 #endif
105 		trg = GPIO_BKUP_TRG_SHIFT_SALVATOR;
106 		gpio = GPIO_INDT1;
107 	}
108 
109 	if (status == DRAM_BOOT_STATUS_WARM) {
110 #if DRAM_BACKUP_GPIO_USE == 1
111 		mmio_setbits_32(outd, BIT(reqb));
112 #else
113 #if PMIC_ROHM_BD9571
114 		/* Set BKUP_CRTL_OUT=High (BKUP mode cnt register) */
115 		i2c_dvfs_ret = rcar_iic_dvfs_receive(PMIC_SLAVE_ADDR,
116 						     PMIC_BKUP_MODE_CNT,
117 						     &bkup_mode_cnt);
118 		if (i2c_dvfs_ret) {
119 			ERROR("BKUP mode cnt READ ERROR.\n");
120 			ret = DRAM_UPDATE_STATUS_ERR;
121 		} else {
122 			bkup_mode_cnt &= (uint8_t)~BIT_BKUP_CTRL_OUT;
123 			i2c_dvfs_ret = rcar_iic_dvfs_send(PMIC_SLAVE_ADDR,
124 							  PMIC_BKUP_MODE_CNT,
125 							  bkup_mode_cnt);
126 			if (i2c_dvfs_ret) {
127 				ERROR("BKUP mode cnt WRITE ERROR. value = %d\n",
128 				      bkup_mode_cnt);
129 				ret = DRAM_UPDATE_STATUS_ERR;
130 			}
131 		}
132 #endif /* PMIC_ROHM_BD9571 */
133 #endif /* DRAM_BACKUP_GPIO_USE == 1 */
134 		/* Wait BKUP_TRG=Low */
135 		loop_count = DRAM_BKUP_TRG_LOOP_CNT;
136 		while (loop_count > 0) {
137 			reg_data = mmio_read_32(gpio);
138 			if (!(reg_data & BIT(trg)))
139 				break;
140 			loop_count--;
141 		}
142 
143 		if (!loop_count) {
144 			ERROR("\nWarm booting...\n"
145 			      " The potential of BKUP_TRG did not switch to Low.\n"
146 			      " If you expect the operation of cold boot,\n"
147 			      " check the board configuration (ex, Dip-SW) and/or the H/W failure.\n");
148 			ret = DRAM_UPDATE_STATUS_ERR;
149 		}
150 	}
151 #if PMIC_ROHM_BD9571
152 	if (!ret) {
153 		qllm_cnt = BIT_QLLM_DDR0_EN | BIT_QLLM_DDR1_EN;
154 		i2c_dvfs_ret = rcar_iic_dvfs_send(PMIC_SLAVE_ADDR,
155 						  PMIC_QLLM_CNT,
156 						  qllm_cnt);
157 		if (i2c_dvfs_ret) {
158 			ERROR("QLLM cnt WRITE ERROR. value = %d\n", qllm_cnt);
159 			ret = DRAM_UPDATE_STATUS_ERR;
160 		}
161 	}
162 #endif
163 #endif
164 	return ret;
165 }
166