rcar_gen3: drivers: i2c dvfs
authorJorge Ramirez-Ortiz <jramirez@baylibre.com>
Sun, 23 Sep 2018 07:40:26 +0000 (09:40 +0200)
committerldts <jorge.ramirez.ortiz@gmail.com>
Wed, 17 Oct 2018 16:41:34 +0000 (18:41 +0200)
Signed-off-by: ldts <jramirez@baylibre.com>
drivers/renesas/rcar/iic_dvfs/iic_dvfs.c [new file with mode: 0644]
drivers/renesas/rcar/iic_dvfs/iic_dvfs.h [new file with mode: 0644]

diff --git a/drivers/renesas/rcar/iic_dvfs/iic_dvfs.c b/drivers/renesas/rcar/iic_dvfs/iic_dvfs.c
new file mode 100644 (file)
index 0000000..11d52bf
--- /dev/null
@@ -0,0 +1,568 @@
+/*
+ * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <mmio.h>
+#include <debug.h>
+#include "rcar_def.h"
+#include "cpg_registers.h"
+#include "iic_dvfs.h"
+#include "rcar_private.h"
+
+#define DVFS_RETRY_MAX                         (2U)
+
+#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_0         (0x07)
+#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_1         (0x09)
+#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_2         (0x0B)
+#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_3         (0x0E)
+#define IIC_DVFS_SET_ICCL_EXTAL_TYPE_E         (0x15)
+
+#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_0         (0x01)
+#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_1         (0x02)
+#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_2         (0x03)
+#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_3         (0x05)
+#define IIC_DVFS_SET_ICCH_EXTAL_TYPE_E         (0x07)
+
+#define CPG_BIT_SMSTPCR9_DVFS                  (0x04000000)
+
+#define IIC_DVFS_REG_BASE                      (0xE60B0000)
+#define IIC_DVFS_REG_ICDR                      (IIC_DVFS_REG_BASE + 0x0000)
+#define IIC_DVFS_REG_ICCR                      (IIC_DVFS_REG_BASE + 0x0004)
+#define IIC_DVFS_REG_ICSR                      (IIC_DVFS_REG_BASE + 0x0008)
+#define IIC_DVFS_REG_ICIC                      (IIC_DVFS_REG_BASE + 0x000C)
+#define IIC_DVFS_REG_ICCL                      (IIC_DVFS_REG_BASE + 0x0010)
+#define IIC_DVFS_REG_ICCH                      (IIC_DVFS_REG_BASE + 0x0014)
+
+#define IIC_DVFS_BIT_ICSR_BUSY                 (0x10)
+#define IIC_DVFS_BIT_ICSR_AL                   (0x08)
+#define IIC_DVFS_BIT_ICSR_TACK                 (0x04)
+#define IIC_DVFS_BIT_ICSR_WAIT                 (0x02)
+#define IIC_DVFS_BIT_ICSR_DTE                  (0x01)
+
+#define IIC_DVFS_BIT_ICCR_ENABLE               (0x80)
+#define IIC_DVFS_SET_ICCR_START                        (0x94)
+#define IIC_DVFS_SET_ICCR_STOP                 (0x90)
+#define        IIC_DVFS_SET_ICCR_RETRANSMISSION        (0x94)
+#define        IIC_DVFS_SET_ICCR_CHANGE                (0x81)
+#define        IIC_DVFS_SET_ICCR_STOP_READ             (0xC0)
+
+#define IIC_DVFS_BIT_ICIC_TACKE                        (0x04)
+#define IIC_DVFS_BIT_ICIC_WAITE                        (0x02)
+#define IIC_DVFS_BIT_ICIC_DTEE                 (0x01)
+
+#define        DVFS_READ_MODE                          (0x01)
+#define        DVFS_WRITE_MODE                         (0x00)
+
+#define IIC_DVFS_SET_DUMMY                     (0x52)
+#define IIC_DVFS_SET_BUSY_LOOP                 (500000000U)
+
+typedef enum {
+       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,
+       DVFS_CHANGE_SEND_TO_RECIEVE,
+       DVFS_DONE,
+} DVFS_STATE_T;
+
+#define DVFS_PROCESS                   (1)
+#define DVFS_COMPLETE                  (0)
+#define DVFS_ERROR                     (-1)
+
+#if IMAGE_BL31
+#define IIC_DVFS_FUNC(__name, ...)                                     \
+static int32_t         __attribute__ ((section (".system_ram")))               \
+dvfs_ ##__name(__VA_ARGS__)
+
+#define RCAR_DVFS_API(__name, ...)                                     \
+int32_t __attribute__ ((section (".system_ram")))                      \
+rcar_iic_dvfs_ ##__name(__VA_ARGS__)
+
+#else
+#define IIC_DVFS_FUNC(__name, ...)                                     \
+static int32_t dvfs_ ##__name(__VA_ARGS__)
+
+#define RCAR_DVFS_API(__name, ...)                                     \
+int32_t rcar_iic_dvfs_ ##__name(__VA_ARGS__)
+#endif
+
+IIC_DVFS_FUNC(check_error, DVFS_STATE_T *state, uint32_t *err, uint8_t mode)
+{
+       uint8_t icsr_al = 0, icsr_tack = 0;
+       uint8_t reg, stop;
+       uint32_t i = 0;
+
+       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;
+
+       if (icsr_al == 0 && icsr_tack == 0)
+               return DVFS_PROCESS;
+
+       if (icsr_al) {
+               reg = mmio_read_8(IIC_DVFS_REG_ICSR) & ~IIC_DVFS_BIT_ICSR_AL;
+               mmio_write_8(IIC_DVFS_REG_ICSR, reg);
+
+               if (*state == DVFS_SET_SLAVE)
+                       mmio_write_8(IIC_DVFS_REG_ICDR, IIC_DVFS_SET_DUMMY);
+
+               do {
+                       reg = mmio_read_8(IIC_DVFS_REG_ICSR) &
+                           IIC_DVFS_BIT_ICSR_WAIT;
+               } while (reg == 0);
+
+               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);
+
+               i = 0;
+               do {
+                       reg = mmio_read_8(IIC_DVFS_REG_ICSR) &
+                           IIC_DVFS_BIT_ICSR_BUSY;
+                       if (reg == 0)
+                               break;
+
+                       if (i++ > IIC_DVFS_SET_BUSY_LOOP)
+                               panic();
+
+               } while (1);
+
+               mmio_write_8(IIC_DVFS_REG_ICCR, 0x00U);
+
+               (*err)++;
+               if (*err > DVFS_RETRY_MAX)
+                       return DVFS_ERROR;
+
+               *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);
+
+       i = 0;
+       while ((mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY) != 0) {
+               if (i++ > IIC_DVFS_SET_BUSY_LOOP)
+                       panic();
+       }
+
+       mmio_write_8(IIC_DVFS_REG_ICCR, 0);
+       (*err)++;
+
+       if (*err > DVFS_RETRY_MAX)
+               return DVFS_ERROR;
+
+       *state = DVFS_START;
+
+       return DVFS_PROCESS;
+}
+
+IIC_DVFS_FUNC(start, DVFS_STATE_T * state)
+{
+       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);
+
+       lsi_product = mmio_read_32(RCAR_PRR) & RCAR_PRODUCT_MASK;
+       if (lsi_product == RCAR_PRODUCT_E3)
+               goto start;
+
+       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;
+}
+
+IIC_DVFS_FUNC(set_slave, DVFS_STATE_T * state, uint32_t *err, uint8_t slave)
+{
+       uint8_t mode;
+       int32_t result;
+       uint8_t address;
+
+       result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
+       if (result == DVFS_ERROR)
+               return result;
+
+       mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE;
+       if (mode != IIC_DVFS_BIT_ICSR_DTE)
+               return result;
+
+       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;
+}
+
+IIC_DVFS_FUNC(write_addr, DVFS_STATE_T *state, uint32_t *err, uint8_t reg_addr)
+{
+       uint8_t mode;
+       int32_t result;
+
+       result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
+       if (result == DVFS_ERROR)
+               return result;
+
+       mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
+       if (mode != IIC_DVFS_BIT_ICSR_WAIT)
+               return result;
+
+       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;
+}
+
+IIC_DVFS_FUNC(write_data, DVFS_STATE_T *state, uint32_t *err, uint8_t reg_data)
+{
+       int32_t result;
+       uint8_t mode;
+
+       result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
+       if (result == DVFS_ERROR)
+               return result;
+
+       mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
+       if (mode != IIC_DVFS_BIT_ICSR_WAIT)
+               return result;
+
+       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;
+}
+
+IIC_DVFS_FUNC(stop, DVFS_STATE_T *state, uint32_t *err)
+{
+       int32_t result;
+       uint8_t mode;
+
+       result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
+       if (result == DVFS_ERROR)
+               return result;
+
+       mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
+       if (mode != IIC_DVFS_BIT_ICSR_WAIT)
+               return result;
+
+       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;
+
+       for (i = 0; i < IIC_DVFS_SET_BUSY_LOOP; i++) {
+               if (mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_BUSY)
+                       continue;
+               goto done;
+       }
+
+       panic();
+done:
+       mmio_write_8(IIC_DVFS_REG_ICCR, 0);
+
+       return DVFS_COMPLETE;
+}
+
+IIC_DVFS_FUNC(write_reg_addr_read, DVFS_STATE_T *state, uint32_t *err,
+       uint8_t reg_addr)
+{
+       int32_t result;
+       uint8_t mode;
+
+       result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
+       if (result == DVFS_ERROR)
+               return result;
+
+       mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
+       if (mode != IIC_DVFS_BIT_ICSR_WAIT)
+               return result;
+
+       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;
+}
+
+IIC_DVFS_FUNC(retransmit, DVFS_STATE_T *state, uint32_t *err)
+{
+       int32_t result;
+       uint8_t mode;
+
+       result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
+       if (result == DVFS_ERROR)
+               return result;
+
+       mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
+       if (mode != IIC_DVFS_BIT_ICSR_WAIT)
+               return result;
+
+       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;
+}
+
+IIC_DVFS_FUNC(set_slave_read, DVFS_STATE_T *state, uint32_t *err,
+               uint8_t slave)
+{
+       uint8_t address;
+       int32_t result;
+       uint8_t mode;
+
+       result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
+       if (result == DVFS_ERROR)
+               return result;
+
+       mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE;
+       if (mode != IIC_DVFS_BIT_ICSR_DTE)
+               return result;
+
+       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);
+
+       *state = DVFS_CHANGE_SEND_TO_RECIEVE;
+
+       return result;
+}
+
+IIC_DVFS_FUNC(change_send_to_recieve, DVFS_STATE_T *state, uint32_t *err)
+{
+       int32_t result;
+       uint8_t mode;
+
+       result = dvfs_check_error(state, err, DVFS_WRITE_MODE);
+       if (result == DVFS_ERROR)
+               return result;
+
+       mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
+       if (mode != IIC_DVFS_BIT_ICSR_WAIT)
+               return result;
+
+       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;
+}
+
+IIC_DVFS_FUNC(stop_read, DVFS_STATE_T *state, uint32_t *err)
+{
+       int32_t result;
+       uint8_t mode;
+
+       result = dvfs_check_error(state, err, DVFS_READ_MODE);
+       if (result == DVFS_ERROR)
+               return result;
+
+       mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_WAIT;
+       if (mode != IIC_DVFS_BIT_ICSR_WAIT)
+               return result;
+
+       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;
+}
+
+IIC_DVFS_FUNC(read, DVFS_STATE_T *state, uint8_t *reg_data)
+{
+       uint8_t mode;
+
+       mode = mmio_read_8(IIC_DVFS_REG_ICSR) & IIC_DVFS_BIT_ICSR_DTE;
+       if (mode != IIC_DVFS_BIT_ICSR_DTE)
+               return DVFS_PROCESS;
+
+       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)
+{
+       DVFS_STATE_T state = DVFS_START;
+       int32_t result = DVFS_PROCESS;
+       uint32_t err = 0;
+
+       mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS);
+       mmio_write_8(IIC_DVFS_REG_ICCR, 0);
+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;
+       }
+
+       if (result == DVFS_PROCESS)
+               goto again;
+
+       return result;
+}
+
+RCAR_DVFS_API(receive, uint8_t slave, uint8_t reg, uint8_t *data)
+{
+       DVFS_STATE_T state = DVFS_START;
+       int32_t result = DVFS_PROCESS;
+       uint32_t err = 0;
+
+       mstpcr_write(SCMSTPCR9, CPG_MSTPSR9, CPG_BIT_SMSTPCR9_DVFS);
+       mmio_write_8(IIC_DVFS_REG_ICCR, 0);
+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;
+       case DVFS_CHANGE_SEND_TO_RECIEVE:
+               result = dvfs_change_send_to_recieve(&state, &err);
+               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;
+       }
+
+       if (result == DVFS_PROCESS)
+               goto again;
+
+       return result;
+}
diff --git a/drivers/renesas/rcar/iic_dvfs/iic_dvfs.h b/drivers/renesas/rcar/iic_dvfs/iic_dvfs.h
new file mode 100644 (file)
index 0000000..3c4a9a5
--- /dev/null
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef IIC_DVFS_H__
+#define IIC_DVFS_H__
+
+/* PMIC slave */
+#define PMIC                   (0x30)
+#define        BKUP_MODE_CNT           (0x20)
+#define        DVFS_SET_VID            (0x54)
+#define        REG_KEEP10              (0x79)
+
+/* EEPROM slave */
+#define EEPROM                 (0x50)
+#define        BOARD_ID                (0x70)
+
+int32_t rcar_iic_dvfs_receive(uint8_t slave, uint8_t reg, uint8_t *data);
+int32_t rcar_iic_dvfs_send(uint8_t slave, uint8_t regr, uint8_t data);
+
+#endif