Files

138 lines
3.4 KiB
C

// SPDX-License-Identifier: GPL-2.0+
#include <common.h>
#include <command.h>
#include <linux/io.h>
#include "ddr_if.h"
#define REG_DQ_W_BDL_BASE 0x12104110
#define REG_DQ_R_BDL_BASE 0x12104130
#define REG_DQ_RES_SW 0x12101020
int get_result(struct ddr_training_result *result)
{
int i, j;
unsigned int *result_w, *result_r, *best_w, *best_r;
memset(result, 0, sizeof(struct ddr_training_result));
result->phy_num = DDR_PHY_NUM;
result->phy[0].rank_num = 1;
result->phy[0].rank[0].rank_idx = 0;
result->phy[0].rank[0].ddrtr_data.byte_num = 4;
result_w = result->phy[0].rank[0].ddrtr_data.write.ddr_bit_result;
result_r = result->phy[0].rank[0].ddrtr_data.read.ddr_bit_result;
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
unsigned int v = readl(REG_DQ_W_BDL_BASE + 0x1000 * i + j * 4);
result_w[i * 8 + j * 2] |= v & 0xff;
result_w[i * 8 + j * 2 + 1] |= (v >> 16) & 0xff;
}
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
unsigned int v = readl(REG_DQ_R_BDL_BASE + 0x1000 * i + j * 4);
result_r[i * 8 + j * 2] |= v & 0xff;
result_r[i * 8 + j * 2 + 1] |= (v >> 16) & 0xff;
}
}
/* Switch to getting min bdl */
writel(1, REG_DQ_RES_SW);
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
unsigned int v = readl(REG_DQ_W_BDL_BASE + 0x1000 * i + j * 4);
result_w[i * 8 + j * 2] |= (v & 0xff) << DDR_DATAEYE_RESULT_BIT;
result_w[i * 8 + j * 2 + 1] |= (v >> 16 & 0xff) << DDR_DATAEYE_RESULT_BIT;
}
}
for (i = 0; i < 4; i++) {
for (j = 0; j < 4; j++) {
unsigned int v = readl(REG_DQ_R_BDL_BASE + 0x1000 * i + j * 4);
result_r[i * 8 + j * 2] |= (v & 0xff) << DDR_DATAEYE_RESULT_BIT;
result_r[i * 8 + j * 2 + 1] |= (v >> 16 & 0xff) << DDR_DATAEYE_RESULT_BIT;
}
}
/* Restore function mode */
writel(0, REG_DQ_RES_SW);
best_w = result->phy[0].rank[0].ddrtr_data.write.ddr_bit_best;
best_r = result->phy[0].rank[0].ddrtr_data.read.ddr_bit_best;
for (i = 0; i < DDR_PHY_BIT_MAX; ++i) {
unsigned int res;
unsigned short max, min;
res = result_w[i];
min = res >> DDR_DATAEYE_RESULT_BIT;
max = (res & DDR_DATAEYE_RESULT_MASK) * 2 - min;
result_w[i] = (min << DDR_DATAEYE_RESULT_BIT) | max;
best_w[i] = (res & DDR_DATAEYE_RESULT_MASK) | ((max - min) << DDR_DATAEYE_RESULT_BIT);
res = result_r[i];
min = res >> DDR_DATAEYE_RESULT_BIT;
max = (res & DDR_DATAEYE_RESULT_MASK) * 2 - min;
result_r[i] = (min << DDR_DATAEYE_RESULT_BIT) | max;
best_r[i] = (res & DDR_DATAEYE_RESULT_MASK) | ((max - min) << DDR_DATAEYE_RESULT_BIT);
}
return 0;
}
void show_win_reg(void)
{
int i;
printf("DDR DQ Win REGs\n");
printf("------------------------------------------------------\n");
printf("Avg BDL of Writing:\n");
writel(0x0, REG_DQ_RES_SW);
for (i = 0; i < 4; ++i) {
unsigned long addr = REG_DQ_W_BDL_BASE + 0x1000 * i;
print_buffer(addr, (void *)addr, 4, 4, 4);
}
printf("Min BDL of Writing:\n");
writel(0x1, REG_DQ_RES_SW);
for (i = 0; i < 4; ++i) {
unsigned long addr = REG_DQ_W_BDL_BASE + 0x1000 * i;
print_buffer(addr, (void *)addr, 4, 4, 4);
}
printf("Avg BDL of Reading:\n");
writel(0x0, REG_DQ_RES_SW);
for (i = 0; i < 4; ++i) {
unsigned long addr = REG_DQ_R_BDL_BASE + 0x1000 * i;
print_buffer(addr, (void *)addr, 4, 4, 4);
}
printf("Min BDL of Reading:\n");
writel(0x1, REG_DQ_RES_SW);
for (i = 0; i < 4; ++i) {
unsigned long addr = REG_DQ_R_BDL_BASE + 0x1000 * i;
print_buffer(addr, (void *)addr, 4, 4, 4);
}
writel(0x0, REG_DQ_RES_SW);
}