Compare commits

..

2 Commits

Author SHA1 Message Date
Jeremy Soller
98b7d04574 soc/common/smbus: Support reading SPD5 hubs for DDR5
DDR5 uses a Serial Presence Detect (SPD) with hub function
(SPD5 hub device) to store the SPD data. The SPD5 hub has 1024 bytes of
EEPROM (`CONFIG_DIMM_SPD_SIZE=1024`).

Tested on Clevo V560TU (system76/darp10) with 2x Crucial CT16G48C40S5
DIMMs.

Change-Id: Ic5e6c58f255bef86b68ce90a4f853bf4e7c7ccfe
Co-authored-by: Meera Ravindranath <meera.ravindranath@intel.com>
Signed-off-by: Jeremy Soller <jeremy@system76.com>
Signed-off-by: Tim Crawford <tcrawford@system76.com>
2024-05-31 18:56:42 -06:00
Appukuttan V K
c097c4788b soc/intel: Fix pointer size mismatch errors in crashlog
The crashlog code in intel/common/block and meteorlake soc
was casting integer addresses directly to pointer types,
which caused compilation errors in x86_64 bit builds.

This commit fixes the issue by using uintptr_t for casting
integer addresses to pointer types before dereferencing.

BUG=b:329034258
TEST=Successfully build Meteor Lake (rex) in both x86_32 and
x86_64 modes.

Change-Id: I2d0814a8b767270ec140341bfb51d0782469545d
Signed-off-by: Appukuttan V K <appukuttan.vk@intel.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/82481
Reviewed-by: Subrata Banik <subratabanik@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Eric Lai <ericllai@google.com>
Reviewed-by: Dinesh Gehlot <digehlot@google.com>
Reviewed-by: Kapil Porwal <kapilporwal@google.com>
2024-05-31 20:36:45 +00:00
14 changed files with 107 additions and 256 deletions

View File

@@ -1,4 +0,0 @@
config DRIVERS_INTEL_DTBT
def_bool n
help
Support for discrete Thunderbolt controllers

View File

@@ -1,3 +0,0 @@
# SPDX-License-Identifier: GPL-2.0-only
ramstage-$(CONFIG_DRIVERS_INTEL_DTBT) += dtbt.c

View File

@@ -1,8 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef _DRIVERS_INTEL_DTBT_CHIP_H_
#define _DRIVERS_INTEL_DTBT_CHIP_H_
struct drivers_intel_dtbt_config {};
#endif /* _DRIVERS_INTEL_DTBT_CHIP_H_ */

View File

