diff options
author | Angel Pons <th3fanbus@gmail.com> | 2021-01-06 01:56:14 +0100 |
---|---|---|
committer | Lean Sheng Tan <sheng.tan@9elements.com> | 2023-12-19 15:47:40 +0000 |
commit | b44923969c4794d63c0adda6a54ea5471447c497 (patch) | |
tree | 1104079b17aee5f26e4da7f796597326631c42ff /src/southbridge/intel/bd82x6x/common.c | |
parent | f733703a61d291ec300a233bed03c27d53ae6b1f (diff) |
sb/intel/bd82x6x/pch.c: Extract common functions
PCH identification functions and `pch_iobp_update` are used in multiple
stages. Move them out of `pch.c` to drop some ugly preprocessor usage.
Subsequent commits will use `pch_iobp_update` in romstage as well.
Change-Id: I8d33338a4f74fd03c8f99f8fcece99b63c28adab
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/79624
Reviewed-by: Naresh <naresh.solanki.2011@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/southbridge/intel/bd82x6x/common.c')
-rw-r--r-- | src/southbridge/intel/bd82x6x/common.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/src/southbridge/intel/bd82x6x/common.c b/src/southbridge/intel/bd82x6x/common.c new file mode 100644 index 0000000000..f4c757a060 --- /dev/null +++ b/src/southbridge/intel/bd82x6x/common.c @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define __SIMPLE_DEVICE__ + +#include <console/console.h> +#include <delay.h> +#include <device/pci.h> +#include <device/pci_def.h> +#include <device/pci_ids.h> +#include <device/pci_ops.h> +#include <stdint.h> + +#include "pch.h" + +int pch_silicon_revision(void) +{ + static int pch_revision_id = -1; + + if (pch_revision_id < 0) + pch_revision_id = pci_read_config8(PCH_LPC_DEV, PCI_REVISION_ID); + + return pch_revision_id; +} + +int pch_silicon_type(void) +{ + static int pch_type = -1; + + if (pch_type < 0) + pch_type = pci_read_config8(PCH_LPC_DEV, PCI_DEVICE_ID + 1); + + return pch_type; +} + +int pch_silicon_supported(int type, int rev) +{ + int cur_type = pch_silicon_type(); + int cur_rev = pch_silicon_revision(); + + switch (type) { + case PCH_TYPE_CPT: + /* CougarPoint minimum revision */ + if (cur_type == PCH_TYPE_CPT && cur_rev >= rev) + return 1; + /* PantherPoint any revision */ + if (cur_type == PCH_TYPE_PPT) + return 1; + break; + + case PCH_TYPE_PPT: + /* PantherPoint minimum revision */ + if (cur_type == PCH_TYPE_PPT && cur_rev >= rev) + return 1; + break; + } + + return 0; +} + +#define IOBP_RETRY 1000 +static inline int iobp_poll(void) +{ + unsigned int try = IOBP_RETRY; + u32 data; + + while (try--) { + data = RCBA32(IOBPS); + if ((data & 1) == 0) + return 1; + udelay(10); + } + + printk(BIOS_ERR, "IOBP timeout\n"); + return 0; +} + +void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue) +{ + u32 data; + + /* Set the address */ + RCBA32(IOBPIRI) = address; + + /* READ OPCODE */ + if (pch_silicon_supported(PCH_TYPE_CPT, PCH_STEP_B0)) + RCBA32(IOBPS) = IOBPS_RW_BX; + else + RCBA32(IOBPS) = IOBPS_READ_AX; + if (!iobp_poll()) + return; + + /* Read IOBP data */ + data = RCBA32(IOBPD); + if (!iobp_poll()) + return; + + /* Check for successful transaction */ + if ((RCBA32(IOBPS) & 0x6) != 0) { + printk(BIOS_ERR, "IOBP read 0x%08x failed\n", address); + return; + } + + /* Update the data */ + data &= andvalue; + data |= orvalue; + + /* WRITE OPCODE */ + if (pch_silicon_supported(PCH_TYPE_CPT, PCH_STEP_B0)) + RCBA32(IOBPS) = IOBPS_RW_BX; + else + RCBA32(IOBPS) = IOBPS_WRITE_AX; + if (!iobp_poll()) + return; + + /* Write IOBP data */ + RCBA32(IOBPD) = data; + if (!iobp_poll()) + return; +} |