sys_env_lib.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. /*
  2. * Copyright (C) Marvell International Ltd. and its affiliates
  3. *
  4. * SPDX-License-Identifier: GPL-2.0
  5. */
  6. #include <common.h>
  7. #include <i2c.h>
  8. #include <spl.h>
  9. #include <asm/io.h>
  10. #include <asm/arch/cpu.h>
  11. #include <asm/arch/soc.h>
  12. #include "seq_exec.h"
  13. #include "sys_env_lib.h"
  14. #include "../../../drivers/ddr/marvell/a38x/ddr3_a38x.h"
  15. #ifdef CONFIG_ARMADA_38X
  16. enum unit_id sys_env_soc_unit_nums[MAX_UNITS_ID][MAX_DEV_ID_NUM] = {
  17. /* 6820 6810 6811 6828 */
  18. /* PEX_UNIT_ID */ { 4, 3, 3, 4},
  19. /* ETH_GIG_UNIT_ID */ { 3, 2, 3, 3},
  20. /* USB3H_UNIT_ID */ { 2, 2, 2, 2},
  21. /* USB3D_UNIT_ID */ { 1, 1, 1, 1},
  22. /* SATA_UNIT_ID */ { 2, 2, 2, 4},
  23. /* QSGMII_UNIT_ID */ { 1, 0, 0, 1},
  24. /* XAUI_UNIT_ID */ { 0, 0, 0, 0},
  25. /* RXAUI_UNIT_ID */ { 0, 0, 0, 0}
  26. };
  27. #else /* if (CONFIG_ARMADA_39X) */
  28. enum unit_id sys_env_soc_unit_nums[MAX_UNITS_ID][MAX_DEV_ID_NUM] = {
  29. /* 6920 6928 */
  30. /* PEX_UNIT_ID */ { 4, 4},
  31. /* ETH_GIG_UNIT_ID */ { 3, 4},
  32. /* USB3H_UNIT_ID */ { 1, 2},
  33. /* USB3D_UNIT_ID */ { 0, 1},
  34. /* SATA_UNIT_ID */ { 0, 4},
  35. /* QSGMII_UNIT_ID */ { 0, 1},
  36. /* XAUI_UNIT_ID */ { 1, 1},
  37. /* RXAUI_UNIT_ID */ { 1, 1}
  38. };
  39. #endif
  40. u32 g_dev_id = -1;
  41. u32 mv_board_id_get(void)
  42. {
  43. #if defined(CONFIG_DB_88F6820_GP)
  44. return DB_GP_68XX_ID;
  45. #else
  46. /*
  47. * Return 0 here for custom board as this should not be used
  48. * for custom boards.
  49. */
  50. return 0;
  51. #endif
  52. }
  53. u32 mv_board_tclk_get(void)
  54. {
  55. u32 value;
  56. value = (reg_read(DEVICE_SAMPLE_AT_RESET1_REG) >> 15) & 0x1;
  57. switch (value) {
  58. case (0x0):
  59. return 250000000;
  60. case (0x1):
  61. return 200000000;
  62. default:
  63. return 0xffffffff;
  64. }
  65. }
  66. u32 mv_board_id_index_get(u32 board_id)
  67. {
  68. /*
  69. * Marvell Boards use 0x10 as base for Board ID:
  70. * mask MSB to receive index for board ID
  71. */
  72. return board_id & (MARVELL_BOARD_ID_MASK - 1);
  73. }
  74. /*
  75. * sys_env_suspend_wakeup_check
  76. * DESCRIPTION: Reads GPIO input for suspend-wakeup indication.
  77. * INPUT: None.
  78. * OUTPUT:
  79. * RETURNS: u32 indicating suspend wakeup status:
  80. * 0 - Not supported,
  81. * 1 - supported: read magic word detect wakeup,
  82. * 2 - detected wakeup from GPIO.
  83. */
  84. enum suspend_wakeup_status sys_env_suspend_wakeup_check(void)
  85. {
  86. u32 reg, board_id_index, gpio;
  87. struct board_wakeup_gpio board_gpio[] = MV_BOARD_WAKEUP_GPIO_INFO;
  88. board_id_index = mv_board_id_index_get(mv_board_id_get());
  89. if (!(sizeof(board_gpio) / sizeof(struct board_wakeup_gpio) >
  90. board_id_index)) {
  91. printf("\n_failed loading Suspend-Wakeup information (invalid board ID)\n");
  92. return SUSPEND_WAKEUP_DISABLED;
  93. }
  94. /*
  95. * - Detect if Suspend-Wakeup is supported on current board
  96. * - Fetch the GPIO number for wakeup status input indication
  97. */
  98. if (board_gpio[board_id_index].gpio_num == -1) {
  99. /* Suspend to RAM is not supported */
  100. return SUSPEND_WAKEUP_DISABLED;
  101. } else if (board_gpio[board_id_index].gpio_num == -2) {
  102. /*
  103. * Suspend to RAM is supported but GPIO indication is
  104. * not implemented - Skip
  105. */
  106. return SUSPEND_WAKEUP_ENABLED;
  107. } else {
  108. gpio = board_gpio[board_id_index].gpio_num;
  109. }
  110. /* Initialize MPP for GPIO (set MPP = 0x0) */
  111. reg = reg_read(MPP_CONTROL_REG(MPP_REG_NUM(gpio)));
  112. /* reset MPP21 to 0x0, keep rest of MPP settings*/
  113. reg &= ~MPP_MASK(gpio);
  114. reg_write(MPP_CONTROL_REG(MPP_REG_NUM(gpio)), reg);
  115. /* Initialize GPIO as input */
  116. reg = reg_read(GPP_DATA_OUT_EN_REG(GPP_REG_NUM(gpio)));
  117. reg |= GPP_MASK(gpio);
  118. reg_write(GPP_DATA_OUT_EN_REG(GPP_REG_NUM(gpio)), reg);
  119. /*
  120. * Check GPP for input status from PIC: 0 - regular init,
  121. * 1 - suspend wakeup
  122. */
  123. reg = reg_read(GPP_DATA_IN_REG(GPP_REG_NUM(gpio)));
  124. /* if GPIO is ON: wakeup from S2RAM indication detected */
  125. return (reg & GPP_MASK(gpio)) ? SUSPEND_WAKEUP_ENABLED_GPIO_DETECTED :
  126. SUSPEND_WAKEUP_DISABLED;
  127. }
  128. /*
  129. * mv_ctrl_dev_id_index_get
  130. *
  131. * DESCRIPTION: return SOC device index
  132. * INPUT: None
  133. * OUTPUT: None
  134. * RETURN:
  135. * return SOC device index
  136. */
  137. u32 sys_env_id_index_get(u32 ctrl_model)
  138. {
  139. switch (ctrl_model) {
  140. case MV_6820_DEV_ID:
  141. return MV_6820_INDEX;
  142. case MV_6810_DEV_ID:
  143. return MV_6810_INDEX;
  144. case MV_6811_DEV_ID:
  145. return MV_6811_INDEX;
  146. case MV_6828_DEV_ID:
  147. return MV_6828_INDEX;
  148. case MV_6920_DEV_ID:
  149. return MV_6920_INDEX;
  150. case MV_6928_DEV_ID:
  151. return MV_6928_INDEX;
  152. default:
  153. return MV_6820_INDEX;
  154. }
  155. }
  156. u32 sys_env_unit_max_num_get(enum unit_id unit)
  157. {
  158. u32 dev_id_index;
  159. if (unit >= MAX_UNITS_ID) {
  160. printf("%s: Error: Wrong unit type (%u)\n", __func__, unit);
  161. return 0;
  162. }
  163. dev_id_index = sys_env_id_index_get(sys_env_model_get());
  164. return sys_env_soc_unit_nums[unit][dev_id_index];
  165. }
  166. /*
  167. * sys_env_model_get
  168. * DESCRIPTION: Returns 16bit describing the device model (ID) as defined
  169. * in Vendor ID configuration register
  170. */
  171. u16 sys_env_model_get(void)
  172. {
  173. u32 default_ctrl_id, ctrl_id = reg_read(DEV_ID_REG);
  174. ctrl_id = (ctrl_id & (DEV_ID_REG_DEVICE_ID_MASK)) >>
  175. DEV_ID_REG_DEVICE_ID_OFFS;
  176. switch (ctrl_id) {
  177. case MV_6820_DEV_ID:
  178. case MV_6810_DEV_ID:
  179. case MV_6811_DEV_ID:
  180. case MV_6828_DEV_ID:
  181. case MV_6920_DEV_ID:
  182. case MV_6928_DEV_ID:
  183. return ctrl_id;
  184. default:
  185. /* Device ID Default for A38x: 6820 , for A39x: 6920 */
  186. #ifdef CONFIG_ARMADA_38X
  187. default_ctrl_id = MV_6820_DEV_ID;
  188. #else
  189. default_ctrl_id = MV_6920_DEV_ID;
  190. #endif
  191. printf("%s: Error retrieving device ID (%x), using default ID = %x\n",
  192. __func__, ctrl_id, default_ctrl_id);
  193. return default_ctrl_id;
  194. }
  195. }
  196. /*
  197. * sys_env_device_id_get
  198. * DESCRIPTION: Returns enum (0..7) index of the device model (ID)
  199. */
  200. u32 sys_env_device_id_get(void)
  201. {
  202. char *device_id_str[7] = {
  203. "6810", "6820", "6811", "6828", "NONE", "6920", "6928"
  204. };
  205. if (g_dev_id != -1)
  206. return g_dev_id;
  207. g_dev_id = reg_read(DEVICE_SAMPLE_AT_RESET1_REG);
  208. g_dev_id = g_dev_id >> SAR_DEV_ID_OFFS & SAR_DEV_ID_MASK;
  209. printf("Detected Device ID %s\n", device_id_str[g_dev_id]);
  210. return g_dev_id;
  211. }
  212. #ifdef MV_DDR_TOPOLOGY_UPDATE_FROM_TWSI
  213. /*
  214. * sys_env_get_topology_update_info
  215. * DESCRIPTION: Read TWSI fields to update DDR topology structure
  216. * INPUT: None
  217. * OUTPUT: None, 0 means no topology update
  218. * RETURN:
  219. * Bit mask of changes topology features
  220. */
  221. #ifdef CONFIG_ARMADA_39X
  222. u32 sys_env_get_topology_update_info(
  223. struct topology_update_info *tui)
  224. {
  225. /* Set 16/32 bit configuration*/
  226. tui->update_width = 1;
  227. tui->width = TOPOLOGY_UPDATE_WIDTH_32BIT;
  228. #ifdef CONFIG_DDR3
  229. if (1 == sys_env_config_get(MV_CONFIG_DDR_BUSWIDTH)) {
  230. /* 16bit */
  231. tui->width = TOPOLOGY_UPDATE_WIDTH_16BIT;
  232. } else {
  233. /* 32bit */
  234. tui->width = TOPOLOGY_UPDATE_WIDTH_32BIT;
  235. }
  236. #endif
  237. /* Set ECC/no ECC bit configuration */
  238. tui->update_ecc = 1;
  239. if (0 == sys_env_config_get(MV_CONFIG_DDR_ECC_EN)) {
  240. /* NO ECC */
  241. tui->ecc = TOPOLOGY_UPDATE_ECC_OFF;
  242. } else {
  243. /* ECC */
  244. tui->ecc = TOPOLOGY_UPDATE_ECC_ON;
  245. }
  246. tui->update_ecc_pup3_mode = 1;
  247. tui->ecc_pup_mode_offset = TOPOLOGY_UPDATE_ECC_OFFSET_PUP4;
  248. return MV_OK;
  249. }
  250. #else /*CONFIG_ARMADA_38X*/
  251. u32 sys_env_get_topology_update_info(
  252. struct topology_update_info *tui)
  253. {
  254. u8 config_val;
  255. u8 ecc_mode[A38X_MV_MAX_MARVELL_BOARD_ID -
  256. A38X_MARVELL_BOARD_ID_BASE][5] = TOPOLOGY_UPDATE;
  257. u8 board_id = mv_board_id_get();
  258. int ret;
  259. board_id = mv_board_id_index_get(board_id);
  260. ret = i2c_read(EEPROM_I2C_ADDR, 0, 2, &config_val, 1);
  261. if (ret) {
  262. DEBUG_INIT_S("sys_env_get_topology_update_info: TWSI Read failed\n");
  263. return 0;
  264. }
  265. /* Set 16/32 bit configuration */
  266. if ((0 == (config_val & DDR_SATR_CONFIG_MASK_WIDTH)) ||
  267. (ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT] == 0)) {
  268. /* 16bit by SatR of 32bit mode not supported for the board */
  269. if ((ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT] != 0)) {
  270. tui->update_width = 1;
  271. tui->width = TOPOLOGY_UPDATE_WIDTH_16BIT;
  272. }
  273. } else {
  274. /* 32bit */
  275. if ((ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT] != 0)) {
  276. tui->update_width = 1;
  277. tui->width = TOPOLOGY_UPDATE_WIDTH_32BIT;
  278. }
  279. }
  280. /* Set ECC/no ECC bit configuration */
  281. if (0 == (config_val & DDR_SATR_CONFIG_MASK_ECC)) {
  282. /* NO ECC */
  283. tui->update_ecc = 1;
  284. tui->ecc = TOPOLOGY_UPDATE_ECC_OFF;
  285. } else {
  286. /* ECC */
  287. if ((ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT_ECC] != 0) ||
  288. (ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT_ECC] != 0) ||
  289. (ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT_ECC_PUP3] != 0)) {
  290. tui->update_ecc = 1;
  291. tui->ecc = TOPOLOGY_UPDATE_ECC_ON;
  292. }
  293. }
  294. /* Set ECC pup bit configuration */
  295. if (0 == (config_val & DDR_SATR_CONFIG_MASK_ECC_PUP)) {
  296. /* PUP3 */
  297. /*
  298. * Check if PUP3 configuration allowed, if not -
  299. * force Pup4 with warning message
  300. */
  301. if ((ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT_ECC_PUP3] != 0)) {
  302. if (tui->width == TOPOLOGY_UPDATE_WIDTH_16BIT) {
  303. tui->update_ecc_pup3_mode = 1;
  304. tui->ecc_pup_mode_offset =
  305. TOPOLOGY_UPDATE_ECC_OFFSET_PUP3;
  306. } else {
  307. if ((ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT_ECC] != 0)) {
  308. printf("DDR Topology Update: ECC PUP3 not valid for 32bit mode, force ECC in PUP4\n");
  309. tui->update_ecc_pup3_mode = 1;
  310. tui->ecc_pup_mode_offset =
  311. TOPOLOGY_UPDATE_ECC_OFFSET_PUP4;
  312. }
  313. }
  314. } else {
  315. if (ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT_ECC] !=
  316. 0) {
  317. printf("DDR Topology Update: ECC on PUP3 not supported, force ECC on PUP4\n");
  318. tui->update_ecc_pup3_mode = 1;
  319. tui->ecc_pup_mode_offset =
  320. TOPOLOGY_UPDATE_ECC_OFFSET_PUP4;
  321. }
  322. }
  323. } else {
  324. /* PUP4 */
  325. if ((ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT_ECC] != 0) ||
  326. (ecc_mode[board_id][TOPOLOGY_UPDATE_16BIT_ECC] != 0)) {
  327. tui->update_ecc_pup3_mode = 1;
  328. tui->ecc_pup_mode_offset =
  329. TOPOLOGY_UPDATE_ECC_OFFSET_PUP4;
  330. }
  331. }
  332. /*
  333. * Check for forbidden ECC mode,
  334. * if by default width and pup selection set 32bit ECC mode and this
  335. * mode not supported for the board - config 16bit with ECC on PUP3
  336. */
  337. if ((tui->ecc == TOPOLOGY_UPDATE_ECC_ON) &&
  338. (tui->width == TOPOLOGY_UPDATE_WIDTH_32BIT)) {
  339. if (ecc_mode[board_id][TOPOLOGY_UPDATE_32BIT_ECC] == 0) {
  340. printf("DDR Topology Update: 32bit mode with ECC not allowed on this board, forced 16bit with ECC on PUP3\n");
  341. tui->width = TOPOLOGY_UPDATE_WIDTH_16BIT;
  342. tui->update_ecc_pup3_mode = 1;
  343. tui->ecc_pup_mode_offset =
  344. TOPOLOGY_UPDATE_ECC_OFFSET_PUP3;
  345. }
  346. }
  347. return MV_OK;
  348. }
  349. #endif /* CONFIG_ARMADA_38X */
  350. #endif /* MV_DDR_TOPOLOGY_UPDATE_FROM_TWSI */