diff options
Diffstat (limited to 'ddr_plot.c')
-rw-r--r-- | ddr_plot.c | 474 |
1 files changed, 474 insertions, 0 deletions
diff --git a/ddr_plot.c b/ddr_plot.c new file mode 100644 index 0000000..c41754b --- /dev/null +++ b/ddr_plot.c @@ -0,0 +1,474 @@ +#include <stdint.h> +#include <stdio.h> + +typedef uint32_t u32; +typedef uint16_t u16; +typedef uint8_t u8; + +#define WL_CALIB_SIZE 28 +enum ddr_speed { DDR_400, DDR_533, DDR_667, DDR_800, DDR_1066 }; + +static const u16 wl_cntl_calib[4][WL_CALIB_SIZE] = { + [DDR_533] = { // same as 667 + 0x80, /* 11:8 WL_CNTRL 0000b 0h 0o + * 7:2 WDLL_CNTL 100000b 20h 40o */ + + 0x80, /* 11:8 WL_CNTRL 0000b 0h 0o + * 7:2 WDLL_CNTL 100000b 20h 40o */ + + 0x80, /* 11:8 WL_CNTRL 0000b 0h 0o + * 7:2 WDLL_CNTL 100000b 20h 40o */ + + 0x850, /* 11:8 WL_CNTRL 1000b 8h 10o + * 7:2 WDLL_CNTL 010100b 14h 24o */ + + 0x860, /* 11:8 WL_CNTRL 1000b 8h 10o + * 7:2 WDLL_CNTL 011000b 18h 30o */ + + 0x870, /* 11:8 WL_CNTRL 1000b 8h 10o + * 7:2 WDLL_CNTL 011100b 1ch 34o */ + + 0x880, /* 11:8 WL_CNTRL 1000b 8h 10o + * 7:2 WDLL_CNTL 100000b 20h 40o */ + + 0x910, /* 11:8 WL_CNTRL 1001b 9h 11o + * 7:2 WDLL_CNTL 000100b 4h 4o */ + + 0x920, /* 11:8 WL_CNTRL 1001b 9h 11o + * 7:2 WDLL_CNTL 001000b 8h 10o */ + + 0x930, /* 11:8 WL_CNTRL 1001b 9h 11o + * 7:2 WDLL_CNTL 001100b ch 14o */ + + 0xB40, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 010000b 10h 20o */ + + 0xB50, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 010100b 14h 24o */ + + 0xB60, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 011000b 18h 30o */ + + 0xB70, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 011100b 1ch 34o */ + + 0xB80, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 100000b 20h 40o */ + + 0xA10, /* 11:8 WL_CNTRL 1010b ah 12o + * 7:2 WDLL_CNTL 000100b 4h 4o */ + + 0xA20, /* 11:8 WL_CNTRL 1010b ah 12o + * 7:2 WDLL_CNTL 001000b 8h 10o */ + + 0xA30, /* 11:8 WL_CNTRL 1010b ah 12o + * 7:2 WDLL_CNTL 001100b ch 14o */ + + 0xC40, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 010000b 10h 20o */ + + 0xC50, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 010100b 14h 24o */ + + 0xC60, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 011000b 18h 30o */ + + 0xC70, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 011100b 1ch 34o */ + + 0xC80, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 100000b 20h 40o */ + + 0xD10, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 000100b 4h 4o */ + + 0xD20, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 001000b 8h 10o */ + + 0xD30, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 001100b ch 14o */ + + 0xD40, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 010000b 10h 20o */ + + 0xD50, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 010100b 14h 24o */ + }, + [DDR_800] = { + 0x60, /* 11:8 WL_CNTRL 0000b 0h 0o + * 7:2 WDLL_CNTL 011000b 18h 30o */ + + 0x60, /* 11:8 WL_CNTRL 0000b 0h 0o + * 7:2 WDLL_CNTL 011000b 18h 30o */ + + 0x60, /* 11:8 WL_CNTRL 0000b 0h 0o + * 7:2 WDLL_CNTL 011000b 18h 30o */ + + 0x83C, /* 11:8 WL_CNTRL 1000b 8h 10o + * 7:2 WDLL_CNTL 001111b fh 17o */ + + 0x848, /* 11:8 WL_CNTRL 1000b 8h 10o + * 7:2 WDLL_CNTL 010010b 12h 22o */ + + 0x854, /* 11:8 WL_CNTRL 1000b 8h 10o + * 7:2 WDLL_CNTL 010101b 15h 25o */ + + 0x860, /* 11:8 WL_CNTRL 1000b 8h 10o + * 7:2 WDLL_CNTL 011000b 18h 30o */ + + 0x90C, /* 11:8 WL_CNTRL 1001b 9h 11o + * 7:2 WDLL_CNTL 000011b 3h 3o */ + + 0x918, /* 11:8 WL_CNTRL 1001b 9h 11o + * 7:2 WDLL_CNTL 000110b 6h 6o */ + + 0x924, /* 11:8 WL_CNTRL 1001b 9h 11o + * 7:2 WDLL_CNTL 001001b 9h 11o */ + + 0xB30, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 001100b ch 14o */ + + 0xB3C, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 001111b fh 17o */ + + 0xB48, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 010010b 12h 22o */ + + 0xB54, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 010101b 15h 25o */ + + 0xB60, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 011000b 18h 30o */ + + 0xA0C, /* 11:8 WL_CNTRL 1010b ah 12o + * 7:2 WDLL_CNTL 000011b 3h 3o */ + + 0xA18, /* 11:8 WL_CNTRL 1010b ah 12o + * 7:2 WDLL_CNTL 000110b 6h 6o */ + + 0xA24, /* 11:8 WL_CNTRL 1010b ah 12o + * 7:2 WDLL_CNTL 001001b 9h 11o */ + + 0xC30, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 001100b ch 14o */ + + 0xC3C, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 001111b fh 17o */ + + 0xC48, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 010010b 12h 22o */ + + 0xC54, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 010101b 15h 25o */ + + 0xC60, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 011000b 18h 30o */ + + 0xD0C, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 000011b 3h 3o */ + + 0xD18, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 000110b 6h 6o */ + + 0xD24, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 001001b 9h 11o */ + + 0xD30, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 001100b ch 14o */ + + 0xD3C, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 001111b fh 17o */ + + }, + [DDR_400] = { + 0xC0, /* 11:8 WL_CNTRL 0000b 0h 0o + * 7:2 WDLL_CNTL 110000b 30h 60o */ + + 0xC0, /* 11:8 WL_CNTRL 0000b 0h 0o + * 7:2 WDLL_CNTL 110000b 30h 60o */ + + 0xC0, /* 11:8 WL_CNTRL 0000b 0h 0o + * 7:2 WDLL_CNTL 110000b 30h 60o */ + + 0x878, /* 11:8 WL_CNTRL 1000b 8h 10o + * 7:2 WDLL_CNTL 011110b 1eh 36o */ + + 0x890, /* 11:8 WL_CNTRL 1000b 8h 10o + * 7:2 WDLL_CNTL 100100b 24h 44o */ + + 0x8A8, /* 11:8 WL_CNTRL 1000b 8h 10o + * 7:2 WDLL_CNTL 101010b 2ah 52o */ + + 0x8C0, /* 11:8 WL_CNTRL 1000b 8h 10o + * 7:2 WDLL_CNTL 110000b 30h 60o */ + + 0x918, /* 11:8 WL_CNTRL 1001b 9h 11o + * 7:2 WDLL_CNTL 000110b 6h 6o */ + + 0x930, /* 11:8 WL_CNTRL 1001b 9h 11o + * 7:2 WDLL_CNTL 001100b ch 14o */ + + 0x948, /* 11:8 WL_CNTRL 1001b 9h 11o + * 7:2 WDLL_CNTL 010010b 12h 22o */ + + 0xB60, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 011000b 18h 30o */ + + 0xB78, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 011110b 1eh 36o */ + + 0xB90, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 100100b 24h 44o */ + + 0xBA8, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 101010b 2ah 52o */ + + 0xBC0, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 110000b 30h 60o */ + + 0xA18, /* 11:8 WL_CNTRL 1010b ah 12o + * 7:2 WDLL_CNTL 000110b 6h 6o */ + + 0xA30, /* 11:8 WL_CNTRL 1010b ah 12o + * 7:2 WDLL_CNTL 001100b ch 14o */ + + 0xA48, /* 11:8 WL_CNTRL 1010b ah 12o + * 7:2 WDLL_CNTL 010010b 12h 22o */ + + 0xC60, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 011000b 18h 30o */ + + 0xC78, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 011110b 1eh 36o */ + + 0xC90, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 100100b 24h 44o */ + + 0xCA8, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 101010b 2ah 52o */ + + 0xCC0, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 110000b 30h 60o */ + + 0xD18, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 000110b 6h 6o */ + + 0xD30, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 001100b ch 14o */ + + 0xD48, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 010010b 12h 22o */ + + 0xD60, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 011000b 18h 30o */ + + 0xD78, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 011110b 1eh 36o */ + + }, + [DDR_667] = { // same as 533 + 0x80, /* 11:8 WL_CNTRL 0000b 0h 0o + * 7:2 WDLL_CNTL 100000b 20h 40o */ + + 0x80, /* 11:8 WL_CNTRL 0000b 0h 0o + * 7:2 WDLL_CNTL 100000b 20h 40o */ + + 0x80, /* 11:8 WL_CNTRL 0000b 0h 0o + * 7:2 WDLL_CNTL 100000b 20h 40o */ + + 0x850, /* 11:8 WL_CNTRL 1000b 8h 10o + * 7:2 WDLL_CNTL 010100b 14h 24o */ + + 0x860, /* 11:8 WL_CNTRL 1000b 8h 10o + * 7:2 WDLL_CNTL 011000b 18h 30o */ + + 0x870, /* 11:8 WL_CNTRL 1000b 8h 10o + * 7:2 WDLL_CNTL 011100b 1ch 34o */ + + 0x880, /* 11:8 WL_CNTRL 1000b 8h 10o + * 7:2 WDLL_CNTL 100000b 20h 40o */ + + 0x910, /* 11:8 WL_CNTRL 1001b 9h 11o + * 7:2 WDLL_CNTL 000100b 4h 4o */ + + 0x920, /* 11:8 WL_CNTRL 1001b 9h 11o + * 7:2 WDLL_CNTL 001000b 8h 10o */ + + 0x930, /* 11:8 WL_CNTRL 1001b 9h 11o + * 7:2 WDLL_CNTL 001100b ch 14o */ + + 0xB40, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 010000b 10h 20o */ + + 0xB50, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 010100b 14h 24o */ + + 0xB60, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 011000b 18h 30o */ + + 0xB70, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 011100b 1ch 34o */ + + 0xB80, /* 11:8 WL_CNTRL 1011b bh 13o + * 7:2 WDLL_CNTL 100000b 20h 40o */ + + 0xA10, /* 11:8 WL_CNTRL 1010b ah 12o + * 7:2 WDLL_CNTL 000100b 4h 4o */ + + 0xA20, /* 11:8 WL_CNTRL 1010b ah 12o + * 7:2 WDLL_CNTL 001000b 8h 10o */ + + 0xA30, /* 11:8 WL_CNTRL 1010b ah 12o + * 7:2 WDLL_CNTL 001100b ch 14o */ + + 0xC40, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 010000b 10h 20o */ + + 0xC50, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 010100b 14h 24o */ + + 0xC60, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 011000b 18h 30o */ + + 0xC70, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 011100b 1ch 34o */ + + 0xC80, /* 11:8 WL_CNTRL 1100b ch 14o + * 7:2 WDLL_CNTL 100000b 20h 40o */ + + 0xD10, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 000100b 4h 4o */ + + 0xD20, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 001000b 8h 10o */ + + 0xD30, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 001100b ch 14o */ + + 0xD40, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 010000b 10h 20o */ + + 0xD50, /* 11:8 WL_CNTRL 1101b dh 15o + * 7:2 WDLL_CNTL 010100b 14h 24o */ + + }, +}; + +static const u32 wdll_misc_calib[WL_CALIB_SIZE] = { + + // Delay CK[5:3] + // CK_L[5:3] +/*0*/ 0x1200002, 0x1200002, 0x1200002, + // 24:24 WLCKDLY 1b 1h 1o + // 22:16 WL_PHSEL_MODE 0100000b 20h 40o + // 11:8 WL_CNTRL 0000b 0h 0o 0 + // 7:4 WL_CNTRL_A 0000b 0h 0o + // 2:0 WL_CMD_DLY 010b 2h 2o + +/*3*/ 0x1200902, 0x1200902, 0x1200902, 0x1200902, + 0x1200902, 0x1200902, 0x1200902, + // 24:24 WLCKDLY 1b 1h 1o + // 22:16 WL_PHSEL_MODE 0100000b 20h 40o + // 11:8 WL_CNTRL 1001b 9h 11o 1/4 CLK + // 7:4 WL_CNTRL_A 0000b 0h 0o + // 2:0 WL_CMD_DLY 010b 2h 2o + +/*10*/ 0x1200802, 0x1200802, 0x1200802, 0x1200802, + 0x1200802, 0x1200802, 0x1200802, 0x1200802, + // 24:24 WLCKDLY 1b 1h 1o + // 22:16 WL_PHSEL_MODE 0100000b 20h 40o + // 11:8 WL_CNTRL 1000b 8h 10o 1/2 CLK + // 7:4 WL_CNTRL_A 0000b 0h 0o + // 2:0 WL_CMD_DLY 010b 2h 2o + +/*18*/ 0x1200B02, 0x1200B02, 0x1200B02, 0x1200B02, + 0x1200B02, 0x1200B02, 0x1200B02, 0x1200B02, + // 24:24 WLCKDLY 1b 1h 1o + // 22:16 WL_PHSEL_MODE 0100000b 20h 40o + // 11:8 WL_CNTRL 1011b bh 13o 3/4 CLK + // 7:4 WL_CNTRL_A 0000b 0h 0o + // 2:0 WL_CMD_DLY 010b 2h 2o + +/*26*/ 0x1200C02, 0x1200C02, + // 24:24 WLCKDLY 1b 1h 1o + // 22:16 WL_PHSEL_MODE 0100000b 20h 40o + // 11:8 WL_CNTRL 1100b ch 14o 1 CLK + // 7:4 WL_CNTRL_A 0000b 0h 0o + // 2:0 WL_CMD_DLY 010b 2h 2o + +}; + +static const int freq_to_int[] = { + [DDR_800] = 800, + [DDR_667] = 667, + [DDR_533] = 533, + [DDR_400] = 400, +}; + +static const int ck_period[] = { /* clock period in 10*picoseconds */ + [DDR_800] = 250, /* 2.5ns */ + [DDR_667] = 300, /* 3ns */ + [DDR_533] = 375, /* 3.75ns */ + [DDR_400] = 500, /* 5ns */ +}; + +#define WL_CNTRL(a) (((a)>>8)&0xf) +#define WDLL_CNTRL(a) (((a)>>2)&0x3f) +#define debug printf + +static double delay(u8 wl_cntrl, double wdll_dly, double clk) +{ + if (((wl_cntrl >> 3) & 1) == 0) return 0; + + switch (wl_cntrl) { + case 8: return wdll_dly; + case 0x9: debug("WILD GUESS... "); return 0.25*clk+wdll_dly; + case 0xb: return 0.25*clk+wdll_dly; + case 0xa: debug("WILD GUESS... "); return 0.5*clk+wdll_dly; + case 0xc: return 0.5*clk+wdll_dly; + case 0xd: return 0.75*clk+wdll_dly; + case 0x19: return 0.25*clk; + case 0x18: return 0.5*clk; + case 0x1b: return 0.75*clk; + case 0x1c: return clk; + } + + return 42424242; +} + +#define MASTCNTL(speed) ((speed) == DDR_400 ? 6 : (speed) == DDR_533 ? 4 : (speed) == DDR_667 ? 4 : /* DDR_800 */ 3 ) +static double wdll_dly(u8 wdll_cntrl, double clk, int mastcntl) +{ + double delay_uncomp = 100; + double delay_element = (0.25*clk - delay_uncomp) / (mastcntl + 0.5); + return (delay_element * wdll_cntrl) / 8; +} + +int main(void) +{ + int i; + int f; + FILE *fi; + char fname[10]; + + for (f = 0; f < 4; f++) { + sprintf(fname, "%d.dat", freq_to_int[f]); + fi = fopen(fname, "w"); + for (i = 0; i < WL_CALIB_SIZE; i++) { + u32 wl_cntl = wl_cntl_calib[f][i]; + u32 wdll_misc = wdll_misc_calib[i]; + u8 wdll_misc_wl_cntrl = (wdll_misc >> 8) & 0xf; + u8 wl_cntrl = WL_CNTRL(wl_cntl); + u8 wdll_cntrl = WDLL_CNTRL(wl_cntl); + int clk = ck_period[f]*10; + double dly = wdll_dly(wdll_cntrl, clk, MASTCNTL(f)); + printf("%d WL_CNTRL=%x WDLL_CNTRL=%02x CLK=%d WDLL_DLY=%lf delay=%lf\n", i, + wl_cntrl, wdll_cntrl, clk, dly, + delay(wl_cntrl, dly, clk)); + if (wl_cntrl != wdll_misc_wl_cntrl) + printf("WARNING: WDLL_MISC.WL_CNTRL=%x\n", wdll_misc_wl_cntrl); + fprintf(fi, "%d %lf\n", i, delay(wl_cntrl, dly, clk)); + } + fclose(fi); + } +} |