Angel Pons | 182dbde | 2020-04-02 23:49:05 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 2 | |
| 3 | #include <types.h> |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 4 | #include <arch/io.h> |
Kyösti Mälkki | f1b58b7 | 2019-03-01 13:43:02 +0200 | [diff] [blame] | 5 | #include <device/pci_ops.h> |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 6 | #include <console/console.h> |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 7 | #include <device/pci_def.h> |
Kyösti Mälkki | e31ec29 | 2019-08-10 17:27:01 +0300 | [diff] [blame] | 8 | #include <cpu/intel/em64t101_save_state.h> |
Arthur Heymans | 04326aa | 2019-05-28 10:00:05 +0200 | [diff] [blame] | 9 | #include <cpu/intel/model_2065x/model_2065x.h> |
| 10 | #include <southbridge/intel/common/finalize.h> |
Patrick Rudolph | 63952e1 | 2018-06-28 14:29:49 +0200 | [diff] [blame] | 11 | #include <southbridge/intel/common/pmbase.h> |
Arthur Heymans | 04326aa | 2019-05-28 10:00:05 +0200 | [diff] [blame] | 12 | #include <southbridge/intel/ibexpeak/me.h> |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 13 | #include "pch.h" |
| 14 | |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 15 | /* We are using PCIe accesses for now |
| 16 | * 1. the chipset can do it |
| 17 | * 2. we don't need to worry about how we leave 0xcf8/0xcfc behind |
| 18 | */ |
Angel Pons | 95de231 | 2020-02-17 13:08:53 +0100 | [diff] [blame] | 19 | #include <northbridge/intel/ironlake/ironlake.h> |
Patrick Rudolph | 1010468 | 2016-02-06 18:12:28 +0100 | [diff] [blame] | 20 | #include <southbridge/intel/common/gpio.h> |
Arthur Heymans | 548f33a | 2018-05-15 16:34:50 +0200 | [diff] [blame] | 21 | #include <southbridge/intel/common/pmutil.h> |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 22 | |
Vladimir Serbinenko | 6a7aeb3 | 2014-01-05 11:37:32 +0100 | [diff] [blame] | 23 | static void southbridge_gate_memory_reset_real(int offset, |
| 24 | u16 use, u16 io, u16 lvl) |
| 25 | { |
| 26 | u32 reg32; |
| 27 | |
| 28 | /* Make sure it is set as GPIO */ |
| 29 | reg32 = inl(use); |
| 30 | if (!(reg32 & (1 << offset))) { |
| 31 | reg32 |= (1 << offset); |
| 32 | outl(reg32, use); |
| 33 | } |
| 34 | |
| 35 | /* Make sure it is set as output */ |
| 36 | reg32 = inl(io); |
| 37 | if (reg32 & (1 << offset)) { |
| 38 | reg32 &= ~(1 << offset); |
| 39 | outl(reg32, io); |
| 40 | } |
| 41 | |
| 42 | /* Drive the output low */ |
| 43 | reg32 = inl(lvl); |
| 44 | reg32 &= ~(1 << offset); |
| 45 | outl(reg32, lvl); |
| 46 | } |
| 47 | |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 48 | /* |
| 49 | * Drive GPIO 60 low to gate memory reset in S3. |
| 50 | * |
| 51 | * Intel reference designs all use GPIO 60 but it is |
| 52 | * not a requirement and boards could use a different pin. |
| 53 | */ |
Arthur Heymans | 548f33a | 2018-05-15 16:34:50 +0200 | [diff] [blame] | 54 | void southbridge_gate_memory_reset(void) |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 55 | { |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 56 | u16 gpiobase; |
| 57 | |
| 58 | gpiobase = pci_read_config16(PCI_DEV(0, 0x1f, 0), GPIOBASE) & 0xfffc; |
| 59 | if (!gpiobase) |
| 60 | return; |
| 61 | |
Vladimir Serbinenko | 6a7aeb3 | 2014-01-05 11:37:32 +0100 | [diff] [blame] | 62 | if (CONFIG_DRAM_RESET_GATE_GPIO >= 32) |
| 63 | southbridge_gate_memory_reset_real(CONFIG_DRAM_RESET_GATE_GPIO - 32, |
| 64 | gpiobase + GPIO_USE_SEL2, |
| 65 | gpiobase + GP_IO_SEL2, |
| 66 | gpiobase + GP_LVL2); |
| 67 | else |
| 68 | southbridge_gate_memory_reset_real(CONFIG_DRAM_RESET_GATE_GPIO, |
| 69 | gpiobase + GPIO_USE_SEL, |
| 70 | gpiobase + GP_IO_SEL, |
| 71 | gpiobase + GP_LVL); |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 72 | } |
| 73 | |
Arthur Heymans | 548f33a | 2018-05-15 16:34:50 +0200 | [diff] [blame] | 74 | void southbridge_smi_monitor(void) |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 75 | { |
| 76 | #define IOTRAP(x) (trap_sts & (1 << x)) |
| 77 | u32 trap_sts, trap_cycle; |
| 78 | u32 data, mask = 0; |
| 79 | int i; |
| 80 | |
| 81 | trap_sts = RCBA32(0x1e00); // TRSR - Trap Status Register |
| 82 | RCBA32(0x1e00) = trap_sts; // Clear trap(s) in TRSR |
| 83 | |
| 84 | trap_cycle = RCBA32(0x1e10); |
Angel Pons | 77f340a | 2020-10-17 18:39:04 +0200 | [diff] [blame] | 85 | for (i = 16; i < 20; i++) { |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 86 | if (trap_cycle & (1 << i)) |
Kyösti Mälkki | a072043 | 2022-12-03 19:35:53 +0200 | [diff] [blame] | 87 | mask |= (0xff << ((i - 16) << 3)); |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 88 | } |
| 89 | |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 90 | /* IOTRAP(3) SMI function call */ |
| 91 | if (IOTRAP(3)) { |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 92 | return; |
| 93 | } |
| 94 | |
| 95 | /* IOTRAP(2) currently unused |
| 96 | * IOTRAP(1) currently unused */ |
| 97 | |
| 98 | /* IOTRAP(0) SMIC */ |
| 99 | if (IOTRAP(0)) { |
| 100 | if (!(trap_cycle & (1 << 24))) { // It's a write |
| 101 | printk(BIOS_DEBUG, "SMI1 command\n"); |
| 102 | data = RCBA32(0x1e18); |
| 103 | data &= mask; |
| 104 | // if (smi1) |
| 105 | // southbridge_smi_command(data); |
| 106 | // return; |
| 107 | } |
| 108 | // Fall through to debug |
| 109 | } |
| 110 | |
| 111 | printk(BIOS_DEBUG, " trapped io address = 0x%x\n", trap_cycle & 0xfffc); |
Angel Pons | 77f340a | 2020-10-17 18:39:04 +0200 | [diff] [blame] | 112 | for (i = 0; i < 4; i++) { |
| 113 | if (IOTRAP(i)) |
| 114 | printk(BIOS_DEBUG, " TRAP = %d\n", i); |
| 115 | } |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 116 | printk(BIOS_DEBUG, " AHBE = %x\n", (trap_cycle >> 16) & 0xf); |
| 117 | printk(BIOS_DEBUG, " MASK = 0x%08x\n", mask); |
| 118 | printk(BIOS_DEBUG, " read/write: %s\n", (trap_cycle & (1 << 24)) ? "read" : "write"); |
| 119 | |
| 120 | if (!(trap_cycle & (1 << 24))) { |
| 121 | /* Write Cycle */ |
| 122 | data = RCBA32(0x1e18); |
| 123 | printk(BIOS_DEBUG, " iotrap written data = 0x%08x\n", data); |
| 124 | } |
| 125 | #undef IOTRAP |
| 126 | } |
| 127 | |
Arthur Heymans | 548f33a | 2018-05-15 16:34:50 +0200 | [diff] [blame] | 128 | void southbridge_finalize_all(void) |
| 129 | { |
Angel Pons | fd3df8e | 2021-01-27 12:38:42 +0100 | [diff] [blame] | 130 | /* TODO: Finalize ME */ |
Arthur Heymans | 04326aa | 2019-05-28 10:00:05 +0200 | [diff] [blame] | 131 | intel_pch_finalize_smm(); |
Angel Pons | 95de231 | 2020-02-17 13:08:53 +0100 | [diff] [blame] | 132 | intel_ironlake_finalize_smm(); |
Arthur Heymans | 04326aa | 2019-05-28 10:00:05 +0200 | [diff] [blame] | 133 | intel_model_2065x_finalize_smm(); |
Vladimir Serbinenko | 888d559 | 2013-11-13 17:53:38 +0100 | [diff] [blame] | 134 | } |