blob: bf806972858a951bbf79a1ddf639d7c4ae4123d1 [file] [log] [blame]
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +02001/*
Biju Dasf51d74f2020-12-13 20:05:24 +00002 * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00007#include <common/debug.h>
8#include <lib/mmio.h>
9
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020010#include "cpg_registers.h"
11#include "iic_dvfs.h"
Biju Dasf51d74f2020-12-13 20:05:24 +000012#include "rcar_def.h"
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020013#include "rcar_private.h"
14
15#define DVFS_RETRY_MAX (2U)
16
Biju Dasf51d74f2020-12-13 20:05:24 +000017#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_0 (0x07U)
18#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_1 (0x09U)
19#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_2 (0x0BU)
20#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_3 (0x0EU)
21#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_E (0x15U)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020022
Biju Dasf51d74f2020-12-13 20:05:24 +000023#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_0 (0x01U)
24#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_1 (0x02U)
25#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_2 (0x03U)
26#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_3 (0x05U)
27#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_E (0x07U)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020028
Biju Dasf51d74f2020-12-13 20:05:24 +000029#define CPG_BIT_SMSTPCR9_DVFS (0x04000000U)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020030
Biju Dasf51d74f2020-12-13 20:05:24 +000031#define IIC_DVFS_REG_BASE (0xE60B0000U)
32#define IIC_DVFS_REG_ICDR (IIC_DVFS_REG_BASE + 0x0000U)
33#define IIC_DVFS_REG_ICCR (IIC_DVFS_REG_BASE + 0x0004U)
34#define IIC_DVFS_REG_ICSR (IIC_DVFS_REG_BASE + 0x0008U)
35#define IIC_DVFS_REG_ICIC (IIC_DVFS_REG_BASE + 0x000CU)
36#define IIC_DVFS_REG_ICCL (IIC_DVFS_REG_BASE + 0x0010U)
37#define IIC_DVFS_REG_ICCH (IIC_DVFS_REG_BASE + 0x0014U)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020038
Biju Dasf51d74f2020-12-13 20:05:24 +000039#define IIC_DVFS_BIT_ICSR_BUSY (0x10U)
40#define IIC_DVFS_BIT_ICSR_AL (0x08U)
41#define IIC_DVFS_BIT_ICSR_TACK (0x04U)
42#define IIC_DVFS_BIT_ICSR_WAIT (0x02U)
43#define IIC_DVFS_BIT_ICSR_DTE (0x01U)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020044
Biju Dasf51d74f2020-12-13 20:05:24 +000045#define IIC_DVFS_BIT_ICCR_ENABLE (0x80U)
46#define IIC_DVFS_SET_ICCR_START (0x94U)
47#define IIC_DVFS_SET_ICCR_STOP (0x90U)
48#define IIC_DVFS_SET_ICCR_RETRANSMISSION (0x94U)
49#define IIC_DVFS_SET_ICCR_CHANGE (0x81U)
50#define IIC_DVFS_SET_ICCR_STOP_READ (0xC0U)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020051
Biju Dasf51d74f2020-12-13 20:05:24 +000052#define IIC_DVFS_BIT_ICIC_TACKE (0x04U)
53#define IIC_DVFS_BIT_ICIC_WAITE (0x02U)
54#define IIC_DVFS_BIT_ICIC_DTEE (0x01U)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020055
Biju Dasf51d74f2020-12-13 20:05:24 +000056#define DVFS_READ_MODE (0x01U)
57#define DVFS_WRITE_MODE (0x00U)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020058
Biju Dasf51d74f2020-12-13 20:05:24 +000059#define IIC_DVFS_SET_DUMMY (0x52U)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020060#define IIC_DVFS_SET_BUSY_LOOP (500000000U)
61
Biju Dasf51d74f2020-12-13 20:05:24 +000062enum dvfs_state_t {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020063 DVFS_START = 0,
64 DVFS_STOP,
65 DVFS_RETRANSMIT,
66 DVFS_READ,
67 DVFS_STOP_READ,
68 DVFS_SET_SLAVE_READ,
69 DVFS_SET_SLAVE,
70 DVFS_WRITE_ADDR,
71 DVFS_WRITE_DATA,
Biju Dasf51d74f2020-12-13 20:05:24 +000072 DVFS_CHANGE_SEND_TO_RECEIVE,
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020073 DVFS_DONE,
Biju Dasf51d74f2020-12-13 20:05:24 +000074};
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020075
76#define DVFS_PROCESS (1)
77#define DVFS_COMPLETE (0)
78#define DVFS_ERROR (-1)
79
80#if IMAGE_BL31
81#define IIC_DVFS_FUNC(__name, ...) \
Biju Dasf51d74f2020-12-13 20:05:24 +000082static int32_t __attribute__ ((section(".system_ram"))) \
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020083dvfs_ ##__name(__VA_ARGS__)
84
85#define RCAR_DVFS_API(__name, ...) \
Biju Dasf51d74f2020-12-13 20:05:24 +000086int32_t __attribute__ ((section(".system_ram"))) \
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020087rcar_iic_dvfs_ ##__name(__VA_ARGS__)
88
89#else
Biju Dasf51d74f2020-12-13 20:05:24 +000090#define IIC_DVFS_FUNC(__name, ...) \
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020091static int32_t dvfs_ ##__name(__VA_ARGS__)
92
93#define RCAR_DVFS_API(__name, ...) \
94int32_t rcar_iic_dvfs_ ##__name(__VA_ARGS__)
95#endif
96
Biju Dasf51d74f2020-12-13 20:05:24 +000097IIC_DVFS_FUNC(check_error, enum dvfs_state_t *state, uint32_t *err, uint8_t mode)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +020098{
Biju Dasf51d74f2020-12-13 20:05:24 +000099 uint8_t icsr_al = 0U, icsr_tack = 0U;
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200100 uint8_t reg, stop;
Biju Dasf51d74f2020-12-13 20:05:24 +0000101 uint32_t i = 0U;
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200102
103 stop = mode == DVFS_READ_MODE ? IIC_DVFS_SET_ICCR_STOP_READ :
104 IIC_DVFS_SET_ICCR_STOP;
105
106 reg = mmio_read_8(IIC_DVFS_REG_ICSR);
107 icsr_al = (reg & IIC_DVFS_BIT_ICSR_AL) == IIC_DVFS_BIT_ICSR_AL;
108 icsr_tack = (reg & IIC_DVFS_BIT_ICSR_TACK) == IIC_DVFS_BIT_ICSR_TACK;
109
Biju Dasf51d74f2020-12-13 20:05:24 +0000110 if (icsr_al == 0U && icsr_tack == 0U) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200111 return DVFS_PROCESS;
Biju Dasf51d74f2020-12-13 20:05:24 +0000112 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200113
114 if (icsr_al) {
115 reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_AL;
116 mmio_write_8(IIC_DVFS_REG_ICSR, reg);
117
Biju Dasf51d74f2020-12-13 20:05:24 +0000118 if (*state == DVFS_SET_SLAVE) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200119 mmio_write_8(IIC_DVFS_REG_ICDR, IIC_DVFS_SET_DUMMY);
Biju Dasf51d74f2020-12-13 20:05:24 +0000120 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200121
122 do {
123 reg = mmio_read_8(IIC_DVFS_REG_ICSR) &
124 IIC_DVFS_BIT_ICSR_WAIT;
Biju Dasf51d74f2020-12-13 20:05:24 +0000125 } while (reg == 0U);
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200126
127 mmio_write_8(IIC_DVFS_REG_ICCR, stop);
128
129 reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
130 mmio_write_8(IIC_DVFS_REG_ICSR, reg);
131
Biju Dasf51d74f2020-12-13 20:05:24 +0000132 i = 0U;
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200133 do {
134 reg = mmio_read_8(IIC_DVFS_REG_ICSR) &
135 IIC_DVFS_BIT_ICSR_BUSY;
Biju Dasf51d74f2020-12-13 20:05:24 +0000136 if (reg == 0U) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200137 break;
Biju Dasf51d74f2020-12-13 20:05:24 +0000138 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200139
Biju Dasf51d74f2020-12-13 20:05:24 +0000140 if (i++ > IIC_DVFS_SET_BUSY_LOOP) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200141 panic();
Biju Dasf51d74f2020-12-13 20:05:24 +0000142 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200143
Biju Dasf51d74f2020-12-13 20:05:24 +0000144 } while (true);
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200145
146 mmio_write_8(IIC_DVFS_REG_ICCR, 0x00U);
147
148 (*err)++;
Biju Dasf51d74f2020-12-13 20:05:24 +0000149 if (*err > DVFS_RETRY_MAX) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200150 return DVFS_ERROR;
Biju Dasf51d74f2020-12-13 20:05:24 +0000151 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200152
153 *state = DVFS_START;
154
155 return DVFS_PROCESS;
156
157 }
158
159 /* icsr_tack */
160 mmio_write_8(IIC_DVFS_REG_ICCR, stop);
161
162 reg = mmio_read_8(IIC_DVFS_REG_ICIC);
163 reg &= ~(IIC_DVFS_BIT_ICIC_WAITE | IIC_DVFS_BIT_ICIC_DTEE);
164 mmio_write_8(IIC_DVFS_REG_ICIC, reg);
165
166 reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_TACK;
167 mmio_write_8(IIC_DVFS_REG_ICSR, reg);
168
Biju Dasf51d74f2020-12-13 20:05:24 +0000169 i = 0U;
170 while ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0U) {
171 if (i++ > IIC_DVFS_SET_BUSY_LOOP) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200172 panic();
Biju Dasf51d74f2020-12-13 20:05:24 +0000173 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200174 }
175
Biju Dasf51d74f2020-12-13 20:05:24 +0000176 mmio_write_8(IIC_DVFS_REG_ICCR, 0U);
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200177 (*err)++;
178
Biju Dasf51d74f2020-12-13 20:05:24 +0000179 if (*err > DVFS_RETRY_MAX) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200180 return DVFS_ERROR;
Biju Dasf51d74f2020-12-13 20:05:24 +0000181 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200182
183 *state = DVFS_START;
184
185 return DVFS_PROCESS;
186}
187
Biju Dasf51d74f2020-12-13 20:05:24 +0000188IIC_DVFS_FUNC(start, enum dvfs_state_t *state)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200189{
190 uint8_t iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_E;
191 uint8_t icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_E;
192 int32_t result = DVFS_PROCESS;
193 uint32_t reg, lsi_product;
194 uint8_t mode;
195
196 mode = mmio_read_8(IIC_DVFS_REG_ICCR) | IIC_DVFS_BIT_ICCR_ENABLE;
197 mmio_write_8(IIC_DVFS_REG_ICCR, mode);
198
Marek Vasut9cadc782019-08-06 19:13:22 +0200199 lsi_product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK;
Biju Dasf51d74f2020-12-13 20:05:24 +0000200 if (lsi_product == PRR_PRODUCT_E3) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200201 goto start;
Biju Dasf51d74f2020-12-13 20:05:24 +0000202 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200203
204 reg = mmio_read_32(RCAR_MODEMR) & CHECK_MD13_MD14;
205 switch (reg) {
206 case MD14_MD13_TYPE_0:
207 iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_0;
208 icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_0;
209 break;
210 case MD14_MD13_TYPE_1:
211 iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_1;
212 icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_1;
213 break;
214 case MD14_MD13_TYPE_2:
215 iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_2;
216 icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_2;
217 break;
218 default:
219 iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_3;
220 icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_3;
221 break;
222 }
223start:
224 mmio_write_8(IIC_DVFS_REG_ICCL, iccl);
225 mmio_write_8(IIC_DVFS_REG_ICCH, icch);
226
227 mode = mmio_read_8(IIC_DVFS_REG_ICIC)
228 | IIC_DVFS_BIT_ICIC_TACKE
229 | IIC_DVFS_BIT_ICIC_WAITE | IIC_DVFS_BIT_ICIC_DTEE;
230
231 mmio_write_8(IIC_DVFS_REG_ICIC, mode);
232 mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_START);
233
234 *state = DVFS_SET_SLAVE;
235
236 return result;
237}
238
Biju Dasf51d74f2020-12-13 20:05:24 +0000239IIC_DVFS_FUNC(set_slave, enum dvfs_state_t *state, uint32_t *err, uint8_t slave)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200240{
241 uint8_t mode;
242 int32_t result;
243 uint8_t address;
244
245 result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
Biju Dasf51d74f2020-12-13 20:05:24 +0000246 if (result == DVFS_ERROR) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200247 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000248 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200249
250 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE;
Biju Dasf51d74f2020-12-13 20:05:24 +0000251 if (mode != IIC_DVFS_BIT_ICSR_DTE) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200252 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000253 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200254
255 mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE;
256 mmio_write_8(IIC_DVFS_REG_ICIC, mode);
257
258 address = slave << 1;
259 mmio_write_8(IIC_DVFS_REG_ICDR, address);
260
261 *state = DVFS_WRITE_ADDR;
262
263 return result;
264}
265
Biju Dasf51d74f2020-12-13 20:05:24 +0000266IIC_DVFS_FUNC(write_addr, enum dvfs_state_t *state, uint32_t *err, uint8_t reg_addr)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200267{
268 uint8_t mode;
269 int32_t result;
270
271 result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
Biju Dasf51d74f2020-12-13 20:05:24 +0000272 if (result == DVFS_ERROR) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200273 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000274 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200275
276 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
Biju Dasf51d74f2020-12-13 20:05:24 +0000277 if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200278 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000279 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200280
281 mmio_write_8(IIC_DVFS_REG_ICDR, reg_addr);
282
283 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
284 mmio_write_8(IIC_DVFS_REG_ICSR, mode);
285
286 *state = DVFS_WRITE_DATA;
287
288 return result;
289}
290
Biju Dasf51d74f2020-12-13 20:05:24 +0000291IIC_DVFS_FUNC(write_data, enum dvfs_state_t *state, uint32_t *err,
292 uint8_t reg_data)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200293{
294 int32_t result;
295 uint8_t mode;
296
297 result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
Biju Dasf51d74f2020-12-13 20:05:24 +0000298 if (result == DVFS_ERROR) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200299 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000300 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200301
302 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
Biju Dasf51d74f2020-12-13 20:05:24 +0000303 if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200304 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000305 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200306
307 mmio_write_8(IIC_DVFS_REG_ICDR, reg_data);
308
309 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
310 mmio_write_8(IIC_DVFS_REG_ICSR, mode);
311
312 *state = DVFS_STOP;
313
314 return result;
315}
316
Biju Dasf51d74f2020-12-13 20:05:24 +0000317IIC_DVFS_FUNC(stop, enum dvfs_state_t *state, uint32_t *err)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200318{
319 int32_t result;
320 uint8_t mode;
321
322 result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
Biju Dasf51d74f2020-12-13 20:05:24 +0000323 if (result == DVFS_ERROR) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200324 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000325 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200326
327 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
Biju Dasf51d74f2020-12-13 20:05:24 +0000328 if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200329 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000330 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200331
332 mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_STOP);
333
334 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
335 mmio_write_8(IIC_DVFS_REG_ICSR, mode);
336
337 *state = DVFS_DONE;
338
339 return result;
340}
341
342IIC_DVFS_FUNC(done, void)
343{
344 uint32_t i;
345
Biju Dasf51d74f2020-12-13 20:05:24 +0000346 for (i = 0U; i < IIC_DVFS_SET_BUSY_LOOP; i++) {
347 if ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0U) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200348 continue;
Biju Dasf51d74f2020-12-13 20:05:24 +0000349 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200350 goto done;
351 }
352
353 panic();
354done:
Biju Dasf51d74f2020-12-13 20:05:24 +0000355 mmio_write_8(IIC_DVFS_REG_ICCR, 0U);
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200356
357 return DVFS_COMPLETE;
358}
359
Biju Dasf51d74f2020-12-13 20:05:24 +0000360IIC_DVFS_FUNC(write_reg_addr_read, enum dvfs_state_t *state, uint32_t *err,
361 uint8_t reg_addr)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200362{
363 int32_t result;
364 uint8_t mode;
365
366 result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
Biju Dasf51d74f2020-12-13 20:05:24 +0000367 if (result == DVFS_ERROR) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200368 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000369 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200370
371 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
Biju Dasf51d74f2020-12-13 20:05:24 +0000372 if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200373 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000374 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200375
376 mmio_write_8(IIC_DVFS_REG_ICDR, reg_addr);
377
378 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
379 mmio_write_8(IIC_DVFS_REG_ICSR, mode);
380
381 *state = DVFS_RETRANSMIT;
382
383 return result;
384}
385
Biju Dasf51d74f2020-12-13 20:05:24 +0000386IIC_DVFS_FUNC(retransmit, enum dvfs_state_t *state, uint32_t *err)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200387{
388 int32_t result;
389 uint8_t mode;
390
391 result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
Biju Dasf51d74f2020-12-13 20:05:24 +0000392 if (result == DVFS_ERROR) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200393 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000394 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200395
396 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
Biju Dasf51d74f2020-12-13 20:05:24 +0000397 if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200398 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000399 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200400
401 mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_RETRANSMISSION);
402
403 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
404 mmio_write_8(IIC_DVFS_REG_ICSR, mode);
405
406 mode = mmio_read_8(IIC_DVFS_REG_ICIC) | IIC_DVFS_BIT_ICIC_DTEE;
407 mmio_write_8(IIC_DVFS_REG_ICIC, mode);
408
409 *state = DVFS_SET_SLAVE_READ;
410
411 return result;
412}
413
Biju Dasf51d74f2020-12-13 20:05:24 +0000414IIC_DVFS_FUNC(set_slave_read, enum dvfs_state_t *state, uint32_t *err,
415 uint8_t slave)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200416{
417 uint8_t address;
418 int32_t result;
419 uint8_t mode;
420
421 result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
Biju Dasf51d74f2020-12-13 20:05:24 +0000422 if (result == DVFS_ERROR) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200423 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000424 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200425
426 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE;
Biju Dasf51d74f2020-12-13 20:05:24 +0000427 if (mode != IIC_DVFS_BIT_ICSR_DTE) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200428 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000429 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200430
431 mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE;
432 mmio_write_8(IIC_DVFS_REG_ICIC, mode);
433
434 address = ((uint8_t) (slave << 1) + DVFS_READ_MODE);
435 mmio_write_8(IIC_DVFS_REG_ICDR, address);
436
Biju Dasf51d74f2020-12-13 20:05:24 +0000437 *state = DVFS_CHANGE_SEND_TO_RECEIVE;
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200438
439 return result;
440}
441
Biju Dasf51d74f2020-12-13 20:05:24 +0000442IIC_DVFS_FUNC(change_send_to_receive, enum dvfs_state_t *state, uint32_t *err)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200443{
444 int32_t result;
445 uint8_t mode;
446
447 result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
Biju Dasf51d74f2020-12-13 20:05:24 +0000448 if (result == DVFS_ERROR) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200449 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000450 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200451
452 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
Biju Dasf51d74f2020-12-13 20:05:24 +0000453 if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200454 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000455 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200456
457 mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_CHANGE);
458
459 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
460 mmio_write_8(IIC_DVFS_REG_ICSR, mode);
461
462 *state = DVFS_STOP_READ;
463
464 return result;
465}
466
Biju Dasf51d74f2020-12-13 20:05:24 +0000467IIC_DVFS_FUNC(stop_read, enum dvfs_state_t *state, uint32_t *err)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200468{
469 int32_t result;
470 uint8_t mode;
471
472 result = dvfs_check_error(state, err, DVFS_READ_MODE);
Biju Dasf51d74f2020-12-13 20:05:24 +0000473 if (result == DVFS_ERROR) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200474 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000475 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200476
477 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
Biju Dasf51d74f2020-12-13 20:05:24 +0000478 if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200479 return result;
Biju Dasf51d74f2020-12-13 20:05:24 +0000480 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200481
482 mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_STOP_READ);
483
484 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
485 mmio_write_8(IIC_DVFS_REG_ICSR, mode);
486
487 mode = mmio_read_8(IIC_DVFS_REG_ICIC) | IIC_DVFS_BIT_ICIC_DTEE;
488 mmio_write_8(IIC_DVFS_REG_ICIC, mode);
489
490 *state = DVFS_READ;
491
492 return result;
493}
494
Biju Dasf51d74f2020-12-13 20:05:24 +0000495IIC_DVFS_FUNC(read, enum dvfs_state_t *state, uint8_t *reg_data)
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200496{
497 uint8_t mode;
498
499 mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE;
Biju Dasf51d74f2020-12-13 20:05:24 +0000500 if (mode != IIC_DVFS_BIT_ICSR_DTE) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200501 return DVFS_PROCESS;
Biju Dasf51d74f2020-12-13 20:05:24 +0000502 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200503
504 mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE;
505 mmio_write_8(IIC_DVFS_REG_ICIC, mode);
506
507 *reg_data = mmio_read_8(IIC_DVFS_REG_ICDR);
508 *state = DVFS_DONE;
509
510 return DVFS_PROCESS;
511}
512
513RCAR_DVFS_API(send, uint8_t slave, uint8_t reg_addr, uint8_t reg_data)
514{
Biju Dasf51d74f2020-12-13 20:05:24 +0000515 enum dvfs_state_t state = DVFS_START;
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200516 int32_t result = DVFS_PROCESS;
Biju Dasf51d74f2020-12-13 20:05:24 +0000517 uint32_t err = 0U;
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200518
519 mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS);
Toshiyuki Ogasahara6552f642020-11-30 20:42:27 +0900520 mmio_write_8(IIC_DVFS_REG_ICCR, 1U);
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200521again:
522 switch (state) {
523 case DVFS_START:
524 result = dvfs_start(&state);
525 break;
526 case DVFS_SET_SLAVE:
527 result = dvfs_set_slave(&state, &err, slave);
528 break;
529 case DVFS_WRITE_ADDR:
530 result = dvfs_write_addr(&state, &err, reg_addr);
531 break;
532 case DVFS_WRITE_DATA:
533 result = dvfs_write_data(&state, &err, reg_data);
534 break;
535 case DVFS_STOP:
536 result = dvfs_stop(&state, &err);
537 break;
538 case DVFS_DONE:
539 result = dvfs_done();
540 break;
541 default:
542 panic();
543 break;
544 }
545
Biju Dasf51d74f2020-12-13 20:05:24 +0000546 if (result == DVFS_PROCESS) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200547 goto again;
Biju Dasf51d74f2020-12-13 20:05:24 +0000548 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200549
550 return result;
551}
552
553RCAR_DVFS_API(receive, uint8_t slave, uint8_t reg, uint8_t *data)
554{
Biju Dasf51d74f2020-12-13 20:05:24 +0000555 enum dvfs_state_t state = DVFS_START;
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200556 int32_t result = DVFS_PROCESS;
Biju Dasf51d74f2020-12-13 20:05:24 +0000557 uint32_t err = 0U;
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200558
559 mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS);
Toshiyuki Ogasahara6552f642020-11-30 20:42:27 +0900560 mmio_write_8(IIC_DVFS_REG_ICCR, 1U);
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200561again:
562 switch (state) {
563 case DVFS_START:
564 result = dvfs_start(&state);
565 break;
566 case DVFS_SET_SLAVE:
567 result = dvfs_set_slave(&state, &err, slave);
568 break;
569 case DVFS_WRITE_ADDR:
570 result = dvfs_write_reg_addr_read(&state, &err, reg);
571 break;
572 case DVFS_RETRANSMIT:
573 result = dvfs_retransmit(&state, &err);
574 break;
575 case DVFS_SET_SLAVE_READ:
576 result = dvfs_set_slave_read(&state, &err, slave);
577 break;
Biju Dasf51d74f2020-12-13 20:05:24 +0000578 case DVFS_CHANGE_SEND_TO_RECEIVE:
579 result = dvfs_change_send_to_receive(&state, &err);
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200580 break;
581 case DVFS_STOP_READ:
582 result = dvfs_stop_read(&state, &err);
583 break;
584 case DVFS_READ:
585 result = dvfs_read(&state, data);
586 break;
587 case DVFS_DONE:
588 result = dvfs_done();
589 break;
590 default:
591 panic();
592 break;
593 }
594
Biju Dasf51d74f2020-12-13 20:05:24 +0000595 if (result == DVFS_PROCESS) {
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200596 goto again;
Biju Dasf51d74f2020-12-13 20:05:24 +0000597 }
Jorge Ramirez-Ortizab853b02018-09-23 09:40:26 +0200598
599 return result;
600}