xref: /rk3399_ARM-atf/plat/intel/soc/common/drivers/combophy/combophy.c (revision aa05796e471e2a1a06508c0fb3771f01b44a1d20)
1 /*
2  * Copyright (c) 2022-2023, Intel Corporation. All rights reserved.
3  * Copyright (c) 2025, Altera Corporation. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #include <assert.h>
9 #include <errno.h>
10 #include <stdbool.h>
11 #include <string.h>
12 
13 #include <arch_helpers.h>
14 #include <common/debug.h>
15 #include <drivers/cadence/cdns_sdmmc.h>
16 #include <drivers/delay_timer.h>
17 #include <lib/mmio.h>
18 #include <lib/utils.h>
19 
20 #include "combophy.h"
21 #include "sdmmc/sdmmc.h"
22 
23 /* DFI configuration */
24 int dfi_select(handoff *hoff_ptr)
25 {
26 	uint32_t reg = 0;
27 	uint32_t active_dfi_intf = DFI_CTRL_SEL_HPNFC;
28 
29 	INFO("Power gate enable hand-off: 0x%08x\n", hoff_ptr->peripheral_pwr_gate_array);
30 
31 	if (hoff_ptr->peripheral_pwr_gate_array & POWER_GATE_EN_SDEMMC) {
32 		INFO("SDEMMC power gate enabled, DFI selected to NAND\n");
33 		/*
34 		 * SDEMMC power gate enabled.
35 		 * This means SDEMMC controller is disabled and active DFI
36 		 * interface is selected to NAND via System manager.
37 		 */
38 		active_dfi_intf = DFI_CTRL_SEL_HPNFC;
39 	} else if (hoff_ptr->peripheral_pwr_gate_array & POWER_GATE_EN_NAND) {
40 		INFO("NAND power gate enabled, DFI selected to SDEMMC\n");
41 		/*
42 		 * NAND power gate enabled.
43 		 * This means NAND controller is disabled and active DFI
44 		 * interface is selected to SDEMMC via System manager.
45 		 */
46 		active_dfi_intf = DFI_CTRL_SEL_SDEMMC;
47 	} else {
48 		WARN("Neither SDEMMC nor NAND power gate enabled, by def DFI sel to NAND\n");
49 	}
50 
51 	/* Configure the DFI interface select via System manager. */
52 	mmio_setbits_32(SOCFPGA_SYSMGR(DFI_INTF), active_dfi_intf);
53 
54 	/* Read back and confirm the same.*/
55 	reg = mmio_read_32(SOCFPGA_SYSMGR(DFI_INTF));
56 	if ((reg & DFI_INTF_MASK) != active_dfi_intf) {
57 		ERROR("DFI interface select failed, expected: 0x%08x, got: 0x%08x\n",
58 			active_dfi_intf, (reg & DFI_INTF_MASK));
59 		return -ENXIO;
60 	} else {
61 		NOTICE("DFI interface selected successfully to %s\n",
62 			(reg & DFI_INTF_MASK) == DFI_CTRL_SEL_HPNFC ?
63 			"NAND" : "SDEMMC");
64 	}
65 
66 	return 0;
67 }
68 
69 int combo_phy_init(handoff *hoff_ptr)
70 {
71 	/* SDMMC/NAND DFI selection based on system manager DFI register */
72 	int ret = dfi_select(hoff_ptr);
73 
74 	if (ret != 0U) {
75 		ERROR("DFI configuration failed\n");
76 		return ret;
77 	}
78 
79 	return 0;
80 }