blob: 11e69b103884eab3b1bfc62d9ea75d7008e22383 [file] [log] [blame]
Angel Ponsae593872020-04-04 18:50:57 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Martin Roth5c354b92019-04-22 14:55:16 -06002
Martin Roth5c354b92019-04-22 14:55:16 -06003#include <console/console.h>
Martin Roth5c354b92019-04-22 14:55:16 -06004#include <amdblocks/acpimmio.h>
Karthikeyan Ramasubramanian0dbea482021-03-08 23:23:50 -07005#include <amdblocks/i2c.h>
Martin Roth7e78e562019-11-03 23:29:02 -07006#include <soc/i2c.h>
Martin Roth5c354b92019-04-22 14:55:16 -06007#include <soc/iomap.h>
8#include <soc/pci_devs.h>
9#include <soc/southbridge.h>
Martin Roth5c354b92019-04-22 14:55:16 -060010#include "chip.h"
11
Martin Rothac41f582020-06-14 17:24:12 -060012#if ENV_X86
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060013/* Preferably keep all the I2C controllers operating in a specific mode together. */
14static const struct soc_i2c_ctrlr_info i2c_ctrlr[I2C_CTRLR_COUNT] = {
15 { I2C_MASTER_MODE, 0, "" },
16 { I2C_MASTER_MODE, 0, "" },
17 { I2C_MASTER_MODE, APU_I2C2_BASE, "I2C2" },
18 { I2C_MASTER_MODE, APU_I2C3_BASE, "I2C3" },
19 { I2C_PERIPHERAL_MODE, APU_I2C4_BASE, "I2C4" } /* Can only be used in peripheral mode */
Martin Roth5c354b92019-04-22 14:55:16 -060020};
Martin Rothac41f582020-06-14 17:24:12 -060021#else
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060022static struct soc_i2c_ctrlr_info i2c_ctrlr[I2C_CTRLR_COUNT] = {
23 { I2C_MASTER_MODE, 0, ""},
24 { I2C_MASTER_MODE, 0, "" },
25 { I2C_MASTER_MODE, 0, "" },
26 { I2C_MASTER_MODE, 0, "" },
27 { I2C_PERIPHERAL_MODE, 0, "" },
28};
Martin Roth5c354b92019-04-22 14:55:16 -060029
Martin Rothac41f582020-06-14 17:24:12 -060030void i2c_set_bar(unsigned int bus, uintptr_t bar)
31{
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060032 if (bus >= ARRAY_SIZE(i2c_ctrlr)) {
Martin Rothac41f582020-06-14 17:24:12 -060033 printk(BIOS_ERR, "Error: i2c index out of bounds: %u.", bus);
34 return;
35 }
36
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060037 i2c_ctrlr[bus].bar = bar;
Martin Rothac41f582020-06-14 17:24:12 -060038}
39#endif
40
Marshall Dawsone2c24f72019-06-20 08:47:58 -060041__weak void mainboard_i2c_override(int bus, uint32_t *pad_settings) { }
42
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060043void soc_i2c_misc_init(unsigned int bus, const struct dw_i2c_bus_config *cfg)
Martin Roth5c354b92019-04-22 14:55:16 -060044{
Marshall Dawsone2c24f72019-06-20 08:47:58 -060045 uint32_t pad_ctrl;
46 int misc_reg;
Martin Roth5c354b92019-04-22 14:55:16 -060047
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060048 misc_reg = MISC_I2C0_PAD_CTRL + sizeof(uint32_t) * bus;
49 pad_ctrl = misc_read32(misc_reg);
Martin Roth5c354b92019-04-22 14:55:16 -060050
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060051 pad_ctrl &= ~I2C_PAD_CTRL_NG_MASK;
52 pad_ctrl |= I2C_PAD_CTRL_NG_NORMAL;
Martin Roth5c354b92019-04-22 14:55:16 -060053
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060054 pad_ctrl &= ~I2C_PAD_CTRL_RX_SEL_MASK;
55 pad_ctrl |= I2C_PAD_CTRL_RX_SEL_3_3V;
Martin Roth5c354b92019-04-22 14:55:16 -060056
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060057 pad_ctrl &= ~I2C_PAD_CTRL_FALLSLEW_MASK;
58 pad_ctrl |= cfg->speed == I2C_SPEED_STANDARD ? I2C_PAD_CTRL_FALLSLEW_STD :
59 I2C_PAD_CTRL_FALLSLEW_LOW;
60 pad_ctrl |= I2C_PAD_CTRL_FALLSLEW_EN;
Marshall Dawsone2c24f72019-06-20 08:47:58 -060061
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060062 mainboard_i2c_override(bus, &pad_ctrl);
63 misc_write32(misc_reg, pad_ctrl);
Martin Roth5c354b92019-04-22 14:55:16 -060064}
65
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060066const struct soc_i2c_ctrlr_info *soc_get_i2c_ctrlr_info(size_t *num_ctrlrs)
Martin Roth5c354b92019-04-22 14:55:16 -060067{
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060068 *num_ctrlrs = ARRAY_SIZE(i2c_ctrlr);
69 return i2c_ctrlr;
Martin Roth5c354b92019-04-22 14:55:16 -060070}
71
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060072const struct dw_i2c_bus_config *soc_get_i2c_bus_config(size_t *num_buses)
Martin Roth5c354b92019-04-22 14:55:16 -060073{
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060074 const struct soc_amd_picasso_config *config = config_of_soc();
Martin Roth5c354b92019-04-22 14:55:16 -060075
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060076 *num_buses = ARRAY_SIZE(config->i2c);
77 return config->i2c;
78}