blob: d71843658b336c67aea5a4a8d4e7f6b43b602bf8 [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
Fred Reitberger13831222022-10-17 11:49:55 -040012/* Table to switch SCL pins to outputs to initially reset the I2C peripherals */
13static const struct soc_i2c_scl_pin i2c_scl_pins[] = {
14 I2C_RESET_SCL_PIN(I2C2_SCL_PIN, GPIO_I2C2_SCL),
15 I2C_RESET_SCL_PIN(I2C3_SCL_PIN, GPIO_I2C3_SCL),
16 /* I2C4 is a peripheral device only */
17};
18
Martin Rothac41f582020-06-14 17:24:12 -060019#if ENV_X86
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060020/* Preferably keep all the I2C controllers operating in a specific mode together. */
21static const struct soc_i2c_ctrlr_info i2c_ctrlr[I2C_CTRLR_COUNT] = {
22 { I2C_MASTER_MODE, 0, "" },
23 { I2C_MASTER_MODE, 0, "" },
24 { I2C_MASTER_MODE, APU_I2C2_BASE, "I2C2" },
25 { I2C_MASTER_MODE, APU_I2C3_BASE, "I2C3" },
26 { I2C_PERIPHERAL_MODE, APU_I2C4_BASE, "I2C4" } /* Can only be used in peripheral mode */
Martin Roth5c354b92019-04-22 14:55:16 -060027};
Martin Rothac41f582020-06-14 17:24:12 -060028#else
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060029static struct soc_i2c_ctrlr_info i2c_ctrlr[I2C_CTRLR_COUNT] = {
30 { I2C_MASTER_MODE, 0, ""},
31 { I2C_MASTER_MODE, 0, "" },
32 { I2C_MASTER_MODE, 0, "" },
33 { I2C_MASTER_MODE, 0, "" },
34 { I2C_PERIPHERAL_MODE, 0, "" },
35};
Martin Roth5c354b92019-04-22 14:55:16 -060036
Martin Rothac41f582020-06-14 17:24:12 -060037void i2c_set_bar(unsigned int bus, uintptr_t bar)
38{
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060039 if (bus >= ARRAY_SIZE(i2c_ctrlr)) {
Julius Wernere9665952022-01-21 17:06:20 -080040 printk(BIOS_ERR, "i2c index out of bounds: %u.", bus);
Martin Rothac41f582020-06-14 17:24:12 -060041 return;
42 }
43
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060044 i2c_ctrlr[bus].bar = bar;
Martin Rothac41f582020-06-14 17:24:12 -060045}
46#endif
47
Fred Reitberger13831222022-10-17 11:49:55 -040048void reset_i2c_peripherals(void)
49{
50 const struct soc_amd_picasso_config *cfg = config_of_soc();
51 struct soc_i2c_peripheral_reset_info reset_info;
52
53 reset_info.i2c_scl_reset_mask = cfg->i2c_scl_reset & GPIO_I2C_MASK;
54 reset_info.i2c_scl = i2c_scl_pins;
55 reset_info.num_pins = ARRAY_SIZE(i2c_scl_pins);
56 sb_reset_i2c_peripherals(&reset_info);
57}
58
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060059void soc_i2c_misc_init(unsigned int bus, const struct dw_i2c_bus_config *cfg)
Martin Roth5c354b92019-04-22 14:55:16 -060060{
Felix Held556d1cc2022-02-02 22:11:52 +010061 /* TODO: Picasso supports I2C RX pad configurations 3.3V, 1.8V and off, so make this
62 configurable. */
63 const struct i2c_pad_control ctrl = {
64 .rx_level = I2C_PAD_RX_3_3V,
65 };
Martin Roth5c354b92019-04-22 14:55:16 -060066
Felix Held556d1cc2022-02-02 22:11:52 +010067 fch_i2c_pad_init(bus, cfg->speed, &ctrl);
Martin Roth5c354b92019-04-22 14:55:16 -060068}
69
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060070const struct soc_i2c_ctrlr_info *soc_get_i2c_ctrlr_info(size_t *num_ctrlrs)
Martin Roth5c354b92019-04-22 14:55:16 -060071{
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060072 *num_ctrlrs = ARRAY_SIZE(i2c_ctrlr);
73 return i2c_ctrlr;
Martin Roth5c354b92019-04-22 14:55:16 -060074}
75
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060076const struct dw_i2c_bus_config *soc_get_i2c_bus_config(size_t *num_buses)
Martin Roth5c354b92019-04-22 14:55:16 -060077{
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060078 const struct soc_amd_picasso_config *config = config_of_soc();
Martin Roth5c354b92019-04-22 14:55:16 -060079
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060080 *num_buses = ARRAY_SIZE(config->i2c);
81 return config->i2c;
82}