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 #define SDHCI140_SLOT_0_MIRROR_OFFSET 0x10 17 #define SDHCI240_SLOT_0_MIRROR_OFFSET 0x20 18 #define SDHCI140_SLOT_0_CAP_REG_1_OFFSET 0x140 19 #define SDHCI240_SLOT_0_CAP_REG_1_OFFSET 0x240 20 21 struct aspeed_sdhci_general_reg { 22 u32 genreal_info; 23 u32 debounce_setting; 24 u32 bus_setting; 25 }; 26 27 struct aspeed_sdhci_general_data { 28 struct aspeed_sdhci_general_reg *regs; 29 struct clk_bulk clks; 30 }; 31 32 static int aspeed_sdhci_irq_ofdata_to_platdata(struct udevice *dev) 33 { 34 struct aspeed_sdhci_general_data *priv = dev_get_priv(dev); 35 36 return clk_get_bulk(dev, &priv->clks); 37 } 38 39 static int aspeed_sdhci_irq_probe(struct udevice *dev) 40 { 41 struct aspeed_sdhci_general_data *priv = dev_get_priv(dev); 42 int ret = 0; 43 struct resource regs; 44 void __iomem *sdhci_ctrl_base; 45 u32 timing_phase; 46 u32 reg_val; 47 48 debug("%s(dev=%p) \n", __func__, dev); 49 50 ret = clk_enable_bulk(&priv->clks); 51 if (ret) { 52 pr_debug("fail enable sdhci clk \n"); 53 return ret; 54 } 55 56 ret = dev_read_resource(dev, 0, ®s); 57 if (ret < 0) 58 return ret; 59 60 sdhci_ctrl_base = (void __iomem *)regs.start; 61 62 timing_phase = dev_read_u32_default(dev, "timing-phase", 0); 63 writel(timing_phase, sdhci_ctrl_base + TIMING_PHASE_OFFSET); 64 65 if (dev_read_bool(dev, "sdhci_hs200")) { 66 reg_val = readl(sdhci_ctrl_base + SDHCI140_SLOT_0_CAP_REG_1_OFFSET); 67 /* support 1.8V */ 68 reg_val |= BIT(26); 69 writel(reg_val, sdhci_ctrl_base + SDHCI140_SLOT_0_MIRROR_OFFSET); 70 reg_val = readl(sdhci_ctrl_base + SDHCI240_SLOT_0_CAP_REG_1_OFFSET); 71 /* support 1.8V */ 72 reg_val |= BIT(26); 73 writel(reg_val, sdhci_ctrl_base + SDHCI240_SLOT_0_MIRROR_OFFSET); 74 } 75 76 return 0; 77 } 78 79 static const struct udevice_id aspeed_sdhci_irq_ids[] = { 80 { .compatible = "aspeed,aspeed-sdhci-irq" }, 81 { .compatible = "aspeed,aspeed-emmc-irq" }, 82 { } 83 }; 84 85 U_BOOT_DRIVER(aspeed_sdhci_ic) = { 86 .name = "aspeed_sdhci_ic", 87 .id = UCLASS_MISC, 88 .of_match = aspeed_sdhci_irq_ids, 89 .probe = aspeed_sdhci_irq_probe, 90 .ofdata_to_platdata = aspeed_sdhci_irq_ofdata_to_platdata, 91 .priv_auto_alloc_size = sizeof(struct aspeed_sdhci_general_data), 92 }; 93