1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2017 - 2020, Broadcom 3*91f16700Schasinglulu * 4*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 5*91f16700Schasinglulu */ 6*91f16700Schasinglulu 7*91f16700Schasinglulu #include <assert.h> 8*91f16700Schasinglulu #include <errno.h> 9*91f16700Schasinglulu #include <stdint.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu #include <common/debug.h> 12*91f16700Schasinglulu #include <drivers/delay_timer.h> 13*91f16700Schasinglulu #include <lib/mmio.h> 14*91f16700Schasinglulu 15*91f16700Schasinglulu #include <sr_utils.h> 16*91f16700Schasinglulu #include <swreg.h> 17*91f16700Schasinglulu 18*91f16700Schasinglulu #define MIN_VOLT 760000 19*91f16700Schasinglulu #define MAX_VOLT 1060000 20*91f16700Schasinglulu 21*91f16700Schasinglulu #define BSTI_WRITE 0x1 22*91f16700Schasinglulu #define BSTI_READ 0x2 23*91f16700Schasinglulu #define BSTI_COMMAND_TA 0x2 24*91f16700Schasinglulu #define BSTI_COMMAND_DATA 0xFF 25*91f16700Schasinglulu #define BSTI_CONTROL_VAL 0x81 26*91f16700Schasinglulu #define BSTI_CONTROL_BUSY 0x100 27*91f16700Schasinglulu #define BSTI_TOGGLE_BIT 0x2 28*91f16700Schasinglulu #define BSTI_CONFI_DONE_MASK 0xFFFFFFFD 29*91f16700Schasinglulu #define BSTI_REG_DATA_MASK 0xFFFF 30*91f16700Schasinglulu #define BSTI_CMD(sb, op, pa, ra, ta, data) \ 31*91f16700Schasinglulu ((((sb) & 0x3) << 30) | (((op) & 0x3) << 28) | \ 32*91f16700Schasinglulu (((pa) & 0x1F) << 23) | (((ra) & 0x1F) << 18) | \ 33*91f16700Schasinglulu (((ta) & 0x3) << 16) | (data)) 34*91f16700Schasinglulu 35*91f16700Schasinglulu #define PHY_REG0 0x0 36*91f16700Schasinglulu #define PHY_REG1 0x1 37*91f16700Schasinglulu #define PHY_REG4 0x4 38*91f16700Schasinglulu #define PHY_REG5 0x5 39*91f16700Schasinglulu #define PHY_REG6 0x6 40*91f16700Schasinglulu #define PHY_REG7 0x7 41*91f16700Schasinglulu #define PHY_REGC 0xc 42*91f16700Schasinglulu 43*91f16700Schasinglulu #define IHOST_VDDC_DATA 0x560 44*91f16700Schasinglulu #define DDR_CORE_DATA 0x2560 45*91f16700Schasinglulu #define UPDATE_POS_EDGE(data, set) ((data) | ((set) << 1)) 46*91f16700Schasinglulu 47*91f16700Schasinglulu /* 48*91f16700Schasinglulu * Formula for SR A2 reworked board: 49*91f16700Schasinglulu * step = ((vol/(1.4117 * 0.98)) - 500000)/3125 50*91f16700Schasinglulu * where, 51*91f16700Schasinglulu * vol - input voltage 52*91f16700Schasinglulu * 500000 - Reference voltage 53*91f16700Schasinglulu * 3125 - one step value 54*91f16700Schasinglulu */ 55*91f16700Schasinglulu #define A2_VOL_REF 500000 56*91f16700Schasinglulu #define ONE_STEP_VALUE 3125 57*91f16700Schasinglulu #define VOL_DIV(vol) (((vol*10000ull)/(14117*98ull)) * 100ull) 58*91f16700Schasinglulu #define STEP_VALUE(vol) \ 59*91f16700Schasinglulu ((((((VOL_DIV(vol)) - A2_VOL_REF) / ONE_STEP_VALUE) & 0xFF) << 8) | 4) 60*91f16700Schasinglulu 61*91f16700Schasinglulu #define B0_VOL_REF ((500000/100)*98) 62*91f16700Schasinglulu #define B0_ONE_STEP_VALUE 3125 63*91f16700Schasinglulu /* 64*91f16700Schasinglulu * Formula for SR B0 chip for IHOST12/03 and VDDC_CORE 65*91f16700Schasinglulu * step = ((vol/1.56) - (500000 * 0.98))/3125 66*91f16700Schasinglulu * where, 67*91f16700Schasinglulu * vol - input voltage 68*91f16700Schasinglulu * 500000 - Reference voltage 69*91f16700Schasinglulu * 3125 - one step value 70*91f16700Schasinglulu */ 71*91f16700Schasinglulu #define B0_VOL_DIV(vol) (((vol)*100ull)/156) 72*91f16700Schasinglulu #define B0_STEP_VALUE(vol) \ 73*91f16700Schasinglulu ((((((B0_VOL_DIV(vol)) - B0_VOL_REF) / B0_ONE_STEP_VALUE) \ 74*91f16700Schasinglulu & 0xFF) << 8) | 4) 75*91f16700Schasinglulu 76*91f16700Schasinglulu /* 77*91f16700Schasinglulu * Formula for SR B0 chip for DDR-CORE 78*91f16700Schasinglulu * step = ((vol/1) - (500000 * 0.98))/3125 79*91f16700Schasinglulu * where, 80*91f16700Schasinglulu * vol - input voltage 81*91f16700Schasinglulu * 500000 - Reference voltage 82*91f16700Schasinglulu * 3125 - one step value 83*91f16700Schasinglulu */ 84*91f16700Schasinglulu #define B0_DDR_VDDC_VOL_DIV(vol) ((vol)/1) 85*91f16700Schasinglulu #define B0_DDR_VDDC_STEP_VALUE(vol) \ 86*91f16700Schasinglulu ((((((B0_DDR_VDDC_VOL_DIV(vol)) - B0_VOL_REF) / B0_ONE_STEP_VALUE) \ 87*91f16700Schasinglulu & 0xFF) << 8) | 4) 88*91f16700Schasinglulu 89*91f16700Schasinglulu #define MAX_SWREG_CNT 8 90*91f16700Schasinglulu #define MAX_ADDR_PER_SWREG 16 91*91f16700Schasinglulu #define MAX_REG_ADDR 0xF 92*91f16700Schasinglulu #define MIN_REG_ADDR 0x0 93*91f16700Schasinglulu 94*91f16700Schasinglulu static const char *sw_reg_name[MAX_SWREG_CNT] = { 95*91f16700Schasinglulu "DDR_VDDC", 96*91f16700Schasinglulu "IHOST03", 97*91f16700Schasinglulu "IHOST12", 98*91f16700Schasinglulu "IHOST_ARRAY", 99*91f16700Schasinglulu "DDRIO_SLAVE", 100*91f16700Schasinglulu "VDDC_CORE", 101*91f16700Schasinglulu "VDDC1", 102*91f16700Schasinglulu "DDRIO_MASTER" 103*91f16700Schasinglulu }; 104*91f16700Schasinglulu 105*91f16700Schasinglulu /* firmware values for all SWREG for 3.3V input operation */ 106*91f16700Schasinglulu static const uint16_t swreg_fm_data_bx[MAX_SWREG_CNT][MAX_ADDR_PER_SWREG] = { 107*91f16700Schasinglulu /* DDR logic: Power Domains independent of 12v or 3p3v */ 108*91f16700Schasinglulu {0x25E0, 0x2D54, 0x0EC6, 0x01EC, 0x28BB, 0x1144, 0x0200, 0x69C0, 109*91f16700Schasinglulu 0x0010, 0x0EDF, 0x90D7, 0x8000, 0x820C, 0x0003, 0x0001, 0x0000}, 110*91f16700Schasinglulu 111*91f16700Schasinglulu /* ihost03, 3p3V */ 112*91f16700Schasinglulu {0x05E0, 0x39E5, 0x03C1, 0x007C, 0x8BA9, 0x4444, 0x3300, 0x6B80, 113*91f16700Schasinglulu 0x003F, 0x0FFF, 0x90D7, 0x8000, 0x240C, 0x0003, 0x0001, 0x0000}, 114*91f16700Schasinglulu 115*91f16700Schasinglulu /* ihost12 3p3v */ 116*91f16700Schasinglulu {0x05E0, 0x39E5, 0x03C1, 0x007C, 0x8BA9, 0x4444, 0x3300, 0x6B80, 117*91f16700Schasinglulu 0x003F, 0x0FFF, 0x90D7, 0x8000, 0x240C, 0x0003, 0x0001, 0x0000}, 118*91f16700Schasinglulu 119*91f16700Schasinglulu /* ihost array */ 120*91f16700Schasinglulu {0x25E0, 0x2D94, 0x0EC6, 0x01EC, 0x2ABB, 0x1144, 0x0340, 0x69C0, 121*91f16700Schasinglulu 0x0010, 0x0EDF, 0x90D7, 0x8000, 0x860C, 0x0003, 0x0001, 0x0000}, 122*91f16700Schasinglulu 123*91f16700Schasinglulu /* ddr io slave : 3p3v */ 124*91f16700Schasinglulu {0x0560, 0x4438, 0x0000, 0x001F, 0x8028, 0x4444, 0x0300, 0x4380, 125*91f16700Schasinglulu 0x003F, 0x0FFF, 0x10D7, 0x8000, 0xA70C, 0x0003, 0x0001, 0x0000}, 126*91f16700Schasinglulu 127*91f16700Schasinglulu /* core master 3p3v */ 128*91f16700Schasinglulu {0x05E0, 0x39E5, 0x03C1, 0x007C, 0x8BA9, 0x4444, 0x3300, 0x6B80, 129*91f16700Schasinglulu 0x003F, 0x0FFF, 0x90D7, 0x8000, 0x240C, 0x0003, 0x0001, 0x0000}, 130*91f16700Schasinglulu 131*91f16700Schasinglulu /* core slave 3p3v */ 132*91f16700Schasinglulu {0x0560, 0x4438, 0x0000, 0x001F, 0x8028, 0x4444, 0x0300, 0x4380, 133*91f16700Schasinglulu 0x003F, 0x0FFF, 0x10D7, 0x8000, 0x240C, 0x0003, 0x0001, 0x0000}, 134*91f16700Schasinglulu 135*91f16700Schasinglulu /* ddr io master : 3p3v */ 136*91f16700Schasinglulu {0x05E0, 0x39E5, 0x03C1, 0x007C, 0x8BA9, 0x4444, 0x3300, 0x6B80, 137*91f16700Schasinglulu 0x003F, 0x0FFF, 0x90D7, 0x8000, 0xA70C, 0x0003, 0x0001, 0x0000}, 138*91f16700Schasinglulu }; 139*91f16700Schasinglulu 140*91f16700Schasinglulu #define FM_DATA swreg_fm_data_bx 141*91f16700Schasinglulu 142*91f16700Schasinglulu static int swreg_poll(void) 143*91f16700Schasinglulu { 144*91f16700Schasinglulu uint32_t data; 145*91f16700Schasinglulu int retry = 100; 146*91f16700Schasinglulu 147*91f16700Schasinglulu do { 148*91f16700Schasinglulu data = mmio_read_32(BSTI_CONTROL_OFFSET); 149*91f16700Schasinglulu if ((data & BSTI_CONTROL_BUSY) != BSTI_CONTROL_BUSY) 150*91f16700Schasinglulu return 0; 151*91f16700Schasinglulu retry--; 152*91f16700Schasinglulu udelay(1); 153*91f16700Schasinglulu } while (retry > 0); 154*91f16700Schasinglulu 155*91f16700Schasinglulu return -ETIMEDOUT; 156*91f16700Schasinglulu } 157*91f16700Schasinglulu 158*91f16700Schasinglulu static int write_swreg_config(enum sw_reg reg_id, uint32_t addr, uint32_t data) 159*91f16700Schasinglulu { 160*91f16700Schasinglulu uint32_t cmd; 161*91f16700Schasinglulu int ret; 162*91f16700Schasinglulu 163*91f16700Schasinglulu cmd = BSTI_CMD(0x1, BSTI_WRITE, reg_id, addr, BSTI_COMMAND_TA, data); 164*91f16700Schasinglulu mmio_write_32(BSTI_CONTROL_OFFSET, BSTI_CONTROL_VAL); 165*91f16700Schasinglulu mmio_write_32(BSTI_COMMAND_OFFSET, cmd); 166*91f16700Schasinglulu ret = swreg_poll(); 167*91f16700Schasinglulu if (ret) { 168*91f16700Schasinglulu ERROR("Failed to write swreg %s addr 0x%x\n", 169*91f16700Schasinglulu sw_reg_name[reg_id-1], addr); 170*91f16700Schasinglulu return ret; 171*91f16700Schasinglulu } 172*91f16700Schasinglulu return ret; 173*91f16700Schasinglulu } 174*91f16700Schasinglulu 175*91f16700Schasinglulu static int read_swreg_config(enum sw_reg reg_id, uint32_t addr, uint32_t *data) 176*91f16700Schasinglulu { 177*91f16700Schasinglulu uint32_t cmd; 178*91f16700Schasinglulu int ret; 179*91f16700Schasinglulu 180*91f16700Schasinglulu cmd = BSTI_CMD(0x1, BSTI_READ, reg_id, addr, BSTI_COMMAND_TA, PHY_REG0); 181*91f16700Schasinglulu mmio_write_32(BSTI_CONTROL_OFFSET, BSTI_CONTROL_VAL); 182*91f16700Schasinglulu mmio_write_32(BSTI_COMMAND_OFFSET, cmd); 183*91f16700Schasinglulu ret = swreg_poll(); 184*91f16700Schasinglulu if (ret) { 185*91f16700Schasinglulu ERROR("Failed to read swreg %s addr 0x%x\n", 186*91f16700Schasinglulu sw_reg_name[reg_id-1], addr); 187*91f16700Schasinglulu return ret; 188*91f16700Schasinglulu } 189*91f16700Schasinglulu 190*91f16700Schasinglulu *data = mmio_read_32(BSTI_COMMAND_OFFSET); 191*91f16700Schasinglulu *data &= BSTI_REG_DATA_MASK; 192*91f16700Schasinglulu return ret; 193*91f16700Schasinglulu } 194*91f16700Schasinglulu 195*91f16700Schasinglulu static int swreg_config_done(enum sw_reg reg_id) 196*91f16700Schasinglulu { 197*91f16700Schasinglulu uint32_t read_data; 198*91f16700Schasinglulu int ret; 199*91f16700Schasinglulu 200*91f16700Schasinglulu ret = read_swreg_config(reg_id, PHY_REG0, &read_data); 201*91f16700Schasinglulu if (ret) 202*91f16700Schasinglulu return ret; 203*91f16700Schasinglulu 204*91f16700Schasinglulu read_data &= BSTI_CONFI_DONE_MASK; 205*91f16700Schasinglulu read_data |= BSTI_TOGGLE_BIT; 206*91f16700Schasinglulu ret = write_swreg_config(reg_id, PHY_REG0, read_data); 207*91f16700Schasinglulu if (ret) 208*91f16700Schasinglulu return ret; 209*91f16700Schasinglulu 210*91f16700Schasinglulu ret = read_swreg_config(reg_id, PHY_REG0, &read_data); 211*91f16700Schasinglulu if (ret) 212*91f16700Schasinglulu return ret; 213*91f16700Schasinglulu 214*91f16700Schasinglulu read_data &= BSTI_CONFI_DONE_MASK; 215*91f16700Schasinglulu ret = write_swreg_config(reg_id, PHY_REG0, read_data); 216*91f16700Schasinglulu if (ret) 217*91f16700Schasinglulu return ret; 218*91f16700Schasinglulu 219*91f16700Schasinglulu return ret; 220*91f16700Schasinglulu } 221*91f16700Schasinglulu 222*91f16700Schasinglulu #ifdef DUMP_SWREG 223*91f16700Schasinglulu static void dump_swreg_firmware(void) 224*91f16700Schasinglulu { 225*91f16700Schasinglulu enum sw_reg reg_id; 226*91f16700Schasinglulu uint32_t data; 227*91f16700Schasinglulu int addr; 228*91f16700Schasinglulu int ret; 229*91f16700Schasinglulu 230*91f16700Schasinglulu for (reg_id = DDR_VDDC; reg_id <= DDRIO_MASTER; reg_id++) { 231*91f16700Schasinglulu INFO("SWREG: %s\n", sw_reg_name[reg_id - 1]); 232*91f16700Schasinglulu for (addr = MIN_REG_ADDR; addr <= MAX_REG_ADDR; addr++) { 233*91f16700Schasinglulu ret = read_swreg_config(reg_id, addr, &data); 234*91f16700Schasinglulu if (ret) 235*91f16700Schasinglulu ERROR("Failed to read offset %d\n", addr); 236*91f16700Schasinglulu INFO("\t0x%x: 0x%04x\n", addr, data); 237*91f16700Schasinglulu } 238*91f16700Schasinglulu } 239*91f16700Schasinglulu } 240*91f16700Schasinglulu #endif 241*91f16700Schasinglulu 242*91f16700Schasinglulu int set_swreg(enum sw_reg reg_id, uint32_t micro_volts) 243*91f16700Schasinglulu { 244*91f16700Schasinglulu uint32_t step, programmed_step; 245*91f16700Schasinglulu uint32_t data = IHOST_VDDC_DATA; 246*91f16700Schasinglulu int ret; 247*91f16700Schasinglulu 248*91f16700Schasinglulu if ((micro_volts > MAX_VOLT) || (micro_volts < MIN_VOLT)) { 249*91f16700Schasinglulu ERROR("input voltage out-of-range\n"); 250*91f16700Schasinglulu ret = -EINVAL; 251*91f16700Schasinglulu goto failed; 252*91f16700Schasinglulu } 253*91f16700Schasinglulu 254*91f16700Schasinglulu ret = read_swreg_config(reg_id, PHY_REGC, &programmed_step); 255*91f16700Schasinglulu if (ret) 256*91f16700Schasinglulu goto failed; 257*91f16700Schasinglulu 258*91f16700Schasinglulu if (reg_id == DDR_VDDC) 259*91f16700Schasinglulu step = B0_DDR_VDDC_STEP_VALUE(micro_volts); 260*91f16700Schasinglulu else 261*91f16700Schasinglulu step = B0_STEP_VALUE(micro_volts); 262*91f16700Schasinglulu 263*91f16700Schasinglulu if ((step >> 8) != (programmed_step >> 8)) { 264*91f16700Schasinglulu ret = write_swreg_config(reg_id, PHY_REGC, step); 265*91f16700Schasinglulu if (ret) 266*91f16700Schasinglulu goto failed; 267*91f16700Schasinglulu 268*91f16700Schasinglulu if (reg_id == DDR_VDDC) 269*91f16700Schasinglulu data = DDR_CORE_DATA; 270*91f16700Schasinglulu 271*91f16700Schasinglulu ret = write_swreg_config(reg_id, PHY_REG0, 272*91f16700Schasinglulu UPDATE_POS_EDGE(data, 1)); 273*91f16700Schasinglulu if (ret) 274*91f16700Schasinglulu goto failed; 275*91f16700Schasinglulu 276*91f16700Schasinglulu ret = write_swreg_config(reg_id, PHY_REG0, 277*91f16700Schasinglulu UPDATE_POS_EDGE(data, 0)); 278*91f16700Schasinglulu if (ret) 279*91f16700Schasinglulu goto failed; 280*91f16700Schasinglulu } 281*91f16700Schasinglulu 282*91f16700Schasinglulu INFO("%s voltage updated to %duV\n", sw_reg_name[reg_id-1], 283*91f16700Schasinglulu micro_volts); 284*91f16700Schasinglulu return ret; 285*91f16700Schasinglulu 286*91f16700Schasinglulu failed: 287*91f16700Schasinglulu /* 288*91f16700Schasinglulu * Stop booting if voltages are not set 289*91f16700Schasinglulu * correctly. Booting will fail at random point 290*91f16700Schasinglulu * if we continue with wrong voltage settings. 291*91f16700Schasinglulu */ 292*91f16700Schasinglulu ERROR("Failed to set %s voltage to %duV\n", sw_reg_name[reg_id-1], 293*91f16700Schasinglulu micro_volts); 294*91f16700Schasinglulu assert(0); 295*91f16700Schasinglulu 296*91f16700Schasinglulu return ret; 297*91f16700Schasinglulu } 298*91f16700Schasinglulu 299*91f16700Schasinglulu /* Update SWREG firmware for all power domain for A2 chip */ 300*91f16700Schasinglulu int swreg_firmware_update(void) 301*91f16700Schasinglulu { 302*91f16700Schasinglulu enum sw_reg reg_id; 303*91f16700Schasinglulu uint32_t data; 304*91f16700Schasinglulu int addr; 305*91f16700Schasinglulu int ret; 306*91f16700Schasinglulu 307*91f16700Schasinglulu /* write firmware values */ 308*91f16700Schasinglulu for (reg_id = DDR_VDDC; reg_id <= DDRIO_MASTER; reg_id++) { 309*91f16700Schasinglulu /* write higher location first */ 310*91f16700Schasinglulu for (addr = MAX_REG_ADDR; addr >= MIN_REG_ADDR; addr--) { 311*91f16700Schasinglulu ret = write_swreg_config(reg_id, addr, 312*91f16700Schasinglulu FM_DATA[reg_id - 1][addr]); 313*91f16700Schasinglulu if (ret) 314*91f16700Schasinglulu goto exit; 315*91f16700Schasinglulu } 316*91f16700Schasinglulu } 317*91f16700Schasinglulu 318*91f16700Schasinglulu /* trigger SWREG firmware update */ 319*91f16700Schasinglulu for (reg_id = DDR_VDDC; reg_id <= DDRIO_MASTER; reg_id++) { 320*91f16700Schasinglulu /* 321*91f16700Schasinglulu * Slave regulator doesn't have to be updated, 322*91f16700Schasinglulu * Updating Master is enough 323*91f16700Schasinglulu */ 324*91f16700Schasinglulu if ((reg_id == DDRIO_SLAVE) || (reg_id == VDDC1)) 325*91f16700Schasinglulu continue; 326*91f16700Schasinglulu 327*91f16700Schasinglulu ret = swreg_config_done(reg_id); 328*91f16700Schasinglulu if (ret) { 329*91f16700Schasinglulu ERROR("Failed to trigger SWREG firmware update for %s\n" 330*91f16700Schasinglulu , sw_reg_name[reg_id-1]); 331*91f16700Schasinglulu return ret; 332*91f16700Schasinglulu } 333*91f16700Schasinglulu } 334*91f16700Schasinglulu 335*91f16700Schasinglulu for (reg_id = DDR_VDDC; reg_id <= DDRIO_MASTER; reg_id++) { 336*91f16700Schasinglulu /* 337*91f16700Schasinglulu * IHOST_ARRAY will be used on some boards like STRATUS and 338*91f16700Schasinglulu * there will not be any issue even if it is updated on other 339*91f16700Schasinglulu * boards where it is not used. 340*91f16700Schasinglulu */ 341*91f16700Schasinglulu if (reg_id == IHOST_ARRAY) 342*91f16700Schasinglulu continue; 343*91f16700Schasinglulu 344*91f16700Schasinglulu for (addr = MIN_REG_ADDR; addr <= MAX_REG_ADDR; addr++) { 345*91f16700Schasinglulu ret = read_swreg_config(reg_id, addr, &data); 346*91f16700Schasinglulu if (ret || (!ret && 347*91f16700Schasinglulu (data != FM_DATA[reg_id - 1][addr]))) { 348*91f16700Schasinglulu ERROR("swreg fm update failed: %s at off %d\n", 349*91f16700Schasinglulu sw_reg_name[reg_id - 1], addr); 350*91f16700Schasinglulu ERROR("Read val: 0x%x, expected val: 0x%x\n", 351*91f16700Schasinglulu data, FM_DATA[reg_id - 1][addr]); 352*91f16700Schasinglulu return -1; 353*91f16700Schasinglulu } 354*91f16700Schasinglulu } 355*91f16700Schasinglulu } 356*91f16700Schasinglulu 357*91f16700Schasinglulu INFO("Updated SWREG firmware\n"); 358*91f16700Schasinglulu 359*91f16700Schasinglulu #ifdef DUMP_SWREG 360*91f16700Schasinglulu dump_swreg_firmware(); 361*91f16700Schasinglulu #endif 362*91f16700Schasinglulu return ret; 363*91f16700Schasinglulu 364*91f16700Schasinglulu exit: 365*91f16700Schasinglulu /* 366*91f16700Schasinglulu * Stop booting if swreg firmware update fails. 367*91f16700Schasinglulu * Booting will fail at random point if we 368*91f16700Schasinglulu * continue with wrong voltage settings. 369*91f16700Schasinglulu */ 370*91f16700Schasinglulu ERROR("Failed to update firmware for %s SWREG\n", 371*91f16700Schasinglulu sw_reg_name[reg_id-1]); 372*91f16700Schasinglulu assert(0); 373*91f16700Schasinglulu 374*91f16700Schasinglulu return ret; 375*91f16700Schasinglulu } 376