Tim Wawrzynczak has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/35074 )
Change subject: device: Allow scan_generic_bus to recurse on pseudo-devices
......................................................................
device: Allow scan_generic_bus to recurse on pseudo-devices
To handle cases of pseudo-devices containing a child device, e.g., power
resources, recurse onto them, treating them like a bus.
Change-Id: Ia8442939ef1e840c112ad4dd23e324afd99ff7d3
Signed-off-by: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
---
M src/device/root_device.c
1 file changed, 7 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/74/35074/1
diff --git a/src/device/root_device.c b/src/device/root_device.c
index f8e2907..ec24ff5 100644
--- a/src/device/root_device.c
+++ b/src/device/root_device.c
@@ -112,6 +112,13 @@
printk(BIOS_DEBUG, "%s %s\n", dev_path(child),
child->enabled ? "enabled" : "disabled");
+
+ /*
+ * To handle cases of pseudo-devices containing a child
+ * device when it's not explicitly a bus, e.g., power
+ * resources, we recurse into them.
+ */
+ scan_generic_bus(child);
}
}
--
To view, visit https://review.coreboot.org/c/coreboot/+/35074
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ia8442939ef1e840c112ad4dd23e324afd99ff7d3
Gerrit-Change-Number: 35074
Gerrit-PatchSet: 1
Gerrit-Owner: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
Gerrit-MessageType: newchange
Tim Wawrzynczak has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/35073 )
Change subject: drivers/generic: Add new driver for power resource pseudo-device
......................................................................
drivers/generic: Add new driver for power resource pseudo-device
There is some duplication of fields dealing with ACPI power resources
(see drivers/i2c/generic.c, also used by drivers/i2c/hid, as well as
drivers/spi/acpi). This CL creates a new driver for this pseudo-device.
This patch allows a new style of dealing with power resources in the
device tree:
device pci 00.0
chip drivers/generic/power_resource
register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_A1)"
device generic 0 on
chip drivers/i2c/generic
register ...
end
end
end
end
and then the power resource driver does most of the work. This should
make it easier to support other drivers requiring ACPI power resources
in the future (see the diff in the two changed here).
Change-Id: Id9d66fedd342eb5359d90d9778c515e7aa2de1d7
Signed-off-by: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
---
A src/drivers/generic/power_resource/Kconfig
A src/drivers/generic/power_resource/Makefile.inc
A src/drivers/generic/power_resource/chip.h
A src/drivers/generic/power_resource/power_resource.c
4 files changed, 128 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/73/35073/1
diff --git a/src/drivers/generic/power_resource/Kconfig b/src/drivers/generic/power_resource/Kconfig
new file mode 100644
index 0000000..447edb9
--- /dev/null
+++ b/src/drivers/generic/power_resource/Kconfig
@@ -0,0 +1,5 @@
+# TODO: once everything is moved to the new power resource structure,
+# those drivers that use it should auto-select this config option
+config DRIVERS_GENERIC_POWER_RESOURCE
+ bool
+ depends on HAVE_ACPI_TABLES
diff --git a/src/drivers/generic/power_resource/Makefile.inc b/src/drivers/generic/power_resource/Makefile.inc
new file mode 100644
index 0000000..2120ef1
--- /dev/null
+++ b/src/drivers/generic/power_resource/Makefile.inc
@@ -0,0 +1 @@
+ramstage-$(CONFIG_DRIVERS_GENERIC_POWER_RESOURCE) += power_resource.c
diff --git a/src/drivers/generic/power_resource/chip.h b/src/drivers/generic/power_resource/chip.h
new file mode 100644
index 0000000..e698296
--- /dev/null
+++ b/src/drivers/generic/power_resource/chip.h
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2019 Google LLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __GENERIC_POWER_RESOURCE_CHIP_H__
+#define __GENERIC_POWER_RESOURCE_CHIP_H__
+
+#include <device/device.h>
+#include <arch/acpi_device.h>
+
+extern struct chip_operations drivers_generic_power_resource_ops;
+
+struct drivers_generic_power_resource_config {
+ /* GPIO used to take device out of reset or to put it into reset. */
+ struct acpi_gpio reset_gpio;
+ /* Delay to be inserted after device is taken out of reset. */
+ unsigned int reset_delay_ms;
+ /* Delay to be inserted after device is put into reset. */
+ unsigned int reset_off_delay_ms;
+ /* GPIO used to enable device. */
+ struct acpi_gpio enable_gpio;
+ /* Delay to be inserted after device is enabled. */
+ unsigned int enable_delay_ms;
+ /* Delay to be inserted after device is disabled. */
+ unsigned int enable_off_delay_ms;
+ /* GPIO used to stop operation of device. */
+ struct acpi_gpio stop_gpio;
+ /* Delay to be inserted after disabling stop. */
+ unsigned int stop_delay_ms;
+ /* Delay to be inserted after enabling stop. */
+ unsigned int stop_off_delay_ms;
+ /* ACPI device name */
+ char acpi_name[5];
+};
+
+#endif /* __GENERIC_POWER_RESOURCE_CHIP_H__ */
diff --git a/src/drivers/generic/power_resource/power_resource.c b/src/drivers/generic/power_resource/power_resource.c
new file mode 100644
index 0000000..d08c1a2
--- /dev/null
+++ b/src/drivers/generic/power_resource/power_resource.c
@@ -0,0 +1,75 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2019 Google LLC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <device/device.h>
+#include <device/path.h>
+#include <console/console.h>
+#include <string.h>
+#include "chip.h"
+
+static void power_resource_fill_ssdt(struct device *dev)
+{
+ bool ret;
+ struct drivers_generic_power_resource_config *config = dev->chip_info;
+ const struct acpi_power_res_params power_res_params = {
+ &config->reset_gpio,
+ config->reset_delay_ms,
+ config->reset_off_delay_ms,
+ &config->enable_gpio,
+ config->enable_delay_ms,
+ config->enable_off_delay_ms,
+ &config->stop_gpio,
+ config->stop_delay_ms,
+ config->stop_off_delay_ms
+ };
+
+ ret = acpi_declare_scoped_power_resource(acpi_device_scope(dev),
+ acpi_device_name(dev),
+ &power_res_params);
+ if (!ret)
+ printk(BIOS_ERR, "Failed to add power resource %s\n",
+ acpi_device_name(dev));
+
+}
+
+static const char *power_resource_acpi_name(const struct device *dev)
+{
+ static unsigned int count;
+ struct drivers_generic_power_resource_config *config = dev->chip_info;
+
+ if (config->acpi_name[0] == '\0')
+ snprintf(config->acpi_name, sizeof(config->acpi_name), "PR%02X", count++);
+
+ return config->acpi_name;
+}
+
+static struct device_operations power_resource_ops = {
+ .read_resources = DEVICE_NOOP,
+ .set_resources = DEVICE_NOOP,
+ .enable_resources = DEVICE_NOOP,
+ .scan_bus = scan_generic_bus,
+ .acpi_name = power_resource_acpi_name,
+ .acpi_fill_ssdt_generator = power_resource_fill_ssdt
+};
+
+static void power_resource_enable(struct device *dev)
+{
+ dev->ops = &power_resource_ops;
+}
+
+struct chip_operations drivers_generic_power_resource_ops = {
+ CHIP_NAME("Power Resource")
+ .enable_dev = power_resource_enable
+};
--
To view, visit https://review.coreboot.org/c/coreboot/+/35073
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Id9d66fedd342eb5359d90d9778c515e7aa2de1d7
Gerrit-Change-Number: 35073
Gerrit-PatchSet: 1
Gerrit-Owner: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
Gerrit-Reviewer: Martin Roth <martinroth(a)google.com>
Gerrit-Reviewer: Patrick Georgi <pgeorgi(a)google.com>
Gerrit-Reviewer: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
Gerrit-MessageType: newchange
Nitheesh Sekar has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/32388
Change subject: TEMP: NOT FOR REVIEW: Use absolute jump address
......................................................................
TEMP: NOT FOR REVIEW: Use absolute jump address
When the qcs405 soc jumps from qc_sec to bootblock,
the pc is at 0x0 address mapped to actual SRAM address(0x8c30000).
The mapping happens in a hardware block 'boot-remapper'
only for a maximum of 128K possible.
If the bootflow continues from the 0x0 address,
bootblock references variable beyond 128K crashing the boot.
So change the PC to start execting from the absolute address
instead.
Change-Id: I004798ac73c14a431f2d561099a30295c5675abc
Signed-off-by: Nitheesh Sekar <nsekar(a)codeaurora.org>
---
M src/arch/arm64/armv8/bootblock.S
1 file changed, 4 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/88/32388/1
diff --git a/src/arch/arm64/armv8/bootblock.S b/src/arch/arm64/armv8/bootblock.S
index e5758bc..7dc8b0f 100644
--- a/src/arch/arm64/armv8/bootblock.S
+++ b/src/arch/arm64/armv8/bootblock.S
@@ -23,7 +23,9 @@
ENTRY(_start)
/* Initialize PSTATE, SCTLR and caches to clean state, set up stack. */
- bl arm64_init_cpu
+ ldr x15, =arm64_init_cpu
+ blr x15
- bl main
+ ldr x15, =main
+ blr x15
ENDPROC(_start)
--
To view, visit https://review.coreboot.org/c/coreboot/+/32388
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I004798ac73c14a431f2d561099a30295c5675abc
Gerrit-Change-Number: 32388
Gerrit-PatchSet: 1
Gerrit-Owner: Nitheesh Sekar <nsekar(a)codeaurora.org>
Gerrit-MessageType: newchange
Nitheesh Sekar has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/34931 )
Change subject: qcs405: Add 500 ms delay
......................................................................
qcs405: Add 500 ms delay
Add 500 ms delay before writing the ddr training data
to the spi flash. Actual delay has to be calculated based
on the calibrations taken during waveforms.
Change-Id: Ic956d73ad39481beadc0f3496c2f643b12694702
Signed-off-by: Nitheesh Sekar <nsekar(a)codeaurora.org>
---
M src/soc/qualcomm/common/qclib.c
1 file changed, 3 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/31/34931/1
diff --git a/src/soc/qualcomm/common/qclib.c b/src/soc/qualcomm/common/qclib.c
index ac80a76..f8be4f3 100644
--- a/src/soc/qualcomm/common/qclib.c
+++ b/src/soc/qualcomm/common/qclib.c
@@ -16,6 +16,7 @@
#include <console/cbmem_console.h>
#include <cbmem.h>
#include <boardid.h>
+#include <delay.h>
#include <string.h>
#include <fmap.h>
#include <assert.h>
@@ -82,6 +83,8 @@
} else if (!strncmp(QCLIB_TE_DDR_TRAINING_DATA, te->name,
sizeof(te->name))) {
+ mdelay(500); //Add 500 ms delay
+
assert(fmap_overwrite_area(QCLIB_FR_DDR_TRAINING_DATA,
(const void *)te->blob_address, te->size));
--
To view, visit https://review.coreboot.org/c/coreboot/+/34931
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ic956d73ad39481beadc0f3496c2f643b12694702
Gerrit-Change-Number: 34931
Gerrit-PatchSet: 1
Gerrit-Owner: Nitheesh Sekar <nsekar(a)codeaurora.org>
Gerrit-MessageType: newchange
Hello Yuji Sasaki,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/32692
to review the following change.
Change subject: drivers/i2c: Add LP5562 LED driver
......................................................................
drivers/i2c: Add LP5562 LED driver
Add LP5562 LED driver in Coreboot.
BUG=b:116352348
TEST=Apply board support for LP5562 LED driver, build coreboot.
Signed-off-by: Yuji Sasaki <sasakiy(a)chromium.org>
Change-Id: I0206dc6bfd367a258af88ab61e0928e32e9aa60f
---
A src/drivers/i2c/Kconfig
A src/drivers/i2c/Makefile.inc
A src/drivers/i2c/lp5562/Kconfig
A src/drivers/i2c/lp5562/Makefile.inc
A src/drivers/i2c/lp5562/led_lp5562.c
A src/drivers/i2c/lp5562/led_lp5562.h
A src/drivers/i2c/lp5562/led_lp5562_programs.c
A src/drivers/i2c/lp5562/led_lp5562_programs.h
8 files changed, 863 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/92/32692/1
diff --git a/src/drivers/i2c/Kconfig b/src/drivers/i2c/Kconfig
new file mode 100644
index 0000000..47b79e6
--- /dev/null
+++ b/src/drivers/i2c/Kconfig
@@ -0,0 +1,28 @@
+source src/drivers/i2c/adm1026/Kconfig
+source src/drivers/i2c/adm1027/Kconfig
+source src/drivers/i2c/adt7463/Kconfig
+source src/drivers/i2c/at24rf08c/Kconfig
+source src/drivers/i2c/ck505/Kconfig
+source src/drivers/i2c/da7219/Kconfig
+source src/drivers/i2c/designware/Kconfig
+source src/drivers/i2c/generic/Kconfig
+source src/drivers/i2c/hid/Kconfig
+source src/drivers/i2c/i2cmux/Kconfig
+source src/drivers/i2c/i2cmux2/Kconfig
+source src/drivers/i2c/lm63/Kconfig
+source src/drivers/i2c/lm96000/Kconfig
+source src/drivers/i2c/lp5562/Kconfig
+source src/drivers/i2c/max98373/Kconfig
+source src/drivers/i2c/max98927/Kconfig
+source src/drivers/i2c/nau8825/Kconfig
+source src/drivers/i2c/nct7802y/Kconfig
+source src/drivers/i2c/pca9538/Kconfig
+source src/drivers/i2c/pcf8523/Kconfig
+source src/drivers/i2c/rt5663/Kconfig
+source src/drivers/i2c/rtd2132/Kconfig
+source src/drivers/i2c/rx6110sa/Kconfig
+source src/drivers/i2c/sx9310/Kconfig
+source src/drivers/i2c/tpm/Kconfig
+source src/drivers/i2c/w83793/Kconfig
+source src/drivers/i2c/w83795/Kconfig
+source src/drivers/i2c/ww_ring/Kconfig
diff --git a/src/drivers/i2c/Makefile.inc b/src/drivers/i2c/Makefile.inc
new file mode 100644
index 0000000..7b5ae0c
--- /dev/null
+++ b/src/drivers/i2c/Makefile.inc
@@ -0,0 +1,28 @@
+subdirs-y += adm1026
+subdirs-y += adm1027
+subdirs-y += adt7463
+subdirs-y += at24rf08c
+subdirs-y += ck505
+subdirs-y += da7219
+subdirs-y += designware
+subdirs-y += generic
+subdirs-y += hid
+subdirs-y += i2cmux
+subdirs-y += i2cmux2
+subdirs-y += lm63
+subdirs-y += lm96000
+subdirs-y += lp5562
+subdirs-y += max98373
+subdirs-y += max98927
+subdirs-y += nau8825
+subdirs-y += nct7802y
+subdirs-y += pca9538
+subdirs-y += pcf8523
+subdirs-y += rt5663
+subdirs-y += rtd2132
+subdirs-y += rx6110sa
+subdirs-y += sx9310
+subdirs-y += tpm
+subdirs-y += w83793
+subdirs-y += w83795
+subdirs-y += ww_ring
diff --git a/src/drivers/i2c/lp5562/Kconfig b/src/drivers/i2c/lp5562/Kconfig
new file mode 100644
index 0000000..cd7041a
--- /dev/null
+++ b/src/drivers/i2c/lp5562/Kconfig
@@ -0,0 +1,2 @@
+config DRIVERS_I2C_LED_LP5562
+ bool
diff --git a/src/drivers/i2c/lp5562/Makefile.inc b/src/drivers/i2c/lp5562/Makefile.inc
new file mode 100644
index 0000000..bfdb408
--- /dev/null
+++ b/src/drivers/i2c/lp5562/Makefile.inc
@@ -0,0 +1,5 @@
+verstage-$(CONFIG_DRIVERS_I2C_LED_LP5562) += led_lp5562.c
+verstage-$(CONFIG_DRIVERS_I2C_LED_LP5562) += led_lp5562_programs.c
+
+ramstage-$(CONFIG_DRIVERS_I2C_LED_LP5562) += led_lp5562.c
+ramstage-$(CONFIG_DRIVERS_I2C_LED_LP5562) += led_lp5562_programs.c
diff --git a/src/drivers/i2c/lp5562/led_lp5562.c b/src/drivers/i2c/lp5562/led_lp5562.c
new file mode 100644
index 0000000..6eafee3
--- /dev/null
+++ b/src/drivers/i2c/lp5562/led_lp5562.c
@@ -0,0 +1,430 @@
+/*
+ * Copyright (C) 2019 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * This is a driver for the TI LP5562 (http://www.ti.com/product/lp5562),
+ * driving a tri-color LED.
+ *
+ * The only connection between the LED and the main board is an i2c bus.
+ *
+ * This driver imitates a depthcharge display device. On initialization the
+ * driver sets up the controllers to prepare them to accept programs to run.
+ *
+ * When a certain vboot state needs to be indicated, the program for that
+ * state is loaded into the controllers, resulting in the state appropriate
+ * LED behavior.
+ */
+
+#include <console/console.h>
+#include <delay.h>
+#include <device/i2c_simple.h>
+#include <string.h>
+
+#include "drivers/i2c/lp5562/led_lp5562_programs.h"
+
+/* Key lp5562 registers. */
+#define LP5562_ENABLE_REG 0x00
+#define LP5562_OPMODE_REG 0x01
+#define LP5562_PWMREG_B 0x02
+#define LP5562_PWMREG_G 0x03
+#define LP5562_PWMREG_R 0x04
+#define LP5562_CURRENT_B 0x05
+#define LP5562_CURRENT_G 0x06
+#define LP5562_CURRENT_R 0x07
+#define LP5562_CONFIG_REG 0x08
+#define LP5562_ENGINE1_PC 0x09
+#define LP5562_ENGINE2_PC 0x0a
+#define LP5562_ENGINE3_PC 0x0b
+#define LP5562_STATUS_REG 0x0c
+#define LP5562_RESET_REG 0x0d
+#define LP5562_PWMREG_W 0x0e
+#define LP5562_CURRENT_W 0x0f
+#define LP5562_LED_MAP_REG 0x70
+#define LP5562_PROG_MEM_ENG1 0x10
+#define LP5562_PROG_MEM_ENG2 0x30
+#define LP5562_PROG_MEM_ENG3 0x50
+
+/* LP5562 ENABLE REG fields. */
+#define LP5562_ENABLE_LOG_EN 0x80
+#define LP5562_ENABLE_CHIP_EN 0x40
+#define LP5562_ENABLE_EXEC_HOLD 0x00
+#define LP5562_ENABLE_EXEC_STEP 0x01
+#define LP5562_ENABLE_EXEC_RUN 0x02
+#define LP5562_ENABLE_EXEC_MASK 0x03
+#define LP5562_ENABLE_ENG1_SHIFT 4
+#define LP5562_ENABLE_ENG2_SHIFT 2
+#define LP5562_ENABLE_ENG3_SHIFT 0
+#define LP5562_ENABLE_ALL_MASK 0x3f
+#define LP5562_ENABLE_ALL_HOLD 0x00
+#define LP5562_ENABLE_ALL_RUN 0x2a
+
+/* LP5562 OPMODE REG fields. */
+#define LP5562_OPMODE_DISABLED 0x00
+#define LP5562_OPMODE_LOAD 0x01
+#define LP5562_OPMODE_RUN 0x02
+#define LP5562_OPMODE_DIRECT 0x03
+#define LP5562_OPMODE_MASK 0x03
+#define LP5562_OPMODE_ENG1_SHIFT 4
+#define LP5562_OPMODE_ENG2_SHIFT 2
+#define LP5562_OPMODE_ENG3_SHIFT 0
+#define LP5562_OPMODE_ALL_DISABLE 0x00
+#define LP5562_OPMODE_ALL_LOAD 0x15
+#define LP5562_OPMODE_ALL_RUN 0x2a
+
+/*
+ * LP5562_ENABLE_REG, default value
+ */
+#define LP5562_ENABLE_REG_DEFAULT (LP5562_ENABLE_CHIP_EN)
+
+/*
+ * LP5562_CONFIG_REG, default value
+ * PWM_HF=0(256Hz)
+ * PWRSAVE_EN=0 (Disable)
+ * CLKDET_EN/INT_CLK_EN=1 (Internal Clock)
+ */
+#define LP5562_CONFIG_REG_DEFAULT 0x03
+
+/*
+ * LP5562_LED_MAP_REG, default value
+ * B:ENG1, G:ENG2, R:ENG3
+ */
+#define LP5562_LED_MAP_REG_DEFAULT 0x39
+
+/* LP5562 Current default value, applies to all four of them */
+#define LP5562_CRT_CTRL_DEFAULT 0xaf
+
+/* Goes into LP5562_RESET_REG to reset the chip. */
+#define LP5562_RESET_VALUE 0xff
+
+/*
+ * The controller has 96 bytes of SRAM for code/data, availabe as three 32 byte
+ * pages.
+ */
+#define LP5562_PROG_PAGE_SIZE 32
+#define LP5562_PROG_PAGES 3
+#define LP5562_MAX_PROG_SIZE LP5562_PROG_PAGE_SIZE
+
+/*
+ * Structure to cache data relevant to accessing one controller. I2c interface
+ * to use, device address on the i2c bus and a data buffer for write
+ * transactions. The most bytes sent at a time is the register address plus
+ * the program page size.
+ */
+typedef struct {
+ unsigned i2c_bus;
+ uint8_t dev_addr;
+ uint8_t data_buffer[LP5562_PROG_PAGE_SIZE + 1];
+} TiLp5562;
+
+static void led_lp5562_init(unsigned i2c_bus);
+
+/* Controller descriptors. */
+static TiLp5562 lp5562s[LED_LP5562_NUM_LED_CONTROLLERS];
+
+/*
+ * i2c transfer function for the driver. To keep things simple, the function
+ * repeats the transfer, if the first attempt fails. This is OK with the
+ * controller and makes it easier to handle errors.
+ *
+ * Note that the reset register accesses are expected to fail on writes, but
+ * due to a bug in the ipq806x i2c controller, the error is reported on the
+ * following read attempt.
+ *
+ * To work around this the driver writes and then reads the reset register,
+ * the transfer function ignores errors when accessing the reset register.
+ */
+static int ledc_transfer(TiLp5562 *ledc, struct i2c_msg *segs,
+ int seg_count, int reset)
+{
+ int rv, max_attempts = 2;
+
+ while (max_attempts--) {
+ rv = i2c_transfer(ledc->i2c_bus, segs, seg_count);
+
+ /* Accessing reset regsiter is expected to fail. */
+ if (!rv || reset)
+ break;
+ }
+
+ if (rv) {
+ if (!reset)
+ printk(BIOS_WARNING,
+ "%s: dev %#x, reg %#x, %s transaction error.\n",
+ __func__, segs->slave, segs->buf[0],
+ seg_count == 1 ? "write" : "read");
+ else
+ rv = 0;
+ }
+
+ return rv;
+}
+
+/*
+ * The controller is programmed to autoincrement on writes, so up to page size
+ * bytes can be transmitted in one write transaction.
+ */
+static int ledc_write(TiLp5562 *ledc, uint8_t start_addr,
+ const uint8_t *data, unsigned count)
+{
+ struct i2c_msg seg;
+
+ if (count > (sizeof(ledc->data_buffer) - 1)) {
+ printk(BIOS_WARNING, "%s: transfer size too large (%d bytes)\n",
+ __func__, count);
+ return -1;
+ }
+
+ memcpy(ledc->data_buffer + 1, data, count);
+ ledc->data_buffer[0] = start_addr;
+
+ seg.flags = 0;
+ seg.slave = ledc->dev_addr;
+ seg.buf = ledc->data_buffer;
+ seg.len = count + 1;
+
+ return ledc_transfer(ledc, &seg, 1, start_addr == LP5562_RESET_REG);
+}
+
+/* To keep things simple, read is limited to one byte at a time. */
+static int ledc_read(TiLp5562 *ledc, uint8_t addr, uint8_t *data)
+{
+ struct i2c_msg seg[2];
+
+ seg[0].flags = 0;
+ seg[0].slave = ledc->dev_addr;
+ seg[0].buf = &addr;
+ seg[0].len = 1;
+
+ seg[1].flags = I2C_M_RD;
+ seg[1].slave = ledc->dev_addr;
+ seg[1].buf = data;
+ seg[1].len = 1;
+
+ return ledc_transfer(ledc, seg, ARRAY_SIZE(seg),
+ addr == LP5562_RESET_REG);
+}
+
+/*
+ * Reset transaction is expected to result in a failing i2c command. But even
+ * before trying it, read the reset register, which is supposed to always
+ * return 0. If this fails - there is no lp5562 at this address.
+ *
+ * Return 0 on success, -1 on failure to detect controller.
+ */
+static int ledc_reset(TiLp5562 *ledc)
+{
+ uint8_t data;
+
+ data = ~0;
+ ledc_read(ledc, LP5562_RESET_REG, &data);
+ if (data) {
+ printk(BIOS_WARNING,
+ "LED_LP5562: no controller found at address %#2.2x\n",
+ ledc->dev_addr);
+ return -1;
+ }
+
+ data = LP5562_RESET_VALUE;
+ ledc_write(ledc, LP5562_RESET_REG, &data, 1);
+
+ /*
+ * This read is not necessary for the chip reset, but is required to
+ * work around the i2c driver bug where the missing ACK on the last
+ * byte of the write transaction is ignored, but the next transaction
+ * fails.
+ */
+ ledc_read(ledc, LP5562_RESET_REG, &data);
+ return 0;
+}
+
+/*
+ * Write a program into the internal lp5562 memory.
+ */
+static void ledc_write_program(TiLp5562 *ledc, uint8_t load_addr,
+ const uint8_t *program, unsigned count)
+{
+ if (count > LP5562_MAX_PROG_SIZE) {
+ printk(BIOS_WARNING,
+ "%s: program of size %#x does not fit at addr %#x\n",
+ __func__, count, load_addr);
+ return;
+ }
+ ledc_write(ledc, load_addr, program, count);
+}
+
+static void ledc_write_enable(TiLp5562 *ledc, uint8_t value)
+{
+ ledc_write(ledc, LP5562_ENABLE_REG, &value, 1);
+ udelay(500); /* Must wait longer than 488usec */
+}
+
+static void ledc_write_opmode(TiLp5562 *ledc, uint8_t value)
+{
+ ledc_write(ledc, LP5562_OPMODE_REG, &value, 1);
+ udelay(160); /* Must wait longer than 153usec */
+}
+
+/* Run an lp5562 program on a controller. */
+static void ledc_run_program(TiLp5562 *ledc,
+ const TiLp5562Program *program_desc)
+{
+ int i;
+ uint8_t data;
+ uint8_t enable_reg;
+ uint8_t load_addr;
+
+ /* All engines on hold. */
+ ledc_read(ledc, LP5562_ENABLE_REG, &enable_reg);
+ enable_reg &= ~LP5562_ENABLE_ALL_MASK;
+ enable_reg |= LP5562_ENABLE_CHIP_EN;
+ enable_reg |= LP5562_ENABLE_ALL_HOLD;
+ ledc_write_enable(ledc, enable_reg);
+
+ /* All engines in LOAD mode. */
+ ledc_write_opmode(ledc, LP5562_OPMODE_ALL_LOAD);
+
+ /* Inject program code for each engine and start address */
+ load_addr = LP5562_PROG_MEM_ENG1;
+ for (i = 0; i < LED_LP5562_NUM_OF_ENGINES; i++) {
+ ledc_write_program(ledc, load_addr,
+ program_desc->engine_program[i].program_text,
+ program_desc->engine_program[i].program_size);
+ data = program_desc->engine_program[i].engine_start_addr;
+ ledc_write(ledc, LP5562_ENGINE1_PC + i, &data, 1);
+ udelay(160); /* Must wait longer than 153usec */
+ load_addr += LP5562_PROG_PAGE_SIZE;
+ }
+
+ /* All engines on run. */
+ ledc_write_opmode(ledc, LP5562_OPMODE_ALL_RUN);
+
+ enable_reg &= ~LP5562_ENABLE_ALL_MASK;
+ enable_reg |= LP5562_ENABLE_ALL_RUN;
+ ledc_write_enable(ledc, enable_reg);
+}
+
+/*
+ * Initialize a controller to a state were it is ready to accept programs, and
+ * try to confirm that we are in fact talking to a lp5562
+ */
+static int ledc_init_validate(TiLp5562 *ledc)
+{
+ uint8_t data;
+ int i;
+
+ if (ledc_reset(ledc))
+ return -1;
+
+ /* Enable the chip, keep engines in hold state. */
+ ledc_write_enable(ledc, LP5562_ENABLE_REG_DEFAULT | LP5562_ENABLE_ALL_HOLD);
+
+ data = LP5562_CONFIG_REG_DEFAULT;
+ ledc_write(ledc, LP5562_CONFIG_REG, &data, 1);
+
+ data = LP5562_LED_MAP_REG_DEFAULT;
+ ledc_write(ledc, LP5562_LED_MAP_REG, &data, 1);
+
+ /*
+ * All four current control registers are supposed to return the same
+ * value at reset.
+ */
+ for (i = 0; i < 4; i++) {
+ uint8_t reg = (i < 3) ? LP5562_CURRENT_B + i : LP5562_CURRENT_W;
+ ledc_read(ledc, reg, &data);
+ if (data != LP5562_CRT_CTRL_DEFAULT) {
+ printk(BIOS_WARNING,
+ "%s: read %#2.2x from register %#x\n", __func__,
+ data, reg);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Find a program matching screen type, and run it on both controllers, if
+ * found.
+ */
+int led_lp5562_display_pattern(unsigned i2c_bus, enum display_pattern pattern)
+{
+ static int initted;
+ const Led5562StateProg *led_prog;
+
+ if (!initted) {
+ led_lp5562_init(i2c_bus);
+ initted = 1;
+ }
+
+ /* Last entry does not have any actual programs defined. */
+ for (led_prog = led_lp5562_state_programs; led_prog->programs[0]; led_prog++)
+ if (led_prog->led_pattern == pattern) {
+ int j;
+
+ /*
+ * First stop all running programs to avoid
+ * inerference between the controllers.
+ */
+ for (j = 0; j < LED_LP5562_NUM_LED_CONTROLLERS; j++) {
+ if (!lp5562s[j].dev_addr)
+ continue;
+ ledc_write_opmode
+ (lp5562s + j,
+ LP5562_OPMODE_ALL_DISABLE);
+ }
+
+ for (j = 0; j < LED_LP5562_NUM_LED_CONTROLLERS; j++) {
+ if (!lp5562s[j].dev_addr)
+ continue;
+ ledc_run_program(lp5562s + j,
+ led_prog->programs[j]);
+ }
+ return 0;
+ }
+
+ printk(BIOS_WARNING, "%s: did not find program for pattern %d\n",
+ __func__, pattern);
+
+ return -1;
+}
+
+#define LP5562_I2C_BASE_ADDR 0x30
+
+static void led_lp5562_init(unsigned i2c_bus)
+{
+ TiLp5562 *ledc;
+ int i, count = 0;
+
+ for (i = 0, ledc = lp5562s;
+ i < LED_LP5562_NUM_LED_CONTROLLERS;
+ i++, ledc++) {
+
+ ledc->i2c_bus = i2c_bus;
+ ledc->dev_addr = LP5562_I2C_BASE_ADDR + i;
+
+ if (!ledc_init_validate(ledc))
+ count++;
+ else
+ ledc->dev_addr = 0; /* Mark disabled. */
+ }
+
+ printk(BIOS_INFO, "LED_LP5562: initialized %d out of %d\n", count, i);
+ if (count != i) {
+ if (count)
+ printk(BIOS_WARNING,
+ "LED_LP5562: will keep going anyway\n");
+ else
+ printk(BIOS_WARNING,
+ "LED_LP5562: LED ring not present\n");
+ }
+}
diff --git a/src/drivers/i2c/lp5562/led_lp5562.h b/src/drivers/i2c/lp5562/led_lp5562.h
new file mode 100644
index 0000000..3c202eb
--- /dev/null
+++ b/src/drivers/i2c/lp5562/led_lp5562.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2019 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __SRC_DRIVERS_VIDEO_LED_LP5562__H__
+#define __SRC_DRIVERS_VIDEO_LED_LP5562__H__
+
+/*
+ * Different types of display patterns to be shown by the LED while
+ * contrlled by coreboot.
+ */
+enum display_pattern {
+ LED_ALL_OFF, /* Turn the LEDs off. */
+ LED_RECOVERY_PUSHED, /* Recovery button push detected on start up. */
+ LED_WIPEOUT_REQUEST, /* Held long enough for wipout request. */
+ LED_RECOVERY_REQUEST, /* Held long enough for recovery request. */
+ LED_NORMAL_BOOT /* No buttons pressed, normal boot sequence. */
+};
+/*
+ * led_lp5562_display_pattern
+ *
+ * Display pattern on the ring LEDs.
+ */
+int led_lp5562_display_pattern(unsigned i2c_bus, enum display_pattern pattern);
+
+#endif
diff --git a/src/drivers/i2c/lp5562/led_lp5562_programs.c b/src/drivers/i2c/lp5562/led_lp5562_programs.c
new file mode 100644
index 0000000..f322f6a
--- /dev/null
+++ b/src/drivers/i2c/lp5562/led_lp5562_programs.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2019 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * This is a driver for the TI LP5562 (http://www.ti.com/product/lp5562),
+ * driving a tri-color LED.
+ *
+ * The only connection between the LED and the main board is an i2c bus.
+ *
+ * This driver imitates a depthcharge display device. On initialization the
+ * driver sets up the controllers to prepare them to accept programs to run.
+ *
+ * When a certain vboot state needs to be indicated, the program for that
+ * state is loaded into the controllers, resulting in the state appropriate
+ * LED behavior.
+ */
+
+#include "drivers/i2c/lp5562/led_lp5562_programs.h"
+
+/****************************************************************
+ * LED ring program definitions for different patterns.
+ *
+ * Comments below are real lp5562 source code, they are compiled using
+ * lasm.exe, the TI tool available from their Web site (search for lp5562)
+ * and running only on Windows :P.
+ *
+ * Different hex dumps are results of tweaking the source code parameters to
+ * achieve desirable LED ring behavior. It is possible to use just one code
+ * dump and replace certain values in the body to achieve different behaviour
+ * with the same basic dump, but keeping track of location to tweak with every
+ * code change would be quite tedious.
+ */
+
+/*
+ * Solid LED display, the arguments of the set_pwm commands set intensity and
+ * color of the display:
+
+ 1 00 .ENGINE1(R)
+ 2 00 4080 set_pwm 128
+ 3 01 C000 end
+ 4
+ 5 10 .ENGINE2(G)
+ 6 10 4080 set_pwm 128
+ 7 11 C000 end
+ 8
+ 9 20 .ENGINE3(B)
+ 10 20 4080 set_pwm 128
+ 11 21 C000 end
+*/
+
+/* RGB set to 000000, resulting in all LEDs off. */
+static const uint8_t solid_00_text[] = {
+ 0x40, 0x00, 0xc0, 0x00
+};
+
+/* Rgb set to 128, resulting in a brightish white color. */
+static const uint8_t solid_80_text[] = {
+ 0x40, 0x80, 0xc0, 0x00
+};
+
+static const TiLp5562Program solid_000000_program = {
+ {
+ { /* Engine1:Blue */
+ solid_00_text,
+ sizeof(solid_00_text),
+ 0,
+ },
+ { /* Engine2:Green */
+ solid_00_text,
+ sizeof(solid_00_text),
+ 0,
+ },
+ { /* Engine3:Red */
+ solid_00_text,
+ sizeof(solid_00_text),
+ 0,
+ },
+ }
+};
+
+static const TiLp5562Program solid_808080_program = {
+ {
+ { /* Engine1:Blue */
+ solid_80_text,
+ sizeof(solid_80_text),
+ 0,
+ },
+ { /* Engine2:Green */
+ solid_80_text,
+ sizeof(solid_80_text),
+ 0,
+ },
+ { /* Engine3:Red */
+ solid_80_text,
+ sizeof(solid_80_text),
+ 0,
+ },
+ }
+};
+
+/*
+ 1 00 .ENGINE1(B)
+ 2 00 E200 trigger w3
+ 3 01 409B set_pwm 155
+ 4 02 E200 trigger w3
+ 5 03 4000 set_pwm 0
+ 6 04 0000 gotostart
+ 7
+ 8 10 .ENGINE2(G)
+ 9 10 E200 trigger w3
+ 10 11 4032 set_pwm 50
+ 11 12 E200 trigger w3
+ 12 13 4000 set_pwm 0
+ 13 14 0000 gotostart
+ 14
+ 15 20 .ENGINE3(R)
+ 16 20 E006 trigger s21
+ 17 21 4001 set_pwm 1
+ 18 22 5300 wait 300
+ 19 23 E006 trigger s21
+ 20 24 4000 set_pwm 0
+ 21 25 5300 wait 300
+ 22 26 0000 gotostart
+*/
+
+static const uint8_t blink_wipeout1_b_text[] = {
+ 0xe2, 0x00, 0x40, 155, 0xe2, 0x00, 0x40, 0,
+ 0x00, 0x00,
+};
+
+static const uint8_t blink_wipeout1_g_text[] = {
+ 0xe2, 0x00, 0x40, 50, 0xe2, 0x00, 0x40, 0,
+ 0x00, 0x00,
+};
+
+static const uint8_t blink_wipeout1_r_text[] = {
+ 0xe0, 0x06, 0x40, 1, 0x53, 0x00, 0xe0, 0x06,
+ 0x40, 0, 0x53, 0x00, 0x00, 0x00
+};
+
+static const TiLp5562Program blink_wipeout1_program = {
+ {
+ {
+ blink_wipeout1_b_text,
+ sizeof(blink_wipeout1_b_text),
+ 0,
+ },
+ {
+ blink_wipeout1_g_text,
+ sizeof(blink_wipeout1_g_text),
+ 0,
+ },
+ {
+ blink_wipeout1_r_text,
+ sizeof(blink_wipeout1_r_text),
+ 0,
+ },
+ }
+};
+
+static const uint8_t blink_recovery1_b_text[] = {
+ 0xe2, 0x00, 0x40, 10, 0xe2, 0x00, 0x40, 0,
+ 0x00, 0x00,
+};
+
+static const uint8_t blink_recovery1_g_text[] = {
+ 0xe2, 0x00, 0x40, 100, 0xe2, 0x00, 0x40, 0,
+ 0x00, 0x00,
+};
+
+static const uint8_t blink_recovery1_r_text[] = {
+ 0xe0, 0x06, 0x40, 255, 0x53, 0x00, 0xe0, 0x06,
+ 0x40, 0, 0x53, 0x00, 0x00, 0x00
+};
+
+static const TiLp5562Program blink_recovery1_program = {
+ {
+ {
+ blink_recovery1_b_text,
+ sizeof(blink_wipeout1_b_text),
+ 0,
+ },
+ {
+ blink_recovery1_g_text,
+ sizeof(blink_wipeout1_g_text),
+ 0,
+ },
+ {
+ blink_recovery1_r_text,
+ sizeof(blink_wipeout1_r_text),
+ 0,
+ },
+ }
+};
+
+/*
+ * fade_in1.src
+ *
+ 1 00 .ENGINE1(B)
+ 2 00 4000 set_pwm 0
+ 3 01 E200 trigger w3
+ 4 02 1B4C ramp 1000, 77 # ramp up to 155 for 2 seconds
+ 5 03 1A4D ramp 1000, 78
+ 6 04 C000 end
+ 7
+ 8 10 .ENGINE2(G)
+ 9 10 4000 set_pwm 0
+ 10 11 E200 trigger w3
+ 11 12 4318 ramp 1000, 25 # ramp up to 50 for 2 seconds
+ 12 13 4318 ramp 1000, 25
+ 13 14 C000 end
+ 14
+ 15 20 .ENGINE3(R)
+ 16 20 E006 trigger s21
+ 17 21 4001 set_pwm 1
+ 18 22 E006 trigger s21
+ 19 23 C000 end
+*/
+
+static const uint8_t fade_in1_b_text[] = {
+ 0x40, 0, 0xe2, 0x00, 0x1b, 0x4c, 0x1a, 0x4d,
+ 0xc0, 0x00
+};
+static const uint8_t fade_in1_g_text[] = {
+ 0x40, 0, 0xe2, 0x00, 0x43, 0x18, 0x43, 0x18,
+ 0xc0, 0x00
+};
+static const uint8_t fade_in1_r_text[] = {
+ 0xe0, 0x06, 0x40, 1, 0xe0, 0x06, 0x00
+};
+
+static const TiLp5562Program fade_in1_program = {
+ {
+ {
+ fade_in1_b_text,
+ sizeof(fade_in1_b_text),
+ 0,
+ },
+ {
+ fade_in1_g_text,
+ sizeof(fade_in1_g_text),
+ 0,
+ },
+ {
+ fade_in1_r_text,
+ sizeof(fade_in1_r_text),
+ 0,
+ },
+ }
+};
+
+const Led5562StateProg led_lp5562_state_programs[] = {
+ /*
+ * for test purposes the blank screen program is set to blinking, will
+ * be changed soon.
+ */
+ {LED_ALL_OFF, {&solid_000000_program} },
+ {LED_RECOVERY_PUSHED, {&solid_808080_program} },
+ {LED_WIPEOUT_REQUEST, {&blink_wipeout1_program} },
+ {LED_RECOVERY_REQUEST, {&blink_recovery1_program} },
+ {LED_NORMAL_BOOT, {&fade_in1_program} },
+ {}, /* Empty record to mark the end of the table. */
+};
diff --git a/src/drivers/i2c/lp5562/led_lp5562_programs.h b/src/drivers/i2c/lp5562/led_lp5562_programs.h
new file mode 100644
index 0000000..e5373c0
--- /dev/null
+++ b/src/drivers/i2c/lp5562/led_lp5562_programs.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2019 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/*
+ * This is a driver for the TI LP5562 (http://www.ti.com/product/lp5562),
+ * driving a tri-color LED.
+ *
+ * The only connection between the LED and the main board is an i2c bus.
+ *
+ * This driver imitates a depthcharge display device. On initialization the
+ * driver sets up the controllers to prepare them to accept programs to run.
+ *
+ * When a certain vboot state needs to be indicated, the program for that
+ * state is loaded into the controllers, resulting in the state appropriate
+ * LED behavior.
+ */
+
+#ifndef __THIRD_PARTY_COREBOOT_SRC_DRIVERS_I2C_LED_LP5562_LED_LP5562_PROGRAMS_H__
+#define __THIRD_PARTY_COREBOOT_SRC_DRIVERS_I2C_LED_LP5562_LED_LP5562_PROGRAMS_H__
+
+#include <stdint.h>
+#include "drivers/i2c/lp5562/led_lp5562.h"
+
+/* There are threee independent engines/cores in the controller. */
+#define LED_LP5562_NUM_OF_ENGINES 3
+
+/* Number of LP5562 controllers on this implementation */
+#define LED_LP5562_NUM_LED_CONTROLLERS 1
+
+/*
+ * Structure to describe an lp5562 program: pointer to the text of the
+ * program, its size for each engines, and start address relative to
+ * each engine program memory. Program memory address for each engine is
+ * fixed on LP5562.
+ */
+typedef struct {
+ struct {
+ const uint8_t *program_text;
+ uint8_t program_size;
+ uint8_t engine_start_addr;
+ } engine_program[LED_LP5562_NUM_OF_ENGINES];
+} TiLp5562Program;
+
+/* A structure to bind controller programs to a vboot state. */
+typedef struct {
+ enum display_pattern led_pattern;
+ const TiLp5562Program *programs[LED_LP5562_NUM_LED_CONTROLLERS];
+} Led5562StateProg;
+
+extern const Led5562StateProg led_lp5562_state_programs[];
+
+#endif
--
To view, visit https://review.coreboot.org/c/coreboot/+/32692
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I0206dc6bfd367a258af88ab61e0928e32e9aa60f
Gerrit-Change-Number: 32692
Gerrit-PatchSet: 1
Gerrit-Owner: SANTHOSH JANARDHANA HASSAN <sahassan(a)google.com>
Gerrit-Reviewer: Yuji Sasaki <sasakiy(a)chromium.org>
Gerrit-MessageType: newchange
SANTHOSH JANARDHANA HASSAN has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/31426
Change subject: google/mistrtal: Add board ID API.
......................................................................
google/mistrtal: Add board ID API.
BUG=None
TEST=Verified GPIO assignment and board ID values.
BRANCH=None
Change-Id: Ic81b41f799c7bfc47a0daee705db1c01cd0af1a3
Signed-off-by: Santhosh Hassan <sahassan(a)google.com>
---
M src/mainboard/google/mistral/Makefile.inc
A src/mainboard/google/mistral/boardid.c
2 files changed, 49 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/26/31426/1
diff --git a/src/mainboard/google/mistral/Makefile.inc b/src/mainboard/google/mistral/Makefile.inc
index e9013af..ae418f2 100644
--- a/src/mainboard/google/mistral/Makefile.inc
+++ b/src/mainboard/google/mistral/Makefile.inc
@@ -3,6 +3,7 @@
bootblock-y += chromeos.c
bootblock-y += bootblock.c
+verstage-y += boardid.c
verstage-y += memlayout.ld
verstage-y += chromeos.c
verstage-y += verstage.c
@@ -10,7 +11,9 @@
romstage-y += memlayout.ld
romstage-y += chromeos.c
romstage-y += romstage.c
+romstage-y += boardid.c
+ramstage-y += boardid.c
ramstage-y += memlayout.ld
ramstage-y += chromeos.c
ramstage-y += mainboard.c
diff --git a/src/mainboard/google/mistral/boardid.c b/src/mainboard/google/mistral/boardid.c
new file mode 100644
index 0000000..f20960c
--- /dev/null
+++ b/src/mainboard/google/mistral/boardid.c
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2018 Google LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <boardid.h>
+#include <gpio.h>
+#include <console/console.h>
+#include <stdlib.h>
+
+/*
+ * Mistral boards dedicate to the board ID three GPIOs in ternary mode: 105, 106
+ * and 107.
+ */
+
+static uint32_t board_id_val = UNDEFINED_STRAPPING_ID;
+
+static uint32_t get_board_id(void)
+{
+ uint32_t bid;
+ const gpio_t pins[] = {[2] = GPIO(107), [1] = GPIO(106), [0] = GPIO(105)};
+
+ bid = gpio_binary_first_base3_value(pins, ARRAY_SIZE(pins));
+ printk(BIOS_INFO, "Board ID %d\n", bid);
+
+ return bid;
+}
+
+uint32_t board_id(void)
+{
+ if (board_id_val == UNDEFINED_STRAPPING_ID)
+ board_id_val = get_board_id();
+
+ return board_id_val;
+}
+
--
To view, visit https://review.coreboot.org/c/coreboot/+/31426
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ic81b41f799c7bfc47a0daee705db1c01cd0af1a3
Gerrit-Change-Number: 31426
Gerrit-PatchSet: 1
Gerrit-Owner: SANTHOSH JANARDHANA HASSAN <sahassan(a)google.com>
Gerrit-MessageType: newchange