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