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 <platform_def.h>
15
16 /*
17 * This function loads the training firmware DMEM image and write the
18 * Message Block parameters for the training firmware into the PHY.
19 *
20 * This function performs the following tasks:
21 *
22 * -# Load the firmware DMEM segment to initialize the data structures from the
23 * DDR firmware source memory area.
24 * -# Write the Firmware Message Block with the required contents detailing the training parameters.
25 *
26 * \return 0 on success.
27 */
ddrphy_phyinit_f_loaddmem(struct stm32mp_ddr_config * config,struct pmu_smb_ddr_1d * mb_ddr_1d)28 int ddrphy_phyinit_f_loaddmem(struct stm32mp_ddr_config *config, struct pmu_smb_ddr_1d *mb_ddr_1d)
29 {
30 uint32_t sizeofmsgblk;
31 uint16_t *ptr16;
32 uint32_t *ptr32;
33
34 /* Some basic checks on MessageBlock */
35 #if STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE
36 if ((mb_ddr_1d->enableddqs > (8U * (uint8_t)config->uib.numactivedbytedfi0)) ||
37 (mb_ddr_1d->enableddqs <= 0U)) {
38 ERROR("%s %d\n", __func__, __LINE__);
39 VERBOSE("%s enableddqs is Zero or greater than NumActiveDbytes for Dfi0\n",
40 __func__);
41 return -1;
42 }
43 #else /* STM32MP_LPDDR4_TYPE */
44 if (((mb_ddr_1d->enableddqscha % 16U) != 0U) || ((mb_ddr_1d->enableddqschb % 16U) != 0U)) {
45 ERROR("%s %d\n", __func__, __LINE__);
46 VERBOSE("%s Lp3/Lp4 - Number of Dq's Enabled per Channel much be multipe of 16\n",
47 __func__);
48 return -1;
49 }
50
51 if ((mb_ddr_1d->enableddqscha > (uint8_t)(8U * config->uib.numactivedbytedfi0)) ||
52 (mb_ddr_1d->enableddqschb > (uint8_t)(8U * config->uib.numactivedbytedfi1)) ||
53 ((mb_ddr_1d->enableddqscha == 0U) && (mb_ddr_1d->enableddqschb == 0U))) {
54 ERROR("%s %d\n", __func__, __LINE__);
55 VERBOSE("%s EnabledDqsChA/B are not set correctly./1\n", __func__);
56 return -1;
57 }
58 #endif /* STM32MP_DDR3_TYPE || STM32MP_DDR4_TYPE */
59
60 sizeofmsgblk = sizeof(struct pmu_smb_ddr_1d);
61
62 ptr16 = (uint16_t *)mb_ddr_1d;
63 ddrphy_phyinit_writeoutmsgblk(ptr16, DMEM_ST_ADDR, sizeofmsgblk);
64
65 ptr32 = (uint32_t *)(STM32MP_DDR_FW_BASE + STM32MP_DDR_FW_DMEM_OFFSET);
66 ddrphy_phyinit_writeoutmem(ptr32, DMEM_ST_ADDR + DMEM_BIN_OFFSET,
67 DMEM_SIZE - STM32MP_DDR_FW_DMEM_OFFSET);
68
69 return 0;
70 }
71