1*ddaf02d1SJit Loon Lim /* 2*ddaf02d1SJit Loon Lim * Copyright (c) 2022-2023, Intel Corporation. All rights reserved. 3*ddaf02d1SJit Loon Lim * 4*ddaf02d1SJit Loon Lim * SPDX-License-Identifier: BSD-3-Clause 5*ddaf02d1SJit Loon Lim */ 6*ddaf02d1SJit Loon Lim 7*ddaf02d1SJit Loon Lim #include <assert.h> 8*ddaf02d1SJit Loon Lim #include <errno.h> 9*ddaf02d1SJit Loon Lim #include <stdbool.h> 10*ddaf02d1SJit Loon Lim #include <string.h> 11*ddaf02d1SJit Loon Lim 12*ddaf02d1SJit Loon Lim #include <arch_helpers.h> 13*ddaf02d1SJit Loon Lim #include <common/debug.h> 14*ddaf02d1SJit Loon Lim #include <drivers/cadence/cdns_sdmmc.h> 15*ddaf02d1SJit Loon Lim #include <drivers/delay_timer.h> 16*ddaf02d1SJit Loon Lim #include <lib/mmio.h> 17*ddaf02d1SJit Loon Lim #include <lib/utils.h> 18*ddaf02d1SJit Loon Lim 19*ddaf02d1SJit Loon Lim #include "combophy.h" 20*ddaf02d1SJit Loon Lim #include "sdmmc/sdmmc.h" 21*ddaf02d1SJit Loon Lim 22*ddaf02d1SJit Loon Lim /* Temp assigned handoff data, need to remove when SDM up and run. */ 23*ddaf02d1SJit Loon Lim void config_nand(handoff *hoff_ptr) 24*ddaf02d1SJit Loon Lim { 25*ddaf02d1SJit Loon Lim /* This is hardcoded input value for Combo PHY and SD host controller. */ 26*ddaf02d1SJit Loon Lim hoff_ptr->peripheral_pwr_gate_array = 0x40; 27*ddaf02d1SJit Loon Lim 28*ddaf02d1SJit Loon Lim } 29*ddaf02d1SJit Loon Lim 30*ddaf02d1SJit Loon Lim /* DFI configuration */ 31*ddaf02d1SJit Loon Lim int dfi_select(handoff *hoff_ptr) 32*ddaf02d1SJit Loon Lim { 33*ddaf02d1SJit Loon Lim uint32_t data = 0; 34*ddaf02d1SJit Loon Lim 35*ddaf02d1SJit Loon Lim /* Temp assigned handoff data, need to remove when SDM up and run. */ 36*ddaf02d1SJit Loon Lim handoff reverse_handoff_ptr; 37*ddaf02d1SJit Loon Lim 38*ddaf02d1SJit Loon Lim /* Temp assigned handoff data, need to remove when SDM up and run. */ 39*ddaf02d1SJit Loon Lim config_nand(&reverse_handoff_ptr); 40*ddaf02d1SJit Loon Lim 41*ddaf02d1SJit Loon Lim if (((reverse_handoff_ptr.peripheral_pwr_gate_array) & PERIPHERAL_SDMMC_MASK) == 0U) { 42*ddaf02d1SJit Loon Lim ERROR("SDMMC/NAND is not set properly\n"); 43*ddaf02d1SJit Loon Lim return -ENXIO; 44*ddaf02d1SJit Loon Lim } 45*ddaf02d1SJit Loon Lim 46*ddaf02d1SJit Loon Lim mmio_setbits_32(SOCFPGA_SYSMGR(DFI_INTF), 47*ddaf02d1SJit Loon Lim (((reverse_handoff_ptr.peripheral_pwr_gate_array) & 48*ddaf02d1SJit Loon Lim PERIPHERAL_SDMMC_MASK) >> PERIPHERAL_SDMMC_OFFSET)); 49*ddaf02d1SJit Loon Lim data = mmio_read_32(SOCFPGA_SYSMGR(DFI_INTF)); 50*ddaf02d1SJit Loon Lim if ((data & DFI_INTF_MASK) != (((reverse_handoff_ptr.peripheral_pwr_gate_array) & 51*ddaf02d1SJit Loon Lim PERIPHERAL_SDMMC_MASK) >> PERIPHERAL_SDMMC_OFFSET)) { 52*ddaf02d1SJit Loon Lim ERROR("DFI is not set properly\n"); 53*ddaf02d1SJit Loon Lim return -ENXIO; 54*ddaf02d1SJit Loon Lim } 55*ddaf02d1SJit Loon Lim 56*ddaf02d1SJit Loon Lim return 0; 57*ddaf02d1SJit Loon Lim } 58*ddaf02d1SJit Loon Lim 59*ddaf02d1SJit Loon Lim int combo_phy_init(handoff *hoff_ptr) 60*ddaf02d1SJit Loon Lim { 61*ddaf02d1SJit Loon Lim /* SDMMC/NAND DFI selection based on system manager DFI register */ 62*ddaf02d1SJit Loon Lim int ret = dfi_select(hoff_ptr); 63*ddaf02d1SJit Loon Lim 64*ddaf02d1SJit Loon Lim if (ret != 0U) { 65*ddaf02d1SJit Loon Lim ERROR("DFI configuration failed\n"); 66*ddaf02d1SJit Loon Lim return ret; 67*ddaf02d1SJit Loon Lim } 68*ddaf02d1SJit Loon Lim 69*ddaf02d1SJit Loon Lim return 0; 70*ddaf02d1SJit Loon Lim } 71