1 /*
2 * Copyright (C) 2021-2024, STMicroelectronics - All Rights Reserved
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9
10 #include <common/debug.h>
11
12 #include <ddrphy_phyinit.h>
13
14 #include <lib/mmio.h>
15
16 #include <platform_def.h>
17
18 /* DDRDBG registers */
19 #define DDRDBG_DDR34_AC_SWIZZLE_ADD3_0 U(0x100)
20
21 /*
22 * This function is called before training firmware is executed. Any
23 * register override in this function might affect the firmware training
24 * results.
25 *
26 * This function is executed before firmware execution loop. Thus this function
27 * should be used only for the following:
28 *
29 * - Override PHY register values written by
30 * ddrphy_phyinit_c_initphyconfig. An example use case is when this
31 * function does not perform the exact programing desired by the user.
32 * - Write custom PHY registers that need to take effect before training
33 * firmware execution.
34 *
35 * User shall use mmio_write_16 to write PHY registers in order for the register
36 * to be tracked by PhyInit for retention restore.
37 *
38 * To override settings in the message block, users can assign values to the
39 * fields in the message block data structure directly.
40 *
41 * \ref examples/simple/ddrphy_phyinit_usercustom_custompretrain.c example of this function.
42 *
43 * @return Void
44 */
ddrphy_phyinit_usercustom_custompretrain(struct stm32mp_ddr_config * config)45 void ddrphy_phyinit_usercustom_custompretrain(struct stm32mp_ddr_config *config)
46 {
47 uint32_t byte __unused;
48 uint32_t i = 0U;
49 uint32_t j;
50 uintptr_t base;
51
52 #if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
53 base = (uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_HWTSWIZZLEHWTADDRESS0_ADDR)));
54
55 for (i = 0U; i < NB_HWT_SWIZZLE; i++) {
56 mmio_write_16(base + (i * sizeof(uint32_t)),
57 (uint16_t)config->uis.swizzle[i]);
58 }
59
60 base = (uintptr_t)(stm32_ddrdbg_get_base() + DDRDBG_DDR34_AC_SWIZZLE_ADD3_0);
61
62 for (j = 0U; j < NB_AC_SWIZZLE; j++, i++) {
63 mmio_write_32(base + (j * sizeof(uint32_t)), config->uis.swizzle[i]);
64 }
65 #else /* STM32MP_LPDDR4_TYPE */
66 for (byte = 0U; byte < config->uib.numdbyte; byte++) {
67 base = (uintptr_t)(DDRPHYC_BASE + (4U *
68 ((byte << 12) | TDBYTE | CSR_DQ0LNSEL_ADDR)));
69
70 for (j = 0U; j < NB_DQLNSEL_SWIZZLE_PER_BYTE; j++, i++) {
71 mmio_write_16(base + (j * sizeof(uint32_t)),
72 (uint16_t)config->uis.swizzle[i]);
73 }
74 }
75
76 base = (uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_MAPCAA0TODFI_ADDR)));
77
78 for (j = 0U; j < NB_MAPCAATODFI_SWIZZLE; j++, i++) {
79 mmio_write_16(base + (j * sizeof(uint32_t)),
80 (uint16_t)config->uis.swizzle[i]);
81 }
82
83 base = (uintptr_t)(DDRPHYC_BASE + (4U * (TMASTER | CSR_MAPCAB0TODFI_ADDR)));
84
85 for (j = 0U; j < NB_MAPCABTODFI_SWIZZLE; j++, i++) {
86 mmio_write_16(base + (j * sizeof(uint32_t)),
87 (uint16_t)config->uis.swizzle[i]);
88 }
89 #endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
90 }
91