1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) ASPEED Technology Inc. 4 */ 5 6 #include <common.h> 7 #include <clk.h> 8 #include <dm.h> 9 #include <errno.h> 10 #include <fdtdec.h> 11 #include <asm/io.h> 12 #include <linux/io.h> 13 #include <linux/ioport.h> 14 15 #define TIMING_PHASE_OFFSET 0xf4 16 17 struct aspeed_sdhci_general_reg { 18 u32 genreal_info; 19 u32 debounce_setting; 20 u32 bus_setting; 21 }; 22 23 struct aspeed_sdhci_general_data { 24 struct aspeed_sdhci_general_reg *regs; 25 struct clk_bulk clks; 26 }; 27 28 static int aspeed_sdhci_irq_ofdata_to_platdata(struct udevice *dev) 29 { 30 struct aspeed_sdhci_general_data *priv = dev_get_priv(dev); 31 32 return clk_get_bulk(dev, &priv->clks); 33 } 34 35 static int aspeed_sdhci_irq_probe(struct udevice *dev) 36 { 37 struct aspeed_sdhci_general_data *priv = dev_get_priv(dev); 38 int ret = 0; 39 struct resource regs; 40 void __iomem *sdhci_ctrl_base; 41 u32 timing_phase; 42 43 debug("%s(dev=%p) \n", __func__, dev); 44 45 ret = clk_enable_bulk(&priv->clks); 46 if (ret) { 47 pr_debug("fail enable sdhci clk \n"); 48 return ret; 49 } 50 51 ret = dev_read_resource(dev, 0, ®s); 52 if (ret < 0) 53 return ret; 54 55 sdhci_ctrl_base = (void __iomem *)regs.start; 56 57 timing_phase = dev_read_u32_default(dev, "timing-phase", 0); 58 writel(timing_phase, sdhci_ctrl_base + TIMING_PHASE_OFFSET); 59 60 return 0; 61 } 62 63 static const struct udevice_id aspeed_sdhci_irq_ids[] = { 64 { .compatible = "aspeed,aspeed-sdhci-irq" }, 65 { .compatible = "aspeed,aspeed-emmc-irq" }, 66 { } 67 }; 68 69 U_BOOT_DRIVER(aspeed_sdhci_ic) = { 70 .name = "aspeed_sdhci_ic", 71 .id = UCLASS_MISC, 72 .of_match = aspeed_sdhci_irq_ids, 73 .probe = aspeed_sdhci_irq_probe, 74 .ofdata_to_platdata = aspeed_sdhci_irq_ofdata_to_platdata, 75 .priv_auto_alloc_size = sizeof(struct aspeed_sdhci_general_data), 76 }; 77