Skip to content

Instantly share code, notes, and snippets.

@jernejsk
Created December 6, 2022 20:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jernejsk/1957a252267e72979935f1d5236018c8 to your computer and use it in GitHub Desktop.
Save jernejsk/1957a252267e72979935f1d5236018c8 to your computer and use it in GitHub Desktop.
H616 DRAM settings parser
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
struct dram_para {
uint32_t clk;
uint32_t type;
uint32_t dx_odt;
uint32_t dx_dri;
uint32_t ca_dri;
uint32_t odt_en;
uint32_t para1;
uint32_t para2;
uint32_t mr0;
uint32_t mr1;
uint32_t mr2;
uint32_t mr3;
uint32_t mr4;
uint32_t mr5;
uint32_t mr6;
uint32_t mr11;
uint32_t mr12;
uint32_t mr13;
uint32_t mr14;
uint32_t mr16;
uint32_t mr17;
uint32_t mr22;
uint32_t tpr0;
uint32_t tpr1;
uint32_t tpr2;
uint32_t tpr3;
uint32_t tpr6;
uint32_t tpr10;
uint32_t tpr11;
uint32_t tpr12;
uint32_t tpr13;
};
struct header {
uint32_t jump;
char signature[8];
uint32_t reserved[11];
};
int main(int argc, char** argv)
{
struct dram_para dram;
struct header hdr;
FILE *f;
if (argc < 2) {
printf("Usage: %s <h616 spl file>\n", argv[0]);
return 0;
}
f = fopen(argv[1], "rb");
if (fread(&hdr, sizeof(hdr), 1, f) != 1) {
printf("failed to read header\n");
fclose(f);
return 0;
}
if (strncmp(hdr.signature, "eGON.BT0", 8)) {
printf("incorrect signature\n");
fclose(f);
return 0;
}
if (fread(&dram, sizeof(dram), 1, f) != 1) {
printf("failed to read dram config\n");
fclose(f);
return 0;
}
fclose(f);
printf("Vendor DRAM config for your H616 board is:\n");
printf("dram_clk: %d\n", dram.clk);
printf("dram_type: %d\n", dram.type);
printf("dram_dx_odt: 0x%08x\n", dram.dx_odt);
printf("dram_dx_dri: 0x%08x\n", dram.dx_dri);
printf("dram_ca_dri: 0x%08x\n", dram.ca_dri);
printf("dram_odt_en: 0x%08x\n", dram.odt_en);
printf("dram_para1: 0x%08x\n", dram.para1);
printf("dram_para2: 0x%08x\n", dram.para2);
printf("dram_mr0: 0x%08x\n", dram.mr0);
printf("dram_mr1: 0x%08x\n", dram.mr1);
printf("dram_mr2: 0x%08x\n", dram.mr2);
printf("dram_mr3: 0x%08x\n", dram.mr3);
printf("dram_mr4: 0x%08x\n", dram.mr4);
printf("dram_mr5: 0x%08x\n", dram.mr5);
printf("dram_mr6: 0x%08x\n", dram.mr6);
printf("dram_mr11: 0x%08x\n", dram.mr11);
printf("dram_mr12: 0x%08x\n", dram.mr12);
printf("dram_mr13: 0x%08x\n", dram.mr13);
printf("dram_mr14: 0x%08x\n", dram.mr14);
printf("dram_mr16: 0x%08x\n", dram.mr16);
printf("dram_mr17: 0x%08x\n", dram.mr17);
printf("dram_mr22: 0x%08x\n", dram.mr22);
printf("dram_tpr0: 0x%08x\n", dram.tpr0);
printf("dram_tpr1: 0x%08x\n", dram.tpr1);
printf("dram_tpr2: 0x%08x\n", dram.tpr2);
printf("dram_tpr3: 0x%08x\n", dram.tpr3);
printf("dram_tpr6: 0x%08x\n", dram.tpr6);
printf("dram_tpr10: 0x%08x\n", dram.tpr10);
printf("dram_tpr11: 0x%08x\n", dram.tpr11);
printf("dram_tpr12: 0x%08x\n", dram.tpr12);
printf("dram_tpr13: 0x%08x\n\n", dram.tpr13);
if (dram.type != 3) {
printf("Only DDR3 is supported by mainline U-Boot\n");
return 0;
}
printf("Use following settings for mainline U-Boot:\n");
printf("CONFIG_DRAM_CLK=%d\n", dram.clk);
/*
* ODT is always enabled in vendor DRAM code. I guess dram_odt_en
* parameter should tell if it's used or not
*/
printf("CONFIG_DRAM_ODT_EN=y\n");
if (dram.tpr10 & 0x10000)
printf("CONFIG_DRAM_SUN50I_H616_UNKNOWN_FEATURE=y\n");
/*
* FIXME: is "if (dram.tpr10 & 0x80000)" check correct here? It's
* more likely that bit delay compensation should be always enabled.
*/
printf("CONFIG_DRAM_SUN50I_H616_BIT_DELAY_COMPENSATION=y\n");
if (dram.tpr10 & 0x100000)
printf("CONFIG_DRAM_SUN50I_H616_WRITE_LEVELING=y\n");
if (dram.tpr10 & 0x200000)
printf("CONFIG_DRAM_SUN50I_H616_READ_CALIBRATION=y\n");
if (dram.tpr10 & 0x400000)
printf("CONFIG_DRAM_SUN50I_H616_READ_TRAINING=y\n");
if (dram.tpr10 & 0x800000)
printf("CONFIG_DRAM_SUN50I_H616_WRITE_TRAINING=y\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment