iic_dvfs.c 13.5 KB
Newer Older
1
/*
2
 * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
3
4
5
6
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

7
8
9
#include <common/debug.h>
#include <lib/mmio.h>

10
11
#include "cpg_registers.h"
#include "iic_dvfs.h"
12
#include "rcar_def.h"
13
14
15
16
#include "rcar_private.h"

#define DVFS_RETRY_MAX				(2U)

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
#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_0		(0x07U)
#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_1		(0x09U)
#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_2		(0x0BU)
#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_3		(0x0EU)
#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_E		(0x15U)

#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_0		(0x01U)
#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_1		(0x02U)
#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_2		(0x03U)
#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_3		(0x05U)
#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_E		(0x07U)

#define CPG_BIT_SMSTPCR9_DVFS			(0x04000000U)

#define IIC_DVFS_REG_BASE			(0xE60B0000U)
#define IIC_DVFS_REG_ICDR			(IIC_DVFS_REG_BASE + 0x0000U)
#define IIC_DVFS_REG_ICCR			(IIC_DVFS_REG_BASE + 0x0004U)
#define IIC_DVFS_REG_ICSR			(IIC_DVFS_REG_BASE + 0x0008U)
#define IIC_DVFS_REG_ICIC			(IIC_DVFS_REG_BASE + 0x000CU)
#define IIC_DVFS_REG_ICCL			(IIC_DVFS_REG_BASE + 0x0010U)
#define IIC_DVFS_REG_ICCH			(IIC_DVFS_REG_BASE + 0x0014U)

#define IIC_DVFS_BIT_ICSR_BUSY			(0x10U)
#define IIC_DVFS_BIT_ICSR_AL			(0x08U)
#define IIC_DVFS_BIT_ICSR_TACK			(0x04U)
#define IIC_DVFS_BIT_ICSR_WAIT			(0x02U)
#define IIC_DVFS_BIT_ICSR_DTE			(0x01U)

#define IIC_DVFS_BIT_ICCR_ENABLE		(0x80U)
#define IIC_DVFS_SET_ICCR_START			(0x94U)
#define IIC_DVFS_SET_ICCR_STOP			(0x90U)
#define IIC_DVFS_SET_ICCR_RETRANSMISSION	(0x94U)
#define IIC_DVFS_SET_ICCR_CHANGE		(0x81U)
#define IIC_DVFS_SET_ICCR_STOP_READ		(0xC0U)

#define IIC_DVFS_BIT_ICIC_TACKE			(0x04U)
#define IIC_DVFS_BIT_ICIC_WAITE			(0x02U)
#define IIC_DVFS_BIT_ICIC_DTEE			(0x01U)

#define DVFS_READ_MODE				(0x01U)
#define DVFS_WRITE_MODE				(0x00U)

#define IIC_DVFS_SET_DUMMY			(0x52U)
60
61
#define IIC_DVFS_SET_BUSY_LOOP			(500000000U)

62
enum dvfs_state_t {
63
64
65
66
67
68
69
70
71
	DVFS_START = 0,
	DVFS_STOP,
	DVFS_RETRANSMIT,
	DVFS_READ,
	DVFS_STOP_READ,
	DVFS_SET_SLAVE_READ,
	DVFS_SET_SLAVE,
	DVFS_WRITE_ADDR,
	DVFS_WRITE_DATA,
72
	DVFS_CHANGE_SEND_TO_RECEIVE,
73
	DVFS_DONE,
74
};
75
76
77
78
79
80
81

#define DVFS_PROCESS			(1)
#define DVFS_COMPLETE			(0)
#define DVFS_ERROR			(-1)

#if IMAGE_BL31
#define IIC_DVFS_FUNC(__name, ...)					\
82
static int32_t	__attribute__ ((section(".system_ram")))		\
83
84
85
dvfs_ ##__name(__VA_ARGS__)

#define RCAR_DVFS_API(__name, ...)					\
86
int32_t __attribute__ ((section(".system_ram")))			\
87
88
89
rcar_iic_dvfs_ ##__name(__VA_ARGS__)

#else
90
#define IIC_DVFS_FUNC(__name, ...)					\
91
92
93
94
95
96
static int32_t dvfs_ ##__name(__VA_ARGS__)

#define RCAR_DVFS_API(__name, ...)					\
int32_t rcar_iic_dvfs_ ##__name(__VA_ARGS__)
#endif

97
IIC_DVFS_FUNC(check_error, enum dvfs_state_t *state, uint32_t *err, uint8_t mode)
98
{
99
	uint8_t icsr_al = 0U, icsr_tack = 0U;
100
	uint8_t reg, stop;
101
	uint32_t i = 0U;
102
103
104
105
106
107
108
109

	stop = mode == DVFS_READ_MODE ? IIC_DVFS_SET_ICCR_STOP_READ :
	    IIC_DVFS_SET_ICCR_STOP;

	reg = mmio_read_8(IIC_DVFS_REG_ICSR);
	icsr_al = (reg & IIC_DVFS_BIT_ICSR_AL) == IIC_DVFS_BIT_ICSR_AL;
	icsr_tack = (reg & IIC_DVFS_BIT_ICSR_TACK) == IIC_DVFS_BIT_ICSR_TACK;

110
	if (icsr_al == 0U && icsr_tack == 0U) {
111
		return DVFS_PROCESS;
112
	}
113
114
115
116
117

	if (icsr_al) {
		reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_AL;
		mmio_write_8(IIC_DVFS_REG_ICSR, reg);

118
		if (*state == DVFS_SET_SLAVE) {
119
			mmio_write_8(IIC_DVFS_REG_ICDR, IIC_DVFS_SET_DUMMY);
120
		}
121
122
123
124

		do {
			reg = mmio_read_8(IIC_DVFS_REG_ICSR) &
			    IIC_DVFS_BIT_ICSR_WAIT;
125
		} while (reg == 0U);
126
127
128
129
130
131

		mmio_write_8(IIC_DVFS_REG_ICCR, stop);

		reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
		mmio_write_8(IIC_DVFS_REG_ICSR, reg);

132
		i = 0U;
133
134
135
		do {
			reg = mmio_read_8(IIC_DVFS_REG_ICSR) &
			    IIC_DVFS_BIT_ICSR_BUSY;
136
			if (reg == 0U) {
137
				break;
138
			}
139

140
			if (i++ > IIC_DVFS_SET_BUSY_LOOP) {
141
				panic();
142
			}
143

144
		} while (true);
145
146
147
148

		mmio_write_8(IIC_DVFS_REG_ICCR, 0x00U);

		(*err)++;
149
		if (*err > DVFS_RETRY_MAX) {
150
			return DVFS_ERROR;
151
		}
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168

		*state = DVFS_START;

		return DVFS_PROCESS;

	}

	/* icsr_tack */
	mmio_write_8(IIC_DVFS_REG_ICCR, stop);

	reg = mmio_read_8(IIC_DVFS_REG_ICIC);
	reg &= ~(IIC_DVFS_BIT_ICIC_WAITE | IIC_DVFS_BIT_ICIC_DTEE);
	mmio_write_8(IIC_DVFS_REG_ICIC, reg);

	reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_TACK;
	mmio_write_8(IIC_DVFS_REG_ICSR, reg);

169
170
171
	i = 0U;
	while ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0U) {
		if (i++ > IIC_DVFS_SET_BUSY_LOOP) {
172
			panic();
173
		}
174
175
	}

176
	mmio_write_8(IIC_DVFS_REG_ICCR, 0U);
177
178
	(*err)++;

179
	if (*err > DVFS_RETRY_MAX) {
180
		return DVFS_ERROR;
181
	}
182
183
184
185
186
187

	*state = DVFS_START;

	return DVFS_PROCESS;
}

188
IIC_DVFS_FUNC(start, enum dvfs_state_t *state)
189
190
191
192
193
194
195
196
197
198
{
	uint8_t iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_E;
	uint8_t icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_E;
	int32_t result = DVFS_PROCESS;
	uint32_t reg, lsi_product;
	uint8_t mode;

	mode = mmio_read_8(IIC_DVFS_REG_ICCR) | IIC_DVFS_BIT_ICCR_ENABLE;
	mmio_write_8(IIC_DVFS_REG_ICCR, mode);

199
	lsi_product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK;
200
	if (lsi_product == PRR_PRODUCT_E3) {
201
		goto start;
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

	reg = mmio_read_32(RCAR_MODEMR) & CHECK_MD13_MD14;
	switch (reg) {
	case MD14_MD13_TYPE_0:
		iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_0;
		icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_0;
		break;
	case MD14_MD13_TYPE_1:
		iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_1;
		icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_1;
		break;
	case MD14_MD13_TYPE_2:
		iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_2;
		icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_2;
		break;
	default:
		iccl = IIC_DVFS_SET_ICCL_EXTAL_TYPE_3;
		icch = IIC_DVFS_SET_ICCH_EXTAL_TYPE_3;
		break;
	}
start:
	mmio_write_8(IIC_DVFS_REG_ICCL, iccl);
	mmio_write_8(IIC_DVFS_REG_ICCH, icch);

	mode = mmio_read_8(IIC_DVFS_REG_ICIC)
	    | IIC_DVFS_BIT_ICIC_TACKE
	    | IIC_DVFS_BIT_ICIC_WAITE | IIC_DVFS_BIT_ICIC_DTEE;

	mmio_write_8(IIC_DVFS_REG_ICIC, mode);
	mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_START);

	*state = DVFS_SET_SLAVE;

	return result;
}

239
IIC_DVFS_FUNC(set_slave, enum dvfs_state_t *state, uint32_t *err, uint8_t slave)
240
241
242
243
244
245
{
	uint8_t mode;
	int32_t result;
	uint8_t address;

	result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
246
	if (result == DVFS_ERROR) {
247
		return result;
248
	}
249
250

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE;
251
	if (mode != IIC_DVFS_BIT_ICSR_DTE) {
252
		return result;
253
	}
254
255
256
257
258
259
260
261
262
263
264
265

	mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE;
	mmio_write_8(IIC_DVFS_REG_ICIC, mode);

	address = slave << 1;
	mmio_write_8(IIC_DVFS_REG_ICDR, address);

	*state = DVFS_WRITE_ADDR;

	return result;
}

266
IIC_DVFS_FUNC(write_addr, enum dvfs_state_t *state, uint32_t *err, uint8_t reg_addr)
267
268
269
270
271
{
	uint8_t mode;
	int32_t result;

	result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
272
	if (result == DVFS_ERROR) {
273
		return result;
274
	}
275
276

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
277
	if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
278
		return result;
279
	}
280
281
282
283
284
285
286
287
288
289
290

	mmio_write_8(IIC_DVFS_REG_ICDR, reg_addr);

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
	mmio_write_8(IIC_DVFS_REG_ICSR, mode);

	*state = DVFS_WRITE_DATA;

	return result;
}

291
292
IIC_DVFS_FUNC(write_data, enum dvfs_state_t *state, uint32_t *err,
	      uint8_t reg_data)
293
294
295
296
297
{
	int32_t result;
	uint8_t mode;

	result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
298
	if (result == DVFS_ERROR) {
299
		return result;
300
	}
301
302

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
303
	if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
304
		return result;
305
	}
306
307
308
309
310
311
312
313
314
315
316

	mmio_write_8(IIC_DVFS_REG_ICDR, reg_data);

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
	mmio_write_8(IIC_DVFS_REG_ICSR, mode);

	*state = DVFS_STOP;

	return result;
}

317
IIC_DVFS_FUNC(stop, enum dvfs_state_t *state, uint32_t *err)
318
319
320
321
322
{
	int32_t result;
	uint8_t mode;

	result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
323
	if (result == DVFS_ERROR) {
324
		return result;
325
	}
326
327

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
328
	if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
329
		return result;
330
	}
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345

	mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_STOP);

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
	mmio_write_8(IIC_DVFS_REG_ICSR, mode);

	*state = DVFS_DONE;

	return result;
}

IIC_DVFS_FUNC(done, void)
{
	uint32_t i;

346
347
	for (i = 0U; i < IIC_DVFS_SET_BUSY_LOOP; i++) {
		if ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0U) {
348
			continue;
349
		}
350
351
352
353
354
		goto done;
	}

	panic();
done:
355
	mmio_write_8(IIC_DVFS_REG_ICCR, 0U);
356
357
358
359

	return DVFS_COMPLETE;
}

360
361
IIC_DVFS_FUNC(write_reg_addr_read, enum dvfs_state_t *state, uint32_t *err,
	      uint8_t reg_addr)
362
363
364
365
366
{
	int32_t result;
	uint8_t mode;

	result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
367
	if (result == DVFS_ERROR) {
368
		return result;
369
	}
370
371

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
372
	if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
373
		return result;
374
	}
375
376
377
378
379
380
381
382
383
384
385

	mmio_write_8(IIC_DVFS_REG_ICDR, reg_addr);

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
	mmio_write_8(IIC_DVFS_REG_ICSR, mode);

	*state = DVFS_RETRANSMIT;

	return result;
}

386
IIC_DVFS_FUNC(retransmit, enum dvfs_state_t *state, uint32_t *err)
387
388
389
390
391
{
	int32_t result;
	uint8_t mode;

	result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
392
	if (result == DVFS_ERROR) {
393
		return result;
394
	}
395
396

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
397
	if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
398
		return result;
399
	}
400
401
402
403
404
405
406
407
408
409
410
411
412
413

	mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_RETRANSMISSION);

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
	mmio_write_8(IIC_DVFS_REG_ICSR, mode);

	mode = mmio_read_8(IIC_DVFS_REG_ICIC) | IIC_DVFS_BIT_ICIC_DTEE;
	mmio_write_8(IIC_DVFS_REG_ICIC, mode);

	*state = DVFS_SET_SLAVE_READ;

	return result;
}

414
415
IIC_DVFS_FUNC(set_slave_read, enum dvfs_state_t *state, uint32_t *err,
	      uint8_t slave)
416
417
418
419
420
421
{
	uint8_t address;
	int32_t result;
	uint8_t mode;

	result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
422
	if (result == DVFS_ERROR) {
423
		return result;
424
	}
425
426

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE;
427
	if (mode != IIC_DVFS_BIT_ICSR_DTE) {
428
		return result;
429
	}
430
431
432
433
434
435
436

	mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE;
	mmio_write_8(IIC_DVFS_REG_ICIC, mode);

	address = ((uint8_t) (slave << 1) + DVFS_READ_MODE);
	mmio_write_8(IIC_DVFS_REG_ICDR, address);

437
	*state = DVFS_CHANGE_SEND_TO_RECEIVE;
438
439
440
441

	return result;
}

442
IIC_DVFS_FUNC(change_send_to_receive, enum dvfs_state_t *state, uint32_t *err)
443
444
445
446
447
{
	int32_t result;
	uint8_t mode;

	result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
448
	if (result == DVFS_ERROR) {
449
		return result;
450
	}
451
452

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
453
	if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
454
		return result;
455
	}
456
457
458
459
460
461
462
463
464
465
466

	mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_CHANGE);

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
	mmio_write_8(IIC_DVFS_REG_ICSR, mode);

	*state = DVFS_STOP_READ;

	return result;
}

