blob: ec6cb0382daa9fb29569d0987d6d5611dbff4148 [file] [log] [blame]
Zheng Baob0f00ed2021-03-16 15:28:49 +08001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <amdblocks/acpimmio.h>
4#include <amdblocks/i2c.h>
5#include <soc/i2c.h>
6#include <soc/southbridge.h>
7#include "chip.h"
8
9#if ENV_X86
10static const struct soc_i2c_ctrlr_info i2c_ctrlr[I2C_CTRLR_COUNT] = {
11 { I2C_MASTER_MODE, APU_I2C0_BASE, "I2C0" },
12 { I2C_MASTER_MODE, APU_I2C1_BASE, "I2C1" },
13 { I2C_MASTER_MODE, APU_I2C2_BASE, "I2C2" },
14 { I2C_MASTER_MODE, APU_I2C3_BASE, "I2C3" }
15};
16#else
17static struct soc_i2c_ctrlr_info i2c_ctrlr[I2C_CTRLR_CNT] = {
18 { I2C_MASTER_MODE, 0, "" },
19 { I2C_MASTER_MODE, 0, "" },
20 { I2C_MASTER_MODE, 0, "" },
21 { I2C_MASTER_MODE, 0, "" }
22};
23
24void i2c_set_bar(unsigned int bus, uintptr_t bar)
25{
26 if (bus >= ARRAY_SIZE(i2c_ctrlr)) {
27 printk(BIOS_ERR, "Error: i2c index out of bounds: %u.", bus);
28 return;
29 }
30
31 i2c_ctrlr[bus].bar = bar;
32}
33#endif
34
35__weak void mainboard_i2c_override(int bus, uint32_t *pad_settings) { }
36
37void soc_i2c_misc_init(unsigned int bus, const struct dw_i2c_bus_config *cfg)
38{
39 uint32_t pad_ctrl;
40 int misc_reg;
41
42 misc_reg = MISC_I2C0_PAD_CTRL + sizeof(uint32_t) * bus;
43 pad_ctrl = misc_read32(misc_reg);
44
45 pad_ctrl &= ~I2C_PAD_CTRL_NG_MASK;
46 pad_ctrl |= I2C_PAD_CTRL_NG_NORMAL;
47
48 pad_ctrl &= ~I2C_PAD_CTRL_RX_SEL_MASK;
49 pad_ctrl |= I2C_PAD_CTRL_RX_SEL_3_3V;
50
51 pad_ctrl &= ~I2C_PAD_CTRL_FALLSLEW_MASK;
52 pad_ctrl |= cfg->speed == I2C_SPEED_STANDARD ?
53 I2C_PAD_CTRL_FALLSLEW_STD : I2C_PAD_CTRL_FALLSLEW_LOW;
54 pad_ctrl |= I2C_PAD_CTRL_FALLSLEW_EN;
55
56 mainboard_i2c_override(bus, &pad_ctrl);
57 misc_write32(misc_reg, pad_ctrl);
58}
59
60const struct soc_i2c_ctrlr_info *soc_get_i2c_ctrlr_info(size_t *num_ctrlrs)
61{
62 *num_ctrlrs = ARRAY_SIZE(i2c_ctrlr);
63 return i2c_ctrlr;
64}
65
66const struct dw_i2c_bus_config *soc_get_i2c_bus_config(size_t *num_buses)
67{
68 const struct soc_amd_cezanne_config *config = config_of_soc();
69
70 *num_buses = ARRAY_SIZE(config->i2c);
71 return config->i2c;
72}