1 /* SPDX-License-Identifier: GPL-2.0-only */
3 /* TODO: Update for Phoenix */
5 #include <acpi/acpigen.h>
6 #include <amdblocks/alib.h>
7 #include <amdblocks/data_fabric.h>
8 #include <amdblocks/ioapic.h>
9 #include <amdblocks/root_complex.h>
10 #include <arch/ioapic.h>
11 #include <device/device.h>
12 #include <device/pci.h>
13 #include <soc/iomap.h>
18 #define DPTC_TOTAL_UPDATE_PARAMS 7
22 struct alib_dptc_param params
[DPTC_TOTAL_UPDATE_PARAMS
];
25 #define DPTC_INPUTS(_thermctllmit, _sustained, _fast, _slow, \
26 _vrmCurrentLimit, _vrmMaxCurrentLimit, _vrmSocCurrentLimit) \
28 .size = sizeof(struct dptc_input), \
31 .id = ALIB_DPTC_THERMAL_CONTROL_LIMIT_ID, \
32 .value = _thermctllmit, \
35 .id = ALIB_DPTC_SUSTAINED_POWER_LIMIT_ID, \
36 .value = _sustained, \
39 .id = ALIB_DPTC_FAST_PPT_LIMIT_ID, \
43 .id = ALIB_DPTC_SLOW_PPT_LIMIT_ID, \
47 .id = ALIB_DPTC_VRM_CURRENT_LIMIT_ID, \
48 .value = _vrmCurrentLimit, \
51 .id = ALIB_DPTC_VRM_MAXIMUM_CURRENT_LIMIT, \
52 .value = _vrmMaxCurrentLimit, \
55 .id = ALIB_DPTC_VRM_SOC_CURRENT_LIMIT_ID, \
56 .value = _vrmSocCurrentLimit, \
61 static void acipgen_dptci(void)
63 const struct soc_amd_phoenix_config
*config
= config_of_soc();
65 /* Normal mode DPTC values. */
66 struct dptc_input default_input
= DPTC_INPUTS(config
->thermctl_limit_degreeC
,
67 config
->sustained_power_limit_mW
,
68 config
->fast_ppt_limit_mW
,
69 config
->slow_ppt_limit_mW
,
70 config
->vrm_current_limit_mA
,
71 config
->vrm_maximum_current_limit_mA
,
72 config
->vrm_soc_current_limit_mA
);
73 acpigen_write_alib_dptc_default((uint8_t *)&default_input
, sizeof(default_input
));
76 struct dptc_input no_battery_input
= DPTC_INPUTS(
77 config
->thermctl_limit_degreeC
,
78 config
->sustained_power_limit_mW
,
79 config
->fast_ppt_limit_mW
,
80 config
->slow_ppt_limit_mW
,
81 config
->vrm_current_limit_throttle_mA
,
82 config
->vrm_maximum_current_limit_throttle_mA
,
83 config
->vrm_soc_current_limit_throttle_mA
);
84 acpigen_write_alib_dptc_no_battery((uint8_t *)&no_battery_input
,
85 sizeof(no_battery_input
));
88 static void root_complex_fill_ssdt(const struct device
*device
)
90 if (CONFIG(SOC_AMD_COMMON_BLOCK_ACPI_DPTC
))
94 static const char *gnb_acpi_name(const struct device
*dev
)
99 struct device_operations phoenix_root_complex_operations
= {
100 /* The root complex has no PCI BARs implemented, so there's no need to call
101 pci_dev_read_resources for it */
102 .read_resources
= noop_read_resources
,
103 .set_resources
= noop_set_resources
,
104 .enable_resources
= pci_dev_enable_resources
,
105 .acpi_name
= gnb_acpi_name
,
106 .acpi_fill_ssdt
= root_complex_fill_ssdt
,
109 static const struct domain_iohc_info iohc_info
[] = {
111 .fabric_id
= IOMS0_FABRIC_ID
,
112 .misc_smn_base
= SMN_IOHC_MISC_BASE_13B1
,
116 const struct domain_iohc_info
*get_iohc_info(size_t *count
)
118 *count
= ARRAY_SIZE(iohc_info
);
122 static const struct non_pci_mmio_reg non_pci_mmio
[] = {
123 { 0x2d0, 0xfffffff00000ull
, 1 * MiB
, NON_PCI_RES_IDX_AUTO
},
124 { 0x2d8, 0xfffffff00000ull
, 1 * MiB
, NON_PCI_RES_IDX_AUTO
},
125 { 0x2e0, 0xfffffff00000ull
, 1 * MiB
, NON_PCI_RES_IDX_AUTO
},
126 { 0x2e8, 0xfffffff00000ull
, 1 * MiB
, NON_PCI_RES_IDX_AUTO
},
127 /* The hardware has a 256 byte alignment requirement for the IOAPIC MMIO base, but we
128 tell the FSP to configure a 4k-aligned base address and this is reported as 4 KiB
130 { 0x2f0, 0xffffffffff00ull
, 4 * KiB
, IOMMU_IOAPIC_IDX
},
131 { 0x2f8, 0xfffffff00000ull
, 1 * MiB
, NON_PCI_RES_IDX_AUTO
},
132 { 0x300, 0xfffffff00000ull
, 1 * MiB
, NON_PCI_RES_IDX_AUTO
},
133 { 0x308, 0xfffffffff000ull
, 4 * KiB
, NON_PCI_RES_IDX_AUTO
},
134 { 0x310, 0xfffffff00000ull
, 1 * MiB
, NON_PCI_RES_IDX_AUTO
},
135 { 0x318, 0xfffffff80000ull
, 512 * KiB
, NON_PCI_RES_IDX_AUTO
},
136 { 0x320, 0xfffffff00000ull
, 1 * MiB
, NON_PCI_RES_IDX_AUTO
},
139 const struct non_pci_mmio_reg
*get_iohc_non_pci_mmio_regs(size_t *count
)
141 *count
= ARRAY_SIZE(non_pci_mmio
);