1be92e5a2SBiju Das /*
2be92e5a2SBiju Das * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
3be92e5a2SBiju Das *
4be92e5a2SBiju Das * SPDX-License-Identifier: BSD-3-Clause
5be92e5a2SBiju Das */
6be92e5a2SBiju Das
7be92e5a2SBiju Das #include <common/debug.h>
8be92e5a2SBiju Das #include <lib/mmio.h>
9be92e5a2SBiju Das
10be92e5a2SBiju Das #include "cpg_registers.h"
11be92e5a2SBiju Das #include "iic_dvfs.h"
12be92e5a2SBiju Das #include "rcar_def.h"
13be92e5a2SBiju Das #include "rcar_private.h"
14be92e5a2SBiju Das
15be92e5a2SBiju Das #define DVFS_RETRY_MAX (2U)
16be92e5a2SBiju Das
17be92e5a2SBiju Das #define IIC_DVFS_SET_ICCL_EXTAL_TYPE_0 (0x07U)
18be92e5a2SBiju Das #define IIC_DVFS_SET_ICCL_EXTAL_TYPE_1 (0x09U)
19be92e5a2SBiju Das #define IIC_DVFS_SET_ICCL_EXTAL_TYPE_2 (0x0BU)
20be92e5a2SBiju Das #define IIC_DVFS_SET_ICCL_EXTAL_TYPE_3 (0x0EU)
21be92e5a2SBiju Das #define IIC_DVFS_SET_ICCL_EXTAL_TYPE_E (0x15U)
22be92e5a2SBiju Das
23be92e5a2SBiju Das #define IIC_DVFS_SET_ICCH_EXTAL_TYPE_0 (0x01U)
24be92e5a2SBiju Das #define IIC_DVFS_SET_ICCH_EXTAL_TYPE_1 (0x02U)
25be92e5a2SBiju Das #define IIC_DVFS_SET_ICCH_EXTAL_TYPE_2 (0x03U)
26be92e5a2SBiju Das #define IIC_DVFS_SET_ICCH_EXTAL_TYPE_3 (0x05U)
27be92e5a2SBiju Das #define IIC_DVFS_SET_ICCH_EXTAL_TYPE_E (0x07U)
28be92e5a2SBiju Das
29be92e5a2SBiju Das #define CPG_BIT_SMSTPCR9_DVFS (0x04000000U)
30be92e5a2SBiju Das
31be92e5a2SBiju Das #define IIC_DVFS_REG_BASE (0xE60B0000U)
32be92e5a2SBiju Das #define IIC_DVFS_REG_ICDR (IIC_DVFS_REG_BASE + 0x0000U)
33be92e5a2SBiju Das #define IIC_DVFS_REG_ICCR (IIC_DVFS_REG_BASE + 0x0004U)
34be92e5a2SBiju Das #define IIC_DVFS_REG_ICSR (IIC_DVFS_REG_BASE + 0x0008U)
35be92e5a2SBiju Das #define IIC_DVFS_REG_ICIC (IIC_DVFS_REG_BASE + 0x000CU)
36be92e5a2SBiju Das #define IIC_DVFS_REG_ICCL (IIC_DVFS_REG_BASE + 0x0010U)
37be92e5a2SBiju Das #define IIC_DVFS_REG_ICCH (IIC_DVFS_REG_BASE + 0x0014U)
38be92e5a2SBiju Das
39be92e5a2SBiju Das #define IIC_DVFS_BIT_ICSR_BUSY (0x10U)
40be92e5a2SBiju Das #define IIC_DVFS_BIT_ICSR_AL (0x08U)
41be92e5a2SBiju Das #define IIC_DVFS_BIT_ICSR_TACK (0x04U)
42be92e5a2SBiju Das #define IIC_DVFS_BIT_ICSR_WAIT (0x02U)
43be92e5a2SBiju Das #define IIC_DVFS_BIT_ICSR_DTE (0x01U)
44be92e5a2SBiju Das
45be92e5a2SBiju Das #define IIC_DVFS_BIT_ICCR_ENABLE (0x80U)
46be92e5a2SBiju Das #define IIC_DVFS_SET_ICCR_START (0x94U)
47be92e5a2SBiju Das #define IIC_DVFS_SET_ICCR_STOP (0x90U)
48be92e5a2SBiju Das #define IIC_DVFS_SET_ICCR_RETRANSMISSION (0x94U)
49be92e5a2SBiju Das #define IIC_DVFS_SET_ICCR_CHANGE (0x81U)
50be92e5a2SBiju Das #define IIC_DVFS_SET_ICCR_STOP_READ (0xC0U)
51be92e5a2SBiju Das
52be92e5a2SBiju Das #define IIC_DVFS_BIT_ICIC_TACKE (0x04U)
53be92e5a2SBiju Das #define IIC_DVFS_BIT_ICIC_WAITE (0x02U)
54be92e5a2SBiju Das #define IIC_DVFS_BIT_ICIC_DTEE (0x01U)
55be92e5a2SBiju Das
56be92e5a2SBiju Das #define DVFS_READ_MODE (0x01U)
57be92e5a2SBiju Das #define DVFS_WRITE_MODE (0x00U)
58be92e5a2SBiju Das
59be92e5a2SBiju Das #define IIC_DVFS_SET_DUMMY (0x52U)
60be92e5a2SBiju Das #define IIC_DVFS_SET_BUSY_LOOP (500000000U)
61be92e5a2SBiju Das
62be92e5a2SBiju Das enum dvfs_state_t {
63be92e5a2SBiju Das DVFS_START = 0,
64be92e5a2SBiju Das DVFS_STOP,
65be92e5a2SBiju Das DVFS_RETRANSMIT,
66be92e5a2SBiju Das DVFS_READ,
67be92e5a2SBiju Das DVFS_STOP_READ,
68be92e5a2SBiju Das DVFS_SET_SLAVE_READ,
69be92e5a2SBiju Das DVFS_SET_SLAVE,
70be92e5a2SBiju Das DVFS_WRITE_ADDR,
71be92e5a2SBiju Das DVFS_WRITE_DATA,
72be92e5a2SBiju Das DVFS_CHANGE_SEND_TO_RECEIVE,
73be92e5a2SBiju Das DVFS_DONE,
74be92e5a2SBiju Das };
75be92e5a2SBiju Das
76be92e5a2SBiju Das #define DVFS_PROCESS (1)
77be92e5a2SBiju Das #define DVFS_COMPLETE (0)
78be92e5a2SBiju Das #define DVFS_ERROR (-1)
79be92e5a2SBiju Das
80be92e5a2SBiju Das #if IMAGE_BL31
81be92e5a2SBiju Das #define IIC_DVFS_FUNC(__name, ...) \
82be92e5a2SBiju Das static int32_t __attribute__ ((section(".system_ram"))) \
83be92e5a2SBiju Das dvfs_ ##__name(__VA_ARGS__)
84be92e5a2SBiju Das
85be92e5a2SBiju Das #define RCAR_DVFS_API(__name, ...) \
86be92e5a2SBiju Das int32_t __attribute__ ((section(".system_ram"))) \
87be92e5a2SBiju Das rcar_iic_dvfs_ ##__name(__VA_ARGS__)
88be92e5a2SBiju Das
89be92e5a2SBiju Das #else
90be92e5a2SBiju Das #define IIC_DVFS_FUNC(__name, ...) \
91be92e5a2SBiju Das static int32_t dvfs_ ##__name(__VA_ARGS__)
92be92e5a2SBiju Das
93be92e5a2SBiju Das #define RCAR_DVFS_API(__name, ...) \
94be92e5a2SBiju Das int32_t rcar_iic_dvfs_ ##__name(__VA_ARGS__)
95be92e5a2SBiju Das #endif
96be92e5a2SBiju Das
IIC_DVFS_FUNC(check_error,enum dvfs_state_t * state,uint32_t * err,uint8_t mode)97be92e5a2SBiju Das IIC_DVFS_FUNC(check_error, enum dvfs_state_t *state, uint32_t *err, uint8_t mode)
98be92e5a2SBiju Das {
99be92e5a2SBiju Das uint8_t icsr_al = 0U, icsr_tack = 0U;
100be92e5a2SBiju Das uint8_t reg, stop;
101be92e5a2SBiju Das uint32_t i = 0U;
102be92e5a2SBiju Das
103be92e5a2SBiju Das stop = mode == DVFS_READ_MODE ? IIC_DVFS_SET_ICCR_STOP_READ :
104be92e5a2SBiju Das IIC_DVFS_SET_ICCR_STOP;
105be92e5a2SBiju Das
106be92e5a2SBiju Das reg = mmio_read_8(IIC_DVFS_REG_ICSR);
107be92e5a2SBiju Das icsr_al = (reg & IIC_DVFS_BIT_ICSR_AL) == IIC_DVFS_BIT_ICSR_AL;
108be92e5a2SBiju Das icsr_tack = (reg & IIC_DVFS_BIT_ICSR_TACK) == IIC_DVFS_BIT_ICSR_TACK;
109be92e5a2SBiju Das
110be92e5a2SBiju Das if (icsr_al == 0U && icsr_tack == 0U) {
111be92e5a2SBiju Das return DVFS_PROCESS;
112be92e5a2SBiju Das }
113be92e5a2SBiju Das
114be92e5a2SBiju Das if (icsr_al) {
115be92e5a2SBiju Das reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_AL;
116be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICSR, reg);
117be92e5a2SBiju Das
118be92e5a2SBiju Das if (*state == DVFS_SET_SLAVE) {
119be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICDR, IIC_DVFS_SET_DUMMY);
120be92e5a2SBiju Das }
121be92e5a2SBiju Das
122be92e5a2SBiju Das do {
123be92e5a2SBiju Das reg = mmio_read_8(IIC_DVFS_REG_ICSR) &
124be92e5a2SBiju Das IIC_DVFS_BIT_ICSR_WAIT;
125be92e5a2SBiju Das } while (reg == 0U);
126be92e5a2SBiju Das
127be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICCR, stop);
128be92e5a2SBiju Das
129be92e5a2SBiju Das reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
130be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICSR, reg);
131be92e5a2SBiju Das
132be92e5a2SBiju Das i = 0U;
133be92e5a2SBiju Das do {
134be92e5a2SBiju Das reg = mmio_read_8(IIC_DVFS_REG_ICSR) &
135be92e5a2SBiju Das IIC_DVFS_BIT_ICSR_BUSY;
136be92e5a2SBiju Das if (reg == 0U) {
137be92e5a2SBiju Das break;
138be92e5a2SBiju Das }
139be92e5a2SBiju Das
140be92e5a2SBiju Das if (i++ > IIC_DVFS_SET_BUSY_LOOP) {
141be92e5a2SBiju Das panic();
142be92e5a2SBiju Das }
143be92e5a2SBiju Das
144be92e5a2SBiju Das } while (true);
145be92e5a2SBiju Das
146be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICCR, 0x00U);
147be92e5a2SBiju Das
148be92e5a2SBiju Das (*err)++;
149be92e5a2SBiju Das if (*err > DVFS_RETRY_MAX) {
150be92e5a2SBiju Das return DVFS_ERROR;
151be92e5a2SBiju Das }
152be92e5a2SBiju Das
153be92e5a2SBiju Das *state = DVFS_START;
154be92e5a2SBiju Das
155be92e5a2SBiju Das return DVFS_PROCESS;
156be92e5a2SBiju Das
157be92e5a2SBiju Das }
158be92e5a2SBiju Das
159be92e5a2SBiju Das /* icsr_tack */
160be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICCR, stop);
161be92e5a2SBiju Das
162be92e5a2SBiju Das reg = mmio_read_8(IIC_DVFS_REG_ICIC);
163be92e5a2SBiju Das reg &= ~(IIC_DVFS_BIT_ICIC_WAITE | IIC_DVFS_BIT_ICIC_DTEE);
164be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICIC, reg);
165be92e5a2SBiju Das
166be92e5a2SBiju Das reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_TACK;
167be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICSR, reg);
168be92e5a2SBiju Das
169be92e5a2SBiju Das i = 0U;
170be92e5a2SBiju Das while ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0U) {
171be92e5a2SBiju Das if (i++ > IIC_DVFS_SET_BUSY_LOOP) {
172be92e5a2SBiju Das panic();
173be92e5a2SBiju Das }
174be92e5a2SBiju Das }
175be92e5a2SBiju Das
176be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICCR, 0U);
177be92e5a2SBiju Das (*err)++;
178be92e5a2SBiju Das
179be92e5a2SBiju Das if (*err > DVFS_RETRY_MAX) {
180be92e5a2SBiju Das return DVFS_ERROR;
181be92e5a2SBiju Das }
182be92e5a2SBiju Das
183be92e5a2SBiju Das *state = DVFS_START;
184be92e5a2SBiju Das
185be92e5a2SBiju Das return DVFS_PROCESS;
186be92e5a2SBiju Das }
187be92e5a2SBiju Das
IIC_DVFS_FUNC(start,enum dvfs_state_t * state)188be92e5a2SBiju Das IIC_DVFS_FUNC(start, enum dvfs_state_t *state)
189be92e5a2SBiju Das {
190be92e5a2SBiju Das uint8_t iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_E;
191be92e5a2SBiju Das uint8_t icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_E;
192be92e5a2SBiju Das int32_t result = DVFS_PROCESS;
193be92e5a2SBiju Das uint32_t reg, lsi_product;
194be92e5a2SBiju Das uint8_t mode;
195be92e5a2SBiju Das
196be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICCR) | IIC_DVFS_BIT_ICCR_ENABLE;
197be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICCR, mode);
198be92e5a2SBiju Das
199be92e5a2SBiju Das lsi_product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK;
200be92e5a2SBiju Das if (lsi_product == PRR_PRODUCT_E3) {
201be92e5a2SBiju Das goto start;
202be92e5a2SBiju Das }
203be92e5a2SBiju Das
204be92e5a2SBiju Das reg = mmio_read_32(RCAR_MODEMR) & CHECK_MD13_MD14;
205be92e5a2SBiju Das switch (reg) {
206be92e5a2SBiju Das case MD14_MD13_TYPE_0:
207be92e5a2SBiju Das iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_0;
208be92e5a2SBiju Das icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_0;
209be92e5a2SBiju Das break;
210be92e5a2SBiju Das case MD14_MD13_TYPE_1:
211be92e5a2SBiju Das iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_1;
212be92e5a2SBiju Das icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_1;
213be92e5a2SBiju Das break;
214be92e5a2SBiju Das case MD14_MD13_TYPE_2:
215be92e5a2SBiju Das iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_2;
216be92e5a2SBiju Das icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_2;
217be92e5a2SBiju Das break;
218be92e5a2SBiju Das default:
219be92e5a2SBiju Das iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_3;
220be92e5a2SBiju Das icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_3;
221be92e5a2SBiju Das break;
222be92e5a2SBiju Das }
223be92e5a2SBiju Das start:
224be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICCL, iccl);
225be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICCH, icch);
226be92e5a2SBiju Das
227be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICIC)
228be92e5a2SBiju Das | IIC_DVFS_BIT_ICIC_TACKE
229be92e5a2SBiju Das | IIC_DVFS_BIT_ICIC_WAITE | IIC_DVFS_BIT_ICIC_DTEE;
230be92e5a2SBiju Das
231be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICIC, mode);
232be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_START);
233be92e5a2SBiju Das
234be92e5a2SBiju Das *state = DVFS_SET_SLAVE;
235be92e5a2SBiju Das
236be92e5a2SBiju Das return result;
237be92e5a2SBiju Das }
238be92e5a2SBiju Das
IIC_DVFS_FUNC(set_slave,enum dvfs_state_t * state,uint32_t * err,uint8_t slave)239be92e5a2SBiju Das IIC_DVFS_FUNC(set_slave, enum dvfs_state_t *state, uint32_t *err, uint8_t slave)
240be92e5a2SBiju Das {
241be92e5a2SBiju Das uint8_t mode;
242be92e5a2SBiju Das int32_t result;
243be92e5a2SBiju Das uint8_t address;
244be92e5a2SBiju Das
245be92e5a2SBiju Das result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
246be92e5a2SBiju Das if (result == DVFS_ERROR) {
247be92e5a2SBiju Das return result;
248be92e5a2SBiju Das }
249be92e5a2SBiju Das
250be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE;
251be92e5a2SBiju Das if (mode != IIC_DVFS_BIT_ICSR_DTE) {
252be92e5a2SBiju Das return result;
253be92e5a2SBiju Das }
254be92e5a2SBiju Das
255be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE;
256be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICIC, mode);
257be92e5a2SBiju Das
258be92e5a2SBiju Das address = slave << 1;
259be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICDR, address);
260be92e5a2SBiju Das
261be92e5a2SBiju Das *state = DVFS_WRITE_ADDR;
262be92e5a2SBiju Das
263be92e5a2SBiju Das return result;
264be92e5a2SBiju Das }
265be92e5a2SBiju Das
IIC_DVFS_FUNC(write_addr,enum dvfs_state_t * state,uint32_t * err,uint8_t reg_addr)266be92e5a2SBiju Das IIC_DVFS_FUNC(write_addr, enum dvfs_state_t *state, uint32_t *err, uint8_t reg_addr)
267be92e5a2SBiju Das {
268be92e5a2SBiju Das uint8_t mode;
269be92e5a2SBiju Das int32_t result;
270be92e5a2SBiju Das
271be92e5a2SBiju Das result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
272be92e5a2SBiju Das if (result == DVFS_ERROR) {
273be92e5a2SBiju Das return result;
274be92e5a2SBiju Das }
275be92e5a2SBiju Das
276be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
277be92e5a2SBiju Das if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
278be92e5a2SBiju Das return result;
279be92e5a2SBiju Das }
280be92e5a2SBiju Das
281be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICDR, reg_addr);
282be92e5a2SBiju Das
283be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
284be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICSR, mode);
285be92e5a2SBiju Das
286be92e5a2SBiju Das *state = DVFS_WRITE_DATA;
287be92e5a2SBiju Das
288be92e5a2SBiju Das return result;
289be92e5a2SBiju Das }
290be92e5a2SBiju Das
IIC_DVFS_FUNC(write_data,enum dvfs_state_t * state,uint32_t * err,uint8_t reg_data)291be92e5a2SBiju Das IIC_DVFS_FUNC(write_data, enum dvfs_state_t *state, uint32_t *err,
292be92e5a2SBiju Das uint8_t reg_data)
293be92e5a2SBiju Das {
294be92e5a2SBiju Das int32_t result;
295be92e5a2SBiju Das uint8_t mode;
296be92e5a2SBiju Das
297be92e5a2SBiju Das result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
298be92e5a2SBiju Das if (result == DVFS_ERROR) {
299be92e5a2SBiju Das return result;
300be92e5a2SBiju Das }
301be92e5a2SBiju Das
302be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
303be92e5a2SBiju Das if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
304be92e5a2SBiju Das return result;
305be92e5a2SBiju Das }
306be92e5a2SBiju Das
307be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICDR, reg_data);
308be92e5a2SBiju Das
309be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
310be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICSR, mode);
311be92e5a2SBiju Das
312be92e5a2SBiju Das *state = DVFS_STOP;
313be92e5a2SBiju Das
314be92e5a2SBiju Das return result;
315be92e5a2SBiju Das }
316be92e5a2SBiju Das
IIC_DVFS_FUNC(stop,enum dvfs_state_t * state,uint32_t * err)317be92e5a2SBiju Das IIC_DVFS_FUNC(stop, enum dvfs_state_t *state, uint32_t *err)
318be92e5a2SBiju Das {
319be92e5a2SBiju Das int32_t result;
320be92e5a2SBiju Das uint8_t mode;
321be92e5a2SBiju Das
322be92e5a2SBiju Das result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
323be92e5a2SBiju Das if (result == DVFS_ERROR) {
324be92e5a2SBiju Das return result;
325be92e5a2SBiju Das }
326be92e5a2SBiju Das
327be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
328be92e5a2SBiju Das if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
329be92e5a2SBiju Das return result;
330be92e5a2SBiju Das }
331be92e5a2SBiju Das
332be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_STOP);
333be92e5a2SBiju Das
334be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
335be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICSR, mode);
336be92e5a2SBiju Das
337be92e5a2SBiju Das *state = DVFS_DONE;
338be92e5a2SBiju Das
339be92e5a2SBiju Das return result;
340be92e5a2SBiju Das }
341be92e5a2SBiju Das
IIC_DVFS_FUNC(done,void)342be92e5a2SBiju Das IIC_DVFS_FUNC(done, void)
343be92e5a2SBiju Das {
344be92e5a2SBiju Das uint32_t i;
345be92e5a2SBiju Das
346be92e5a2SBiju Das for (i = 0U; i < IIC_DVFS_SET_BUSY_LOOP; i++) {
347be92e5a2SBiju Das if ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0U) {
348be92e5a2SBiju Das continue;
349be92e5a2SBiju Das }
350be92e5a2SBiju Das goto done;
351be92e5a2SBiju Das }
352be92e5a2SBiju Das
353be92e5a2SBiju Das panic();
354be92e5a2SBiju Das done:
355be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICCR, 0U);
356be92e5a2SBiju Das
357be92e5a2SBiju Das return DVFS_COMPLETE;
358be92e5a2SBiju Das }
359be92e5a2SBiju Das
IIC_DVFS_FUNC(write_reg_addr_read,enum dvfs_state_t * state,uint32_t * err,uint8_t reg_addr)360be92e5a2SBiju Das IIC_DVFS_FUNC(write_reg_addr_read, enum dvfs_state_t *state, uint32_t *err,
361be92e5a2SBiju Das uint8_t reg_addr)
362be92e5a2SBiju Das {
363be92e5a2SBiju Das int32_t result;
364be92e5a2SBiju Das uint8_t mode;
365be92e5a2SBiju Das
366be92e5a2SBiju Das result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
367be92e5a2SBiju Das if (result == DVFS_ERROR) {
368be92e5a2SBiju Das return result;
369be92e5a2SBiju Das }
370be92e5a2SBiju Das
371be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
372be92e5a2SBiju Das if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
373be92e5a2SBiju Das return result;
374be92e5a2SBiju Das }
375be92e5a2SBiju Das
376be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICDR, reg_addr);
377be92e5a2SBiju Das
378be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
379be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICSR, mode);
380be92e5a2SBiju Das
381be92e5a2SBiju Das *state = DVFS_RETRANSMIT;
382be92e5a2SBiju Das
383be92e5a2SBiju Das return result;
384be92e5a2SBiju Das }
385be92e5a2SBiju Das
IIC_DVFS_FUNC(retransmit,enum dvfs_state_t * state,uint32_t * err)386be92e5a2SBiju Das IIC_DVFS_FUNC(retransmit, enum dvfs_state_t *state, uint32_t *err)
387be92e5a2SBiju Das {
388be92e5a2SBiju Das int32_t result;
389be92e5a2SBiju Das uint8_t mode;
390be92e5a2SBiju Das
391be92e5a2SBiju Das result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
392be92e5a2SBiju Das if (result == DVFS_ERROR) {
393be92e5a2SBiju Das return result;
394be92e5a2SBiju Das }
395be92e5a2SBiju Das
396be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
397be92e5a2SBiju Das if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
398be92e5a2SBiju Das return result;
399be92e5a2SBiju Das }
400be92e5a2SBiju Das
401be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_RETRANSMISSION);
402be92e5a2SBiju Das
403be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
404be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICSR, mode);
405be92e5a2SBiju Das
406be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICIC) | IIC_DVFS_BIT_ICIC_DTEE;
407be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICIC, mode);
408be92e5a2SBiju Das
409be92e5a2SBiju Das *state = DVFS_SET_SLAVE_READ;
410be92e5a2SBiju Das
411be92e5a2SBiju Das return result;
412be92e5a2SBiju Das }
413be92e5a2SBiju Das
IIC_DVFS_FUNC(set_slave_read,enum dvfs_state_t * state,uint32_t * err,uint8_t slave)414be92e5a2SBiju Das IIC_DVFS_FUNC(set_slave_read, enum dvfs_state_t *state, uint32_t *err,
415be92e5a2SBiju Das uint8_t slave)
416be92e5a2SBiju Das {
417be92e5a2SBiju Das uint8_t address;
418be92e5a2SBiju Das int32_t result;
419be92e5a2SBiju Das uint8_t mode;
420be92e5a2SBiju Das
421be92e5a2SBiju Das result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
422be92e5a2SBiju Das if (result == DVFS_ERROR) {
423be92e5a2SBiju Das return result;
424be92e5a2SBiju Das }
425be92e5a2SBiju Das
426be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE;
427be92e5a2SBiju Das if (mode != IIC_DVFS_BIT_ICSR_DTE) {
428be92e5a2SBiju Das return result;
429be92e5a2SBiju Das }
430be92e5a2SBiju Das
431be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE;
432be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICIC, mode);
433be92e5a2SBiju Das
434be92e5a2SBiju Das address = ((uint8_t) (slave << 1) + DVFS_READ_MODE);
435be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICDR, address);
436be92e5a2SBiju Das
437be92e5a2SBiju Das *state = DVFS_CHANGE_SEND_TO_RECEIVE;
438be92e5a2SBiju Das
439be92e5a2SBiju Das return result;
440be92e5a2SBiju Das }
441be92e5a2SBiju Das
IIC_DVFS_FUNC(change_send_to_receive,enum dvfs_state_t * state,uint32_t * err)442be92e5a2SBiju Das IIC_DVFS_FUNC(change_send_to_receive, enum dvfs_state_t *state, uint32_t *err)
443be92e5a2SBiju Das {
444be92e5a2SBiju Das int32_t result;
445be92e5a2SBiju Das uint8_t mode;
446be92e5a2SBiju Das
447be92e5a2SBiju Das result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
448be92e5a2SBiju Das if (result == DVFS_ERROR) {
449be92e5a2SBiju Das return result;
450be92e5a2SBiju Das }
451be92e5a2SBiju Das
452be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
453be92e5a2SBiju Das if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
454be92e5a2SBiju Das return result;
455be92e5a2SBiju Das }
456be92e5a2SBiju Das
457be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_CHANGE);
458be92e5a2SBiju Das
459be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
460be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICSR, mode);
461be92e5a2SBiju Das
462be92e5a2SBiju Das *state = DVFS_STOP_READ;
463be92e5a2SBiju Das
464be92e5a2SBiju Das return result;
465be92e5a2SBiju Das }
466be92e5a2SBiju Das
IIC_DVFS_FUNC(stop_read,enum dvfs_state_t * state,uint32_t * err)467be92e5a2SBiju Das IIC_DVFS_FUNC(stop_read, enum dvfs_state_t *state, uint32_t *err)
468be92e5a2SBiju Das {
469be92e5a2SBiju Das int32_t result;
470be92e5a2SBiju Das uint8_t mode;
471be92e5a2SBiju Das
472be92e5a2SBiju Das result = dvfs_check_error(state, err, DVFS_READ_MODE);
473be92e5a2SBiju Das if (result == DVFS_ERROR) {
474be92e5a2SBiju Das return result;
475be92e5a2SBiju Das }
476be92e5a2SBiju Das
477be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
478be92e5a2SBiju Das if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
479be92e5a2SBiju Das return result;
480be92e5a2SBiju Das }
481be92e5a2SBiju Das
482be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_STOP_READ);
483be92e5a2SBiju Das
484be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
485be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICSR, mode);
486be92e5a2SBiju Das
487be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICIC) | IIC_DVFS_BIT_ICIC_DTEE;
488be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICIC, mode);
489be92e5a2SBiju Das
490be92e5a2SBiju Das *state = DVFS_READ;
491be92e5a2SBiju Das
492be92e5a2SBiju Das return result;
493be92e5a2SBiju Das }
494be92e5a2SBiju Das
IIC_DVFS_FUNC(read,enum dvfs_state_t * state,uint8_t * reg_data)495be92e5a2SBiju Das IIC_DVFS_FUNC(read, enum dvfs_state_t *state, uint8_t *reg_data)
496be92e5a2SBiju Das {
497be92e5a2SBiju Das uint8_t mode;
498be92e5a2SBiju Das
499be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE;
500be92e5a2SBiju Das if (mode != IIC_DVFS_BIT_ICSR_DTE) {
501be92e5a2SBiju Das return DVFS_PROCESS;
502be92e5a2SBiju Das }
503be92e5a2SBiju Das
504be92e5a2SBiju Das mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE;
505be92e5a2SBiju Das mmio_write_8(IIC_DVFS_REG_ICIC, mode);
506be92e5a2SBiju Das
507be92e5a2SBiju Das *reg_data = mmio_read_8(IIC_DVFS_REG_ICDR);
508be92e5a2SBiju Das *state = DVFS_DONE;
509be92e5a2SBiju Das
510be92e5a2SBiju Das return DVFS_PROCESS;
511be92e5a2SBiju Das }
512be92e5a2SBiju Das
RCAR_DVFS_API(send,uint8_t slave,uint8_t reg_addr,uint8_t reg_data)513be92e5a2SBiju Das RCAR_DVFS_API(send, uint8_t slave, uint8_t reg_addr, uint8_t reg_data)
514be92e5a2SBiju Das {
515be92e5a2SBiju Das enum dvfs_state_t state = DVFS_START;
516be92e5a2SBiju Das int32_t result = DVFS_PROCESS;
517be92e5a2SBiju Das uint32_t err = 0U;
518be92e5a2SBiju Das
519be92e5a2SBiju Das mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS);
520*b757d3a1SToshiyuki Ogasahara mmio_write_8(IIC_DVFS_REG_ICCR, 1U);
521be92e5a2SBiju Das again:
522be92e5a2SBiju Das switch (state) {
523be92e5a2SBiju Das case DVFS_START:
524be92e5a2SBiju Das result = dvfs_start(&state);
525be92e5a2SBiju Das break;
526be92e5a2SBiju Das case DVFS_SET_SLAVE:
527be92e5a2SBiju Das result = dvfs_set_slave(&state, &err, slave);
528be92e5a2SBiju Das break;
529be92e5a2SBiju Das case DVFS_WRITE_ADDR:
530be92e5a2SBiju Das result = dvfs_write_addr(&state, &err, reg_addr);
531be92e5a2SBiju Das break;
532be92e5a2SBiju Das case DVFS_WRITE_DATA:
533be92e5a2SBiju Das result = dvfs_write_data(&state, &err, reg_data);
534be92e5a2SBiju Das break;
535be92e5a2SBiju Das case DVFS_STOP:
536be92e5a2SBiju Das result = dvfs_stop(&state, &err);
537be92e5a2SBiju Das break;
538be92e5a2SBiju Das case DVFS_DONE:
539be92e5a2SBiju Das result = dvfs_done();
540be92e5a2SBiju Das break;
541be92e5a2SBiju Das default:
542be92e5a2SBiju Das panic();
543be92e5a2SBiju Das break;
544be92e5a2SBiju Das }
545be92e5a2SBiju Das
546be92e5a2SBiju Das if (result == DVFS_PROCESS) {
547be92e5a2SBiju Das goto again;
548be92e5a2SBiju Das }
549be92e5a2SBiju Das
550be92e5a2SBiju Das return result;
551be92e5a2SBiju Das }
552be92e5a2SBiju Das
RCAR_DVFS_API(receive,uint8_t slave,uint8_t reg,uint8_t * data)553be92e5a2SBiju Das RCAR_DVFS_API(receive, uint8_t slave, uint8_t reg, uint8_t *data)
554be92e5a2SBiju Das {
555be92e5a2SBiju Das enum dvfs_state_t state = DVFS_START;
556be92e5a2SBiju Das int32_t result = DVFS_PROCESS;
557be92e5a2SBiju Das uint32_t err = 0U;
558be92e5a2SBiju Das
559be92e5a2SBiju Das mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS);
560*b757d3a1SToshiyuki Ogasahara mmio_write_8(IIC_DVFS_REG_ICCR, 1U);
561be92e5a2SBiju Das again:
562be92e5a2SBiju Das switch (state) {
563be92e5a2SBiju Das case DVFS_START:
564be92e5a2SBiju Das result = dvfs_start(&state);
565be92e5a2SBiju Das break;
566be92e5a2SBiju Das case DVFS_SET_SLAVE:
567be92e5a2SBiju Das result = dvfs_set_slave(&state, &err, slave);
568be92e5a2SBiju Das break;
569be92e5a2SBiju Das case DVFS_WRITE_ADDR:
570be92e5a2SBiju Das result = dvfs_write_reg_addr_read(&state, &err, reg);
571be92e5a2SBiju Das break;
572be92e5a2SBiju Das case DVFS_RETRANSMIT:
573be92e5a2SBiju Das result = dvfs_retransmit(&state, &err);
574be92e5a2SBiju Das break;
575be92e5a2SBiju Das case DVFS_SET_SLAVE_READ:
576be92e5a2SBiju Das result = dvfs_set_slave_read(&state, &err, slave);
577be92e5a2SBiju Das break;
578be92e5a2SBiju Das case DVFS_CHANGE_SEND_TO_RECEIVE:
579be92e5a2SBiju Das result = dvfs_change_send_to_receive(&state, &err);
580be92e5a2SBiju Das break;
581be92e5a2SBiju Das case DVFS_STOP_READ:
582be92e5a2SBiju Das result = dvfs_stop_read(&state, &err);
583be92e5a2SBiju Das break;
584be92e5a2SBiju Das case DVFS_READ:
585be92e5a2SBiju Das result = dvfs_read(&state, data);
586be92e5a2SBiju Das break;
587be92e5a2SBiju Das case DVFS_DONE:
588be92e5a2SBiju Das result = dvfs_done();
589be92e5a2SBiju Das break;
590be92e5a2SBiju Das default:
591be92e5a2SBiju Das panic();
592be92e5a2SBiju Das break;
593be92e5a2SBiju Das }
594be92e5a2SBiju Das
595be92e5a2SBiju Das if (result == DVFS_PROCESS) {
596be92e5a2SBiju Das goto again;
597be92e5a2SBiju Das }
598be92e5a2SBiju Das
599be92e5a2SBiju Das return result;
600be92e5a2SBiju Das }
601