1ddaf02d1SJit Loon Lim /* 2ddaf02d1SJit Loon Lim * Copyright (c) 2022-2023, Intel Corporation. All rights reserved. 3*6f7f8b18SGirisha Dengi * Copyright (c) 2025, Altera Corporation. All rights reserved. 4ddaf02d1SJit Loon Lim * 5ddaf02d1SJit Loon Lim * SPDX-License-Identifier: BSD-3-Clause 6ddaf02d1SJit Loon Lim */ 7ddaf02d1SJit Loon Lim 8ddaf02d1SJit Loon Lim #include <assert.h> 9ddaf02d1SJit Loon Lim #include <errno.h> 10ddaf02d1SJit Loon Lim #include <stdbool.h> 11ddaf02d1SJit Loon Lim #include <string.h> 12ddaf02d1SJit Loon Lim 13ddaf02d1SJit Loon Lim #include <arch_helpers.h> 14ddaf02d1SJit Loon Lim #include <common/debug.h> 15ddaf02d1SJit Loon Lim #include <drivers/cadence/cdns_sdmmc.h> 16ddaf02d1SJit Loon Lim #include <drivers/delay_timer.h> 17ddaf02d1SJit Loon Lim #include <lib/mmio.h> 18ddaf02d1SJit Loon Lim #include <lib/utils.h> 19ddaf02d1SJit Loon Lim 20ddaf02d1SJit Loon Lim #include "combophy.h" 21ddaf02d1SJit Loon Lim #include "sdmmc/sdmmc.h" 22ddaf02d1SJit Loon Lim 23ddaf02d1SJit Loon Lim /* DFI configuration */ 24ddaf02d1SJit Loon Lim int dfi_select(handoff *hoff_ptr) 25ddaf02d1SJit Loon Lim { 266993598fSGirisha Dengi uint32_t reg = 0; 276993598fSGirisha Dengi uint32_t active_dfi_intf = DFI_CTRL_SEL_HPNFC; 28ddaf02d1SJit Loon Lim 296993598fSGirisha Dengi INFO("Power gate enable hand-off: 0x%08x\n", hoff_ptr->peripheral_pwr_gate_array); 30ddaf02d1SJit Loon Lim 31*6f7f8b18SGirisha Dengi if (hoff_ptr->peripheral_pwr_gate_array & POWER_GATE_EN_SDEMMC) { 326993598fSGirisha Dengi INFO("SDEMMC power gate enabled, DFI selected to NAND\n"); 336993598fSGirisha Dengi /* 346993598fSGirisha Dengi * SDEMMC power gate enabled. 356993598fSGirisha Dengi * This means SDEMMC controller is disabled and active DFI 366993598fSGirisha Dengi * interface is selected to NAND via System manager. 376993598fSGirisha Dengi */ 386993598fSGirisha Dengi active_dfi_intf = DFI_CTRL_SEL_HPNFC; 39*6f7f8b18SGirisha Dengi } else if (hoff_ptr->peripheral_pwr_gate_array & POWER_GATE_EN_NAND) { 406993598fSGirisha Dengi INFO("NAND power gate enabled, DFI selected to SDEMMC\n"); 416993598fSGirisha Dengi /* 426993598fSGirisha Dengi * NAND power gate enabled. 436993598fSGirisha Dengi * This means NAND controller is disabled and active DFI 446993598fSGirisha Dengi * interface is selected to SDEMMC via System manager. 456993598fSGirisha Dengi */ 466993598fSGirisha Dengi active_dfi_intf = DFI_CTRL_SEL_SDEMMC; 476993598fSGirisha Dengi } else { 486993598fSGirisha Dengi WARN("Neither SDEMMC nor NAND power gate enabled, by def DFI sel to NAND\n"); 49ddaf02d1SJit Loon Lim } 50ddaf02d1SJit Loon Lim 516993598fSGirisha Dengi /* Configure the DFI interface select via System manager. */ 526993598fSGirisha Dengi mmio_setbits_32(SOCFPGA_SYSMGR(DFI_INTF), active_dfi_intf); 536993598fSGirisha Dengi 546993598fSGirisha Dengi /* Read back and confirm the same.*/ 556993598fSGirisha Dengi reg = mmio_read_32(SOCFPGA_SYSMGR(DFI_INTF)); 566993598fSGirisha Dengi if ((reg & DFI_INTF_MASK) != active_dfi_intf) { 576993598fSGirisha Dengi ERROR("DFI interface select failed, expected: 0x%08x, got: 0x%08x\n", 586993598fSGirisha Dengi active_dfi_intf, (reg & DFI_INTF_MASK)); 59ddaf02d1SJit Loon Lim return -ENXIO; 606993598fSGirisha Dengi } else { 616993598fSGirisha Dengi NOTICE("DFI interface selected successfully to %s\n", 626993598fSGirisha Dengi (reg & DFI_INTF_MASK) == DFI_CTRL_SEL_HPNFC ? 636993598fSGirisha Dengi "NAND" : "SDEMMC"); 64ddaf02d1SJit Loon Lim } 65ddaf02d1SJit Loon Lim 66ddaf02d1SJit Loon Lim return 0; 67ddaf02d1SJit Loon Lim } 68ddaf02d1SJit Loon Lim 69ddaf02d1SJit Loon Lim int combo_phy_init(handoff *hoff_ptr) 70ddaf02d1SJit Loon Lim { 71ddaf02d1SJit Loon Lim /* SDMMC/NAND DFI selection based on system manager DFI register */ 72ddaf02d1SJit Loon Lim int ret = dfi_select(hoff_ptr); 73ddaf02d1SJit Loon Lim 74ddaf02d1SJit Loon Lim if (ret != 0U) { 75ddaf02d1SJit Loon Lim ERROR("DFI configuration failed\n"); 76ddaf02d1SJit Loon Lim return ret; 77ddaf02d1SJit Loon Lim } 78ddaf02d1SJit Loon Lim 79ddaf02d1SJit Loon Lim return 0; 80ddaf02d1SJit Loon Lim }