blob: d75f7f05a697658502dd41354f1dca10e0839f96 [file] [log] [blame]
Angel Pons80d92382020-04-05 15:47:00 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Mariusz Szafranskia4041332017-08-02 17:28:17 +02002
Furquan Shaikh76cedd22020-05-02 10:24:23 -07003#include <acpi/acpi.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02004#include <device/pci_ops.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +02005#include <console/console.h>
6#include <device/device.h>
7#include <device/pci.h>
8#include <device/pci_ids.h>
9
10#include <soc/iomap.h>
11#include <soc/pmc.h>
12#include <soc/pci_devs.h>
13#include <soc/ramstage.h>
14#include <cpu/x86/smm.h>
15
16/* While we read BAR dynamically in case it changed, let's
17 * initialize it with a same value
18 */
Angel Pons83bdb452021-01-10 18:02:27 +010019static u16 acpi_base = ACPI_BASE_ADDRESS;
Mariusz Szafranskia4041332017-08-02 17:28:17 +020020static u32 pwrm_base = DEFAULT_PWRM_BASE;
21
Elyes HAOUAS2ec41832018-05-27 17:40:58 +020022static void pch_power_options(struct device *dev) { /* TODO */ }
Mariusz Szafranskia4041332017-08-02 17:28:17 +020023
24static void pch_set_acpi_mode(void)
25{
Kyösti Mälkkiad882c32020-06-02 05:05:30 +030026 if (!acpi_is_wakeup_s3()) {
Kyösti Mälkkib6585482020-06-01 15:11:14 +030027 apm_control(APM_CNT_ACPI_DISABLE);
Mariusz Szafranskia4041332017-08-02 17:28:17 +020028 }
29}
30
Elyes HAOUAS2ec41832018-05-27 17:40:58 +020031static void pmc_init(struct device *dev)
Mariusz Szafranskia4041332017-08-02 17:28:17 +020032{
Elyes HAOUAS7dbc4a42021-01-16 17:33:27 +010033 printk(BIOS_DEBUG, "pch: %s\n", __func__);
Mariusz Szafranskia4041332017-08-02 17:28:17 +020034
35 /* Get the base address */
36 acpi_base = pci_read_config16(dev, PMC_ACPI_BASE) & MASK_PMC_ACPI_BASE;
37 pwrm_base = pci_read_config32(dev, PMC_PWRM_BASE) & MASK_PMC_PWRM_BASE;
38
39 /* Set the value for PCI command register. */
40 pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER |
41 PCI_COMMAND_MEMORY |
42 PCI_COMMAND_IO);
43
44 /* Setup power options. */
45 pch_power_options(dev);
46
47 /* Configure ACPI mode. */
48 pch_set_acpi_mode();
49}
50
Elyes HAOUAS2ec41832018-05-27 17:40:58 +020051static void pci_pmc_read_resources(struct device *dev)
Mariusz Szafranskia4041332017-08-02 17:28:17 +020052{
53 struct resource *res;
54
55 /* Get the normal PCI resources of this device. */
56 pci_dev_read_resources(dev);
57
58 /* Add MMIO resource
59 * Use 0xaa as an unused index for PWRM BAR.
60 */
61 u32 reg32 = pci_read_config32(dev, PMC_PWRM_BASE) & MASK_PMC_PWRM_BASE;
62 if ((reg32 != 0x0) && (reg32 != 0xffffffff)) {
63 res = new_resource(dev, 0xaa);
64 res->base = reg32;
65 res->size = 64 * 1024; /* 64K bytes memory config space */
66 res->flags =
67 IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
68 printk(BIOS_DEBUG,
69 "Adding PMC PWRM config space BAR 0x%08lx-0x%08lx.\n",
70 (unsigned long)(res->base),
71 (unsigned long)(res->base + res->size));
72 }
73
74 /* Add MMIO resource
75 * Use 0xab as an unused index for ACPI BAR.
76 */
77 u16 reg16 = pci_read_config16(dev, PMC_ACPI_BASE) & MASK_PMC_ACPI_BASE;
78 if ((reg16 != 0x0) && (reg16 != 0xffff)) {
79 res = new_resource(dev, 0xab);
80 res->base = reg16;
81 res->size = 0x100; /* 256 bytes I/O config space */
82 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
83 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
84 }
85}
86
87static struct device_operations pmc_ops = {
88 .read_resources = pci_pmc_read_resources,
89 .set_resources = pci_dev_set_resources,
90 .enable_resources = pci_dev_enable_resources,
Mariusz Szafranskia4041332017-08-02 17:28:17 +020091 .init = pmc_init,
92 .ops_pci = &soc_pci_ops,
93};
94
95static const struct pci_driver pch_pmc __pci_driver = {
96 .ops = &pmc_ops,
97 .vendor = PCI_VENDOR_ID_INTEL,
Felix Singerdbc90df2019-11-22 00:10:20 +010098 .device = PCI_DEVICE_ID_INTEL_DENVERTON_PMC,
Mariusz Szafranskia4041332017-08-02 17:28:17 +020099};