@@ -1,199 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0-only */
#include "chip.h"
#include <acpi/acpigen.h>
#include <console/console.h>
#include <delay.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pciexp.h>
#include <device/pci_ids.h>
#include <timer.h>
#define PCIE2TBT 0x54C
#define PCIE2TBT_VALID BIT(0)
#define PCIE2TBT_GO2SX 2
#define PCIE2TBT_GO2SX_NO_WAKE 3
#define PCIE2TBT_SX_EXIT_TBT_CONNECTED 4
#define PCIE2TBT_OS_UP 6
#define PCIE2TBT_SET_SECURITY_LEVEL 8
#define PCIE2TBT_GET_SECURITY_LEVEL 9
#define PCIE2TBT_BOOT_ON 24
#define PCIE2TBT_USB_ON 25
#define PCIE2TBT_GET_ENUMERATION_METHOD 26
#define PCIE2TBT_SET_ENUMERATION_METHOD 27
#define PCIE2TBT_POWER_CYCLE 28
#define PCIE2TBT_SX_START 29
#define PCIE2TBT_ACL_BOOT 30
#define PCIE2TBT_CONNECT_TOPOLOGY 31
#define TBT2PCIE 0x548
#define TBT2PCIE_DONE BIT(0)
// Default timeout for mailbox commands unless otherwise specified.
#define TIMEOUT_MS 1000
// Default timeout for controller to ack GO2SX/GO2SX_NO_WAKE mailbox command.
#define GO2SX_TIMEOUT_MS 600
static void dtbt_cmd(struct device *dev, u32 command, u32 data, u32 timeout)
{
u32 reg = (data << 8) | (command << 1) | PCIE2TBT_VALID;
u32 status;
printk(BIOS_DEBUG, "dTBT send command %08x\n", command);
pci_write_config32(dev, PCIE2TBT, reg);
if (!wait_ms(timeout, (status = pci_read_config32(dev, TBT2PCIE)) & TBT2PCIE_DONE)) {
printk(BIOS_ERR, "dTBT command %08x send timeout %08x\n", command, status);
}
pci_write_config32(dev, PCIE2TBT, 0);
if (!wait_ms(timeout, !(pci_read_config32(dev, TBT2PCIE) & TBT2PCIE_DONE))) {
printk(BIOS_ERR, "dTBT command %08x clear timeout\n", command);
}
}
static void dtbt_write_dsd(void)
{
struct acpi_dp *dsd = acpi_dp_new_table("_DSD");
acpi_device_add_hotplug_support_in_d3(dsd);
acpi_device_add_external_facing_port(dsd);
acpi_dp_write(dsd);
}
static void dtbt_write_opregion(const struct bus *bus)
{
uintptr_t mmconf_base = (uintptr_t)CONFIG_ECAM_MMCONF_BASE_ADDRESS
+ (((uintptr_t)(bus->secondary)) << 20);
const struct opregion opregion = OPREGION("PXCS", SYSTEMMEMORY, mmconf_base, 0x1000);
const struct fieldlist fieldlist[] = {
FIELDLIST_OFFSET(TBT2PCIE),
FIELDLIST_NAMESTR("TB2P", 32),
FIELDLIST_OFFSET(PCIE2TBT),
FIELDLIST_NAMESTR("P2TB", 32),
};
acpigen_write_opregion(&opregion);
acpigen_write_field("PXCS", fieldlist, ARRAY_SIZE(fieldlist),
FIELD_DWORDACC | FIELD_NOLOCK | FIELD_PRESERVE);
}
static void dtbt_fill_ssdt(const struct device *dev)
{
struct bus *bus;
struct device *parent;
const char *parent_scope;
const char *dev_name = acpi_device_name(dev);
bus = dev->upstream;
if (!bus) {
printk(BIOS_ERR, "dTBT bus invalid\n");
return;
}
parent = bus->dev;
if (!parent || parent->path.type != DEVICE_PATH_PCI) {
printk(BIOS_ERR, "dTBT parent invalid\n");
return;
}
parent_scope = acpi_device_path(parent);
if (!parent_scope) {
printk(BIOS_ERR, "dTBT parent scope not valid\n");
return;
}
/* Scope */
acpigen_write_scope(parent_scope);
dtbt_write_dsd();
/* Device */
acpigen_write_device(dev_name);
acpigen_write_name_integer("_ADR", 0);
dtbt_write_opregion(bus);
/* Method */
acpigen_write_method_serialized("PTS", 0);
acpigen_write_debug_string("dTBT prepare to sleep");
acpigen_write_store_int_to_namestr(PCIE2TBT_GO2SX_NO_WAKE << 1, "P2TB");
acpigen_write_delay_until_namestr_int(GO2SX_TIMEOUT_MS, "TB2P", PCIE2TBT_GO2SX_NO_WAKE << 1);
acpigen_write_debug_namestr("TB2P");
acpigen_write_store_int_to_namestr(0, "P2TB");
acpigen_write_delay_until_namestr_int(GO2SX_TIMEOUT_MS, "TB2P", 0);
acpigen_write_debug_namestr("TB2P");
acpigen_write_method_end();
acpigen_write_device_end();
acpigen_write_scope_end();
printk(BIOS_DEBUG, "dTBT fill SSDT\n");
printk(BIOS_DEBUG, " Dev %s\n", dev_path(dev));
//printk(BIOS_DEBUG, " Bus %s\n", bus_path(bus));
printk(BIOS_DEBUG, " Parent %s\n", dev_path(parent));
printk(BIOS_DEBUG, " Scope %s\n", parent_scope);
printk(BIOS_DEBUG, " Device %s\n", dev_name);
// \.TBTS Method
acpigen_write_scope("\\");
acpigen_write_method("TBTS", 0);
acpigen_emit_namestring(acpi_device_path_join(dev, "PTS"));
acpigen_write_method_end();
acpigen_write_scope_end();
}
static const char *dtbt_acpi_name(const struct device *dev)
{
return "DTBT";
}
static struct pci_operations dtbt_device_ops_pci = {
.set_subsystem = 0,
};
static struct device_operations dtbt_device_ops = {
.read_resources = pci_bus_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_bus_enable_resources,
.acpi_fill_ssdt = dtbt_fill_ssdt,
.acpi_name = dtbt_acpi_name,
.scan_bus = pciexp_scan_bridge,
.reset_bus = pci_bus_reset,
.ops_pci = &dtbt_device_ops_pci,
};
static void dtbt_enable(struct device *dev)
{
if (!is_dev_enabled(dev) || dev->path.type != DEVICE_PATH_PCI)
return;
if (pci_read_config16(dev, PCI_VENDOR_ID) != PCI_VID_INTEL)
return;
// TODO: check device ID
dev->ops = &dtbt_device_ops;
printk(BIOS_INFO, "dTBT controller found at %s\n", dev_path(dev));
// XXX: Recommendation is to set SL1 ("User Authorization")
printk(BIOS_DEBUG, "dTBT set security level SL0\n");
dtbt_cmd(dev, PCIE2TBT_SET_SECURITY_LEVEL, 0, TIMEOUT_MS);
// XXX: Must verify change or rollback all controllers
if (acpi_is_wakeup_s3()) {
printk(BIOS_DEBUG, "dTBT SX exit\n");
dtbt_cmd(dev, PCIE2TBT_SX_EXIT_TBT_CONNECTED, 0, TIMEOUT_MS);
// TODO: "wait for fast link bring-up" loop (timeout: 5s)
} else {
printk(BIOS_DEBUG, "dTBT boot on\n");
dtbt_cmd(dev, PCIE2TBT_BOOT_ON, 0, TIMEOUT_MS);
}
}
struct chip_operations drivers_intel_dtbt_ops = {
.name = "Intel Discrete Thunderbolt",
.enable_dev = dtbt_enable,
};

