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