aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/apollolake/chip.h11
-rw-r--r--src/soc/intel/apollolake/i2c.c18
-rw-r--r--src/soc/intel/apollolake/i2c_early.c14
-rw-r--r--src/soc/intel/common/lpss_i2c.c93
-rw-r--r--src/soc/intel/common/lpss_i2c.h40
-rw-r--r--src/soc/intel/skylake/bootblock/i2c.c14
-rw-r--r--src/soc/intel/skylake/chip.h2
-rw-r--r--src/soc/intel/skylake/i2c.c18
8 files changed, 73 insertions, 137 deletions
diff --git a/src/soc/intel/apollolake/chip.h b/src/soc/intel/apollolake/chip.h
index 6c3bcd8cad..dd301067cc 100644
--- a/src/soc/intel/apollolake/chip.h
+++ b/src/soc/intel/apollolake/chip.h
@@ -28,15 +28,6 @@
#define CLKREQ_DISABLED 0xf
#define APOLLOLAKE_I2C_DEV_MAX 8
-struct apollolake_i2c_config {
- /* Bus should be enabled prior to ramstage with temporary base */
- int early_init;
- /* Bus speed in Hz, default is I2C_SPEED_FAST (400 KHz) */
- enum i2c_speed speed;
- /* Specific bus speed configuration */
- struct lpss_i2c_speed_config speed_config[LPSS_I2C_SPEED_CONFIG_COUNT];
-};
-
/* Serial IRQ control. SERIRQ_QUIET is the default (0). */
enum serirq_mode {
SERIRQ_QUIET,
@@ -95,7 +86,7 @@ struct soc_intel_apollolake_config {
enum serirq_mode serirq_mode;
/* I2C bus configuration */
- struct apollolake_i2c_config i2c[APOLLOLAKE_I2C_DEV_MAX];
+ struct lpss_i2c_bus_config i2c[APOLLOLAKE_I2C_DEV_MAX];
uint8_t gpe0_dw1; /* GPE0_63_32 STS/EN */
uint8_t gpe0_dw2; /* GPE0_95_64 STS/EN */
diff --git a/src/soc/intel/apollolake/i2c.c b/src/soc/intel/apollolake/i2c.c
index 1c16a06058..69cb4b8d5f 100644
--- a/src/soc/intel/apollolake/i2c.c
+++ b/src/soc/intel/apollolake/i2c.c
@@ -60,24 +60,12 @@ static int i2c_dev_to_bus(struct device *dev)
static void i2c_dev_init(struct device *dev)
{
struct soc_intel_apollolake_config *config = dev->chip_info;
- const struct lpss_i2c_speed_config *sptr;
- enum i2c_speed speed;
- int i, bus = i2c_dev_to_bus(dev);
+ int bus = i2c_dev_to_bus(dev);
if (!config || bus < 0)
return;
- speed = config->i2c[bus].speed ? : I2C_SPEED_FAST;
- lpss_i2c_init(bus, speed);
-
- /* Apply custom speed config if it has been set by the board */
- for (i = 0; i < LPSS_I2C_SPEED_CONFIG_COUNT; i++) {
- sptr = &config->i2c[bus].speed_config[i];
- if (sptr->speed == speed) {
- lpss_i2c_set_speed_config(bus, sptr);
- break;
- }
- }
+ lpss_i2c_init(bus, &config->i2c[bus]);
}
static void i2c_fill_ssdt(struct device *dev)
@@ -89,7 +77,7 @@ static void i2c_fill_ssdt(struct device *dev)
return;
acpigen_write_scope(acpi_device_path(dev));
- lpss_i2c_acpi_fill_ssdt(config->i2c[bus].speed_config);
+ lpss_i2c_acpi_fill_ssdt(&config->i2c[bus]);
acpigen_pop_len();
}
diff --git a/src/soc/intel/apollolake/i2c_early.c b/src/soc/intel/apollolake/i2c_early.c
index 82883f847d..7c188a8544 100644
--- a/src/soc/intel/apollolake/i2c_early.c
+++ b/src/soc/intel/apollolake/i2c_early.c
@@ -29,8 +29,6 @@ static int i2c_early_init_bus(unsigned bus)
{
ROMSTAGE_CONST struct soc_intel_apollolake_config *config;
ROMSTAGE_CONST struct device *tree_dev;
- const struct lpss_i2c_speed_config *sptr;
- enum i2c_speed speed;
pci_devfn_t dev;
int devfn;
uintptr_t base;
@@ -72,21 +70,11 @@ static int i2c_early_init_bus(unsigned bus)
write32(reg, value);
/* Initialize the controller */
- speed = config->i2c[bus].speed ? : I2C_SPEED_FAST;
- if (lpss_i2c_init(bus, speed) < 0) {
+ if (lpss_i2c_init(bus, &config->i2c[bus]) < 0) {
printk(BIOS_ERR, "I2C%u failed to initialize\n", bus);
return -1;
}
- /* Apply custom speed config if it has been set by the board */
- for (value = 0; value < LPSS_I2C_SPEED_CONFIG_COUNT; value++) {
- sptr = &config->i2c[bus].speed_config[value];
- if (sptr->speed == speed) {
- lpss_i2c_set_speed_config(bus, sptr);
- break;
- }
- }
-
return 0;
}
diff --git a/src/soc/intel/common/lpss_i2c.c b/src/soc/intel/common/lpss_i2c.c
index 58d44b85dd..51c59154ec 100644
--- a/src/soc/intel/common/lpss_i2c.c
+++ b/src/soc/intel/common/lpss_i2c.c
@@ -370,39 +370,8 @@ static void lpss_i2c_acpi_write_speed_config(
acpigen_pop_len();
}
-void lpss_i2c_acpi_fill_ssdt(const struct lpss_i2c_speed_config *override)
-{
- const struct lpss_i2c_speed_config *sptr;
- struct lpss_i2c_speed_config sgen;
- enum i2c_speed speeds[LPSS_I2C_SPEED_CONFIG_COUNT] = {
- I2C_SPEED_STANDARD,
- I2C_SPEED_FAST,
- I2C_SPEED_FAST_PLUS,
- I2C_SPEED_HIGH,
- };
- int i;
-
- /* Report timing values for the OS driver */
- for (i = 0; i < LPSS_I2C_SPEED_CONFIG_COUNT; i++) {
- /* Generate speed config for default case */
- if (lpss_i2c_gen_speed_config(speeds[i], &sgen) < 0)
- continue;
-
- /* Apply board specific override for this speed if found */
- for (sptr = override; sptr && sptr->speed; sptr++) {
- if (sptr->speed == speeds[i]) {
- memcpy(&sgen, sptr, sizeof(sgen));
- break;
- }
- }
-
- /* Generate ACPI based on selected speed config */
- lpss_i2c_acpi_write_speed_config(&sgen);
- }
-}
-
-int lpss_i2c_set_speed_config(unsigned bus,
- const struct lpss_i2c_speed_config *config)
+static int lpss_i2c_set_speed_config(unsigned bus,
+ const struct lpss_i2c_speed_config *config)
{
struct lpss_i2c_regs *regs;
void *hcnt_reg, *lcnt_reg;
@@ -442,16 +411,26 @@ int lpss_i2c_set_speed_config(unsigned bus,
return 0;
}
-int lpss_i2c_gen_speed_config(enum i2c_speed speed,
- struct lpss_i2c_speed_config *config)
+static int lpss_i2c_gen_speed_config(enum i2c_speed speed,
+ const struct lpss_i2c_bus_config *bcfg,
+ struct lpss_i2c_speed_config *config)
{
const int ic_clk = CONFIG_SOC_INTEL_COMMON_LPSS_I2C_CLOCK_MHZ;
uint16_t hcnt_min, lcnt_min;
+ int i;
/* Clock must be provided by Kconfig */
- if (!ic_clk || !config)
+ if (!ic_clk)
return -1;
+ /* Apply board specific override for this speed if found */
+ for (i = 0; i < LPSS_I2C_SPEED_CONFIG_COUNT; i++) {
+ if (bcfg->speed_config[i].speed != speed)
+ continue;
+ memcpy(config, &bcfg->speed_config[i], sizeof(*config));
+ return 0;
+ }
+
if (speed >= I2C_SPEED_HIGH) {
/* High speed */
hcnt_min = MIN_HS_SCL_HIGHTIME;
@@ -478,7 +457,8 @@ int lpss_i2c_gen_speed_config(enum i2c_speed speed,
return 0;
}
-int lpss_i2c_set_speed(unsigned bus, enum i2c_speed speed)
+static int lpss_i2c_set_speed(unsigned bus, enum i2c_speed speed,
+ const struct lpss_i2c_bus_config *bcfg)
{
struct lpss_i2c_regs *regs;
struct lpss_i2c_speed_config config;
@@ -504,7 +484,7 @@ int lpss_i2c_set_speed(unsigned bus, enum i2c_speed speed)
}
/* Generate speed config based on clock */
- if (lpss_i2c_gen_speed_config(speed, &config) < 0)
+ if (lpss_i2c_gen_speed_config(speed, bcfg, &config) < 0)
return -1;
/* Select this speed in the control register */
@@ -516,9 +496,40 @@ int lpss_i2c_set_speed(unsigned bus, enum i2c_speed speed)
return 0;
}
-int lpss_i2c_init(unsigned bus, enum i2c_speed speed)
+void lpss_i2c_acpi_fill_ssdt(const struct lpss_i2c_bus_config *bcfg)
+{
+ struct lpss_i2c_speed_config sgen;
+ enum i2c_speed speeds[LPSS_I2C_SPEED_CONFIG_COUNT] = {
+ I2C_SPEED_STANDARD,
+ I2C_SPEED_FAST,
+ I2C_SPEED_FAST_PLUS,
+ I2C_SPEED_HIGH,
+ };
+ int i;
+
+ if (!bcfg)
+ return;
+
+ /* Report timing values for the OS driver */
+ for (i = 0; i < LPSS_I2C_SPEED_CONFIG_COUNT; i++) {
+ /* Generate speed config. */
+ if (lpss_i2c_gen_speed_config(speeds[i], bcfg, &sgen) < 0)
+ continue;
+
+ /* Generate ACPI based on selected speed config */
+ lpss_i2c_acpi_write_speed_config(&sgen);
+ }
+}
+
+int lpss_i2c_init(unsigned bus, const struct lpss_i2c_bus_config *bcfg)
{
struct lpss_i2c_regs *regs;
+ enum i2c_speed speed;
+
+ if (!bcfg)
+ return -1;
+
+ speed = bcfg->speed ? : I2C_SPEED_FAST;
regs = (struct lpss_i2c_regs *)lpss_i2c_base_address(bus);
if (!regs) {
@@ -536,7 +547,7 @@ int lpss_i2c_init(unsigned bus, enum i2c_speed speed)
CONTROL_RESTART_ENABLE);
/* Set bus speed to FAST by default */
- if (lpss_i2c_set_speed(bus, speed ? : I2C_SPEED_FAST) < 0) {
+ if (lpss_i2c_set_speed(bus, speed, bcfg) < 0) {
printk(BIOS_ERR, "I2C failed to set speed for bus %u\n", bus);
return -1;
}
@@ -549,7 +560,7 @@ int lpss_i2c_init(unsigned bus, enum i2c_speed speed)
write32(&regs->intr_mask, INTR_STAT_STOP_DET);
printk(BIOS_INFO, "LPSS I2C bus %u at 0x%p (%u KHz)\n",
- bus, regs, (speed ? : I2C_SPEED_FAST) / KHz);
+ bus, regs, speed / KHz);
return 0;
}
diff --git a/src/soc/intel/common/lpss_i2c.h b/src/soc/intel/common/lpss_i2c.h
index 3ec92134c7..f4a48bddef 100644
--- a/src/soc/intel/common/lpss_i2c.h
+++ b/src/soc/intel/common/lpss_i2c.h
@@ -50,6 +50,15 @@ struct lpss_i2c_speed_config {
*/
#define LPSS_I2C_SPEED_CONFIG_COUNT 4
+struct lpss_i2c_bus_config {
+ /* Bus should be enabled prior to ramstage with temporary base */
+ int early_init;
+ /* Bus speed in Hz, default is I2C_SPEED_FAST (400 KHz) */
+ enum i2c_speed speed;
+ /* Specific bus speed configuration */
+ struct lpss_i2c_speed_config speed_config[LPSS_I2C_SPEED_CONFIG_COUNT];
+};
+
#define LPSS_I2C_SPEED_CONFIG(speedval,lcnt,hcnt,hold) \
{ \
.speed = I2C_SPEED_ ## speedval, \
@@ -67,37 +76,10 @@ struct lpss_i2c_speed_config {
uintptr_t lpss_i2c_base_address(unsigned bus);
/*
- * Generate speed configuration for requested controller and bus speed.
- *
- * This allows a SOC or board to automatically generate speed config to use
- * in firmware and provide to the OS.
- */
-int lpss_i2c_gen_speed_config(enum i2c_speed speed,
- struct lpss_i2c_speed_config *config);
-
-/*
- * Set raw speed configuration for given speed type.
- *
- * This allows a SOC or board to override the automatic bus speed calculation
- * and provided specific values for the driver to use.
- */
-int lpss_i2c_set_speed_config(unsigned bus,
- const struct lpss_i2c_speed_config *config);
-
-/*
* Generate I2C timing information into the SSDT for the OS driver to consume,
* optionally applying override values provided by the caller.
*/
-void lpss_i2c_acpi_fill_ssdt(const struct lpss_i2c_speed_config *override);
-
-/*
- * Set I2C bus speed for this controller.
- *
- * This allows an SOC or board to set the basic I2C bus speed. Values for the
- * controller configuration registers will be calculated, for more specific
- * control the raw configuration can be provided to lpss_i2c_set_speed_config().
- */
-int lpss_i2c_set_speed(unsigned bus, enum i2c_speed speed);
+void lpss_i2c_acpi_fill_ssdt(const struct lpss_i2c_bus_config *bcfg);
/*
* Initialize this bus controller and set the speed.
@@ -108,6 +90,6 @@ int lpss_i2c_set_speed(unsigned bus, enum i2c_speed speed);
* The SOC *must* define CONFIG_SOC_INTEL_COMMON_LPSS_I2C_CLOCK for the
* bus speed calculation to be correct.
*/
-int lpss_i2c_init(unsigned bus, enum i2c_speed speed);
+int lpss_i2c_init(unsigned bus, const struct lpss_i2c_bus_config *bcfg);
#endif
diff --git a/src/soc/intel/skylake/bootblock/i2c.c b/src/soc/intel/skylake/bootblock/i2c.c
index 64b1fb57e7..92ca861dcb 100644
--- a/src/soc/intel/skylake/bootblock/i2c.c
+++ b/src/soc/intel/skylake/bootblock/i2c.c
@@ -46,8 +46,6 @@ static void i2c_early_init_bus(unsigned bus)
{
ROMSTAGE_CONST struct soc_intel_skylake_config *config;
ROMSTAGE_CONST struct device *tree_dev;
- const struct lpss_i2c_speed_config *sptr;
- enum i2c_speed speed;
pci_devfn_t dev;
int devfn;
uintptr_t base;
@@ -86,17 +84,7 @@ static void i2c_early_init_bus(unsigned bus)
write32(reg, value);
/* Initialize the controller */
- speed = config->i2c[bus].speed ? : I2C_SPEED_FAST;
- lpss_i2c_init(bus, speed);
-
- /* Apply custom speed config if it has been set by the board */
- for (value = 0; value < LPSS_I2C_SPEED_CONFIG_COUNT; value++) {
- sptr = &config->i2c[bus].speed_config[value];
- if (sptr->speed == speed) {
- lpss_i2c_set_speed_config(bus, sptr);
- break;
- }
- }
+ lpss_i2c_init(bus, &config->i2c[bus]);
}
void i2c_early_init(void)
diff --git a/src/soc/intel/skylake/chip.h b/src/soc/intel/skylake/chip.h
index a141a34916..1b699520ac 100644
--- a/src/soc/intel/skylake/chip.h
+++ b/src/soc/intel/skylake/chip.h
@@ -201,7 +201,7 @@ struct soc_intel_skylake_config {
/* I2C */
/* Bus voltage level, default is 3.3V */
enum skylake_i2c_voltage i2c_voltage[SKYLAKE_I2C_DEV_MAX];
- struct skylake_i2c_config i2c[SKYLAKE_I2C_DEV_MAX];
+ struct lpss_i2c_bus_config i2c[SKYLAKE_I2C_DEV_MAX];
/* Camera */
u8 Cio2Enable;
diff --git a/src/soc/intel/skylake/i2c.c b/src/soc/intel/skylake/i2c.c
index d37c290079..c8f02943d1 100644
--- a/src/soc/intel/skylake/i2c.c
+++ b/src/soc/intel/skylake/i2c.c
@@ -56,24 +56,12 @@ static int i2c_dev_to_bus(struct device *dev)
static void i2c_dev_init(struct device *dev)
{
struct soc_intel_skylake_config *config = dev->chip_info;
- const struct lpss_i2c_speed_config *sptr;
- enum i2c_speed speed;
- int i, bus = i2c_dev_to_bus(dev);
+ int bus = i2c_dev_to_bus(dev);
if (!config || bus < 0)
return;
- speed = config->i2c[bus].speed ? : I2C_SPEED_FAST;
- lpss_i2c_init(bus, speed);
-
- /* Apply custom speed config if it has been set by the board */
- for (i = 0; i < LPSS_I2C_SPEED_CONFIG_COUNT; i++) {
- sptr = &config->i2c[bus].speed_config[i];
- if (sptr->speed == speed) {
- lpss_i2c_set_speed_config(bus, sptr);
- break;
- }
- }
+ lpss_i2c_init(bus, &config->i2c[bus]);
}
/* Generate ACPI I2C device objects */
@@ -86,7 +74,7 @@ static void i2c_fill_ssdt(struct device *dev)
return;
acpigen_write_scope(acpi_device_path(dev));
- lpss_i2c_acpi_fill_ssdt(config->i2c[bus].speed_config);
+ lpss_i2c_acpi_fill_ssdt(&config->i2c[bus]);
acpigen_pop_len();
}