ARM: mvebu: a38x: sync ddr training code with upstream
[oweals/u-boot.git] / drivers / ddr / marvell / a38x / mv_ddr_sys_env_lib.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) Marvell International Ltd. and its affiliates
4  */
5
6 #include "mv_ddr_regs.h"
7 #include "mv_ddr_sys_env_lib.h"
8
9 static u32 mv_ddr_board_id_get(void)
10 {
11 #if defined(CONFIG_TARGET_DB_88F6820_GP)
12         return DB_GP_68XX_ID;
13 #else
14         /*
15          * Return 0 here for custom board as this should not be used
16          * for custom boards.
17          */
18         return 0;
19 #endif
20 }
21
22 static u32 mv_ddr_board_id_index_get(u32 board_id)
23 {
24         /*
25          * Marvell Boards use 0x10 as base for Board ID:
26          * mask MSB to receive index for board ID
27          */
28         return board_id & (MARVELL_BOARD_ID_MASK - 1);
29 }
30
31 /*
32  * read gpio input for suspend-wakeup indication
33  * return indicating suspend wakeup status:
34  * 0 - not supported,
35  * 1 - supported: read magic word detect wakeup,
36  * 2 - detected wakeup from gpio
37  */
38 enum suspend_wakeup_status mv_ddr_sys_env_suspend_wakeup_check(void)
39 {
40         u32 reg, board_id_index, gpio;
41         struct board_wakeup_gpio board_gpio[] = MV_BOARD_WAKEUP_GPIO_INFO;
42
43         board_id_index = mv_ddr_board_id_index_get(mv_ddr_board_id_get());
44         if (!(sizeof(board_gpio) / sizeof(struct board_wakeup_gpio) >
45               board_id_index)) {
46                 printf("\n_failed loading Suspend-Wakeup information (invalid board ID)\n");
47                 return SUSPEND_WAKEUP_DISABLED;
48         }
49
50         /*
51          * - Detect if Suspend-Wakeup is supported on current board
52          * - Fetch the GPIO number for wakeup status input indication
53          */
54         if (board_gpio[board_id_index].gpio_num == -1) {
55                 /* Suspend to RAM is not supported */
56                 return SUSPEND_WAKEUP_DISABLED;
57         } else if (board_gpio[board_id_index].gpio_num == -2) {
58                 /*
59                  * Suspend to RAM is supported but GPIO indication is
60                  * not implemented - Skip
61                  */
62                 return SUSPEND_WAKEUP_ENABLED;
63         } else {
64                 gpio = board_gpio[board_id_index].gpio_num;
65         }
66
67         /* Initialize MPP for GPIO (set MPP = 0x0) */
68         reg = reg_read(MPP_CONTROL_REG(MPP_REG_NUM(gpio)));
69         /* reset MPP21 to 0x0, keep rest of MPP settings*/
70         reg &= ~MPP_MASK(gpio);
71         reg_write(MPP_CONTROL_REG(MPP_REG_NUM(gpio)), reg);
72
73         /* Initialize GPIO as input */
74         reg = reg_read(GPP_DATA_OUT_EN_REG(GPP_REG_NUM(gpio)));
75         reg |= GPP_MASK(gpio);
76         reg_write(GPP_DATA_OUT_EN_REG(GPP_REG_NUM(gpio)), reg);
77
78         /*
79          * Check GPP for input status from PIC: 0 - regular init,
80          * 1 - suspend wakeup
81          */
82         reg = reg_read(GPP_DATA_IN_REG(GPP_REG_NUM(gpio)));
83
84         /* if GPIO is ON: wakeup from S2RAM indication detected */
85         return (reg & GPP_MASK(gpio)) ? SUSPEND_WAKEUP_ENABLED_GPIO_DETECTED :
86                 SUSPEND_WAKEUP_DISABLED;
87 }
88
89 /*
90  * get bit mask of enabled cs
91  * return bit mask of enabled cs:
92  * 1 - only cs0 enabled,
93  * 3 - both cs0 and cs1 enabled
94  */
95 u32 mv_ddr_sys_env_get_cs_ena_from_reg(void)
96 {
97         return reg_read(DDR3_RANK_CTRL_REG) &
98                 ((CS_EXIST_MASK << CS_EXIST_OFFS(0)) |
99                  (CS_EXIST_MASK << CS_EXIST_OFFS(1)) |
100                  (CS_EXIST_MASK << CS_EXIST_OFFS(2)) |
101                  (CS_EXIST_MASK << CS_EXIST_OFFS(3)));
102 }