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 }