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