/* STB Spill to DRAM Message Definition */ #define STB_FORCE_FLUSH_DATA 0xCF #define FIFO_SIZE 4096
/* STB S2D(Spill to DRAM) has different message port offset */ #define AMD_S2D_REGISTER_MESSAGE 0xA20 #define AMD_S2D_REGISTER_RESPONSE 0xA80 #define AMD_S2D_REGISTER_ARGUMENT 0xA88
/* STB S2D (Spill to DRAM) message port offset for 44h model */ #define AMD_GNR_REGISTER_MESSAGE 0x524 #define AMD_GNR_REGISTER_RESPONSE 0x570 #define AMD_GNR_REGISTER_ARGUMENT 0xA40
int amd_stb_write(struct amd_pmc_dev *dev, u32 data)
{ int err;
err = amd_smn_write(0, AMD_STB_PMI_0, data); if (err) {
dev_err(dev->dev, "failed to write data in stb: 0x%X\n", AMD_STB_PMI_0); return pcibios_err_to_errno(err);
}
return 0;
}
int amd_stb_read(struct amd_pmc_dev *dev, u32 *buf)
{ int i, err;
for (i = 0; i < FIFO_SIZE; i++) {
err = amd_smn_read(0, AMD_STB_PMI_0, buf++); if (err) {
dev_err(dev->dev, "error reading data from stb: 0x%X\n", AMD_STB_PMI_0); return pcibios_err_to_errno(err);
}
}
/* Write dummy postcode while reading the STB buffer */
ret = amd_stb_write(dev, AMD_PMC_STB_DUMMY_PC); if (ret)
dev_err(dev->dev, "error writing to STB: %d\n", ret);
/* Spill to DRAM num_samples uses separate SMU message port */
dev->msg_port = MSG_PORT_S2D;
ret = amd_pmc_send_cmd(dev, 0, &val, STB_FORCE_FLUSH_DATA, 1); if (ret)
dev_dbg_once(dev->dev, "S2D force flush not supported: %d\n", ret);
/* * We have a custom stb size and the PMFW is supposed to give * the enhanced dram size. Note that we land here only for the * platforms that support enhanced dram size reporting.
*/ if (dump_custom_stb) return amd_stb_handle_efr(filp);
/* Get the num_samples to calculate the last push location */
ret = amd_pmc_send_cmd(dev, S2D_NUM_SAMPLES, &num_samples, dev->stb_arg.s2d_msg_id, true); /* Clear msg_port for other SMU operation */
dev->msg_port = MSG_PORT_PMC; if (ret) {
dev_err(dev->dev, "error: S2D_NUM_SAMPLES not supported : %d\n", ret); return ret;
}
/* * Start capturing data from the last push location. * This is for general cases, where the stb limits * are meant for standard usage.
*/ if (num_samples > S2D_TELEMETRY_BYTES_MAX) { /* First read oldest data starting 1 behind last write till end of ringbuffer */
stb_rdptr_offset = num_samples % S2D_TELEMETRY_BYTES_MAX;
fsize = S2D_TELEMETRY_BYTES_MAX - stb_rdptr_offset;
memcpy_fromio(stb_data_arr->data, dev->stb_virt_addr + stb_rdptr_offset, fsize); /* Second copy the newer samples from offset 0 - last write */
memcpy_fromio(stb_data_arr->data + fsize, dev->stb_virt_addr, stb_rdptr_offset);
} else {
memcpy_fromio(stb_data_arr->data, dev->stb_virt_addr, fsize);
}
/* Get DRAM size */
ret = amd_pmc_send_cmd(dev, S2D_DRAM_SIZE, &dev->dram_size, dev->stb_arg.s2d_msg_id, true); if (ret || !dev->dram_size)
dev->dram_size = S2D_TELEMETRY_DRAMBYTES_MAX;
/* Get STB DRAM address */
amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_LOW, &phys_addr_low, dev->stb_arg.s2d_msg_id, true);
amd_pmc_send_cmd(dev, S2D_PHYS_ADDR_HIGH, &phys_addr_hi, dev->stb_arg.s2d_msg_id, true);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.