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(u32 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_NO_CD | SDHCI_QUIRK_WAIT_SEND_CMD | 29 SDHCI_QUIRK_BROKEN_R1B; 30 host->version = sdhci_readw(host, SDHCI_HOST_VERSION); 31 32 host->host_caps = MMC_MODE_HC; 33 34 add_sdhci(host, 52000000, 52000000 >> 9); 35 return 0; 36 } 37 38 #ifdef CONFIG_OF_CONTROL 39 int zynq_sdhci_of_init(const void *blob) 40 { 41 int offset = 0; 42 u32 ret = 0; 43 u32 reg; 44 45 debug("ZYNQ SDHCI: Initialization\n"); 46 47 do { 48 offset = fdt_node_offset_by_compatible(blob, offset, 49 "arasan,sdhci-8.9a"); 50 if (offset != -1) { 51 reg = fdtdec_get_addr(blob, offset, "reg"); 52 if (reg != FDT_ADDR_T_NONE) { 53 ret |= zynq_sdhci_init(reg); 54 } else { 55 debug("ZYNQ SDHCI: Can't get base address\n"); 56 return -1; 57 } 58 } 59 } while (offset != -1); 60 61 return ret; 62 } 63 #endif 64