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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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