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, &regs);
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