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