blob: ba89e9c589a3a10ca600022d43edb3569896394f [file] [log] [blame]
Karthikeyan Ramasubramanian0dbea482021-03-08 23:23:50 -07001/* SPDX-License-Identifier: GPL-2.0-only */
2
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -06003#include <acpi/acpi.h>
Karthikeyan Ramasubramanian0dbea482021-03-08 23:23:50 -07004#include <assert.h>
Karthikeyan Ramasubramanian0dbea482021-03-08 23:23:50 -07005#include <amdblocks/acpimmio.h>
6#include <amdblocks/gpio_banks.h>
7#include <amdblocks/gpio_defs.h>
8#include <amdblocks/i2c.h>
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -06009#include <console/console.h>
10#include <delay.h>
11#include <device/device.h>
12#include <device/i2c.h>
13#include <device/mmio.h>
14#include <drivers/i2c/designware/dw_i2c.h>
Angel Ponsc57cae82021-03-25 11:29:32 +010015#include <types.h>
Karthikeyan Ramasubramanian0dbea482021-03-08 23:23:50 -070016
17#define MAX_PIN_COUNT 4
18
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060019uintptr_t dw_i2c_base_address(unsigned int bus)
20{
21 size_t num_ctrlrs;
22 const struct soc_i2c_ctrlr_info *ctrlr = soc_get_i2c_ctrlr_info(&num_ctrlrs);
23
24 if (bus >= num_ctrlrs) {
Angel Ponscf72a512021-03-25 11:15:32 +010025 printk(BIOS_ERR, "Bus ID %u is >= number of I2C controllers %zu\n",
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060026 bus, num_ctrlrs);
27 return 0;
28 }
29
30 return ctrlr[bus].bar;
31}
32
33const struct dw_i2c_bus_config *dw_i2c_get_soc_cfg(unsigned int bus)
34{
35 size_t num_buses = 0;
36 const struct dw_i2c_bus_config *cfg = soc_get_i2c_bus_config(&num_buses);
37
38 if (bus >= num_buses) {
Angel Ponscf72a512021-03-25 11:15:32 +010039 printk(BIOS_ERR, "Bus ID %u is >= number of I2C buses %zu\n", bus, num_buses);
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -060040 return NULL;
41 }
42
43 return &cfg[bus];
44}
45
46static const char *i2c_acpi_name(const struct device *dev)
47{
48 size_t i;
49 size_t num_ctrlrs;
50 const struct soc_i2c_ctrlr_info *ctrlr = soc_get_i2c_ctrlr_info(&num_ctrlrs);
51
52 if (!(uintptr_t)dev->path.mmio.addr)
53 die("NULL MMIO address at %s\n", __func__);
54
55 for (i = 0; i < num_ctrlrs; i++) {
56 if ((uintptr_t)dev->path.mmio.addr == ctrlr[i].bar)
57 return ctrlr[i].acpi_name;
58 }
59 printk(BIOS_ERR, "%s: Could not find %lu\n", __func__, (uintptr_t)dev->path.mmio.addr);
60 return NULL;
61}
62
63int dw_i2c_soc_dev_to_bus(const struct device *dev)
64{
65 size_t i;
66 size_t num_ctrlrs;
67 const struct soc_i2c_ctrlr_info *ctrlr = soc_get_i2c_ctrlr_info(&num_ctrlrs);
68
69 if (!(uintptr_t)dev->path.mmio.addr)
70 die("NULL MMIO address at %s\n", __func__);
71
72 for (i = 0; i < num_ctrlrs; i++) {
73 if ((uintptr_t)dev->path.mmio.addr == ctrlr[i].bar)
74 return i;
75 }
76 printk(BIOS_ERR, "%s: Could not find %lu\n", __func__, (uintptr_t)dev->path.mmio.addr);
77 return -1;
78}
79
80void __weak soc_i2c_misc_init(unsigned int bus, const struct dw_i2c_bus_config *cfg)
81{
82 /* Nothing by default. */
83}
84
85static void dw_i2c_soc_init(bool is_early_init)
86{
87 unsigned int bus;
88 size_t num_buses = 0, num_ctrlrs = 0;
89 const struct dw_i2c_bus_config *cfg = soc_get_i2c_bus_config(&num_buses);
90 const struct soc_i2c_ctrlr_info *ctrlr = soc_get_i2c_ctrlr_info(&num_ctrlrs);
91
92 /* Ensure that the number of controllers in devicetree and SoC match. */
93 assert(num_buses == num_ctrlrs);
94
95 for (bus = 0; bus < num_buses; bus++, cfg++, ctrlr++) {
96 /*
97 * Skip initialization when controller is in peripheral mode or base address
98 * is not configured or is not the expected stage to initialize.
99 */
100 if (ctrlr->mode == I2C_PERIPHERAL_MODE || !ctrlr->bar ||
101 cfg->early_init != is_early_init)
102 continue;
103
Felix Helda16a09f2021-03-25 02:07:23 +0100104 if (dw_i2c_init(bus, cfg)) {
Angel Ponscf72a512021-03-25 11:15:32 +0100105 printk(BIOS_ERR, "Failed to init i2c bus %u\n", bus);
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -0600106 continue;
Felix Helda16a09f2021-03-25 02:07:23 +0100107 }
Karthikeyan Ramasubramanian4f87ae12021-03-18 23:16:29 -0600108
109 soc_i2c_misc_init(bus, cfg);
110 }
111}
112
113void i2c_soc_early_init(void)
114{
115 dw_i2c_soc_init(true);
116}
117
118void i2c_soc_init(void)
119{
120 dw_i2c_soc_init(false);
121}
122
123struct device_operations soc_amd_i2c_mmio_ops = {
124 /* TODO(kramasub): Move I2C resource info here. */
125 .read_resources = noop_read_resources,
126 .set_resources = noop_set_resources,
127 .scan_bus = scan_smbus,
128 .acpi_name = i2c_acpi_name,
129 .acpi_fill_ssdt = dw_i2c_acpi_fill_ssdt,
130};
131
Karthikeyan Ramasubramanian0dbea482021-03-08 23:23:50 -0700132struct common_i2c_save {
133 uint32_t control_value;
134 uint8_t mux_value;
135};
136
137/*
138 * To program I2C pins without destroying their programming, the registers
139 * that will be changed need to be saved first.
140 */
141static void save_i2c_pin_registers(uint8_t gpio, struct common_i2c_save *save_table)
142{
143 save_table->mux_value = iomux_read8(gpio);
144 save_table->control_value = gpio_read32(gpio);
145}
146
147static void restore_i2c_pin_registers(uint8_t gpio, struct common_i2c_save *save_table)
148{
149 /* Write and flush posted writes. */
150 iomux_write8(gpio, save_table->mux_value);
151 iomux_read8(gpio);
152 gpio_write32(gpio, save_table->control_value);
153 gpio_read32(gpio);
154}
155
156static void drive_scl(const struct soc_i2c_peripheral_reset_info *reset_info, uint32_t val)
157{
Angel Ponsc57cae82021-03-25 11:29:32 +0100158 size_t j;
Karthikeyan Ramasubramanian0dbea482021-03-08 23:23:50 -0700159
160 for (j = 0; j < reset_info->num_pins; j++) {
161 if (reset_info->i2c_scl_reset_mask & reset_info->i2c_scl[j].pin_mask)
162 gpio_write32(reset_info->i2c_scl[j].pin.gpio, val);
163 }
164
165 gpio_read32(0); /* Flush posted write */
166 /*
167 * TODO(b/183010197): 4usec gets 85KHz for 1 pin, 70KHz for 4 pins. Ensure this delay
168 * works fine for all SoCs and make this delay configurable if required.
169 */
170 udelay(4);
171}
172
173void sb_reset_i2c_peripherals(const struct soc_i2c_peripheral_reset_info *reset_info)
174{
175 struct common_i2c_save save_table[MAX_PIN_COUNT];
Angel Ponsc57cae82021-03-25 11:29:32 +0100176 size_t i;
Karthikeyan Ramasubramanian0dbea482021-03-08 23:23:50 -0700177
178 if (!reset_info || !reset_info->i2c_scl || !reset_info->num_pins ||
179 !reset_info->i2c_scl_reset_mask)
180 return;
181
182 assert(reset_info->num_pins <= MAX_PIN_COUNT);
183
184 /* Save and reprogram I2C SCL pins */
185 for (i = 0; i < reset_info->num_pins; i++) {
186 save_i2c_pin_registers(reset_info->i2c_scl[i].pin.gpio, &save_table[i]);
187 program_gpios(&reset_info->i2c_scl[i].pin, 1);
188 }
189
190 /*
191 * Toggle SCL back and forth 9 times under 100KHz. A single read is
192 * needed after the writes to force the posted write to complete.
193 */
194 for (i = 0; i < 9; i++) {
195 drive_scl(reset_info, GPIO_OUTPUT_OUT_HIGH);
196 drive_scl(reset_info, GPIO_OUTPUT_OUT_LOW);
197 }
198
199 /* Restore I2C pins. */
200 for (i = 0; i < reset_info->num_pins; i++)
201 restore_i2c_pin_registers(reset_info->i2c_scl[i].pin.gpio, &save_table[i]);
202}