467
IIC_DVFS_FUNC(stop_read, enum dvfs_state_t *state, uint32_t *err)
468
469
470
471
472
{
	int32_t result;
	uint8_t mode;

	result = dvfs_check_error(state, err, DVFS_READ_MODE);
473
	if (result == DVFS_ERROR) {
474
		return result;
475
	}
476
477

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
478
	if (mode != IIC_DVFS_BIT_ICSR_WAIT) {
479
		return result;
480
	}
481
482
483
484
485
486
487
488
489
490
491
492
493
494

	mmio_write_8(IIC_DVFS_REG_ICCR, IIC_DVFS_SET_ICCR_STOP_READ);

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_WAIT;
	mmio_write_8(IIC_DVFS_REG_ICSR, mode);

	mode = mmio_read_8(IIC_DVFS_REG_ICIC) | IIC_DVFS_BIT_ICIC_DTEE;
	mmio_write_8(IIC_DVFS_REG_ICIC, mode);

	*state = DVFS_READ;

	return result;
}

495
IIC_DVFS_FUNC(read, enum dvfs_state_t *state, uint8_t *reg_data)
496
497
498
499
{
	uint8_t mode;

	mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE;
500
	if (mode != IIC_DVFS_BIT_ICSR_DTE) {
501
		return DVFS_PROCESS;
502
	}
503
504
505
506
507
508
509
510
511
512
513
514

	mode = mmio_read_8(IIC_DVFS_REG_ICIC) & ~IIC_DVFS_BIT_ICIC_DTEE;
	mmio_write_8(IIC_DVFS_REG_ICIC, mode);

	*reg_data = mmio_read_8(IIC_DVFS_REG_ICDR);
	*state = DVFS_DONE;

	return DVFS_PROCESS;
}

RCAR_DVFS_API(send, uint8_t slave, uint8_t reg_addr, uint8_t reg_data)
{
515
	enum dvfs_state_t state = DVFS_START;
516
	int32_t result = DVFS_PROCESS;
517
	uint32_t err = 0U;
518
519

	mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS);
520
	mmio_write_8(IIC_DVFS_REG_ICCR, 0U);
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
again:
	switch (state) {
	case DVFS_START:
		result = dvfs_start(&state);
		break;
	case DVFS_SET_SLAVE:
		result = dvfs_set_slave(&state, &err, slave);
		break;
	case DVFS_WRITE_ADDR:
		result = dvfs_write_addr(&state, &err, reg_addr);
		break;
	case DVFS_WRITE_DATA:
		result = dvfs_write_data(&state, &err, reg_data);
		break;
	case DVFS_STOP:
		result = dvfs_stop(&state, &err);
		break;
	case DVFS_DONE:
		result = dvfs_done();
		break;
	default:
		panic();
		break;
	}

546
	if (result == DVFS_PROCESS) {
547
		goto again;
548
	}
549
550
551
552
553
554

	return result;
}

RCAR_DVFS_API(receive, uint8_t slave, uint8_t reg, uint8_t *data)
{
555
	enum dvfs_state_t state = DVFS_START;
556
	int32_t result = DVFS_PROCESS;
557
	uint32_t err = 0U;
558
559

	mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS);
560
	mmio_write_8(IIC_DVFS_REG_ICCR, 0U);
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
again:
	switch (state) {
	case DVFS_START:
		result = dvfs_start(&state);
		break;
	case DVFS_SET_SLAVE:
		result = dvfs_set_slave(&state, &err, slave);
		break;
	case DVFS_WRITE_ADDR:
		result = dvfs_write_reg_addr_read(&state, &err, reg);
		break;
	case DVFS_RETRANSMIT:
		result = dvfs_retransmit(&state, &err);
		break;
	case DVFS_SET_SLAVE_READ:
		result = dvfs_set_slave_read(&state, &err, slave);
		break;
578
579
	case DVFS_CHANGE_SEND_TO_RECEIVE:
		result = dvfs_change_send_to_receive(&state, &err);
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
		break;
	case DVFS_STOP_READ:
		result = dvfs_stop_read(&state, &err);
		break;
	case DVFS_READ:
		result = dvfs_read(&state, data);
		break;
	case DVFS_DONE:
		result = dvfs_done();
		break;
	default:
		panic();
		break;
	}

595
	if (result == DVFS_PROCESS) {
596
		goto again;
597
	}
598
599
600

	return result;
}