1 /* 2 * (C) Copyright 2013 Inc. 3 * 4 * Xilinx Zynq SD Host Controller Interface 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9 #include <common.h> 10 #include <fdtdec.h> 11 #include <libfdt.h> 12 #include <malloc.h> 13 #include <sdhci.h> 14 #include <asm/arch/sys_proto.h> 15 16 int zynq_sdhci_init(phys_addr_t regbase) 17 { 18 struct sdhci_host *host = NULL; 19 20 host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host)); 21 if (!host) { 22 printf("zynq_sdhci_init: sdhci_host malloc fail\n"); 23 return 1; 24 } 25 26 host->name = "zynq_sdhci"; 27 host->ioaddr = (void *)regbase; 28 host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD | 29 SDHCI_QUIRK_BROKEN_R1B; 30 host->version = sdhci_readw(host, SDHCI_HOST_VERSION); 31 32 add_sdhci(host, CONFIG_ZYNQ_SDHCI_MAX_FREQ, 52000000 >> 9); 33 return 0; 34 } 35 36 #if CONFIG_IS_ENABLED(OF_CONTROL) 37 int zynq_sdhci_of_init(const void *blob) 38 { 39 int offset = 0; 40 u32 ret = 0; 41 phys_addr_t reg; 42 43 debug("ZYNQ SDHCI: Initialization\n"); 44 45 do { 46 offset = fdt_node_offset_by_compatible(blob, offset, 47 "arasan,sdhci-8.9a"); 48 if (offset != -1) { 49 reg = fdtdec_get_addr(blob, offset, "reg"); 50 if (reg != FDT_ADDR_T_NONE) { 51 ret |= zynq_sdhci_init(reg); 52 } else { 53 debug("ZYNQ SDHCI: Can't get base address\n"); 54 return -1; 55 } 56 } 57 } while (offset != -1); 58 59 return ret; 60 } 61 #endif 62