diff options
author | Mate Kukri <kukri.mate@gmail.com> | 2024-04-23 18:04:38 +0100 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2024-04-24 17:42:40 +0000 |
commit | 75dd80649925a5a30486a40068b7bb287c07b167 (patch) | |
tree | b0f988cd57edecef37d2dcbcda46e3312fa2f631 /src/mainboard/dell/optiplex_9020/sch5555_ec.c | |
parent | 51e472d568339fd76222933b16b88ddafaa8177b (diff) |
mb/dell/optiplex_9020: Implement late HWM initialization
There are 4 different chassis types specified by vendor firmware, each
with a slightly different HWM configuration.
The chassis type to use is determined at runtime by reading a set of
4 PCH GPIOs: 70, 38, 17, and 1.
Additionally vendor firmware also provides an option to run the fans at
full speed. This is substituted with a coreboot nvram option in this
implementation.
This was tested to make fan control work on my OptiPlex 7020 SFF.
NOTE: This is superficially similar to the OptiPlex 9010's SCH5545
however the OptiPlex 9020's SCH5555 does not use externally
programmed EC firmware.
Change-Id: Ibdccd3fc7364e03e84ca606592928410624eed43
Signed-off-by: Mate Kukri <kukri.mate@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/81529
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/mainboard/dell/optiplex_9020/sch5555_ec.c')
-rw-r--r-- | src/mainboard/dell/optiplex_9020/sch5555_ec.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/mainboard/dell/optiplex_9020/sch5555_ec.c b/src/mainboard/dell/optiplex_9020/sch5555_ec.c new file mode 100644 index 0000000000..1df5026531 --- /dev/null +++ b/src/mainboard/dell/optiplex_9020/sch5555_ec.c @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <arch/io.h> +#include <device/pnp_ops.h> +#include <superio/smsc/sch555x/sch555x.h> +#include "sch5555_ec.h" + +uint8_t sch5555_mbox_read(uint8_t addr1, uint16_t addr2) +{ + // clear ec-to-host mailbox + uint8_t tmp = inb(SCH555x_EMI_IOBASE + 1); + outb(tmp, SCH555x_EMI_IOBASE + 1); + + // send address + outw(0 | 0x8001, SCH555x_EMI_IOBASE + 2); + outw((addr1 * 2) | 0x100, SCH555x_EMI_IOBASE + 4); + + outw(4 | 0x8002, SCH555x_EMI_IOBASE + 2); + outl(addr2 << 16, SCH555x_EMI_IOBASE + 4); + + // send message to ec + outb(1, SCH555x_EMI_IOBASE); + + // wait for ack + for (size_t retry = 0; retry < 0xfff; ++retry) + if (inb(SCH555x_EMI_IOBASE + 1) & 1) + break; + + // read result + outw(4 | 0x8000, SCH555x_EMI_IOBASE + 2); + return inb(SCH555x_EMI_IOBASE + 4); +} + +void sch5555_mbox_write(uint8_t addr1, uint16_t addr2, uint8_t val) +{ + // clear ec-to-host mailbox + uint8_t tmp = inb(SCH555x_EMI_IOBASE + 1); + outb(tmp, SCH555x_EMI_IOBASE + 1); + + // send address and value + outw(0 | 0x8001, SCH555x_EMI_IOBASE + 2); + outw((addr1 * 2) | 0x101, SCH555x_EMI_IOBASE + 4); + + outw(4 | 0x8002, SCH555x_EMI_IOBASE + 2); + outl(val | (addr2 << 16), SCH555x_EMI_IOBASE + 4); + + // send message to ec + outb(1, SCH555x_EMI_IOBASE); + + // wait for ack + for (size_t retry = 0; retry < 0xfff; ++retry) + if (inb(SCH555x_EMI_IOBASE + 1) & 1) + break; +} |