plat_ble_setup.c 23 KB

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