View File

@@ -36,6 +36,18 @@
#define DDR4_SPD_PART_OFF 329 #define DDR4_SPD_PART_OFF 329
#define DDR4_SPD_PART_LEN 20 #define DDR4_SPD_PART_LEN 20
#define DDR4_SPD_SN_OFF 325 #define DDR4_SPD_SN_OFF 325
#define MAX_SPD_PAGE_SIZE_SPD5 128
#define MAX_SPD_SIZE (SPD_PAGE_LEN * 4)
#define SPD_HUB_MEMREG(addr) ((u8)(0x80 | (addr)))
#define SPD5_MR11 0x0B
#define SPD5_MR0 0x00
#define SPD5_MEMREG_REG(addr) ((u8)((~0x80) & (addr)))
#define SPD5_MR0_SPD5_HUB_DEV 0x51
struct spd_offset_table {
u16 start; /* Offset 0 */
u16 end; /* Offset 2 */
};
struct spd_block { struct spd_block {
u8 addr_map[CONFIG_DIMM_MAX]; /* 7 bit I2C addresses */ u8 addr_map[CONFIG_DIMM_MAX]; /* 7 bit I2C addresses */

View File

@@ -209,7 +209,9 @@ enum cb_err spd_fill_from_cache(uint8_t *spd_cache, struct spd_block *blk)
dram_type = *(spd_cache + SC_SPD_OFFSET(i) + SPD_DRAM_TYPE); dram_type = *(spd_cache + SC_SPD_OFFSET(i) + SPD_DRAM_TYPE);
if (dram_type == SPD_DRAM_DDR4) if (dram_type == SPD_DRAM_DDR5)
blk->len = CONFIG_DIMM_SPD_SIZE;
else if (dram_type == SPD_DRAM_DDR4)
blk->len = SPD_PAGE_LEN_DDR4; blk->len = SPD_PAGE_LEN_DDR4;
else else
blk->len = SPD_PAGE_LEN; blk->len = SPD_PAGE_LEN;

View File

@@ -27,7 +27,6 @@ config BOARD_SYSTEM76_RPL_COMMON
config BOARD_SYSTEM76_ADDW3 config BOARD_SYSTEM76_ADDW3
select BOARD_SYSTEM76_RPL_COMMON select BOARD_SYSTEM76_RPL_COMMON
select DRIVERS_INTEL_DTBT
select EC_SYSTEM76_EC_DGPU select EC_SYSTEM76_EC_DGPU
select MAINBOARD_USES_IFD_GBE_REGION select MAINBOARD_USES_IFD_GBE_REGION
select PCIEXP_HOTPLUG select PCIEXP_HOTPLUG
@@ -41,7 +40,6 @@ config BOARD_SYSTEM76_ADDW4
config BOARD_SYSTEM76_BONW15 config BOARD_SYSTEM76_BONW15
select BOARD_SYSTEM76_RPL_COMMON select BOARD_SYSTEM76_RPL_COMMON
select DRIVERS_INTEL_DTBT
select EC_SYSTEM76_EC_DGPU select EC_SYSTEM76_EC_DGPU
select PCIEXP_HOTPLUG select PCIEXP_HOTPLUG
select SOC_INTEL_ALDERLAKE_PCH_S select SOC_INTEL_ALDERLAKE_PCH_S
@@ -76,14 +74,12 @@ config BOARD_SYSTEM76_ORYP11
config BOARD_SYSTEM76_ORYP12 config BOARD_SYSTEM76_ORYP12
select BOARD_SYSTEM76_RPL_COMMON select BOARD_SYSTEM76_RPL_COMMON
select DRIVERS_I2C_TAS5825M select DRIVERS_I2C_TAS5825M
select DRIVERS_INTEL_DTBT
select EC_SYSTEM76_EC_DGPU select EC_SYSTEM76_EC_DGPU
select PCIEXP_HOTPLUG select PCIEXP_HOTPLUG
select SOC_INTEL_ALDERLAKE_PCH_S select SOC_INTEL_ALDERLAKE_PCH_S
config BOARD_SYSTEM76_SERW13 config BOARD_SYSTEM76_SERW13
select BOARD_SYSTEM76_RPL_COMMON select BOARD_SYSTEM76_RPL_COMMON
select DRIVERS_INTEL_DTBT
select EC_SYSTEM76_EC_DGPU select EC_SYSTEM76_EC_DGPU
select PCIEXP_HOTPLUG select PCIEXP_HOTPLUG
select SOC_INTEL_ALDERLAKE_PCH_S select SOC_INTEL_ALDERLAKE_PCH_S

View File

@@ -101,9 +101,6 @@ chip soc/intel/alderlake
.clk_req = 15, .clk_req = 15,
.flags = PCIE_RP_HOTPLUG | PCIE_RP_LTR, .flags = PCIE_RP_HOTPLUG | PCIE_RP_LTR,
}" }"
chip drivers/intel/dtbt
device pci 00.0 on end
end
end end
device ref pcie_rp25 on device ref pcie_rp25 on

View File

@@ -97,9 +97,6 @@ chip soc/intel/alderlake
.clk_req = 15, .clk_req = 15,
.flags = PCIE_RP_HOTPLUG | PCIE_RP_LTR, .flags = PCIE_RP_HOTPLUG | PCIE_RP_LTR,
}" }"
chip drivers/intel/dtbt
device pci 00.0 on end
end
end end
device ref pcie_rp21 on device ref pcie_rp21 on

