1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright 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 <reset.h>
13 #include "ast2600_i2c_global.h"
14
15 enum global_version {
16 ASPEED_I2C_GLOBAL = 0,
17 AST2600_I2C_GLOBAL,
18 };
19
20 struct ast2600_i2c_global_priv {
21 void __iomem *regs;
22 struct reset_ctl reset;
23 int version;
24 };
25
26 /*
27 * APB clk : 100Mhz
28 * div : scl : baseclk [APB/((div/2) + 1)] : tBuf [1/bclk * 16]
29 * I2CG10[31:24] base clk4 for i2c auto recovery timeout counter (0xC6)
30 * I2CG10[23:16] base clk3 for Standard-mode (100Khz) min tBuf 4.7us
31 * 0x3c : 100.8Khz : 3.225Mhz : 4.96us
32 * 0x3d : 99.2Khz : 3.174Mhz : 5.04us
33 * 0x3e : 97.65Khz : 3.125Mhz : 5.12us
34 * 0x40 : 97.75Khz : 3.03Mhz : 5.28us
35 * 0x41 : 99.5Khz : 2.98Mhz : 5.36us (default)
36 * I2CG10[15:8] base clk2 for Fast-mode (400Khz) min tBuf 1.3us
37 * 0x12 : 400Khz : 10Mhz : 1.6us
38 * I2CG10[7:0] base clk1 for Fast-mode Plus (1Mhz) min tBuf 0.5us
39 * 0x08 : 1Mhz : 20Mhz : 0.8us
40 */
41
aspeed_i2c_global_probe(struct udevice * dev)42 static int aspeed_i2c_global_probe(struct udevice *dev)
43 {
44 struct ast2600_i2c_global_priv *i2c_global = dev_get_priv(dev);
45 int ret = 0;
46
47 i2c_global->regs = devfdt_get_addr_ptr(dev);
48 if (IS_ERR(i2c_global->regs))
49 return PTR_ERR(i2c_global->regs);
50
51 debug("%s(dev=%p)\n", __func__, dev);
52
53 ret = reset_get_by_index(dev, 0, &i2c_global->reset);
54 if (ret) {
55 printf("%s(): Failed to get reset signal\n", __func__);
56 return ret;
57 }
58
59 i2c_global->version = dev_get_driver_data(dev);
60
61 reset_deassert(&i2c_global->reset);
62
63 if (IS_ENABLED(SYS_I2C_AST2600) &&
64 i2c_global->version == AST2600_I2C_GLOBAL) {
65 writel(AST2600_GLOBAL_INIT, i2c_global->regs +
66 AST2600_I2CG_CTRL);
67 writel(I2CCG_DIV_CTRL, i2c_global->regs +
68 AST2600_I2CG_CLK_DIV_CTRL);
69 }
70
71 return 0;
72 }
73
74 static const struct udevice_id aspeed_i2c_global_ids[] = {
75 {
76 .compatible = "aspeed,ast2500-i2c-ic",
77 .data = ASPEED_I2C_GLOBAL
78 },
79 {
80 .compatible = "aspeed,ast2600-i2c-global",
81 .data = AST2600_I2C_GLOBAL
82 },
83 { }
84 };
85
86 U_BOOT_DRIVER(aspeed_i2c_global) = {
87 .name = "aspeed_i2c_global",
88 .id = UCLASS_MISC,
89 .of_match = aspeed_i2c_global_ids,
90 .probe = aspeed_i2c_global_probe,
91 .priv_auto_alloc_size = sizeof(struct ast2600_i2c_global_priv),
92 };
93