1 /* 2 * Copyright (C) 2018 Marvell International Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 * https://spdx.org/licenses 6 */ 7 8 #include <common/debug.h> 9 #include <drivers/marvell/ap807_clocks_init.h> 10 #include <drivers/marvell/aro.h> 11 #include <drivers/marvell/ccu.h> 12 #include <drivers/marvell/io_win.h> 13 #include <drivers/marvell/mochi/ap_setup.h> 14 #include <drivers/marvell/mochi/cp110_setup.h> 15 16 #include <armada_common.h> 17 #include <mv_ddr_if.h> 18 #include <mvebu_def.h> 19 #include <plat_marvell.h> 20 21 /* Register for skip image use */ 22 #define SCRATCH_PAD_REG2 0xF06F00A8 23 #define SCRATCH_PAD_SKIP_VAL 0x01 24 #define NUM_OF_GPIO_PER_REG 32 25 26 #define MMAP_SAVE_AND_CONFIG 0 27 #define MMAP_RESTORE_SAVED 1 28 29 /* SAR clock settings */ 30 #define MVEBU_AP_GEN_MGMT_BASE (MVEBU_RFU_BASE + 0x8000) 31 #define MVEBU_AP_SAR_REG_BASE(r) (MVEBU_AP_GEN_MGMT_BASE + 0x200 +\ 32 ((r) << 2)) 33 34 #define SAR_CLOCK_FREQ_MODE_OFFSET (0) 35 #define SAR_CLOCK_FREQ_MODE_MASK (0x1f << SAR_CLOCK_FREQ_MODE_OFFSET) 36 #define SAR_PIDI_LOW_SPEED_OFFSET (20) 37 #define SAR_PIDI_LOW_SPEED_MASK (1 << SAR_PIDI_LOW_SPEED_OFFSET) 38 #define SAR_PIDI_LOW_SPEED_SHIFT (15) 39 #define SAR_PIDI_LOW_SPEED_SET (1 << SAR_PIDI_LOW_SPEED_SHIFT) 40 41 #define FREQ_MODE_AP_SAR_REG_NUM (0) 42 #define SAR_CLOCK_FREQ_MODE(v) (((v) & SAR_CLOCK_FREQ_MODE_MASK) >> \ 43 SAR_CLOCK_FREQ_MODE_OFFSET) 44 45 #define AVS_I2C_EEPROM_ADDR 0x57 /* EEPROM */ 46 #define AVS_EN_CTRL_REG (MVEBU_AP_GEN_MGMT_BASE + 0x130) 47 #define AVS_ENABLE_OFFSET (0) 48 #define AVS_SOFT_RESET_OFFSET (2) 49 #define AVS_TARGET_DELTA_OFFSET (21) 50 51 #ifndef MVEBU_SOC_AP807 52 /* AP806 SVC bits */ 53 #define AVS_LOW_VDD_LIMIT_OFFSET (4) 54 #define AVS_HIGH_VDD_LIMIT_OFFSET (12) 55 #define AVS_VDD_LOW_LIMIT_MASK (0xFF << AVS_LOW_VDD_LIMIT_OFFSET) 56 #define AVS_VDD_HIGH_LIMIT_MASK (0xFF << AVS_HIGH_VDD_LIMIT_OFFSET) 57 #else 58 /* AP807 SVC bits */ 59 #define AVS_LOW_VDD_LIMIT_OFFSET (3) 60 #define AVS_HIGH_VDD_LIMIT_OFFSET (13) 61 #define AVS_VDD_LOW_LIMIT_MASK (0x3FF << AVS_LOW_VDD_LIMIT_OFFSET) 62 #define AVS_VDD_HIGH_LIMIT_MASK (0x3FF << AVS_HIGH_VDD_LIMIT_OFFSET) 63 #endif 64 65 /* VDD limit is 0.9V for A70x0 @ CPU frequency < 1600MHz */ 66 #define AVS_A7K_LOW_CLK_VALUE ((0x80 << AVS_TARGET_DELTA_OFFSET) | \ 67 (0x1A << AVS_HIGH_VDD_LIMIT_OFFSET) | \ 68 (0x1A << AVS_LOW_VDD_LIMIT_OFFSET) | \ 69 (0x1 << AVS_SOFT_RESET_OFFSET) | \ 70 (0x1 << AVS_ENABLE_OFFSET)) 71 /* VDD limit is 1.0V for all A80x0 devices */ 72 #define AVS_A8K_CLK_VALUE ((0x80 << AVS_TARGET_DELTA_OFFSET) | \ 73 (0x24 << AVS_HIGH_VDD_LIMIT_OFFSET) | \ 74 (0x24 << AVS_LOW_VDD_LIMIT_OFFSET) | \ 75 (0x1 << AVS_SOFT_RESET_OFFSET) | \ 76 (0x1 << AVS_ENABLE_OFFSET)) 77 /* VDD limit is 0.82V for all A3900 devices 78 * AVS offsets are not the same as in A70x0 79 */ 80 #define AVS_A3900_CLK_VALUE ((0x80u << 24) | \ 81 (0x2c2 << 13) | \ 82 (0x2c2 << 3) | \ 83 (0x1 << AVS_SOFT_RESET_OFFSET) | \ 84 (0x1 << AVS_ENABLE_OFFSET)) 85 /* VDD is 0.88V for 2GHz clock */ 86 #define AVS_A3900_HIGH_CLK_VALUE ((0x80u << 24) | \ 87 (0x2f5 << 13) | \ 88 (0x2f5 << 3) | \ 89 (0x1 << AVS_SOFT_RESET_OFFSET) | \ 90 (0x1 << AVS_ENABLE_OFFSET)) 91 92 #define AVS_CN9130_HIGH_CLK_VALUE ((0x80 << 24) | \ 93 (0x2dc << 13) | \ 94 (0x2dc << 3) | \ 95 (0x1 << AVS_SOFT_RESET_OFFSET) | \ 96 (0x1 << AVS_ENABLE_OFFSET)) 97 98 #define MVEBU_AP_EFUSE_SRV_CTRL_REG (MVEBU_AP_GEN_MGMT_BASE + 0x8) 99 #define EFUSE_SRV_CTRL_LD_SELECT_OFFS 6 100 #define EFUSE_SRV_CTRL_LD_SEL_USER_MASK (1 << EFUSE_SRV_CTRL_LD_SELECT_OFFS) 101 102 103 /* 104 * - Identification information in the LD-0 eFuse: 105 * DRO: LD0[74:65] - Not used by the SW 106 * Revision: LD0[78:75] - Not used by the SW 107 * Bin: LD0[80:79] - Not used by the SW 108 * SW Revision: LD0[115:113] 109 * Cluster 1 PWR: LD0[193] - if set to 1, power down CPU Cluster-1 110 * resulting in 2 CPUs active only (7020) 111 */ 112 #define MVEBU_AP_LD_EFUSE_BASE (MVEBU_AP_GEN_MGMT_BASE + 0xF00) 113 /* Bits [94:63] - 32 data bits total */ 114 #define MVEBU_AP_LD0_94_63_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x8) 115 /* Bits [125:95] - 31 data bits total, 32nd bit is parity for bits [125:63] */ 116 #define MVEBU_AP_LD0_125_95_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0xC) 117 /* Bits [220:189] - 32 data bits total */ 118 #define MVEBU_AP_LD0_220_189_EFUSE_OFFS (MVEBU_AP_LD_EFUSE_BASE + 0x18) 119 /* Offsets for the above 2 fields combined into single 64-bit value [125:63] */ 120 #define EFUSE_AP_LD0_DRO_OFFS 2 /* LD0[74:65] */ 121 #define EFUSE_AP_LD0_DRO_MASK 0x3FF 122 #define EFUSE_AP_LD0_REVID_OFFS 12 /* LD0[78:75] */ 123 #define EFUSE_AP_LD0_REVID_MASK 0xF 124 #define EFUSE_AP_LD0_BIN_OFFS 16 /* LD0[80:79] */ 125 #define EFUSE_AP_LD0_BIN_MASK 0x3 126 #define EFUSE_AP_LD0_SWREV_OFFS 50 /* LD0[115:113] */ 127 #define EFUSE_AP_LD0_SWREV_MASK 0x7 128 129 #ifndef MVEBU_SOC_AP807 130 /* AP806 AVS work points in the LD0 eFuse 131 * SVC1 work point: LD0[88:81] 132 * SVC2 work point: LD0[96:89] 133 * SVC3 work point: LD0[104:97] 134 * SVC4 work point: LD0[112:105] 135 */ 136 #define EFUSE_AP_LD0_SVC1_OFFS 18 /* LD0[88:81] */ 137 #define EFUSE_AP_LD0_SVC2_OFFS 26 /* LD0[96:89] */ 138 #define EFUSE_AP_LD0_SVC3_OFFS 34 /* LD0[104:97] */ 139 #define EFUSE_AP_LD0_WP_MASK 0xFF 140 #else 141 /* AP807 AVS work points in the LD0 eFuse 142 * SVC1 work point: LD0[91:81] 143 * SVC2 work point: LD0[102:92] 144 * SVC3 work point: LD0[113:103] 145 */ 146 #define EFUSE_AP_LD0_SVC1_OFFS 17 /* LD0[91:81] */ 147 #define EFUSE_AP_LD0_SVC2_OFFS 28 /* LD0[102:92] */ 148 #define EFUSE_AP_LD0_SVC3_OFFS 39 /* LD0[113:103] */ 149 #define EFUSE_AP_LD0_WP_MASK 0x3FF 150 #endif 151 152 #define EFUSE_AP_LD0_SVC4_OFFS 42 /* LD0[112:105] */ 153 154 #define EFUSE_AP_LD0_CLUSTER_DOWN_OFFS 4 155 156 #if MARVELL_SVC_TEST 157 #define MVEBU_CP_MPP_CTRL37_OFFS 20 158 #define MVEBU_CP_MPP_CTRL38_OFFS 24 159 #define MVEBU_CP_MPP_I2C_FUNC 2 160 #define MVEBU_MPP_CTRL_MASK 0xf 161 #endif 162 163 /* Return the AP revision of the chip */ 164 static unsigned int ble_get_ap_type(void) 165 { 166 unsigned int chip_rev_id; 167 168 chip_rev_id = mmio_read_32(MVEBU_CSS_GWD_CTRL_IIDR2_REG); 169 chip_rev_id = ((chip_rev_id & GWD_IIDR2_CHIP_ID_MASK) >> 170 GWD_IIDR2_CHIP_ID_OFFSET); 171 172 return chip_rev_id; 173 } 174 175 /****************************************************************************** 176 * The routine allows to save the CCU and IO windows configuration during DRAM 177 * setup and restore them afterwards before exiting the BLE stage. 178 * Such window configuration is required since not all default settings coming 179 * from the HW and the BootROM allow access to peripherals connected to 180 * all available CPn components. 181 * For instance, when the boot device is located on CP0, the IO window to CP1 182 * is not opened automatically by the HW and if the DRAM SPD is located on CP1 183 * i2c channel, it cannot be read at BLE stage. 184 * Therefore the DRAM init procedure have to provide access to all available 185 * CPn peripherals during the BLE stage by setting the CCU IO window to all 186 * CPnph addresses and by enabling the IO windows accordingly. 187 * Additionally this function configures the CCU GCR to DRAM, which allows 188 * usage or more than 4GB DRAM as it configured by the default CCU DRAM window. 189 * 190 * IN: 191 * MMAP_SAVE_AND_CONFIG - save the existing configuration and update it 192 * MMAP_RESTORE_SAVED - restore saved configuration 193 * OUT: 194 * NONE 195 **************************************************************************** 196 */ 197 static void ble_plat_mmap_config(int restore) 198 { 199 if (restore == MMAP_RESTORE_SAVED) { 200 /* Restore all orig. settings that were modified by BLE stage */ 201 ccu_restore_win_all(MVEBU_AP0); 202 /* Restore CCU */ 203 iow_restore_win_all(MVEBU_AP0); 204 return; 205 } 206 207 /* Store original values */ 208 ccu_save_win_all(MVEBU_AP0); 209 /* Save CCU */ 210 iow_save_win_all(MVEBU_AP0); 211 212 init_ccu(MVEBU_AP0); 213 /* The configuration saved, now all the changes can be done */ 214 init_io_win(MVEBU_AP0); 215 } 216 217 /**************************************************************************** 218 * Setup Adaptive Voltage Switching - this is required for some platforms 219 **************************************************************************** 220 */ 221 #if !MARVELL_SVC_TEST 222 static void ble_plat_avs_config(void) 223 { 224 uint32_t freq_mode, device_id; 225 uint32_t avs_val = 0; 226 227 freq_mode = 228 SAR_CLOCK_FREQ_MODE(mmio_read_32(MVEBU_AP_SAR_REG_BASE( 229 FREQ_MODE_AP_SAR_REG_NUM))); 230 /* Check which SoC is running and act accordingly */ 231 if (ble_get_ap_type() == CHIP_ID_AP807) { 232 /* Increase CPU voltage for higher CPU clock */ 233 switch (freq_mode) { 234 case CPU_2000_DDR_1200_RCLK_1200: 235 avs_val = AVS_A3900_HIGH_CLK_VALUE; 236 break; 237 #ifdef MVEBU_SOC_AP807 238 case CPU_2200_DDR_1200_RCLK_1200: 239 avs_val = AVS_CN9130_HIGH_CLK_VALUE; 240 break; 241 #endif 242 default: 243 avs_val = AVS_A3900_CLK_VALUE; 244 } 245 246 } else { 247 /* Check which SoC is running and act accordingly */ 248 device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); 249 switch (device_id) { 250 case MVEBU_80X0_DEV_ID: 251 case MVEBU_80X0_CP115_DEV_ID: 252 /* Always fix the default AVS value on A80x0 */ 253 avs_val = AVS_A8K_CLK_VALUE; 254 break; 255 case MVEBU_70X0_DEV_ID: 256 case MVEBU_70X0_CP115_DEV_ID: 257 /* Fix AVS for CPU clocks lower than 1600MHz on A70x0 */ 258 if ((freq_mode > CPU_1600_DDR_900_RCLK_900_2) && 259 (freq_mode < CPU_DDR_RCLK_INVALID)) 260 avs_val = AVS_A7K_LOW_CLK_VALUE; 261 break; 262 default: 263 ERROR("Unsupported Device ID 0x%x\n", device_id); 264 return; 265 } 266 } 267 268 if (avs_val) { 269 VERBOSE("AVS: Setting AVS CTRL to 0x%x\n", avs_val); 270 mmio_write_32(AVS_EN_CTRL_REG, avs_val); 271 } 272 } 273 #endif 274 /****************************************************************************** 275 * Update or override current AVS work point value using data stored in EEPROM 276 * This is only required by QA/validation flows and activated by 277 * MARVELL_SVC_TEST flag. 278 * 279 * The function is expected to be called twice. 280 * 281 * First time with AVS value of 0 for testing if the EEPROM requests completely 282 * override the AVS value and bypass the eFuse test 283 * 284 * Second time - with non-zero AVS value obtained from eFuses as an input. 285 * In this case the EEPROM may contain AVS correction value (either positive 286 * or negative) that is added to the input AVS value and returned back for 287 * further processing. 288 ****************************************************************************** 289 */ 290 static uint32_t avs_update_from_eeprom(uint32_t avs_workpoint) 291 { 292 uint32_t new_wp = avs_workpoint; 293 #if MARVELL_SVC_TEST 294 /* --------------------------------------------------------------------- 295 * EEPROM | Data description (avs_step) 296 * address | 297 * --------------------------------------------------------------------- 298 * 0x120 | AVS workpoint correction value 299 * | if not 0 and not 0xff, correct the AVS taken from eFuse 300 * | by the number of steps indicated by bit[6:0] 301 * | bit[7] defines correction direction. 302 * | If bit[7]=1, add the value from bit[6:0] to AVS workpoint, 303 * | othervise substruct this value from AVS workpoint. 304 * --------------------------------------------------------------------- 305 * 0x121 | AVS workpoint override value 306 * | Override the AVS workpoint with the value stored in this 307 * | byte. When running on AP806, the AVS workpoint is 7 bits 308 * | wide and override value is valid when bit[6:0] holds 309 * | value greater than zero and smaller than 0x33. 310 * | When running on AP807, the AVS workpoint is 10 bits wide. 311 * | Additional 2 MSB bits are supplied by EEPROM byte 0x122. 312 * | AVS override value is valid when byte @ 0x121 and bit[1:0] 313 * | of byte @ 0x122 combined have non-zero value. 314 * --------------------------------------------------------------------- 315 * 0x122 | Extended AVS workpoint override value 316 * | Valid only for AP807 platforms and must be less than 0x4 317 * --------------------------------------------------------------------- 318 */ 319 static uint8_t avs_step[3] = {0}; 320 uintptr_t reg; 321 uint32_t val; 322 unsigned int ap_type = ble_get_ap_type(); 323 324 /* Always happens on second call to this function */ 325 if (avs_workpoint != 0) { 326 /* Get correction steps from the EEPROM */ 327 if ((avs_step[0] != 0) && (avs_step[0] != 0xff)) { 328 NOTICE("AVS request to step %s by 0x%x from old 0x%x\n", 329 avs_step[0] & 0x80 ? "DOWN" : "UP", 330 avs_step[0] & 0x7f, new_wp); 331 if (avs_step[0] & 0x80) 332 new_wp -= avs_step[0] & 0x7f; 333 else 334 new_wp += avs_step[0] & 0x7f; 335 } 336 337 return new_wp; 338 } 339 340 /* AVS values are located in EEPROM 341 * at CP0 i2c bus #0, device 0x57 offset 0x120 342 * The SDA and SCK pins of CP0 i2c-0: MPP[38:37], i2c function 0x2. 343 */ 344 reg = MVEBU_CP_MPP_REGS(0, 4); 345 val = mmio_read_32(reg); 346 val &= ~((MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL37_OFFS) | 347 (MVEBU_MPP_CTRL_MASK << MVEBU_CP_MPP_CTRL38_OFFS)); 348 val |= (MVEBU_CP_MPP_I2C_FUNC << MVEBU_CP_MPP_CTRL37_OFFS) | 349 (MVEBU_CP_MPP_I2C_FUNC << MVEBU_CP_MPP_CTRL38_OFFS); 350 mmio_write_32(reg, val); 351 352 /* Init CP0 i2c-0 */ 353 i2c_init((void *)(MVEBU_CP0_I2C_BASE)); 354 355 /* Read EEPROM only once at the fist call! */ 356 i2c_read(AVS_I2C_EEPROM_ADDR, 0x120, 2, avs_step, 3); 357 NOTICE("== SVC test build ==\n"); 358 NOTICE("EEPROM holds values 0x%x, 0x%x and 0x%x\n", 359 avs_step[0], avs_step[1], avs_step[2]); 360 361 /* Override the AVS value? */ 362 if ((ap_type != CHIP_ID_AP807) && (avs_step[1] < 0x33)) { 363 /* AP806 - AVS is 7 bits */ 364 new_wp = avs_step[1]; 365 366 } else if (ap_type == CHIP_ID_AP807 && (avs_step[2] < 0x4)) { 367 /* AP807 - AVS is 10 bits */ 368 new_wp = avs_step[2]; 369 new_wp <<= 8; 370 new_wp |= avs_step[1]; 371 } 372 373 if (new_wp == 0) 374 NOTICE("Ignore BAD AVS Override value in EEPROM!\n"); 375 else 376 NOTICE("Override AVS by EEPROM value 0x%x\n", new_wp); 377 #endif /* MARVELL_SVC_TEST */ 378 return new_wp; 379 } 380 381 /**************************************************************************** 382 * SVC flow - v0.10 383 * The feature is intended to configure AVS value according to eFuse values 384 * that are burned individually for each SoC during the test process. 385 * Primary AVS value is stored in HD efuse and processed on power on 386 * by the HW engine 387 * Secondary AVS value is located in LD efuse and contains 4 work points for 388 * various CPU frequencies. 389 * The Secondary AVS value is only taken into account if the SW Revision stored 390 * in the efuse is greater than 0 and the CPU is running in a certain speed. 391 **************************************************************************** 392 */ 393 static void ble_plat_svc_config(void) 394 { 395 uint32_t reg_val, avs_workpoint, freq_pidi_mode; 396 uint64_t efuse; 397 uint32_t device_id, single_cluster; 398 uint16_t svc[4], perr[4], i, sw_ver; 399 unsigned int ap_type; 400 401 /* Set access to LD0 */ 402 avs_workpoint = avs_update_from_eeprom(0); 403 if (avs_workpoint) 404 goto set_aws_wp; 405 406 /* Set access to LD0 */ 407 reg_val = mmio_read_32(MVEBU_AP_EFUSE_SRV_CTRL_REG); 408 reg_val &= ~EFUSE_SRV_CTRL_LD_SELECT_OFFS; 409 mmio_write_32(MVEBU_AP_EFUSE_SRV_CTRL_REG, reg_val); 410 411 /* Obtain the value of LD0[125:63] */ 412 efuse = mmio_read_32(MVEBU_AP_LD0_125_95_EFUSE_OFFS); 413 efuse <<= 32; 414 efuse |= mmio_read_32(MVEBU_AP_LD0_94_63_EFUSE_OFFS); 415 416 /* SW Revision: 417 * Starting from SW revision 1 the SVC flow is supported. 418 * SW version 0 (efuse not programmed) should follow the 419 * regular AVS update flow. 420 */ 421 sw_ver = (efuse >> EFUSE_AP_LD0_SWREV_OFFS) & EFUSE_AP_LD0_SWREV_MASK; 422 if (sw_ver < 1) { 423 NOTICE("SVC: SW Revision 0x%x. SVC is not supported\n", sw_ver); 424 #if MARVELL_SVC_TEST 425 NOTICE("SVC_TEST: AVS bypassed\n"); 426 427 #else 428 ble_plat_avs_config(); 429 #endif 430 return; 431 } 432 433 /* Frequency mode from SAR */ 434 freq_pidi_mode = SAR_CLOCK_FREQ_MODE( 435 mmio_read_32( 436 MVEBU_AP_SAR_REG_BASE( 437 FREQ_MODE_AP_SAR_REG_NUM))); 438 439 /* Decode all SVC work points */ 440 svc[0] = (efuse >> EFUSE_AP_LD0_SVC1_OFFS) & EFUSE_AP_LD0_WP_MASK; 441 svc[1] = (efuse >> EFUSE_AP_LD0_SVC2_OFFS) & EFUSE_AP_LD0_WP_MASK; 442 svc[2] = (efuse >> EFUSE_AP_LD0_SVC3_OFFS) & EFUSE_AP_LD0_WP_MASK; 443 444 /* Fetch AP type to distinguish between AP806 and AP807 */ 445 ap_type = ble_get_ap_type(); 446 447 if (ap_type != CHIP_ID_AP807) { 448 svc[3] = (efuse >> EFUSE_AP_LD0_SVC4_OFFS) 449 & EFUSE_AP_LD0_WP_MASK; 450 INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x, [3]=0x%x\n", 451 svc[0], svc[1], svc[2], svc[3]); 452 } else { 453 INFO("SVC: Efuse WP: [0]=0x%x, [1]=0x%x, [2]=0x%x\n", 454 svc[0], svc[1], svc[2]); 455 } 456 457 /* Validate parity of SVC workpoint values */ 458 for (i = 0; i < 4; i++) { 459 uint8_t parity, bit; 460 461 perr[i] = 0; 462 463 for (bit = 1, parity = svc[i] & 1; bit < 7; bit++) 464 parity ^= (svc[i] >> bit) & 1; 465 466 /* Starting from SW version 2, the parity check is mandatory */ 467 if ((sw_ver > 1) && (parity != ((svc[i] >> 7) & 1))) 468 perr[i] = 1; /* register the error */ 469 } 470 471 single_cluster = mmio_read_32(MVEBU_AP_LD0_220_189_EFUSE_OFFS); 472 single_cluster = (single_cluster >> EFUSE_AP_LD0_CLUSTER_DOWN_OFFS) & 1; 473 474 device_id = cp110_device_id_get(MVEBU_CP_REGS_BASE(0)); 475 if (device_id == MVEBU_80X0_DEV_ID || 476 device_id == MVEBU_80X0_CP115_DEV_ID) { 477 /* A8040/A8020 */ 478 NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", 479 single_cluster == 0 ? "8040" : "8020", freq_pidi_mode); 480 switch (freq_pidi_mode) { 481 case CPU_1800_DDR_1050_RCLK_1050: 482 if (perr[1]) 483 goto perror; 484 avs_workpoint = svc[1]; 485 break; 486 case CPU_1600_DDR_1050_RCLK_1050: 487 case CPU_1600_DDR_900_RCLK_900_2: 488 if (perr[2]) 489 goto perror; 490 avs_workpoint = svc[2]; 491 break; 492 case CPU_1300_DDR_800_RCLK_800: 493 case CPU_1300_DDR_650_RCLK_650: 494 if (perr[3]) 495 goto perror; 496 avs_workpoint = svc[3]; 497 break; 498 case CPU_2000_DDR_1200_RCLK_1200: 499 case CPU_2000_DDR_1050_RCLK_1050: 500 default: 501 if (perr[0]) 502 goto perror; 503 avs_workpoint = svc[0]; 504 break; 505 } 506 } else if (device_id == MVEBU_70X0_DEV_ID || 507 device_id == MVEBU_70X0_CP115_DEV_ID) { 508 /* A7040/A7020/A6040 */ 509 NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", 510 single_cluster == 0 ? "7040" : "7020", freq_pidi_mode); 511 switch (freq_pidi_mode) { 512 case CPU_1400_DDR_800_RCLK_800: 513 if (single_cluster) {/* 7020 */ 514 if (perr[1]) 515 goto perror; 516 avs_workpoint = svc[1]; 517 } else { 518 if (perr[0]) 519 goto perror; 520 avs_workpoint = svc[0]; 521 } 522 break; 523 case CPU_1200_DDR_800_RCLK_800: 524 if (single_cluster) {/* 7020 */ 525 if (perr[2]) 526 goto perror; 527 avs_workpoint = svc[2]; 528 } else { 529 if (perr[1]) 530 goto perror; 531 avs_workpoint = svc[1]; 532 } 533 break; 534 case CPU_800_DDR_800_RCLK_800: 535 case CPU_1000_DDR_800_RCLK_800: 536 if (single_cluster) {/* 7020 */ 537 if (perr[3]) 538 goto perror; 539 avs_workpoint = svc[3]; 540 } else { 541 if (perr[2]) 542 goto perror; 543 avs_workpoint = svc[2]; 544 } 545 break; 546 case CPU_600_DDR_800_RCLK_800: 547 if (perr[3]) 548 goto perror; 549 avs_workpoint = svc[3]; /* Same for 6040 and 7020 */ 550 break; 551 case CPU_1600_DDR_800_RCLK_800: /* 7020 only */ 552 default: 553 if (single_cluster) {/* 7020 */ 554 if (perr[0]) 555 goto perror; 556 avs_workpoint = svc[0]; 557 } else 558 avs_workpoint = 0; 559 break; 560 } 561 } else if (device_id == MVEBU_3900_DEV_ID) { 562 NOTICE("SVC: DEV ID: %s, FREQ Mode: 0x%x\n", 563 "3900", freq_pidi_mode); 564 switch (freq_pidi_mode) { 565 case CPU_1600_DDR_1200_RCLK_1200: 566 if (perr[0]) 567 goto perror; 568 avs_workpoint = svc[0]; 569 break; 570 case CPU_1300_DDR_800_RCLK_800: 571 if (perr[1]) 572 goto perror; 573 avs_workpoint = svc[1]; 574 break; 575 default: 576 if (perr[0]) 577 goto perror; 578 avs_workpoint = svc[0]; 579 break; 580 } 581 } else { 582 ERROR("SVC: Unsupported Device ID 0x%x\n", device_id); 583 return; 584 } 585 586 /* Set AVS control if needed */ 587 if (avs_workpoint == 0) { 588 ERROR("SVC: AVS work point not changed\n"); 589 return; 590 } 591 592 /* Remove parity bit */ 593 if (ap_type != CHIP_ID_AP807) 594 avs_workpoint &= 0x7F; 595 596 /* Update WP from EEPROM if needed */ 597 avs_workpoint = avs_update_from_eeprom(avs_workpoint); 598 599 set_aws_wp: 600 reg_val = mmio_read_32(AVS_EN_CTRL_REG); 601 NOTICE("SVC: AVS work point changed from 0x%x to 0x%x\n", 602 (reg_val & AVS_VDD_LOW_LIMIT_MASK) >> AVS_LOW_VDD_LIMIT_OFFSET, 603 avs_workpoint); 604 reg_val &= ~(AVS_VDD_LOW_LIMIT_MASK | AVS_VDD_HIGH_LIMIT_MASK); 605 reg_val |= 0x1 << AVS_ENABLE_OFFSET; 606 reg_val |= avs_workpoint << AVS_HIGH_VDD_LIMIT_OFFSET; 607 reg_val |= avs_workpoint << AVS_LOW_VDD_LIMIT_OFFSET; 608 mmio_write_32(AVS_EN_CTRL_REG, reg_val); 609 return; 610 611 perror: 612 ERROR("Failed SVC WP[%d] parity check!\n", i); 613 ERROR("Ignoring the WP values\n"); 614 } 615 616 #if PLAT_RECOVERY_IMAGE_ENABLE 617 static int ble_skip_image_i2c(struct skip_image *skip_im) 618 { 619 ERROR("skipping image using i2c is not supported\n"); 620 /* not supported */ 621 return 0; 622 } 623 624 static int ble_skip_image_other(struct skip_image *skip_im) 625 { 626 ERROR("implementation missing for skip image request\n"); 627 /* not supported, make your own implementation */ 628 return 0; 629 } 630 631 static int ble_skip_image_gpio(struct skip_image *skip_im) 632 { 633 unsigned int val; 634 unsigned int mpp_address = 0; 635 unsigned int offset = 0; 636 637 switch (skip_im->info.test.cp_ap) { 638 case(CP): 639 mpp_address = MVEBU_CP_GPIO_DATA_IN(skip_im->info.test.cp_index, 640 skip_im->info.gpio.num); 641 if (skip_im->info.gpio.num > NUM_OF_GPIO_PER_REG) 642 offset = skip_im->info.gpio.num - NUM_OF_GPIO_PER_REG; 643 else 644 offset = skip_im->info.gpio.num; 645 break; 646 case(AP): 647 mpp_address = MVEBU_AP_GPIO_DATA_IN; 648 offset = skip_im->info.gpio.num; 649 break; 650 } 651 652 val = mmio_read_32(mpp_address); 653 val &= (1 << offset); 654 if ((!val && skip_im->info.gpio.button_state == HIGH) || 655 (val && skip_im->info.gpio.button_state == LOW)) { 656 mmio_write_32(SCRATCH_PAD_REG2, SCRATCH_PAD_SKIP_VAL); 657 return 1; 658 } 659 660 return 0; 661 } 662 663 /* 664 * This function checks if there's a skip image request: 665 * return values: 666 * 1: (true) images request been made. 667 * 0: (false) no image request been made. 668 */ 669 static int ble_skip_current_image(void) 670 { 671 struct skip_image *skip_im; 672 673 /*fetching skip image info*/ 674 skip_im = (struct skip_image *)plat_marvell_get_skip_image_data(); 675 676 if (skip_im == NULL) 677 return 0; 678 679 /* check if skipping image request has already been made */ 680 if (mmio_read_32(SCRATCH_PAD_REG2) == SCRATCH_PAD_SKIP_VAL) 681 return 0; 682 683 switch (skip_im->detection_method) { 684 case GPIO: 685 return ble_skip_image_gpio(skip_im); 686 case I2C: 687 return ble_skip_image_i2c(skip_im); 688 case USER_DEFINED: 689 return ble_skip_image_other(skip_im); 690 } 691 692 return 0; 693 } 694 #endif 695 696 697 int ble_plat_setup(int *skip) 698 { 699 int ret; 700 unsigned int freq_mode; 701 702 /* Power down unused CPUs */ 703 plat_marvell_early_cpu_powerdown(); 704 705 /* 706 * Save the current CCU configuration and make required changes: 707 * - Allow access to DRAM larger than 4GB 708 * - Open memory access to all CPn peripherals 709 */ 710 ble_plat_mmap_config(MMAP_SAVE_AND_CONFIG); 711 712 #if PLAT_RECOVERY_IMAGE_ENABLE 713 /* Check if there's a skip request to bootRom recovery Image */ 714 if (ble_skip_current_image()) { 715 /* close memory access to all CPn peripherals. */ 716 ble_plat_mmap_config(MMAP_RESTORE_SAVED); 717 *skip = 1; 718 return 0; 719 } 720 #endif 721 /* Do required CP-110 setups for BLE stage */ 722 cp110_ble_init(MVEBU_CP_REGS_BASE(0)); 723 724 /* Setup AVS */ 725 ble_plat_svc_config(); 726 727 /* read clk option from sampled-at-reset register */ 728 freq_mode = 729 SAR_CLOCK_FREQ_MODE(mmio_read_32(MVEBU_AP_SAR_REG_BASE( 730 FREQ_MODE_AP_SAR_REG_NUM))); 731 732 /* work with PLL clock driver in AP807 */ 733 if (ble_get_ap_type() == CHIP_ID_AP807) 734 ap807_clocks_init(freq_mode); 735 736 /* Do required AP setups for BLE stage */ 737 ap_ble_init(); 738 739 /* Update DRAM topology (scan DIMM SPDs) */ 740 plat_marvell_dram_update_topology(); 741 742 /* Kick it in */ 743 ret = dram_init(); 744 745 /* Restore the original CCU configuration before exit from BLE */ 746 ble_plat_mmap_config(MMAP_RESTORE_SAVED); 747 748 return ret; 749 } 750