View File

@@ -116,9 +116,6 @@ chip soc/intel/alderlake
.clk_req = 15, .clk_req = 15,
.flags = PCIE_RP_LTR | PCIE_RP_HOTPLUG, .flags = PCIE_RP_LTR | PCIE_RP_HOTPLUG,
}" }"
chip drivers/intel/dtbt
device pci 00.0 on end
end
end end
end end
end end

View File

@@ -106,9 +106,6 @@ chip soc/intel/alderlake
.clk_req = 15, .clk_req = 15,
.flags = PCIE_RP_LTR | PCIE_RP_HOTPLUG, // XXX: AER causes UnsupReq warnings .flags = PCIE_RP_LTR | PCIE_RP_HOTPLUG, // XXX: AER causes UnsupReq warnings
}" }"
chip drivers/intel/dtbt
device pci 00.0 on end
end
end end
end end
end end

View File

@@ -112,7 +112,7 @@ int cpu_cl_poll_mailbox_ready(u32 cl_mailbox_addr)
u16 stall_cnt = 0; u16 stall_cnt = 0;
do { do {
cl_mailbox_interface.data = read32((u32 *)cl_mailbox_addr); cl_mailbox_interface.data = read32((u32 *)(uintptr_t)cl_mailbox_addr);
udelay(CPU_CRASHLOG_WAIT_STALL); udelay(CPU_CRASHLOG_WAIT_STALL);
stall_cnt++; stall_cnt++;
} while ((cl_mailbox_interface.fields.busy == 1) } while ((cl_mailbox_interface.fields.busy == 1)
@@ -140,7 +140,7 @@ int cpu_cl_mailbox_cmd(u8 cmd, u8 param)
cl_mailbox_intf.fields.param = param; cl_mailbox_intf.fields.param = param;
cl_mailbox_intf.fields.busy = 1; cl_mailbox_intf.fields.busy = 1;
write32((u32 *)(cl_base_addr + cl_get_cpu_mb_int_addr()), write32((u32 *)(uintptr_t)(cl_base_addr + cl_get_cpu_mb_int_addr()),
cl_mailbox_intf.data); cl_mailbox_intf.data);
cpu_cl_poll_mailbox_ready(cl_base_addr + cl_get_cpu_mb_int_addr()); cpu_cl_poll_mailbox_ready(cl_base_addr + cl_get_cpu_mb_int_addr());
@@ -167,7 +167,7 @@ int pmc_cl_gen_descriptor_table(u32 desc_table_addr,
pmc_crashlog_desc_table_t *descriptor_table) pmc_crashlog_desc_table_t *descriptor_table)
{ {
int total_data_size = 0; int total_data_size = 0;
descriptor_table->numb_regions = read32((u32 *)desc_table_addr); descriptor_table->numb_regions = read32((u32 *)(uintptr_t)desc_table_addr);
printk(BIOS_DEBUG, "CL PMC desc table: numb of regions is 0x%x at addr 0x%x\n", printk(BIOS_DEBUG, "CL PMC desc table: numb of regions is 0x%x at addr 0x%x\n",
descriptor_table->numb_regions, desc_table_addr); descriptor_table->numb_regions, desc_table_addr);
for (int i = 0; i < descriptor_table->numb_regions; i++) { for (int i = 0; i < descriptor_table->numb_regions; i++) {
@@ -178,7 +178,7 @@ int pmc_cl_gen_descriptor_table(u32 desc_table_addr,
break; break;
} }
desc_table_addr += 4; desc_table_addr += 4;
descriptor_table->regions[i].data = read32((u32 *)(desc_table_addr)); descriptor_table->regions[i].data = read32((u32 *)(uintptr_t)(desc_table_addr));
total_data_size += descriptor_table->regions[i].bits.size * sizeof(u32); total_data_size += descriptor_table->regions[i].bits.size * sizeof(u32);
printk(BIOS_DEBUG, "CL PMC desc table: region 0x%x has size 0x%x at offset 0x%x\n", printk(BIOS_DEBUG, "CL PMC desc table: region 0x%x has size 0x%x at offset 0x%x\n",
i, descriptor_table->regions[i].bits.size, i, descriptor_table->regions[i].bits.size,
@@ -295,7 +295,7 @@ bool cl_copy_data_from_sram(u32 src_bar,
u32 src_addr = src_bar + offset; u32 src_addr = src_bar + offset;
u32 data = read32((u32 *)src_addr); u32 data = read32((u32 *)(uintptr_t)src_addr);
/* First 32bits of the record must not be 0xdeadbeef */ /* First 32bits of the record must not be 0xdeadbeef */
if (data == INVALID_CRASHLOG_RECORD) { if (data == INVALID_CRASHLOG_RECORD) {
@@ -320,7 +320,7 @@ bool cl_copy_data_from_sram(u32 src_bar,
u32 copied = 0; u32 copied = 0;
while (copied < size) { while (copied < size) {
/* DW by DW copy: byte access to PMC SRAM not allowed */ /* DW by DW copy: byte access to PMC SRAM not allowed */
*dest_addr = read32((u32 *)src_addr); *dest_addr = read32((u32 *)(uintptr_t)src_addr);
dest_addr++; dest_addr++;
src_addr += 4; src_addr += 4;
copied++; copied++;

View File

@@ -13,8 +13,11 @@ static void update_spd_len(struct spd_block *blk)
if (blk->spd_array[i] != NULL) if (blk->spd_array[i] != NULL)
j |= blk->spd_array[i][SPD_DRAM_TYPE]; j |= blk->spd_array[i][SPD_DRAM_TYPE];
/* If spd used is DDR5, then its length is 1024 byte. */
if (j == SPD_DRAM_DDR5)
blk->len = CONFIG_DIMM_SPD_SIZE;
/* If spd used is DDR4, then its length is 512 byte. */ /* If spd used is DDR4, then its length is 512 byte. */
if (j == SPD_DRAM_DDR4) else if (j == SPD_DRAM_DDR4)
blk->len = SPD_PAGE_LEN_DDR4; blk->len = SPD_PAGE_LEN_DDR4;
else else
blk->len = SPD_PAGE_LEN; blk->len = SPD_PAGE_LEN;
@@ -37,6 +40,61 @@ static void smbus_read_spd(u8 *spd, u8 addr)
} }
} }
static void switch_page(u8 spd_addr, u8 new_page)
{
u32 offset;
/*
* By default,an SPD5 hub accepts 1 byte addressing pointing
* to the first 128 bytes of memory. MR11[2:0] selects the page
* pointer to address the entire 1024 bytes of non-volatile memory.
*/
offset = SPD5_MEMREG_REG(SPD5_MR11);
smbus_write_byte(spd_addr, offset, new_page);
}
/*
* Read the SPD data over the SMBus, at the specified SPD address,
* starting at the specified starting offset and read the given amount of data.
*/
static void smbus_read_spd5(u8 *spd, u8 spd_addr, u16 size)
{
u8 page = ~0;
u32 max_page_size = MAX_SPD_PAGE_SIZE_SPD5;
if (size > MAX_SPD_SIZE) {
printk(BIOS_ERR, "Maximum SPD size reached\n");
return;
}
for (int i = 0; i < size; i++) {
u8 next_page = (u8) (i / max_page_size);
if (next_page != page) {
switch_page(spd_addr, next_page);
page = next_page;
}
unsigned int byte_addr = SPD_HUB_MEMREG(i % max_page_size);
spd[i] = smbus_read_byte(spd_addr, byte_addr);
}
}
/* Read SPD5 MR0 and check if SPD Byte 0 matches the SPD5 HUB MR0 identifier.*/
static int is_spd5_hub(u8 spd_addr)
{
u8 spd_hub_byte;
spd_hub_byte = smbus_read_byte(spd_addr, SPD5_MEMREG_REG(SPD5_MR0));
return spd_hub_byte == SPD5_MR0_SPD5_HUB_DEV;
}
/*
* Reset the SPD page back to page 0 on an SPD5 Hub device at the
* input SPD SMbus address.
*/
static void reset_page_spd5(u8 spd_addr)
{
/* Set SPD5 MR11[2:0] = 0 (Page 0) */
smbus_write_byte(spd_addr, SPD5_MEMREG_REG(SPD5_MR11), 0);
}
/* return -1 if SMBus errors otherwise return 0 */ /* return -1 if SMBus errors otherwise return 0 */
static int get_spd(u8 *spd, u8 addr) static int get_spd(u8 *spd, u8 addr)
{ {
@@ -52,22 +110,31 @@ static int get_spd(u8 *spd, u8 addr)
return -1; return -1;
} }
if (i2c_eeprom_read(addr, 0, SPD_PAGE_LEN, spd) < 0) { if (is_spd5_hub(addr)) {
printk(BIOS_INFO, "do_i2c_eeprom_read failed, using fallback\n"); smbus_read_spd5(spd, addr, CONFIG_DIMM_SPD_SIZE);
smbus_read_spd(spd, addr);
}
/* Check if module is DDR4, DDR4 spd is 512 byte. */ /* Reset the page for the next loop iteration */
if (spd[SPD_DRAM_TYPE] == SPD_DRAM_DDR4 && CONFIG_DIMM_SPD_SIZE > SPD_PAGE_LEN) { reset_page_spd5(addr);
/* Switch to page 1 */ } else {
smbus_write_byte(SPD_PAGE_1, 0, 0);
if (i2c_eeprom_read(addr, 0, SPD_PAGE_LEN, spd + SPD_PAGE_LEN) < 0) { if (i2c_eeprom_read(addr, 0, SPD_PAGE_LEN, spd) < 0) {
printk(BIOS_INFO, "do_i2c_eeprom_read failed, using fallback\n"); printk(BIOS_INFO, "do_i2c_eeprom_read failed, using fallback\n");
smbus_read_spd(spd + SPD_PAGE_LEN, addr); smbus_read_spd(spd, addr);
}
/* Check if module is DDR4, DDR4 spd is 512 byte. */
if (spd[SPD_DRAM_TYPE] == SPD_DRAM_DDR4 &&
CONFIG_DIMM_SPD_SIZE > SPD_PAGE_LEN) {
/* Switch to page 1 */
smbus_write_byte(SPD_PAGE_1, 0, 0);
if (i2c_eeprom_read(addr, 0, SPD_PAGE_LEN, spd + SPD_PAGE_LEN) < 0) {
printk(BIOS_INFO, "do_i2c_eeprom_read failed, using fallback\n");
smbus_read_spd(spd + SPD_PAGE_LEN, addr);
}
/* Restore to page 0 */
smbus_write_byte(SPD_PAGE_0, 0, 0);
} }
/* Restore to page 0 */
smbus_write_byte(SPD_PAGE_0, 0, 0);
} }
return 0; return 0;
} }

View File

@@ -34,7 +34,7 @@ static u32 disc_tab_addr;
static u64 get_disc_tab_header(void) static u64 get_disc_tab_header(void)
{ {
return read64((void *)disc_tab_addr); return read64((void *)(uintptr_t)disc_tab_addr);
} }
/* Get the SRAM BAR. */ /* Get the SRAM BAR. */
@@ -338,7 +338,7 @@ static bool cpu_cl_gen_discovery_table(void)
disc_tab_addr = bar_addr + get_disc_table_offset(); disc_tab_addr = bar_addr + get_disc_table_offset();
u32 dw0 = read32((u32 *)disc_tab_addr); u32 dw0 = read32((u32 *)(uintptr_t)disc_tab_addr);
if (!is_crashlog_data_valid(dw0)) if (!is_crashlog_data_valid(dw0))
return false; return false;
@@ -351,7 +351,7 @@ static bool cpu_cl_gen_discovery_table(void)
for (int i = 0; i < cpu_cl_disc_tab.header.fields.count; i++) { for (int i = 0; i < cpu_cl_disc_tab.header.fields.count; i++) {
cur_offset = 8 + 24 * i; cur_offset = 8 + 24 * i;
dw0 = read32((u32 *)disc_tab_addr + cur_offset); dw0 = read32((u32 *)(uintptr_t)disc_tab_addr + cur_offset);
if (!is_crashlog_data_valid(dw0)) if (!is_crashlog_data_valid(dw0))
continue; continue;
@@ -361,7 +361,7 @@ static bool cpu_cl_gen_discovery_table(void)
break; break;
} }
cpu_cl_disc_tab.buffers[i].data = read64((void *)(disc_tab_addr + cur_offset)); cpu_cl_disc_tab.buffers[i].data = read64((void *)(uintptr_t)(disc_tab_addr + cur_offset));
printk(BIOS_DEBUG, "cpu_crashlog_discovery_table buffer: 0x%x size: " printk(BIOS_DEBUG, "cpu_crashlog_discovery_table buffer: 0x%x size: "
"0x%x offset: 0x%x\n", i, cpu_cl_disc_tab.buffers[i].fields.size, "0x%x offset: 0x%x\n", i, cpu_cl_disc_tab.buffers[i].fields.size,
cpu_cl_disc_tab.buffers[i].fields.offset); cpu_cl_disc_tab.buffers[i].fields.offset);
@@ -450,7 +450,7 @@ void cpu_cl_rearm(void)
cl_punit_control_interface_t punit_ctrl_intfc; cl_punit_control_interface_t punit_ctrl_intfc;
memset(&punit_ctrl_intfc, 0, sizeof(cl_punit_control_interface_t)); memset(&punit_ctrl_intfc, 0, sizeof(cl_punit_control_interface_t));
punit_ctrl_intfc.fields.set_re_arm = 1; punit_ctrl_intfc.fields.set_re_arm = 1;
write32((u32 *)(ctrl_sts_intfc_addr), punit_ctrl_intfc.data); write32((u32 *)(uintptr_t)(ctrl_sts_intfc_addr), punit_ctrl_intfc.data);
if (!wait_and_check(CRASHLOG_RE_ARM_STATUS_MASK)) if (!wait_and_check(CRASHLOG_RE_ARM_STATUS_MASK))
printk(BIOS_ERR, "CPU crashlog re_arm not asserted\n"); printk(BIOS_ERR, "CPU crashlog re_arm not asserted\n");
@@ -480,7 +480,7 @@ void cpu_cl_cleanup(void)
cl_punit_control_interface_t punit_ctrl_intfc; cl_punit_control_interface_t punit_ctrl_intfc;
memset(&punit_ctrl_intfc, 0, sizeof(cl_punit_control_interface_t)); memset(&punit_ctrl_intfc, 0, sizeof(cl_punit_control_interface_t));
punit_ctrl_intfc.fields.set_storage_off = 1; punit_ctrl_intfc.fields.set_storage_off = 1;
write32((u32 *)(ctrl_sts_intfc_addr), punit_ctrl_intfc.data); write32((u32 *)(uintptr_t)(ctrl_sts_intfc_addr), punit_ctrl_intfc.data);
if (!wait_and_check(CRASHLOG_PUNIT_STORAGE_OFF_MASK)) if (!wait_and_check(CRASHLOG_PUNIT_STORAGE_OFF_MASK))
printk(BIOS_ERR, "CPU crashlog storage_off not asserted\n"); printk(BIOS_ERR, "CPU crashlog storage_off not asserted\n");