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