blob: dbd982b5937abf8172a2811b76e8328243dd029a [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <intelblocks/lpc_lib.h>
#include <soc/pm.h>
#include "lpc_def.h"
/* SoC overrides */
/* Common weak definition, needs to be implemented in each soc LPC driver. */
__weak void lpc_soc_init(struct device *dev)
{
/* no-op */
}
/* Fill up LPC IO resource structure inside SoC directory */
__weak void pch_lpc_soc_fill_io_resources(struct device *dev)
{
/* no-op */
}
void pch_lpc_add_new_resource(struct device *dev, uint8_t offset,
uintptr_t base, size_t size, unsigned long flags)
{
struct resource *res;
res = new_resource(dev, offset);
res->base = base;
res->size = size;
res->flags = flags;
}
static void pch_lpc_add_io_resources(struct device *dev)
{
uint32_t gen_io_dec;
uint16_t base, size;
/* Add the default claimed legacy IO range for the LPC device. */
pch_lpc_add_new_resource(dev, 0, 0, 0x1000, IORESOURCE_IO |
IORESOURCE_ASSIGNED | IORESOURCE_FIXED);
/* LPC Generic IO Decode ranges */
for (size_t i = 0; i < LPC_NUM_GENERIC_IO_RANGES; i++) {
gen_io_dec = pci_read_config32(dev, LPC_GENERIC_IO_RANGE(i));
if (gen_io_dec & LPC_LGIR_EN) {
base = gen_io_dec & LPC_LGIR_ADDR_MASK;
size = (0x3 | ((gen_io_dec >> 16) & 0xfc)) + 1;
pch_lpc_add_new_resource(dev, LPC_GENERIC_IO_RANGE(i), base, size,
IORESOURCE_IO | IORESOURCE_ASSIGNED |
IORESOURCE_FIXED);
}
}
/* SoC IO resource overrides */
pch_lpc_soc_fill_io_resources(dev);
}
static void pch_lpc_add_mmio_resources(struct device *dev)
{
/* LPC Memory Decode */
uint32_t lgmr = pci_read_config32(dev, LPC_GENERIC_MEM_RANGE);
if (lgmr & LPC_LGMR_EN) {
lgmr &= LPC_LGMR_ADDR_MASK;
pch_lpc_add_new_resource(dev, LPC_GENERIC_MEM_RANGE, lgmr, LPC_LGMR_WINDOW_SIZE,
IORESOURCE_MEM | IORESOURCE_ASSIGNED |
IORESOURCE_FIXED | IORESOURCE_RESERVE);
}
}
static void pch_lpc_read_resources(struct device *dev)
{
/* Get the PCI resources of this device. */
pci_dev_read_resources(dev);
/* Add IO resources to LPC. */
pch_lpc_add_io_resources(dev);
/* Add non-standard MMIO resources. */
pch_lpc_add_mmio_resources(dev);
}
static void pch_lpc_set_child_resources(struct device *dev);
static void pch_lpc_loop_resources(struct device *dev)
{
struct resource *res;
for (res = dev->resource_list; res; res = res->next) {
if (res->flags & IORESOURCE_IO)
lpc_open_pmio_window(res->base, res->size);
}
pch_lpc_set_child_resources(dev);
}
/*
* Loop through all the child devices' resources, and open up windows to the
* LPC bus, as appropriate.
*/
static void pch_lpc_set_child_resources(struct device *dev)
{
struct device *child;
if (!dev->downstream)
return;
for (child = dev->downstream->children; child; child = child->sibling)
pch_lpc_loop_resources(child);
}
static void pch_lpc_set_resources(struct device *dev)
{
pci_dev_set_resources(dev);
/* Now open up windows to devices which have declared resources. */
pch_lpc_set_child_resources(dev);
}
#if CONFIG(HAVE_ACPI_TABLES)
static const char *lpc_acpi_name(const struct device *dev)
{
return "LPCB";
}
#endif
struct device_operations lpc_ops = {
.read_resources = pch_lpc_read_resources,
.set_resources = pch_lpc_set_resources,
.enable_resources = pci_dev_enable_resources,
#if CONFIG(HAVE_ACPI_TABLES)
.write_acpi_tables = southbridge_write_acpi_tables,
.acpi_name = lpc_acpi_name,
#endif
.init = lpc_soc_init,
.scan_bus = scan_static_bus,
.ops_pci = &pci_dev_ops_pci,
};
static const unsigned short pci_device_ids[] = {
PCI_DID_INTEL_LNL_ESPI_0,
PCI_DID_INTEL_LNL_ESPI_1,
PCI_DID_INTEL_LNL_ESPI_2,
PCI_DID_INTEL_LNL_ESPI_3,
PCI_DID_INTEL_LNL_ESPI_4,
PCI_DID_INTEL_LNL_ESPI_5,
PCI_DID_INTEL_LNL_ESPI_6,
PCI_DID_INTEL_LNL_ESPI_7,
PCI_DID_INTEL_MTL_ESPI_0,
PCI_DID_INTEL_MTL_ESPI_1,
PCI_DID_INTEL_MTL_ESPI_2,
PCI_DID_INTEL_MTL_ESPI_3,
PCI_DID_INTEL_MTL_ESPI_4,
PCI_DID_INTEL_MTL_ESPI_5,
PCI_DID_INTEL_MTL_ESPI_6,
PCI_DID_INTEL_MTL_ESPI_7,
PCI_DID_INTEL_RPP_P_ESPI_0,
PCI_DID_INTEL_RPP_P_ADP_P_ESPI_1,
PCI_DID_INTEL_RPP_P_ADP_P_ESPI_2,
PCI_DID_INTEL_RPP_P_ESPI_3,
PCI_DID_INTEL_RPP_P_ESPI_4,
PCI_DID_INTEL_RPP_P_ESPI_5,
PCI_DID_INTEL_RPP_P_ADP_M_ESPI_6,
PCI_DID_INTEL_RPP_P_ESPI_7,
PCI_DID_INTEL_RPP_P_ESPI_8,
PCI_DID_INTEL_RPP_P_ESPI_9,
PCI_DID_INTEL_RPP_P_ESPI_10,
PCI_DID_INTEL_RPP_P_ESPI_11,
PCI_DID_INTEL_RPP_P_ESPI_12,
PCI_DID_INTEL_RPP_P_ESPI_13,
PCI_DID_INTEL_RPP_P_ESPI_14,
PCI_DID_INTEL_RPP_P_ESPI_15,
PCI_DID_INTEL_RPP_P_ESPI_16,
PCI_DID_INTEL_RPP_P_ESPI_17,
PCI_DID_INTEL_RPP_P_ESPI_18,
PCI_DID_INTEL_RPP_P_ESPI_19,
PCI_DID_INTEL_RPP_P_ESPI_20,
PCI_DID_INTEL_RPP_P_ESPI_21,
PCI_DID_INTEL_RPP_P_ESPI_22,
PCI_DID_INTEL_RPP_P_ESPI_23,
PCI_DID_INTEL_RPP_P_ESPI_24,
PCI_DID_INTEL_RPP_P_ESPI_25,
PCI_DID_INTEL_RPP_P_ESPI_26,
PCI_DID_INTEL_RPP_P_ESPI_27,
PCI_DID_INTEL_RPP_P_ESPI_28,
PCI_DID_INTEL_RPP_P_ESPI_29,
PCI_DID_INTEL_RPP_P_ESPI_30,
PCI_DID_INTEL_RPP_P_ESPI_31,
PCI_DID_INTEL_RPP_S_ESPI_0,
PCI_DID_INTEL_RPP_S_ESPI_1,
PCI_DID_INTEL_RPP_S_ESPI_2,
PCI_DID_INTEL_RPP_S_ESPI_3,
PCI_DID_INTEL_RPP_S_ESPI_Z790,
PCI_DID_INTEL_RPP_S_ESPI_H770,
PCI_DID_INTEL_RPP_S_ESPI_B760,
PCI_DID_INTEL_RPP_S_ESPI_7,
PCI_DID_INTEL_RPP_S_ESPI_8,
PCI_DID_INTEL_RPP_S_ESPI_9,
PCI_DID_INTEL_RPP_S_ESPI_10,
PCI_DID_INTEL_RPP_S_ESPI_11,
PCI_DID_INTEL_RPP_S_ESPI_HM770,
PCI_DID_INTEL_RPP_S_ESPI_WM790,
PCI_DID_INTEL_RPP_S_ESPI_14,
PCI_DID_INTEL_RPP_S_ESPI_15,
PCI_DID_INTEL_RPP_S_ESPI_16,
PCI_DID_INTEL_RPP_S_ESPI_17,
PCI_DID_INTEL_RPP_S_ESPI_18,
PCI_DID_INTEL_RPP_S_ESPI_19,
PCI_DID_INTEL_RPP_S_ESPI_20,
PCI_DID_INTEL_RPP_S_ESPI_21,
PCI_DID_INTEL_RPP_S_ESPI_22,
PCI_DID_INTEL_RPP_S_ESPI_23,
PCI_DID_INTEL_RPP_S_ESPI_24,
PCI_DID_INTEL_RPP_S_ESPI_25,
PCI_DID_INTEL_RPP_S_ESPI_26,
PCI_DID_INTEL_RPP_S_ESPI_27,
PCI_DID_INTEL_RPP_S_ESPI_28,
PCI_DID_INTEL_RPP_S_ESPI_29,
PCI_DID_INTEL_RPP_S_ESPI_30,
PCI_DID_INTEL_RPP_S_ESPI_31,
PCI_DID_INTEL_LWB_C621,
PCI_DID_INTEL_LWB_C622,
PCI_DID_INTEL_LWB_C624,
PCI_DID_INTEL_LWB_C625,
PCI_DID_INTEL_LWB_C626,
PCI_DID_INTEL_LWB_C627,
PCI_DID_INTEL_LWB_C628,
PCI_DID_INTEL_LWB_C629,
PCI_DID_INTEL_LWB_C621A,
PCI_DID_INTEL_LWB_C627A,
PCI_DID_INTEL_LWB_C629A,
PCI_DID_INTEL_LWB_C624_SUPER,
PCI_DID_INTEL_LWB_C627_SUPER_1,
PCI_DID_INTEL_LWB_C621_SUPER,
PCI_DID_INTEL_LWB_C627_SUPER_2,
PCI_DID_INTEL_LWB_C628_SUPER,
PCI_DID_INTEL_LWB_C621A_SUPER,
PCI_DID_INTEL_LWB_C627A_SUPER,
PCI_DID_INTEL_LWB_C629A_SUPER,
PCI_DID_INTEL_EMB_SUPER,
PCI_DID_INTEL_APL_LPC,
PCI_DID_INTEL_GLK_LPC,
PCI_DID_INTEL_GLK_ESPI,
PCI_DID_INTEL_CNL_BASE_U_LPC,
PCI_DID_INTEL_CNL_U_PREMIUM_LPC,
PCI_DID_INTEL_CNL_Y_PREMIUM_LPC,
PCI_DID_INTEL_CNP_H_LPC_H310,
PCI_DID_INTEL_CNP_H_LPC_H370,
PCI_DID_INTEL_CNP_H_LPC_Z390,
PCI_DID_INTEL_CNP_H_LPC_Q370,
PCI_DID_INTEL_CNP_H_LPC_B360,
PCI_DID_INTEL_CNP_H_LPC_C246,
PCI_DID_INTEL_CNP_H_LPC_C242,
PCI_DID_INTEL_CNP_H_LPC_QM370,
PCI_DID_INTEL_CNP_H_LPC_HM370,
PCI_DID_INTEL_CNP_H_LPC_CM246,
PCI_DID_INTEL_CMP_SUPER_U_LPC,
PCI_DID_INTEL_CMP_PREMIUM_Y_LPC,
PCI_DID_INTEL_CMP_PREMIUM_U_LPC,
PCI_DID_INTEL_CMP_BASE_U_LPC,
PCI_DID_INTEL_CMP_SUPER_Y_LPC,
PCI_DID_INTEL_CMP_H_LPC_HM470,
PCI_DID_INTEL_CMP_H_LPC_WM490,
PCI_DID_INTEL_CMP_H_LPC_QM480,
PCI_DID_INTEL_CMP_H_LPC_W480,
PCI_DID_INTEL_CMP_H_LPC_H470,
PCI_DID_INTEL_CMP_H_LPC_Z490,
PCI_DID_INTEL_CMP_H_LPC_Q470,
PCI_DID_INTEL_TGP_ESPI_0,
PCI_DID_INTEL_TGP_SUPER_U_ESPI,
PCI_DID_INTEL_TGP_PREMIUM_U_ESPI,
PCI_DID_INTEL_TGP_BASE_U_ESPI,
PCI_DID_INTEL_TGP_ESPI_1,
PCI_DID_INTEL_TGP_ESPI_2,
PCI_DID_INTEL_TGP_SUPER_Y_ESPI,
PCI_DID_INTEL_TGP_PREMIUM_Y_ESPI,
PCI_DID_INTEL_TGP_ESPI_3,
PCI_DID_INTEL_TGP_ESPI_4,
PCI_DID_INTEL_TGP_ESPI_5,
PCI_DID_INTEL_TGP_ESPI_6,
PCI_DID_INTEL_TGP_ESPI_7,
PCI_DID_INTEL_TGP_ESPI_8,
PCI_DID_INTEL_TGP_ESPI_9,
PCI_DID_INTEL_TGP_ESPI_10,
PCI_DID_INTEL_TGP_ESPI_11,
PCI_DID_INTEL_TGP_ESPI_12,
PCI_DID_INTEL_TGP_ESPI_13,
PCI_DID_INTEL_TGP_ESPI_14,
PCI_DID_INTEL_TGP_ESPI_15,
PCI_DID_INTEL_TGP_ESPI_16,
PCI_DID_INTEL_TGP_ESPI_17,
PCI_DID_INTEL_TGP_ESPI_18,
PCI_DID_INTEL_TGP_ESPI_19,
PCI_DID_INTEL_TGP_ESPI_20,
PCI_DID_INTEL_TGP_ESPI_21,
PCI_DID_INTEL_TGP_ESPI_22,
PCI_DID_INTEL_TGP_ESPI_23,
PCI_DID_INTEL_TGP_ESPI_24,
PCI_DID_INTEL_TGP_ESPI_25,
PCI_DID_INTEL_TGP_ESPI_26,
PCI_DID_INTEL_TGP_H_ESPI_B560,
PCI_DID_INTEL_TGP_H_ESPI_H510,
PCI_DID_INTEL_TGP_H_ESPI_H570,
PCI_DID_INTEL_TGP_H_ESPI_Q570,
PCI_DID_INTEL_TGP_H_ESPI_W580,
PCI_DID_INTEL_TGP_H_ESPI_Z590,
PCI_DID_INTEL_TGP_H_ESPI_HM570,
PCI_DID_INTEL_TGP_H_ESPI_QM580,
PCI_DID_INTEL_TGP_H_ESPI_WM590,
PCI_DID_INTEL_MCC_ESPI_0,
PCI_DID_INTEL_MCC_ESPI_1,
PCI_DID_INTEL_MCC_BASE_ESPI,
PCI_DID_INTEL_MCC_PREMIUM_ESPI,
PCI_DID_INTEL_MCC_SUPER_ESPI,
PCI_DID_INTEL_MCC_ESPI_2,
PCI_DID_INTEL_MCC_ESPI_3,
PCI_DID_INTEL_MCC_ESPI_4,
PCI_DID_INTEL_JSP_SUPER_ESPI,
PCI_DID_INTEL_ADP_S_ESPI_WM690,
PCI_DID_INTEL_ADP_S_ESPI_HM670,
PCI_DID_INTEL_ADP_S_ESPI_W790,
PCI_DID_INTEL_ADP_S_ESPI_W680,
PCI_DID_INTEL_ADP_S_ESPI_H610,
PCI_DID_INTEL_ADP_S_ESPI_B660,
PCI_DID_INTEL_ADP_S_ESPI_H670,
PCI_DID_INTEL_ADP_S_ESPI_Z690,
PCI_DID_INTEL_ADP_S_ESPI_Q670,
PCI_DID_INTEL_ADP_S_ESPI_0,
PCI_DID_INTEL_ADP_S_ESPI_1,
PCI_DID_INTEL_ADP_S_ESPI_2,
PCI_DID_INTEL_ADP_S_ESPI_9,
PCI_DID_INTEL_ADP_S_ESPI_11,
PCI_DID_INTEL_ADP_S_ESPI_14,
PCI_DID_INTEL_ADP_S_ESPI_15,
PCI_DID_INTEL_ADP_S_ESPI_19,
PCI_DID_INTEL_ADP_S_ESPI_20,
PCI_DID_INTEL_ADP_S_ESPI_21,
PCI_DID_INTEL_ADP_S_ESPI_22,
PCI_DID_INTEL_ADP_S_ESPI_23,
PCI_DID_INTEL_ADP_S_ESPI_24,
PCI_DID_INTEL_ADP_S_ESPI_25,
PCI_DID_INTEL_ADP_S_ESPI_26,
PCI_DID_INTEL_ADP_S_ESPI_27,
PCI_DID_INTEL_ADP_S_ESPI_28,
PCI_DID_INTEL_ADP_S_ESPI_29,
PCI_DID_INTEL_ADP_S_ESPI_30,
PCI_DID_INTEL_ADP_S_ESPI_31,
PCI_DID_INTEL_ADP_S_ESPI_H610E,
PCI_DID_INTEL_ADP_S_ESPI_Q670E,
PCI_DID_INTEL_ADP_S_ESPI_R680E,
PCI_DID_INTEL_ADP_M_N_ESPI_0,
PCI_DID_INTEL_ADP_M_N_ESPI_1,
PCI_DID_INTEL_ADP_M_N_ESPI_2,
PCI_DID_INTEL_ADP_M_N_ESPI_3,
PCI_DID_INTEL_ADP_M_N_ESPI_4,
PCI_DID_INTEL_ADP_M_N_ESPI_5,
PCI_DID_INTEL_ADP_M_N_ESPI_7,
PCI_DID_INTEL_ADP_M_N_ESPI_8,
PCI_DID_INTEL_ADP_M_N_ESPI_9,
PCI_DID_INTEL_ADP_M_N_ESPI_10,
PCI_DID_INTEL_ADP_M_N_ESPI_11,
PCI_DID_INTEL_ADP_M_N_ESPI_12,
PCI_DID_INTEL_ADP_M_N_ESPI_13,
PCI_DID_INTEL_ADP_M_N_ESPI_14,
PCI_DID_INTEL_ADP_M_N_ESPI_15,
PCI_DID_INTEL_ADP_M_N_ESPI_16,
PCI_DID_INTEL_ADP_M_N_ESPI_17,
PCI_DID_INTEL_ADP_M_N_ESPI_18,
PCI_DID_INTEL_ADP_M_N_ESPI_19,
PCI_DID_INTEL_ADP_M_N_ESPI_20,
PCI_DID_INTEL_ADP_M_N_ESPI_21,
PCI_DID_INTEL_ADP_M_N_ESPI_22,
PCI_DID_INTEL_ADP_M_N_ESPI_23,
PCI_DID_INTEL_ADP_M_N_ESPI_24,
PCI_DID_INTEL_ADP_M_N_ESPI_25,
PCI_DID_INTEL_ADP_M_N_ESPI_26,
PCI_DID_INTEL_ADP_M_N_ESPI_27,
PCI_DID_INTEL_ADP_M_N_ESPI_28,
PCI_DID_INTEL_ADP_M_N_ESPI_29,
PCI_DID_INTEL_ADP_M_N_ESPI_30,
PCI_DID_INTEL_ADP_M_N_ESPI_31,
PCI_DID_INTEL_SPR_ESPI_1,
0
};
static const struct pci_driver pch_lpc __pci_driver = {
.ops = &lpc_ops,
.vendor = PCI_VID_INTEL,
.devices = pci_device_ids,
};