huayang duan has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/34332 )
Change subject: mediatek/mt8183: support DDR frequency 3600Mbps ......................................................................
mediatek/mt8183: support DDR frequency 3600Mbps
DDR frequency fix at 3600Mbps
BUG=b:80501386 BRANCH=none TEST=Memory test pass on EMCP platform Signed-off-by: Huayang Duan huayang.duan@mediatek.com
Change-Id: Ic1378ca43fb333c445ca77e7dc0844cdf65f2207 --- M src/soc/mediatek/mt8183/dramc_init_setting.c M src/soc/mediatek/mt8183/dramc_pi_calibration_api.c M src/soc/mediatek/mt8183/emi.c M src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h M src/soc/mediatek/mt8183/include/soc/dramc_register.h 5 files changed, 1,677 insertions(+), 262 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/32/34332/1
diff --git a/src/soc/mediatek/mt8183/dramc_init_setting.c b/src/soc/mediatek/mt8183/dramc_init_setting.c index 09bec01..90b17c4 100644 --- a/src/soc/mediatek/mt8183/dramc_init_setting.c +++ b/src/soc/mediatek/mt8183/dramc_init_setting.c @@ -20,6 +20,8 @@ #include <soc/dramc_register.h> #include <soc/infracfg.h>
+extern u32 freqTbl[LP4X_DDRFREQ_MAX]; + struct reg_init_value { u32 *addr; u32 value; @@ -1084,15 +1086,1223 @@ {&ch[1].ao.mrs, 0x00000dd8}, };
-void dramc_init(void) -{ - for (int i = 0; i < ARRAY_SIZE(dramc_init_sequence); i++) - write32(dramc_init_sequence[i].addr, - dramc_init_sequence[i].value); +struct reg_init_value dramc_init_sequence_3600[] = { + {(u32 *)0x100010b4, 0x00000000}, + {(u32 *)0x1022a04c, 0x20712000}, + {(u32 *)0x1023204c, 0x20712000}, + {(u32 *)0x1022a024, 0x00100480}, + {(u32 *)0x10232024, 0x00100480}, + {(u32 *)0x100010b4, 0x0000001f}, + {(u32 *)0x100010b4, 0x00000000}, + {(u32 *)0x10228308, 0x00000003}, + {(u32 *)0x10230308, 0x00000003}, + {(u32 *)0x100010b4, 0x0000001f}, + {(u32 *)0x10228284, 0x00000101}, + {(u32 *)0x10228284, 0x00000101}, + {(u32 *)0x1022829c, 0x38010000}, + {(u32 *)0x10228278, 0x00000000}, + {(u32 *)0x1022827c, 0x00000000}, + {(u32 *)0x10228274, 0x00000000}, + {(u32 *)0x1022828c, 0x006003bf}, + {(u32 *)0x10228294, 0x333f3f00}, + {(u32 *)0x10228d84, 0x0000001f}, + {(u32 *)0x10228c1c, 0x00000010}, + {(u32 *)0x10228c9c, 0x00000000}, + {(u32 *)0x10228d90, 0xe57800ff}, + {(u32 *)0x10228d98, 0xe57800ff}, + {(u32 *)0x10228db8, 0x00000000}, + {(u32 *)0x10228dd0, 0x00000000}, + {(u32 *)0x102281a0, 0x00000000}, + {(u32 *)0x102280a0, 0x00000000}, + {(u32 *)0x10228120, 0x00000000}, + {(u32 *)0x102280bc, 0x10000000}, + {(u32 *)0x1022813c, 0x10000000}, + {(u32 *)0x102281c0, 0x00000000}, + {(u32 *)0x102285f0, 0x10000022}, + {(u32 *)0x10228670, 0x10000022}, + {(u32 *)0x102285f0, 0x10000222}, + {(u32 *)0x10228670, 0x10000222}, + {(u32 *)0x10228608, 0x20000000}, + {(u32 *)0x10228808, 0x20000000}, + {(u32 *)0x10228c14, 0x0030000e}, + {(u32 *)0x10228604, 0x00020002}, + {(u32 *)0x10228608, 0xb0800000}, + {(u32 *)0x10228804, 0x00020002}, + {(u32 *)0x10228808, 0xb0800000}, + {(u32 *)0x10228688, 0x20000000}, + {(u32 *)0x10228888, 0x20000000}, + {(u32 *)0x10228c94, 0x0030000e}, + {(u32 *)0x10228684, 0x00020002}, + {(u32 *)0x10228688, 0xb0800000}, + {(u32 *)0x10228884, 0x00020002}, + {(u32 *)0x10228888, 0xb0800000}, + {(u32 *)0x102285f0, 0x00000222}, + {(u32 *)0x10228670, 0x00000222}, + {(u32 *)0x102280bc, 0x10000001}, + {(u32 *)0x10228e1c, 0x001f1f00}, + {(u32 *)0x10228f1c, 0x001f1f00}, + {(u32 *)0x102280a8, 0x00001010}, + {(u32 *)0x102280ac, 0x00110e10}, + {(u32 *)0x102280b0, 0x010310c0}, + {(u32 *)0x102280ac, 0x02110e00}, + {(u32 *)0x1022813c, 0x10000001}, + {(u32 *)0x10228e6c, 0x001f1f00}, + {(u32 *)0x10228f6c, 0x001f1f00}, + {(u32 *)0x10228128, 0x00001010}, + {(u32 *)0x1022812c, 0x00110e10}, + {(u32 *)0x10228130, 0x010310c0}, + {(u32 *)0x1022812c, 0x02110e00}, + {(u32 *)0x102281a4, 0x0000008c}, + {(u32 *)0x102281b0, 0x00020000}, + {(u32 *)0x10228008, 0x00000011}, + {(u32 *)0x102280a4, 0x00000008}, + {(u32 *)0x10228124, 0x00000008}, + {(u32 *)0x10228da0, 0x00040000}, + {(u32 *)0x10228da4, 0x00000000}, + {(u32 *)0x10228dac, 0x00000000}, + {(u32 *)0x10228da8, 0x00040000}, + {(u32 *)0x1022800c, 0x000c0000}, + {(u32 *)0x10228d80, 0x00000003}, + {(u32 *)0x10228184, 0x00200000}, + {(u32 *)0x102280a4, 0x0000040e}, + {(u32 *)0x10228124, 0x0000040e}, + {(u32 *)0x100010b4, 0x00000000}, + {(u32 *)0x10228d34, 0x00666009}, + {(u32 *)0x10230d34, 0x00666009}, + {(u32 *)0x100010b4, 0x0000001f}, + {(u32 *)0x10228c34, 0xc0778608}, + {(u32 *)0x10228cb4, 0xc0778608}, + {(u32 *)0x10228d14, 0x00000000}, + {(u32 *)0x10228d00, 0x00104010}, + {(u32 *)0x100010b4, 0x00000000}, + {(u32 *)0x10228d18, 0x000000c0}, + {(u32 *)0x10230d18, 0x00000040}, + {(u32 *)0x100010b4, 0x0000001f}, + {(u32 *)0x10228c18, 0x00000040}, + {(u32 *)0x10228c98, 0x00000040}, + {(u32 *)0x100010b4, 0x00000000}, + {(u32 *)0x10228270, 0x00050909}, + {(u32 *)0x10230270, 0x00090909}, + {(u32 *)0x10228d38, 0x00000004}, + {(u32 *)0x10230d38, 0x00000001}, + {(u32 *)0x100010b4, 0x0000001f}, + {(u32 *)0x10228c38, 0x00000001}, + {(u32 *)0x10228cb8, 0x00000001}, + {(u32 *)0x10228004, 0x00000000}, + {(u32 *)0x10228284, 0x0000000f}, + {(u32 *)0x100010b4, 0x00000000},
- for (int i = 0; i < ARRAY_SIZE(dramc_mode_reg_init_sequence); i++) { - write32(dramc_mode_reg_init_sequence[i].addr, - dramc_mode_reg_init_sequence[i].value); - udelay(2); + //ddr_phy_reserved_rg_setting line + {(u32 *)0x10228d18, 0x000607c0}, + {(u32 *)0x10230d18, 0x000607c0}, + {(u32 *)0x10228d38, 0x0004e104}, + {(u32 *)0x10228c18, 0x00060740}, + {(u32 *)0x10228c38, 0x00022401}, + {(u32 *)0x10228c98, 0x00060740}, + {(u32 *)0x10228cb8, 0x00022401}, + {(u32 *)0x10230d38, 0x0004e101}, + {(u32 *)0x10230c18, 0x00060740}, + {(u32 *)0x10230c38, 0x00022401}, + {(u32 *)0x10230c98, 0x00060740}, + {(u32 *)0x10230cb8, 0x00022401}, + //ddr_phy_pll_setting + {(u32 *)0x10228d90, 0xe5780000}, + {(u32 *)0x10228d98, 0xe5780000}, + {(u32 *)0x10228270, 0x00050909}, + {(u32 *)0x10228308, 0x00000003}, + {(u32 *)0x10228d00, 0x00144010}, + {(u32 *)0x1022a210, 0x00000000}, + {(u32 *)0x10228d34, 0x00698619}, + {(u32 *)0x10228d38, 0x0004e104}, + {(u32 *)0x10228d18, 0x000607c0}, + {(u32 *)0x102280b4, 0x00000055}, + {(u32 *)0x10228134, 0x00000055}, + {(u32 *)0x102281b4, 0x00000055}, + {(u32 *)0x102281a0, 0x00200000}, + {(u32 *)0x10228284, 0x0000000f}, + {(u32 *)0x10228c18, 0x00060740}, + {(u32 *)0x10228c98, 0x00060740}, + {(u32 *)0x10228d18, 0x000607c0}, + {(u32 *)0x1022800c, 0x000c0000}, + {(u32 *)0x10228000, 0x00000000}, + {(u32 *)0x10228004, 0x00000000}, + {(u32 *)0x10228188, 0x00000000}, + {(u32 *)0x10228088, 0x00000000}, + {(u32 *)0x10228108, 0x00000000}, + {(u32 *)0x10228088, 0x880aec00}, + {(u32 *)0x10228108, 0x880aec00}, + {(u32 *)0x10228188, 0x880bac00}, + {(u32 *)0x10228180, 0x00000000}, + {(u32 *)0x10228080, 0x00000000}, + {(u32 *)0x10228100, 0x00000000}, + {(u32 *)0x10228da0, 0x00040000}, + {(u32 *)0x10228da8, 0x00040000}, + {(u32 *)0x10228d94, 0x8a000002}, + {(u32 *)0x10228d9c, 0x8a000002}, + {(u32 *)0x10228180, 0x00000002}, + {(u32 *)0x10228080, 0x00000002}, + {(u32 *)0x10228100, 0x00000002}, + {(u32 *)0x10228184, 0x00200000}, + {(u32 *)0x10228084, 0x00000000}, + {(u32 *)0x10228104, 0x00000000}, + {(u32 *)0x10228c18, 0x02460740}, + {(u32 *)0x10228c98, 0x02460740}, + {(u32 *)0x10228d18, 0x024607c0}, + {(u32 *)0x10228180, 0x0000000a}, + {(u32 *)0x10228080, 0x0000000a}, + {(u32 *)0x10228100, 0x0000000a}, + {(u32 *)0x10228000, 0x80000000}, + {(u32 *)0x10228004, 0x80000000}, + {(u32 *)0x1022800c, 0x004d0000}, + {(u32 *)0x10228c18, 0x06460740}, + {(u32 *)0x10228c98, 0x06460740}, + {(u32 *)0x10228d18, 0x064607c0}, + {(u32 *)0x1022818c, 0x000ba000}, + {(u32 *)0x1022808c, 0x0002e800}, + {(u32 *)0x1022810c, 0x0002e800}, + {(u32 *)0x10228188, 0x00000800}, + {(u32 *)0x10228088, 0x00000800}, + {(u32 *)0x10228108, 0x00000800}, + {(u32 *)0x10228188, 0x00000800}, + {(u32 *)0x10228088, 0x00000000}, + {(u32 *)0x10228108, 0x00000000}, + {(u32 *)0x10228284, 0x0000001f}, + {(u32 *)0x10228188, 0x00000801}, + {(u32 *)0x10228088, 0x00000001}, + {(u32 *)0x10228108, 0x00000001}, + {(u32 *)0x102281a0, 0x00000000}, + {(u32 *)0x102280b4, 0x00000040}, + {(u32 *)0x10228134, 0x00000040}, + {(u32 *)0x102281b4, 0x00000040}, + {(u32 *)0x1022a024, 0x00100400}, + {(u32 *)0x10232024, 0x00100400}, + {(u32 *)0x10228d94, 0x8a000003}, + {(u32 *)0x10228d9c, 0x8a000003}, + {(u32 *)0x10228db8, 0x00000002}, + {(u32 *)0x10228dd0, 0x00000002}, + {(u32 *)0x10228db8, 0x02080002}, + {(u32 *)0x10228dd0, 0x02080002}, + {(u32 *)0x10228dbc, 0x0d960000}, + {(u32 *)0x10228dd4, 0x0d960000}, + + {(u32 *)0x10230d90, 0x00000000}, + {(u32 *)0x10230d98, 0x00000000}, + {(u32 *)0x10230270, 0x00090909}, + {(u32 *)0x10230308, 0x00000003}, + {(u32 *)0x10230d00, 0x00144010}, + {(u32 *)0x10232210, 0x00000000}, + {(u32 *)0x10230d34, 0xc0778609}, + {(u32 *)0x10230d38, 0x0004e101}, + {(u32 *)0x10230d18, 0x00060740}, + {(u32 *)0x102300b4, 0x00000055}, + {(u32 *)0x10230134, 0x00000055}, + {(u32 *)0x102301b4, 0x00000055}, + {(u32 *)0x102301a0, 0x00200000}, + {(u32 *)0x10230284, 0x0000000f}, + {(u32 *)0x10230c18, 0x00060740}, + {(u32 *)0x10230c98, 0x00060740}, + {(u32 *)0x10230d18, 0x00060740}, + {(u32 *)0x1023000c, 0x00000000}, + {(u32 *)0x10230000, 0x00000000}, + {(u32 *)0x10230004, 0x00000000}, + {(u32 *)0x10230188, 0x00000000}, + {(u32 *)0x10230088, 0x00000000}, + {(u32 *)0x10230108, 0x00000000}, + {(u32 *)0x10230088, 0x880aec00}, + {(u32 *)0x10230108, 0x880aec00}, + {(u32 *)0x10230188, 0x880bac00}, + {(u32 *)0x10230180, 0x00000000}, + {(u32 *)0x10230080, 0x00000000}, + {(u32 *)0x10230100, 0x00000000}, + {(u32 *)0x10230da0, 0x00040000}, + {(u32 *)0x10230da8, 0x00040000}, + {(u32 *)0x10230d94, 0x8a000000}, + {(u32 *)0x10230d9c, 0x8a000000}, + {(u32 *)0x10230180, 0x00000002}, + {(u32 *)0x10230080, 0x00000002}, + {(u32 *)0x10230100, 0x00000002}, + {(u32 *)0x10230184, 0x00200000}, + {(u32 *)0x10230084, 0x00000000}, + {(u32 *)0x10230104, 0x00000000}, + {(u32 *)0x10230c18, 0x02460740}, + {(u32 *)0x10230c98, 0x02460740}, + {(u32 *)0x10230d18, 0x02460740}, + {(u32 *)0x10230180, 0x0000000a}, + {(u32 *)0x10230080, 0x0000000a}, + {(u32 *)0x10230100, 0x0000000a}, + {(u32 *)0x10230000, 0x80000000}, + {(u32 *)0x10230004, 0x80000000}, + {(u32 *)0x1023000c, 0x00410000}, + {(u32 *)0x10230c18, 0x06460740}, + {(u32 *)0x10230c98, 0x06460740}, + {(u32 *)0x10230d18, 0x06460740}, + {(u32 *)0x1023018c, 0x0003a000}, + {(u32 *)0x1023008c, 0x0002e800}, + {(u32 *)0x1023010c, 0x0002e800}, + {(u32 *)0x10230188, 0x00000800}, + {(u32 *)0x10230088, 0x00000800}, + {(u32 *)0x10230108, 0x00000800}, + {(u32 *)0x10230188, 0x00000800}, + {(u32 *)0x10230088, 0x00000000}, + {(u32 *)0x10230108, 0x00000000}, + {(u32 *)0x10230284, 0x0000001f}, + {(u32 *)0x10230188, 0x00000801}, + {(u32 *)0x10230088, 0x00000001}, + {(u32 *)0x10230108, 0x00000001}, + {(u32 *)0x102301a0, 0x00000000}, + {(u32 *)0x102300b4, 0x00000040}, + {(u32 *)0x10230134, 0x00000040}, + {(u32 *)0x102301b4, 0x00000040}, + {(u32 *)0x1022a024, 0x00100400}, + {(u32 *)0x10232024, 0x00100400}, + {(u32 *)0x10230d94, 0x00000001}, + {(u32 *)0x10230d9c, 0x00000001}, + {(u32 *)0x10230db8, 0x00000002}, + {(u32 *)0x10230dd0, 0x00000002}, + {(u32 *)0x10230db8, 0x02080000}, + {(u32 *)0x10230dd0, 0x02080000}, + {(u32 *)0x10230dbc, 0x0d960000}, + {(u32 *)0x10230dd4, 0x0d960000}, + {(u32 *)0x100010b4, 0x0000001f}, + {(u32 *)0x1022a028, 0x20080000}, + {(u32 *)0x1022a024, 0x08100400}, + {(u32 *)0x1022a004, 0x30822201}, + {(u32 *)0x1022a064, 0x200007d2}, + {(u32 *)0x102280bc, 0x10000011}, + {(u32 *)0x1022813c, 0x10000011}, + {(u32 *)0x1022ab04, 0x0f0f0f0f}, + {(u32 *)0x1022a204, 0x00014310}, + {(u32 *)0x1022ac54, 0x80200608}, + {(u32 *)0x1022a8a8, 0x14a5294a}, + {(u32 *)0x1022a8ac, 0x14a5294a}, + {(u32 *)0x1022a8b0, 0x14a5294a}, + {(u32 *)0x1022a8b4, 0x14a5294a}, + {(u32 *)0x1022a0dc, 0x0001d00a}, + {(u32 *)0x1022a210, 0x00000001}, + {(u32 *)0x1022a000, 0x04109000}, + {(u32 *)0x1022a208, 0x70000010}, + {(u32 *)0x1022a208, 0x50000010}, + {(u32 *)0x1022a03c, 0x020c0000}, + {(u32 *)0x102280bc, 0x10100011}, + {(u32 *)0x1022813c, 0x10100011}, + {(u32 *)0x102281c0, 0x00000000}, + {(u32 *)0x1022829c, 0xb901020f}, + {(u32 *)0x102282a0, 0x8100908c}, + {(u32 *)0x102302a0, 0x8100908c}, + {(u32 *)0x102285f0, 0x01000222}, + {(u32 *)0x10228670, 0x01000222}, + {(u32 *)0x102286f0, 0x00000000}, + {(u32 *)0x102281b4, 0x00000000}, + {(u32 *)0x102280b4, 0x00000000}, + {(u32 *)0x10228134, 0x00000000}, + {(u32 *)0x1022a840, 0xa10810bf}, + {(u32 *)0x1022a860, 0xc0010003}, + {(u32 *)0x10228c1c, 0x00008010}, + {(u32 *)0x10228c9c, 0x00008000}, + {(u32 *)0x1022a04c, 0x25712000}, + {(u32 *)0x1022a880, 0x00000000}, + {(u32 *)0x1022a884, 0x00070000}, + {(u32 *)0x1022a888, 0x00000000}, + {(u32 *)0x1022a88c, 0x00000000}, + {(u32 *)0x1022a890, 0x11111011}, + {(u32 *)0x1022a8a0, 0x33333333}, + {(u32 *)0x1022a8a4, 0x11114444}, + + {(u32 *)0x1022aa2c, 0x33333333}, + {(u32 *)0x1022aa30, 0x33333333}, + {(u32 *)0x1022aa34, 0x22226666}, + {(u32 *)0x1022aa38, 0x22226666}, + {(u32 *)0x1022ab2c, 0x33333333}, + {(u32 *)0x1022ab30, 0x33333333}, + {(u32 *)0x1022ab34, 0x22226666}, + {(u32 *)0x1022ab38, 0x22226666}, + {(u32 *)0x10228e1c, 0x001a1a00}, + {(u32 *)0x10228f1c, 0x00141400}, + {(u32 *)0x10228e6c, 0x001a1a00}, + {(u32 *)0x10228f6c, 0x00141400}, + {(u32 *)0x102280bc, 0x10100031}, + {(u32 *)0x102280b0, 0x010350c0}, + {(u32 *)0x1022813c, 0x10100031}, + {(u32 *)0x10228130, 0x010350c0}, + {(u32 *)0x1022a200, 0xf0100000}, + {(u32 *)0x1022a048, 0x08400000}, + {(u32 *)0x1022a85c, 0x33210000}, + {(u32 *)0x1022a878, 0xc0000000}, + {(u32 *)0x1022a024, 0x88102400}, + {(u32 *)0x1022a034, 0x00731004}, + {(u32 *)0x1022a848, 0x9007000f}, + {(u32 *)0x1022a064, 0x240007d2}, + {(u32 *)0x1022a0d8, 0x00000040}, + {(u32 *)0x1022a0d4, 0x0001c110}, + {(u32 *)0x1022a050, 0x30000700}, + {(u32 *)0x1022a054, 0x6543b321}, + {(u32 *)0x1022a004, 0x30822001}, + {(u32 *)0x1022a008, 0x81080000}, + {(u32 *)0x1022a00c, 0x00024f13}, + {(u32 *)0x1022a010, 0x00000080}, + {(u32 *)0x1022a020, 0x00000009}, + {(u32 *)0x1022a038, 0x80000106}, + {(u32 *)0x1022a040, 0x3000000c}, + {(u32 *)0x1022a04c, 0x25714001}, + {(u32 *)0x1022a858, 0x64400000}, + {(u32 *)0x1022aa04, 0x00001919}, + {(u32 *)0x1022ab04, 0x00001b1b}, + {(u32 *)0x1022a004, 0x308a2001}, + {(u32 *)0x1022a058, 0x00000a56}, + {(u32 *)0x1022a84c, 0x00ff0000}, + {(u32 *)0x1022a04c, 0x65714001}, + {(u32 *)0x1022a048, 0x48400000}, + {(u32 *)0x1022a06c, 0x00020000}, + {(u32 *)0x1022a038, 0xc0000106}, + {(u32 *)0x1022a038, 0xc0000107}, + {(u32 *)0x1022a20c, 0x00010000}, + {(u32 *)0x1022a204, 0x00014f10}, + {(u32 *)0x1022a09c, 0x12000480}, + {(u32 *)0x1022a01c, 0x57000000}, + {(u32 *)0x1022a01c, 0x17000000}, + {(u32 *)0x1022a074, 0x00000068}, + {(u32 *)0x1022a00c, 0x000a4f13}, + {(u32 *)0x1022a01c, 0x07000000}, + {(u32 *)0x1022a034, 0x00731804}, + {(u32 *)0x1022a064, 0x340007d2}, + {(u32 *)0x1022a20c, 0x00010004}, + {(u32 *)0x1022a004, 0x308a2000}, + {(u32 *)0x1022a06c, 0x00020000}, + {(u32 *)0x1022a8c0, 0xa0000000}, + {(u32 *)0x10228c1c, 0x00008090}, + {(u32 *)0x10228c9c, 0x00008080}, + {(u32 *)0x1022a858, 0x64400000}, + {(u32 *)0x1022aa2c, 0x33333322}, + {(u32 *)0x1022aa30, 0x33333322}, + {(u32 *)0x1022ab2c, 0x33333322}, + {(u32 *)0x1022ab30, 0x33333322}, + {(u32 *)0x1022a204, 0x00034f10}, + {(u32 *)0x1022a204, 0x00014f10}, + {(u32 *)0x1022a200, 0xfc100001}, + {(u32 *)0x1022a204, 0x00014f50}, + {(u32 *)0x1022a8c4, 0x02009800}, + {(u32 *)0x1022829c, 0xb9010200}, + {(u32 *)0x1022a850, 0x00000100}, + {(u32 *)0x1022a200, 0xfc120001}, + {(u32 *)0x10228c1c, 0x00008090}, + {(u32 *)0x10228c9c, 0x00008080}, + {(u32 *)0x1022a850, 0x00000110}, + {(u32 *)0x1022a850, 0x00000112}, + {(u32 *)0x1022a050, 0x30000721}, + {(u32 *)0x1022a0c8, 0x098e0080}, + {(u32 *)0x1022a01c, 0x00000000}, + {(u32 *)0x1022a034, 0x00731814}, + {(u32 *)0x1022a858, 0x64400000}, + {(u32 *)0x1022a8c0, 0x20000000}, + {(u32 *)0x1022aa0c, 0x1a1a1a1a}, + {(u32 *)0x1022ab0c, 0x14141414}, + {(u32 *)0x1022aa34, 0x44446666}, + {(u32 *)0x1022aa38, 0x44446666}, + {(u32 *)0x1022ab34, 0x44446666}, + {(u32 *)0x1022ab38, 0x44446666}, + {(u32 *)0x1022ac54, 0x8120050c}, + {(u32 *)0x10228c1c, 0x0000b090}, + {(u32 *)0x10228c9c, 0x0000b080}, + {(u32 *)0x1022a8d0, 0x00000000}, +// dramc_setting_DDR3600 + {(u32 *)0x1022a8a0, 0x33334444}, + {(u32 *)0x1022a8a4, 0x66661111}, +// update_initial_settings + {(u32 *)0x1022a860, 0xc0010003}, + {(u32 *)0x10228c1c, 0x0000b090}, + {(u32 *)0x10228c9c, 0x0000b080}, + {(u32 *)0x10228608, 0x20000000}, + {(u32 *)0x10228808, 0x20000000}, + {(u32 *)0x10228688, 0x20000000}, + {(u32 *)0x10228888, 0x20000000}, + {(u32 *)0x10228d1c, 0x00000000}, + {(u32 *)0x102281a4, 0x0000048c}, + {(u32 *)0x102281c0, 0x00000020}, + {(u32 *)0x102281b0, 0x00024000}, + {(u32 *)0x102280a4, 0x000004ee}, + {(u32 *)0x10228124, 0x000004ee}, + {(u32 *)0x102281a4, 0x000004ac}, + {(u32 *)0x102280a4, 0x000004ec}, + {(u32 *)0x10228124, 0x000004ec}, + {(u32 *)0x102280ac, 0x82110e00}, + {(u32 *)0x1022812c, 0x82110e00}, + {(u32 *)0x102281ac, 0x80000808}, + {(u32 *)0x102281b0, 0x00034000}, + {(u32 *)0x10228268, 0x00000020}, + {(u32 *)0x102280b0, 0x010352c0}, + {(u32 *)0x10228130, 0x010352c0}, + {(u32 *)0x102281b0, 0x00034200}, + {(u32 *)0x102280b0, 0x010352c1}, + {(u32 *)0x10228130, 0x010352c1}, + {(u32 *)0x102281b0, 0x00034201}, + {(u32 *)0x102281b0, 0x00034241}, + {(u32 *)0x102280b0, 0x010352c9}, + {(u32 *)0x10228130, 0x010352c9}, + {(u32 *)0x102281b0, 0x00034249}, + {(u32 *)0x102280b0, 0x010352e9}, + {(u32 *)0x10228130, 0x010352e9}, + {(u32 *)0x102281b0, 0x00034269}, + {(u32 *)0x10228c14, 0x00300016}, + {(u32 *)0x102280ac, 0x82111600}, + {(u32 *)0x10228c94, 0x00300016}, + {(u32 *)0x1022812c, 0x82111600}, + {(u32 *)0x102280b8, 0x00000007}, + {(u32 *)0x10228138, 0x00000007}, + {(u32 *)0x102281bc, 0x00010007}, + {(u32 *)0x1022a204, 0x00014f70}, + {(u32 *)0x1022a200, 0xfc120001}, + {(u32 *)0x102280b0, 0x010392e9}, + {(u32 *)0x102280bc, 0x10100031}, + {(u32 *)0x102280bc, 0x10100020}, + {(u32 *)0x102280bc, 0x10100031}, + {(u32 *)0x10228130, 0x010392e9}, + {(u32 *)0x1022813c, 0x10100031}, + {(u32 *)0x1022813c, 0x10100020}, + {(u32 *)0x1022813c, 0x10100031}, + {(u32 *)0x102300b8, 0x00000007}, + {(u32 *)0x10230138, 0x00000007}, + {(u32 *)0x102301bc, 0x00010007}, + {(u32 *)0x10232204, 0x00014f70}, + {(u32 *)0x10232200, 0xfc120001}, + {(u32 *)0x102300b0, 0x010392e9}, + {(u32 *)0x102300bc, 0x10100031}, + {(u32 *)0x102300bc, 0x10100020}, + {(u32 *)0x102300bc, 0x10100031}, + {(u32 *)0x10230130, 0x010392e9}, + {(u32 *)0x1023013c, 0x10100031}, + {(u32 *)0x1023013c, 0x10100020}, + {(u32 *)0x1023013c, 0x10100031}, + {(u32 *)0x102281b8, 0x00080a0a}, + {(u32 *)0x102281b8, 0x00080a0a}, + {(u32 *)0x1022a8cc, 0x0000f132}, + {(u32 *)0x1022a8c4, 0x02a19800}, + {(u32 *)0x10228c14, 0x00300016}, + {(u32 *)0x10228c94, 0x00300016}, + {(u32 *)0x10228d14, 0x00000000}, + {(u32 *)0x100010b4, 0x00000000}, + {(u32 *)0x10228c18, 0x06460740}, + {(u32 *)0x10228c98, 0x06460740}, + {(u32 *)0x10228d18, 0x064607c0}, + {(u32 *)0x10230c18, 0x06460740}, + {(u32 *)0x10230c98, 0x06460740}, + {(u32 *)0x10230d18, 0x06460740}, + {(u32 *)0x100010b4, 0x0000001f}, + {(u32 *)0x1022a864, 0x81080004}, + {(u32 *)0x1022a048, 0x4840f000}, + {(u32 *)0x1022a218, 0x00020000}, + {(u32 *)0x1022a8cc, 0x0000f132}, + {(u32 *)0x10228c20, 0xffc07fff}, + {(u32 *)0x10228ca0, 0xffc07fff}, + {(u32 *)0x10228d20, 0xffc07fff}, + {(u32 *)0x102282a8, 0x15351135}, + {(u32 *)0x10228c1c, 0x00008090}, + {(u32 *)0x10228c9c, 0x00008080}, + {(u32 *)0x1022a03c, 0x020cffff}, + {(u32 *)0x1022ac54, 0x8120050c}, + {(u32 *)0x1022a0bc, 0x00080000}, + {(u32 *)0x1022a0d0, 0x01000000}, + {(u32 *)0x1022a208, 0x50000010}, + {(u32 *)0x1022a20c, 0x00010704}, + {(u32 *)0x1022a860, 0xc001000f}, + {(u32 *)0x10228c34, 0xc0778609}, + {(u32 *)0x10228cb4, 0xc0778609}, + {(u32 *)0x10228184, 0x00200000}, + {(u32 *)0x1022a00c, 0x040acf13}, + {(u32 *)0x1022a048, 0x4840f000}, + {(u32 *)0x1022a0d8, 0x0000001a}, + {(u32 *)0x102280b0, 0x010392e9}, + {(u32 *)0x10228130, 0x010392e9}, + {(u32 *)0x102281b0, 0x000352e9}, + {(u32 *)0x1022a208, 0x50010010}, + {(u32 *)0x10228c1c, 0x13008090}, + {(u32 *)0x10228c9c, 0x13008080}, + {(u32 *)0x1022a874, 0x00000000}, + {(u32 *)0x1022a8c4, 0x02a19800}, + {(u32 *)0x1022aa08, 0x00000000}, + {(u32 *)0x1022ab08, 0x00000000}, + {(u32 *)0x1022a850, 0x00000112}, + {(u32 *)0x102280bc, 0x10100431}, + {(u32 *)0x1022813c, 0x10100431}, + {(u32 *)0x102281c0, 0x00000020}, + {(u32 *)0x10228c20, 0xffc07fff}, + {(u32 *)0x10228ca0, 0xffc07fff}, + {(u32 *)0x10228c38, 0x00032401}, + {(u32 *)0x10228cb8, 0x00032401}, + {(u32 *)0x1022a860, 0xc001000f}, + {(u32 *)0x10228c1c, 0x13008090}, + {(u32 *)0x10228c9c, 0x13008080}, + {(u32 *)0x1022a028, 0x20080000}, + {(u32 *)0x1022a04c, 0x75714001}, + {(u32 *)0x1022a058, 0x00080a56}, + {(u32 *)0x1022a0d0, 0x0d000000}, + {(u32 *)0x1022a0dc, 0x0001d10a}, + {(u32 *)0x1022a0e0, 0x0b80000d}, + {(u32 *)0x102282a8, 0x1d351135}, + {(u32 *)0x10228084, 0x00300000}, + {(u32 *)0x10228104, 0x00300000}, + {(u32 *)0x10228184, 0x00300000}, + {(u32 *)0x1022829c, 0xb1010200}, + {(u32 *)0x102285e8, 0x00000101}, + {(u32 *)0x1022a040, 0x3000008c}, + {(u32 *)0x1022a050, 0x300007a1}, + {(u32 *)0x1022a0d4, 0x0c01c1d0}, + {(u32 *)0x1022a0dc, 0x8001dd0a}, + {(u32 *)0x1022a208, 0x50010000}, + {(u32 *)0x1022a218, 0x00020000}, + {(u32 *)0x1022a024, 0x88502400}, + {(u32 *)0x102281d0, 0xa94011c0}, + {(u32 *)0x1022a024, 0x88d02400}, + {(u32 *)0x1022a874, 0x00000000}, + {(u32 *)0x1022a0a0, 0x0080110d}, + {(u32 *)0x1022a84c, 0x00ff0005}, + {(u32 *)0x1022a04c, 0x75774001}, + {(u32 *)0x1022a0dc, 0x8301dd0a}, + {(u32 *)0x1022a04c, 0x75774001}, + {(u32 *)0x1022a004, 0x348a2000}, + {(u32 *)0x1022a0d0, 0x0d426810}, + {(u32 *)0x1022a0a0, 0x4080110d}, + {(u32 *)0x1022a004, 0x348a2000}, + {(u32 *)0x100010b4, 0x00000000}, + {(u32 *)0x1022a0d4, 0x0c03c1d0}, + {(u32 *)0x1022a0dc, 0x8301dd0a}, + {(u32 *)0x102320d4, 0x0c01c1f0}, + {(u32 *)0x102320dc, 0x8301cd0a}, +}; + +static void dramc_power_on_sequence(void) +{ + u8 chn; + + /* reset dram = low */ + for (chn = 0; chn < CHANNEL_MAX; chn++) + clrbits_le32(&ch[chn].phy.misc_ctrl1, (0x1 << 13)); + + /* CKE low */ + dramc_cke_fix_onoff(CHANNEL_A, false, true); + dramc_cke_fix_onoff(CHANNEL_B, false, true); + + /* delay tINIT1=200us(min) & tINIT2=10ns(min)*/ + udelay(200); + + for (chn = 0; chn < CHANNEL_MAX; chn++) + setbits_le32(&ch[chn].phy.misc_ctrl1, (0x1 << 13)); + + /* Disable HW MIOCK control to make CLK always on */ + for (chn = 0; chn < CHANNEL_MAX; chn++) + setbits_le32(&ch[chn].ao.dramc_pd_ctrl, (0x1 << 26)); + + udelay(2000); + + /* CKE high */ + dramc_cke_fix_onoff(CHANNEL_A, true, false); + dramc_cke_fix_onoff(CHANNEL_B, true, false); + udelay(2); +} + +static void dramc_duty_set_clk_delay(u8 chn, s8 clkDelay) +{ + u8 dly, dlyb, revb0, revb1; + + dly = (clkDelay < 0) ? -clkDelay : 0; + dlyb = (clkDelay < 0) ? 0 : clkDelay; + revb0 = dly ? 1 : 0; + revb1 = dlyb ? 1 : 0; + + for (u8 r = 0; r < RANK_MAX; r++) { + clrsetbits_le32(&ch[chn].phy.shu[0].rk[r].ca_cmd[1], + (0xf << 24) | (0xf << 28), (dly << 24) | (dly << 28)); + clrsetbits_le32(&ch[chn].phy.shu[0].rk[r].ca_cmd[0], + (0xf << 24) | (0xf << 28), (dlyb << 24) | (dlyb << 28)); } + clrsetbits_le32(&ch[chn].phy.shu[0].ca_cmd[3], + (0x3 << 8), (revb0 << 8) | (revb1 << 9)); +} + +static void dramc_duty_set_dqs_delay(u8 chn, s8* s_dqsDelay) +{ + u8 dly, dlyb, revb0, revb1; + s8 dqsDelay ; + + for (u8 r = 0; r < RANK_MAX; r++) + for (u8 dqs = 0; dqs < DQS_NUMBER; dqs++) { + dqsDelay = s_dqsDelay[dqs] ; + + dly = (dqsDelay < 0) ? -dqsDelay : 0; + dlyb = (dqsDelay < 0) ? 0 : dqsDelay; + revb0 = dly ? 1 : 0; + revb1 = dlyb ? 1 : 0; + clrsetbits_le32(&ch[chn].phy.shu[0].rk[r].b[dqs].dq[1], + (0xf << 24) | (0xf << 28) | + (0xf << 16) | (0xf << 20), + (dly << 24) | (dly << 28) | + (dlyb << 16) | (dlyb << 20)); + } + clrsetbits_le32(&ch[chn].phy.shu[0].b[0].dll[1], + 0x3 << 8, (revb0 << 8) | (revb1 << 9)); +} + +static void dramc_duty_calibration(const struct sdram_params *params, u32 freq_group) +{ + s8 clkDelay[CHANNEL_MAX]; + s8 dqsDelay[CHANNEL_MAX][DQS_NUMBER]; + + if (freq_group == LP4X_DDR3200) { + clkDelay[CHANNEL_A] = clkDelay[CHANNEL_B] = 1; + dqsDelay[CHANNEL_A][0] = 1; + dqsDelay[CHANNEL_A][1] = -2; + dqsDelay[CHANNEL_B][0] = 1; + dqsDelay[CHANNEL_B][1] = -2; + } else if (freq_group == LP4X_DDR3600) { + clkDelay[CHANNEL_A] = 2; + clkDelay[CHANNEL_B] = 1; + dqsDelay[CHANNEL_A][0] = 0; + dqsDelay[CHANNEL_A][1] = 0; + dqsDelay[CHANNEL_B][0] = -1; + dqsDelay[CHANNEL_B][1] = 0; + } else { + clkDelay[CHANNEL_A] = 2; + clkDelay[CHANNEL_B] = 1; + dqsDelay[CHANNEL_A][0] = 0; + dqsDelay[CHANNEL_A][1] = 0; + dqsDelay[CHANNEL_B][0] = -1; + dqsDelay[CHANNEL_B][1] = 0; + } + + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + dramc_duty_set_clk_delay(chn, clkDelay[chn]); + dramc_duty_set_dqs_delay(chn, dqsDelay[chn]); + } +} + +#define TIME_OUT_CNT 100 //100us +static u8 dramc_zq_calibration(u8 chn, u8 rank) +{ + u32 resp, u4TimeCnt; + struct reg_value regs_bak[] = { + {&ch[chn].ao.mrs, 0x0}, + {&ch[chn].ao.dramc_pd_ctrl, 0x0}, + {&ch[chn].ao.ckectrl, 0x0}, + }; + + dramc_dbg("[%s] rank:%d\n", __func__, rank); + u4TimeCnt = TIME_OUT_CNT; + + for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) + regs_bak[i].value = read32(regs_bak[i].addr); + + setbits_le32(&ch[chn].ao.dramc_pd_ctrl, 0x1 << 26); + dramc_cke_fix_onoff(chn, true, false); + + clrsetbits_le32(&ch[chn].ao.mrs, + MRS_MRSRK_MASK, rank << MRS_MRSRK_SHIFT); + setbits_le32(&ch[chn].ao.mpc_option, 0x1 << MPC_OPTION_MPCRKEN_SHIFT); + setbits_le32(&ch[chn].ao.spcmd, 0x1 << SPCMD_ZQCEN_SHIFT); + do { + resp = (read32(&ch[chn].nao.spcmdresp) & + (0x1 << SPCMDRESP_ZQC_RESPONSE_SHIFT)) >> + SPCMDRESP_ZQC_RESPONSE_SHIFT; + u4TimeCnt--; + udelay(1); + } while ((resp == 0) && (u4TimeCnt > 0)); + + if (u4TimeCnt == 0) { + dramc_dbg("ZQCAL Start fail (time out)\n"); + return 1; + } + + clrbits_le32(&ch[chn].ao.spcmd, 0x1 << SPCMD_ZQCEN_SHIFT); + + udelay(1); + u4TimeCnt = TIME_OUT_CNT; + + setbits_le32(&ch[chn].ao.spcmd, 0x1 << SPCMD_ZQLATEN_SHIFT); + do { + resp = (read32(&ch[chn].nao.spcmdresp) & + (0x1 << SPCMDRESP_ZQLAT_RESPONSE_SHIFT)) >> + SPCMDRESP_ZQLAT_RESPONSE_SHIFT; + u4TimeCnt--; + udelay(1); + } while ((resp == 0) && (u4TimeCnt > 0)); + + if (u4TimeCnt == 0) { + dramc_dbg("ZQCAL Latch fail (time out)\n"); + return 1; + } + + clrbits_le32(&ch[chn].ao.spcmd, 0x1 << SPCMD_ZQLATEN_SHIFT); + + udelay(1); + for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) + write32(regs_bak[i].addr, regs_bak[i].value); + + return 0; +} + +#define MR13_RRO 1 +u8 MR12Value[CHANNEL_MAX][RANK_MAX][FSP_MAX] = { + {{0x5d, 0x5d}, {0x5d, 0x5d} }, {{0x5d, 0x5d}, {0x5d, 0x5d} }, +}; + +u8 MR14Value_06VDDQ[CHANNEL_MAX][RANK_MAX][FSP_MAX] = { + {{0x5d, 0x10}, {0x5d, 0x10} }, {{0x5d, 0x10}, {0x5d, 0x10} }, +}; + +u8 MR01Value[FSP_MAX] = {0x26, 0x56}; +u8 MR13Value = (MR13_RRO<<4) | (1<<3); + +u8 MR02Value[FSP_MAX] = {0x12, 0x12}; +u8 MR03Value = 0x30; +u8 MR11Value[FSP_MAX] = {0x0, 0x23}; +u8 MR22Value[FSP_MAX] = {0x38, 0x38}; + +static void dramc_mode_reg_init(u32 freq_group) +{ + MR01Value[FSP_0] &= 0x8F; + MR01Value[FSP_1] &= 0x8F; + + if (freq_group == LP4X_DDR1600) { + MR02Value[0] = 0x12; + MR02Value[1] = 0x00; + + MR01Value[FSP_0] |= (0x5 << 4); + MR01Value[FSP_1] |= (0x5 << 4); + } else if (freq_group == LP4X_DDR3200) { + MR02Value[0] = 0x00; + MR02Value[1] = 0x2d; + + MR01Value[FSP_0] |= (0x5 << 4); + MR01Value[FSP_1] |= (0x5 << 4); + } else if (freq_group == LP4X_DDR3600) { + MR02Value[0] = 0x00; + MR02Value[1] = 0x36; + + MR01Value[FSP_0] |= (0x6 << 4); + MR01Value[FSP_1] |= (0x6 << 4); + } + + u8 operate_fsp = (freq_group == LP4X_DDR1600) ? FSP_0 : FSP_1; + dramc_dbg("%s operate_fsp:%d, freq:%d\n", __func__, operate_fsp, freq_group); + + u8 chn, rank; + u32 broadcast_bak = dramc_get_broadcast(); + dramc_set_broadcast(DRAMC_BROADCAST_OFF); + dramc_power_on_sequence(); + + for (chn = 0; chn < CHANNEL_MAX; chn++) { + for (rank = 0; rank < 2; rank++) { + dramc_dbg("%s CH%u RK%u, freq:%d\n", __func__, chn, rank, freqTbl[freq_group]); + clrsetbits_le32(&ch[chn].ao.mrs, + (0x3 << 24), (rank << 24)); + + /* ZQ calibration should be done before CBT calibration + * by switching to low frequency */ + dramc_zq_calibration(chn, rank); + + for (uint32_t fsp = FSP_0; fsp < FSP_MAX; fsp++) { + dramc_dbg("chn:%d,rank:%d,fsp%d\n", + chn, rank, fsp); + + if (fsp == FSP_0) + MR13Value = (MR13_RRO<<4) | (1<<3); + else + MR13Value |= 0x40; //OP[6]=1 + dramc_mode_reg_write(chn, + 0xd, MR13Value); + + /* MR12 use previous value + * MR12 VREF-CA */ + dramc_mode_reg_write(chn, + 0xc, MR12Value[chn][rank][fsp]); + dramc_mode_reg_write(chn, + 0x1, MR01Value[fsp]); + dramc_mode_reg_write(chn, + 0x2, MR02Value[fsp]); + dramc_mode_reg_write(chn, + 0xb, MR11Value[fsp]); /* ODT */ + + /* SOC-ODT, ODTE-CK, ODTE-CS, Disable ODTD-CA */ + dramc_mode_reg_write(chn, + 0x16, MR22Value[fsp]); + + /* MR14 use previous value + * MR14 VREF-DQ */ + dramc_mode_reg_write(chn, 0xe, + MR14Value_06VDDQ[chn][rank][fsp]); + + /* MR3 set write-DBI and read-DBI */ + dramc_mode_reg_write(chn, 0x3, MR03Value); + } + + /* freq < 1333 is assumed to be odt_off -> uses FSP_0 */ + if (operate_fsp == FSP_0) + { + MR13Value &= 0x3f; //[7]FSP_OP=0, [6]FSP_WR=0 + } + else + { + MR13Value |= 0xc0; //[7]FSP_OP=1, [6]FSP_WR=1 + } + + dramc_mode_reg_write(chn, 0xd, MR13Value); + } + dramc_dbg("%s with MR13Value:%d,operate_fsp:%d,MR02Value[fsp]%d\n", __func__, + MR13Value, operate_fsp, MR02Value[operate_fsp]); + + clrsetbits_le32(&ch[chn].ao.shu[0].hwset_mr13, + (0x1fff << 0) | (0xff << 16), + (13 << 0) | ((MR13Value | (0x1 << 3)) << 16)); + clrsetbits_le32(&ch[chn].ao.shu[0].hwset_vrcg, + (0x1fff << 0) | (0xff << 16), + (13 << 0) | ((MR13Value | (0x1 << 3)) << 16)); + clrsetbits_le32(&ch[chn].ao.shu[0].hwset_mr2, + (0x1fff << 0) | (0xff << 16), + (2 << 0) | (MR02Value[operate_fsp] << 16)); + } + + clrsetbits_le32(&ch[0].ao.mrs, 0x3 << 24, RANK_0 << 24); + clrsetbits_le32(&ch[1].ao.mrs, 0x3 << 24, RANK_0 << 24); + + dramc_set_broadcast(broadcast_bak); +} +typedef struct +{ + u8 dqsinctl; + u8 datlat; + u8 trcd; + u8 trrd; + u8 twr; + u8 twtr; + u8 trc; + u8 tras; + u8 trp; + u8 trpab; + u8 tfaw; + u8 trtw_ODT_on; + u8 trtp; + u8 txp; + u8 refcnt; + u8 trfc; + u8 trfcpb; + u8 tzqcs; + u8 refcnt_fr_clk; + u8 txrefcnt; + u8 tmrr2w_ODT_on; + u8 twtpd; + u8 trtpd; + u8 xrtw2w; + u8 xrtw2r; + u8 xrtr2w; + u8 xrtr2r; + u8 twtr_05T; + u8 trtw_ODT_on_05T; + u8 twtpd_05T; + u8 trtpd_05T; + u8 tfaw_05T; + u8 trrd_05T; + u8 twr_05T; + u8 tras_05T; + u8 trpab_05T; + u8 trp_05T; + u8 trcd_05T; + u8 trtp_05T; + u8 txp_05T; + u8 trfc_05T; + u8 trfcpb_05T; + u8 trc_05T; + u8 r_dmcatrain_intv; + u8 r_dmmrw_intv; + u8 r_dmfspchg_prdcnt; + u8 ckeprd; + u8 ckelckcnt; + u8 zqlat2; +}ACTime_T; + +const ACTime_T AC_Timing_Tbl[LP4X_DDRFREQ_MAX] = +{ +// LP4-1600, 800MHz, RDBI_OFF, normal mode +{ + .tras = 0, .tras_05T = 0, + .trp = 2, .trp_05T = 0, + .trpab = 0, .trpab_05T = 1, + .trc = 4, .trc_05T = 0, + .trfc = 44, .trfc_05T = 0, + .trfcpb = 16, .trfcpb_05T = 0, + .txp = 0, .txp_05T = 0, + .trtp = 1, .trtp_05T = 1, + .trcd = 3, .trcd_05T = 0, + .twr = 7, .twr_05T = 1, + .twtr = 4, .twtr_05T = 1, + .trrd = 0, .trrd_05T = 0, + .tfaw = 0, .tfaw_05T = 0, + .trtw_ODT_on = 4, .trtw_ODT_on_05T = 0, + .refcnt = 48, + .refcnt_fr_clk = 101, + .txrefcnt = 62, + .tzqcs = 16, + .xrtw2w = 5, + .xrtw2r = 3, + .xrtr2w = 3, + .xrtr2r = 8, + .r_dmcatrain_intv = 8, + .r_dmmrw_intv = 0xf, + .r_dmfspchg_prdcnt = 50, + .trtpd = 6, .trtpd_05T = 0, + .twtpd = 6, .twtpd_05T = 0, + .tmrr2w_ODT_on = 5, + .ckeprd = 1, + .ckelckcnt = 0, + .zqlat2 = 6, + .dqsinctl = 1, .datlat = 10 +}, +// LP4-3200, 1600MHz, RDBI_OFF, normal mode +{ + .tras = 8, .tras_05T = 1, + .trp = 5, .trp_05T = 1, + .trpab = 1, .trpab_05T = 0, + .trc = 16, .trc_05T = 1, + .trfc = 100, .trfc_05T = 0, + .trfcpb = 44, .trfcpb_05T = 0, + .txp = 1, .txp_05T = 0, + .trtp = 2, .trtp_05T = 1, + .trcd = 6, .trcd_05T = 1, + .twr = 12, .twr_05T = 1, + .twtr = 7, .twtr_05T = 0, + .trrd = 2, .trrd_05T = 0, + .tfaw = 7, .tfaw_05T = 0, + .trtw_ODT_on = 7, .trtw_ODT_on_05T = 0, + .refcnt = 97, + .refcnt_fr_clk = 101, + .txrefcnt = 119, + .tzqcs = 34, + .xrtw2w = 5, + .xrtw2r = 3, + .xrtr2w = 6, + .xrtr2r = 9, + .r_dmcatrain_intv = 11, + .r_dmmrw_intv = 0xf, + .r_dmfspchg_prdcnt = 100, + .trtpd = 11, .trtpd_05T = 0, + .twtpd = 12, .twtpd_05T = 1, + .tmrr2w_ODT_on = 10, + .ckeprd = 2, + .ckelckcnt = 0, + .zqlat2 = 12, + .dqsinctl = 4, .datlat = 15 +}, + // LP4-3600, 1800MHz, RDBI_OFF, normal mode +{ + .tras = 11, .tras_05T = 1, + .trp = 6, .trp_05T = 1, + .trpab = 1, .trpab_05T = 1, + .trc = 20, .trc_05T = 1, + .trfc = 118, .trfc_05T = 1, + .trfcpb = 53, .trfcpb_05T = 1, + .txp = 1, .txp_05T = 1, + .trtp = 2, .trtp_05T = 0, + .trcd = 7, .trcd_05T = 1, + .twr = 14, .twr_05T = 1, + .twtr = 8, .twtr_05T = 0, + .trrd = 3, .trrd_05T = 0, + .tfaw = 10, .tfaw_05T = 0, + .trtw_ODT_on = 8, .trtw_ODT_on_05T = 0, + .refcnt = 113, + .refcnt_fr_clk = 101, + .txrefcnt = 138, + .tzqcs = 40, + .xrtw2w = 5, + .xrtw2r = 3, + .xrtr2w = 7, + .xrtr2r = 9, + .r_dmcatrain_intv = 13, + .r_dmmrw_intv = 0xf, //Berson: LP3/4 both use this field -> Formula may change, set to 0xF for now + .r_dmfspchg_prdcnt = 117, + .trtpd = 12, .trtpd_05T = 0, + .twtpd = 13, .twtpd_05T = 0, + .tmrr2w_ODT_on = 11, + .ckeprd = 3, + .ckelckcnt = 0, + .zqlat2 = 14, + .dqsinctl = 6, .datlat = 18 + }, +}; + +typedef struct +{ + u8 u1TRFC : 8; + u8 u1TRFRC_05T : 1; + u16 u2TXREFCNT : 10; +} optimizeACTimexxx; + +static void ddr_update_ac_timing(u32 freq_group) +{ + u32 temp; + u8 u1ROOT = 0, u1TXRANKINCTL = 0, u1TXDLY = 0; + + u8 dqsinctl, datlat, new_datlat, trcd, trrd, twr, twtr, trc, tras; + u8 trp, trpab, tfaw, trtw_ODT_on, trtp, txp, refcnt; + u8 trfc, trfcpb, tzqcs, refcnt_fr_clk, txrefcnt, tmrr2w_ODT_on; + u8 twtpd, trtpd, xrtw2w, xrtw2r, xrtr2w, xrtr2r, twtr_05T; + u8 trtw_ODT_on_05T, twtpd_05T, trtpd_05T, tfaw_05T, trrd_05T; + u8 twr_05T, tras_05T, trpab_05T, trp_05T, trcd_05T, trtp_05T; + u8 txp_05T, trfc_05T, trfcpb_05T, trc_05T, r_dmcatrain_intv; + u8 r_dmmrw_intv, r_dmfspchg_prdcnt, ckeprd, ckelckcnt, zqlat2; + + dqsinctl = AC_Timing_Tbl[freq_group].dqsinctl; + datlat = AC_Timing_Tbl[freq_group].datlat; + new_datlat = AC_Timing_Tbl[freq_group].datlat - 2; + trcd = AC_Timing_Tbl[freq_group].trcd; + trrd = AC_Timing_Tbl[freq_group].trrd; + twr = AC_Timing_Tbl[freq_group].twr; + twtr = AC_Timing_Tbl[freq_group].twtr; + trc = AC_Timing_Tbl[freq_group].trc; + tras = AC_Timing_Tbl[freq_group].tras; + trp = AC_Timing_Tbl[freq_group].trp; + trpab = AC_Timing_Tbl[freq_group].trpab; + tfaw = AC_Timing_Tbl[freq_group].tfaw; + trtw_ODT_on = AC_Timing_Tbl[freq_group].trtw_ODT_on; + trtp = AC_Timing_Tbl[freq_group].trtp; + txp = AC_Timing_Tbl[freq_group].txp; + refcnt = AC_Timing_Tbl[freq_group].refcnt; + trfc = AC_Timing_Tbl[freq_group].trfc; + trfcpb = AC_Timing_Tbl[freq_group].trfcpb; + tzqcs = AC_Timing_Tbl[freq_group].tzqcs; + refcnt_fr_clk = AC_Timing_Tbl[freq_group].refcnt_fr_clk; + txrefcnt = AC_Timing_Tbl[freq_group].txrefcnt; + tmrr2w_ODT_on = AC_Timing_Tbl[freq_group].tmrr2w_ODT_on; + twtpd = AC_Timing_Tbl[freq_group].twtpd; + trtpd = AC_Timing_Tbl[freq_group].trtpd; + xrtw2w = AC_Timing_Tbl[freq_group].xrtw2w; + xrtw2r = AC_Timing_Tbl[freq_group].xrtw2r; + xrtr2w = AC_Timing_Tbl[freq_group].xrtr2w; + xrtr2r = AC_Timing_Tbl[freq_group].xrtr2r; + twtr_05T = AC_Timing_Tbl[freq_group].twtr_05T; + trtw_ODT_on_05T = AC_Timing_Tbl[freq_group].trtw_ODT_on_05T; + twtpd_05T = AC_Timing_Tbl[freq_group].twtpd_05T; + trtpd_05T = AC_Timing_Tbl[freq_group].trtpd_05T; + tfaw_05T = AC_Timing_Tbl[freq_group].tfaw_05T; + trrd_05T = AC_Timing_Tbl[freq_group].trrd_05T; + twr_05T = AC_Timing_Tbl[freq_group].twr_05T; + tras_05T = AC_Timing_Tbl[freq_group].tras_05T; + trpab_05T = AC_Timing_Tbl[freq_group].trpab_05T; + trp_05T = AC_Timing_Tbl[freq_group].trp_05T; + trcd_05T = AC_Timing_Tbl[freq_group].trcd_05T; + trtp_05T = AC_Timing_Tbl[freq_group].trtp_05T; + txp_05T = AC_Timing_Tbl[freq_group].txp_05T; + trfc_05T = AC_Timing_Tbl[freq_group].trfc_05T; + trfcpb_05T = AC_Timing_Tbl[freq_group].trfcpb_05T; + trc_05T = AC_Timing_Tbl[freq_group].trc_05T; + r_dmcatrain_intv = AC_Timing_Tbl[freq_group].r_dmcatrain_intv; + r_dmmrw_intv = AC_Timing_Tbl[freq_group].r_dmmrw_intv; + r_dmfspchg_prdcnt = AC_Timing_Tbl[freq_group].r_dmfspchg_prdcnt; + ckeprd = AC_Timing_Tbl[freq_group].ckeprd; + ckelckcnt = AC_Timing_Tbl[freq_group].ckelckcnt; + zqlat2 = AC_Timing_Tbl[freq_group].zqlat2; + + if (freq_group == LP4X_DDR1600) { + u1ROOT = 0; u1TXRANKINCTL=0; u1TXDLY=1; + } else { + if (freq_group == LP4X_DDR3600) + u1ROOT = 1; + else + u1ROOT = 0; + u1TXRANKINCTL=1; u1TXDLY=2; + } + + for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { + clrsetbits_le32(&ch[chn].ao.shu[0].actim[0], + (0xf << 24) | (0x7 << 16) | (0x1f << 8) | (0xf << 0), + (trcd << 24) | (trrd << 16) | (twr << 8) | (twtr << 0)); + clrsetbits_le32(&ch[chn].ao.shu[0].actim[1], + (0x1f << 24) | (0xf << 16) | (0xf << 8) | (0x7 << 0), + (trc << 24) | (tras << 16) | (trp << 8) | (trpab << 0)); + clrsetbits_le32(&ch[chn].ao.shu[0].actim[2], + (0x1f << 24) | (0xf << 16) | (0x7 << 8) | (0x7 << 0), + (tfaw << 24) | (trtw_ODT_on << 16) | (trtp << 8) | (txp << 0)); + clrsetbits_le32(&ch[chn].ao.shu[0].actim[3], + (0xff << 16) | (0xff << 24) | (0xff << 0), + (trfc << 16) | (refcnt << 24) | (trfcpb << 0)); + clrsetbits_le32(&ch[chn].ao.shu[0].actim[4], + (0xff << 24) | (0xff << 16) | (0x3ff << 0), + (tzqcs << 24) | (refcnt_fr_clk << 16) | (txrefcnt << 0)); + clrsetbits_le32(&ch[chn].ao.shu[0].actim[5], + (0xf << 24) | (0x1f << 8) | (0x1f << 0), + (tmrr2w_ODT_on << 24) | (twtpd << 8) | (trtpd << 0)); + clrsetbits_le32(&ch[chn].ao.shu[0].actim_xrt, + (0xf << 24) | (0x7 << 16) | (0xf << 8) | (0x1f << 0), + (xrtw2w << 24) | (xrtw2r << 16) | (xrtr2w << 8) | (xrtr2r << 0)); + clrsetbits_le32(&ch[chn].ao.shu[0].ac_time_05t, + (0x1 << 25) | (0x0 << 24) | (0x1 << 16) | (0x0 << 15)| + (0x1 << 13) | (0x1 << 12) | (0x1 << 10) | (0x1 << 9) | + (0x1 << 8) | (0x1 << 7) | (0x1 << 6) | (0x1 << 5) | + (0x1 << 4) | (0x1 << 2) | (0x1 << 1) | (0x1 << 0), + (twtr_05T << 25) | (trtw_ODT_on_05T << 24) | (twtpd_05T << 16) | (trtpd_05T << 15) | + (tfaw_05T << 13) | (trrd_05T << 12) | (twr_05T << 10) | (tras_05T << 9) | + (trpab_05T << 8) | (trp_05T << 7) | (trcd_05T << 6) | (trtp_05T << 5) | + (txp_05T << 4) | (trfc_05T << 2) | (trfcpb_05T << 1) | (trc_05T << 0)); + clrsetbits_le32(&ch[chn].ao.catraining1, + (0xff << 24) | (0xf << 20), (r_dmcatrain_intv << 24) | (0x0 << 20)); + + /* DQSINCTL related */ + clrsetbits_le32(&ch[chn].ao.shu[0].rk[0].dqsctl, + (0xf << 0), (dqsinctl << 0)); + clrsetbits_le32(&ch[chn].ao.shu[0].rk[1].dqsctl, + (0xf << 0), (dqsinctl << 0)); + clrsetbits_le32(&ch[chn].ao.shu[0].odtctrl, + (0xf << 4), (dqsinctl << 4)); + + /* DATLAT related, tREFBW */ + clrsetbits_le32(&ch[chn].ao.shu[0].conf[1], + (0x1f << 0) | (0x1f << 8) | + (0x1f << 26) | (0x3ff << 16), + (datlat << 0) | (new_datlat << 8) | (new_datlat << 26) | (0x0 << 16)); + clrsetbits_le32(&ch[chn].ao.shu[0].conf[2], + (0xff << 8), (r_dmfspchg_prdcnt << 8)); + clrsetbits_le32(&ch[chn].ao.shu[0].scintv, + (0x1f << 13) | (0x1f << 6), (r_dmmrw_intv << 13) | (zqlat2 << 6)); + + /* CKEPRD - CKE pulse width */ + clrsetbits_le32(&ch[chn].ao.shu[0].ckectrl, + (0x7 << 20), (ckeprd << 20)); + + /* CKELCKCNT: Valid clock requirement after CKE input low */ + clrsetbits_le32(&ch[chn].ao.ckectrl, (0x7 << 24), (ckelckcnt << 24)); + + temp = (read32(&ch[chn].ao.shu[0].rankctl) & 0x00f00000) >> 20; + clrsetbits_le32(&ch[chn].ao.shu[0].rankctl, + (0xf << 0), (temp << 0)); + + clrsetbits_le32(&ch[chn].ao.shu[0].rankctl, + (0xf << 16) | (0xf << 12) | (0xf << 8), + (u1ROOT << 16) | (u1TXRANKINCTL << 12) | (u1TXDLY << 8)); + } + + u8 dram_cbt_mode = 0; + + setbits_le32(&ch[0].ao.arbctl, (0x3 << 10)); + clrsetbits_le32(&ch[0].ao.rstmask, (0x3 << 13), dram_cbt_mode); + clrsetbits_le32(&ch[0].ao.arbctl, (0x1 << 13), dram_cbt_mode); +} + +void dramc_init(const struct sdram_params *params, u32 freq_group) +{ + dramc_dbg("%s start\n", __func__); + if (freq_group == LP4X_DDR3200) { + for (int i = 0; i < ARRAY_SIZE(dramc_init_sequence); i++) + write32(dramc_init_sequence[i].addr, + dramc_init_sequence[i].value); + for (int i = 0; i < ARRAY_SIZE(dramc_mode_reg_init_sequence); i++) { + write32(dramc_mode_reg_init_sequence[i].addr, + dramc_mode_reg_init_sequence[i].value); + udelay(2); + } + } else if (freq_group == LP4X_DDR3600) { + for (int i = 0; i < ARRAY_SIZE(dramc_init_sequence_3600); i++) + write32(dramc_init_sequence_3600[i].addr, + dramc_init_sequence_3600[i].value); + + dramc_duty_calibration(params, freq_group); + dramc_mode_reg_init(freq_group); + ddr_update_ac_timing(freq_group); + } + dramc_dbg("%s end\n", __func__); } diff --git a/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c index 05f793e..0dc11dc 100644 --- a/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c +++ b/src/soc/mediatek/mt8183/dramc_pi_calibration_api.c @@ -41,7 +41,10 @@ GATING_START = 26, GATING_END = GATING_START + 24, }; +#define WRITE_LEVELING_MOVD_DQS 1//UI
+#define TEST2_1_CAL 0x55000000 +#define TEST2_2_CAL 0xaa000400 enum CAL_TYPE { RX_WIN_RD_DQC = 0, RX_WIN_TEST_ENG, @@ -102,13 +105,13 @@ } }
-static void dramc_cke_fix_onoff(u8 chn, bool fix_on, bool fix_off) +void dramc_cke_fix_onoff(u8 chn, bool fix_on, bool fix_off) { clrsetbits_le32(&ch[chn].ao.ckectrl, (0x1 << 6) | (0x1 << 7), ((fix_on ? 1 : 0) << 6) | ((fix_off ? 1 : 0) << 7)); }
-static void dramc_mode_reg_write(u8 chn, u8 mr_idx, u8 value) +void dramc_mode_reg_write(u8 chn, u8 mr_idx, u8 value) { u32 ckectrl_bak = read32(&ch[chn].ao.ckectrl);
@@ -124,7 +127,8 @@ ;
clrbits_le32(&ch[chn].ao.spcmd, 1 << SPCMD_MRWEN_SHIFT); - setbits_le32(&ch[chn].ao.ckectrl, ckectrl_bak); + write32(&ch[chn].ao.ckectrl, ckectrl_bak); + dramc_dbg("Write MR%d =0x%x\n", mr_idx, value); }
static void dramc_mode_reg_write_by_rank(u8 chn, u8 rank, @@ -138,23 +142,138 @@ clrsetbits_le32(&ch[chn].ao.mrs, MRS_MRSRK_MASK, mrs_back); }
+static void dramc_rank_swap(u8 chn, u8 rank) +{ + u8 multi_rank = 1; + + dramc_dbg("[RankSwap] (Multi %d), Rank %d\n", multi_rank, rank); + + clrsetbits_le32(&ch[chn].ao.rkcfg, + 0x7 << 4 | 0x1 << 7 | 0x3 <<0, + (multi_rank << 4) | (rank << 7) | (rank << 0)); + + /* TXRANK should be set before TXRANKFIX */ + clrsetbits_le32(&ch[chn].ao.rkcfg, 1 << 3, rank << 3); +} + +static void move_dramc_delay(uint32_t *reg_0, uint32_t *reg_1, + u8 shift, s8 shift_coarse_tune) +{ + s32 tmp_0p5t, tmp_2t, sum; + + tmp_0p5t = (((read32(reg_0) >> shift) & DQ_DIV_MASK) & (~(1<<DQ_DIV_SHIFT))); + tmp_2t = (read32(reg_1) >> shift) & DQ_DIV_MASK ; + + sum = (tmp_2t << DQ_DIV_SHIFT) + tmp_0p5t + shift_coarse_tune; + + if (sum < 0) { + tmp_0p5t = 0; + tmp_2t = 0; + } else { + tmp_2t = sum >> DQ_DIV_SHIFT; + tmp_0p5t = sum - (tmp_2t << DQ_DIV_SHIFT); + } + + clrsetbits_le32(reg_0, DQ_DIV_MASK << shift, tmp_0p5t << shift); + clrsetbits_le32(reg_1, DQ_DIV_MASK << shift, tmp_2t << shift); +} + +static void move_dramc_tx_dqs(u8 chn, u8 byte_idx, s8 shift_coarse_tune) +{ + move_dramc_delay(&ch[chn].ao.shu[0].selph_dqs1, + &ch[chn].ao.shu[0].selph_dqs0, + byte_idx * 4, shift_coarse_tune); +} + +static void move_dramc_tx_dqs_oen(u8 chn, u8 byte_idx, + s8 shift_coarse_tune) +{ + move_dramc_delay(&ch[chn].ao.shu[0].selph_dqs1, + &ch[chn].ao.shu[0].selph_dqs0, + (byte_idx * 4) + OEN_SHIFT, shift_coarse_tune); +} + +static void move_dramc_tx_dq(u8 chn, u8 rank, u8 byte_idx, s8 shift_coarse_tune) +{ + //DQM0 + move_dramc_delay(&ch[chn].ao.shu[0].rk[rank].selph_dq[3], + &ch[chn].ao.shu[0].rk[rank].selph_dq[1], + byte_idx * 4, shift_coarse_tune); + + //DQ0 + move_dramc_delay(&ch[chn].ao.shu[0].rk[rank].selph_dq[2], + &ch[chn].ao.shu[0].rk[rank].selph_dq[0], + byte_idx * 4, shift_coarse_tune); +} + +static void move_dramc_tx_dq_oen(u8 chn, u8 rank, + u8 byte_idx, s8 shift_coarse_tune) +{ + //DQM_OEN_0 + move_dramc_delay(&ch[chn].ao.shu[0].rk[rank].selph_dq[3], + &ch[chn].ao.shu[0].rk[rank].selph_dq[1], + (byte_idx * 4) + OEN_SHIFT, shift_coarse_tune); + //DQ_OEN_0 + move_dramc_delay(&ch[chn].ao.shu[0].rk[rank].selph_dq[2], + &ch[chn].ao.shu[0].rk[rank].selph_dq[0], + (byte_idx * 4) + OEN_SHIFT, shift_coarse_tune); +} + +static void write_leveling_move_dqs_instead_of_clk(u8 chn) +{ + for (u8 byte_idx = 0; byte_idx < DQS_NUMBER; byte_idx++) { + move_dramc_tx_dqs(chn, byte_idx, -WRITE_LEVELING_MOVD_DQS); + move_dramc_tx_dqs_oen(chn, byte_idx, -WRITE_LEVELING_MOVD_DQS); + + for (u8 rk = RANK_0; rk < RANK_MAX; rk++) { + move_dramc_tx_dq(chn, rk, byte_idx, -WRITE_LEVELING_MOVD_DQS); + move_dramc_tx_dq_oen(chn, rk, byte_idx, -WRITE_LEVELING_MOVD_DQS); + } + } +} + static void dramc_write_leveling(u8 chn, u8 rank, const u8 wr_level[CHANNEL_MAX][RANK_MAX][DQS_NUMBER]) { - clrsetbits_le32(&ch[chn].phy.shu[0].rk[rank].ca_cmd[9], - SHU1_CA_CMD9_RG_RK_ARFINE_TUNE_CLK_MASK, 0); + struct reg_value regs_bak[] = { + {&ch[chn].ao.refctrl0, 0x0}, + {&ch[chn].ao.spcmdctrl, 0x0}, + {&ch[chn].ao.dramc_pd_ctrl, 0x0}, + {&ch[chn].ao.write_lev, 0x0}, + {&ch[chn].ao.ckectrl, 0x0}, + }; + for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) + regs_bak[i].value = read32(regs_bak[i].addr); + dramc_rank_swap(chn, rank);
- for (size_t i = 0; i < DQS_NUMBER; i++) { - s32 wrlevel_dq_delay = wr_level[chn][rank][i] + 0x10; + dramc_auto_refresh_switch(chn, false); + if (rank == RANK_0) + write_leveling_move_dqs_instead_of_clk(chn); + + for (size_t i = 0; i < ARRAY_SIZE(regs_bak); i++) + write32(regs_bak[i].addr, regs_bak[i].value); + + + for (u8 i = 0; i < DQS_NUMBER; i++) { + u32 wrlevel_dq_delay = wr_level[chn][rank][i] + 0x10; + dramc_dbg("%s ch:%d, rank:%d,DQ:%d, wrlevel: %d\n", + __func__, chn, rank, i, wr_level[chn][rank][i]); + clrsetbits_le32(&ch[chn].phy.shu[0].rk[rank].b[i].dq[7], + FINE_TUNE_PBYTE_MASK, + wr_level[chn][rank][i] << FINE_TUNE_PBYTE_SHIFT); assert(wrlevel_dq_delay < 0x40); + if (wrlevel_dq_delay >= 0x40) { + wrlevel_dq_delay -= 0x40; + move_dramc_tx_dq(chn, rank, i, 2); + move_dramc_tx_dq_oen(chn, rank, i, 2); + }
clrsetbits_le32(&ch[chn].phy.shu[0].rk[rank].b[i].dq[7], - FINE_TUNE_PBYTE_MASK | FINE_TUNE_DQM_MASK | - FINE_TUNE_DQ_MASK, - (wr_level[chn][rank][i] << FINE_TUNE_PBYTE_SHIFT) | + FINE_TUNE_DQM_MASK | FINE_TUNE_DQ_MASK, (wrlevel_dq_delay << FINE_TUNE_DQM_SHIFT) | (wrlevel_dq_delay << FINE_TUNE_DQ_SHIFT)); } + dramc_rank_swap(chn, RANK_0); }
static void dramc_cmd_bus_training(u8 chn, u8 rank, @@ -344,10 +463,12 @@ } }
+extern u8 MR13Value; static void dramc_set_mr13_vrcg_to_Normal(u8 chn) { + MR13Value &= ~(0x1<<3); for (u8 rank = 0; rank < RANK_MAX; rank++) - dramc_mode_reg_write_by_rank(chn, rank, 13, 0xd0); + dramc_mode_reg_write_by_rank(chn, rank, 13, MR13Value);
for (u8 shu = 0; shu < DRAM_DFS_SHUFFLE_MAX; shu++) clrbits_le32(&ch[chn].ao.shu[shu].hwset_vrcg, 0x1 << 19); @@ -405,12 +526,33 @@ rank << TEST2_4_TESTAGENTRK_SHIFT); }
-static void dramc_engine2_init(u8 chn, u8 rank, u32 size, bool test_pat) +static void dramc_engine2_setpat(u8 chn, bool test_pat) { - const u32 pat0 = 0x55; - const u32 pat1 = 0xaa; - const u32 addr = 0; + clrbits_le32(&ch[chn].ao.test2_4, + (0x1 << TEST2_4_TEST_REQ_LEN1_SHIFT) | + (0x1 << TEST2_4_TESTXTALKPAT_SHIFT) | + (0x1 << TEST2_4_TESTAUDMODE_SHIFT) | + (0x1 << TEST2_4_TESTAUDBITINV_SHIFT));
+ if (!test_pat) { + setbits_le32(&ch[chn].ao.perfctl0, 1 << PERFCTL0_RWOFOEN_SHIFT); + + clrsetbits_le32(&ch[chn].ao.test2_4, + (0x1 << TEST2_4_TESTSSOPAT_SHIFT) | + (0x1 << TEST2_4_TESTSSOXTALKPAT_SHIFT), + (0x1 << TEST2_4_TESTXTALKPAT_SHIFT)); + } else { + clrsetbits_le32(&ch[chn].ao.test2_4, + TEST2_4_TESTAUDINIT_MASK | TEST2_4_TESTAUDINC_MASK, + (0x11 << 8) | (0xd << 0) | (0x1 << 14)); + } + clrsetbits_le32(&ch[chn].ao.test2_3, + (0x1 << TEST2_3_TESTAUDPAT_SHIFT) | TEST2_3_TESTCNT_MASK, + (test_pat ? 1 : 0) << TEST2_3_TESTAUDPAT_SHIFT); +} + +static void dramc_engine2_init(u8 chn, u8 rank, u32 t2_1, u32 t2_2, bool test_pat) +{ dramc_set_rank_engine2(chn, rank);
clrbits_le32(&ch[chn].ao.dummy_rd, @@ -420,55 +562,53 @@ (0x1 << DUMMY_RD_SREF_DMYRD_EN_SHIFT) | (0x1 << DUMMY_RD_DMY_RD_DBG_SHIFT) | (0x1 << DUMMY_RD_DMY_WR_DBG_SHIFT)); - clrbits_le32(&ch[chn].nao.testchip_dma1, - 0x1 << TESTCHIP_DMA1_DMA_LP4MATAB_OPT_SHIFT); + clrbits_le32(&ch[chn].nao.testchip_dma1, 0x1 << 12); clrbits_le32(&ch[chn].ao.test2_3, (0x1 << TEST2_3_TEST2W_SHIFT) | (0x1 << TEST2_3_TEST2R_SHIFT) | (0x1 << TEST2_3_TEST1_SHIFT)); clrsetbits_le32(&ch[chn].ao.test2_0, TEST2_0_PAT0_MASK | TEST2_0_PAT1_MASK, - (pat0 << TEST2_0_PAT0_SHIFT) | - (pat1 << TEST2_0_PAT1_SHIFT)); - write32(&ch[chn].ao.test2_1, (addr << 4) & 0x00ffffff); - write32(&ch[chn].ao.test2_2, (size << 4) & 0x00ffffff); + ((t2_1 >> 24) << TEST2_0_PAT0_SHIFT) | + ((t2_2 >> 24) << TEST2_0_PAT1_SHIFT)); + clrsetbits_le32(&ch[chn].ao.test2_1, 0xfffffff0, (t2_1 & 0x00ffffff) << 4); + clrsetbits_le32(&ch[chn].ao.test2_2, 0xfffffff0, (t2_2 & 0x00ffffff) << 4);
- clrsetbits_le32(&ch[chn].ao.test2_4, - (0x1 << TEST2_4_TESTAUDMODE_SHIFT) | - (0x1 << TEST2_4_TESTAUDBITINV_SHIFT) | - (0x1 << TEST2_4_TESTXTALKPAT_SHIFT), - ((!test_pat ? 1 : 0) << TEST2_4_TESTXTALKPAT_SHIFT) | - ((test_pat ? 1 : 0) << TEST2_4_TESTAUDMODE_SHIFT) | - ((test_pat ? 1 : 0) << TEST2_4_TESTAUDBITINV_SHIFT)); - - if (!test_pat) { - clrbits_le32(&ch[chn].ao.test2_4, - (0x1 << TEST2_4_TEST_REQ_LEN1_SHIFT) | - (0x1 << TEST2_4_TESTSSOPAT_SHIFT) | - (0x1 << TEST2_4_TESTSSOXTALKPAT_SHIFT)); - setbits_le32(&ch[chn].ao.perfctl0, - 0x1 << PERFCTL0_RWOFOEN_SHIFT); - } else { - clrsetbits_le32(&ch[chn].ao.test2_4, - TEST2_4_TESTAUDINIT_MASK | TEST2_4_TESTAUDINC_MASK, - (0x11 << TEST2_4_TESTAUDINIT_SHIFT) | - (0xd << TEST2_4_TESTAUDINC_SHIFT)); - } - clrsetbits_le32(&ch[chn].ao.test2_3, - TEST2_3_TESTCNT_MASK | (0x1 << TEST2_3_TESTAUDPAT_SHIFT), - (test_pat ? 1 : 0) << TEST2_3_TESTAUDPAT_SHIFT); + dramc_engine2_setpat(chn, test_pat); }
-static void dramc_engine2_check_complete(u8 chn) +static void dramc_engine2_check_complete(u8 chn, u8 status) { + u32 loop = 0; /* In some case test engine finished but the complete signal late come, * system will wait very long time. Hence, we set a timeout here. * After system receive complete signal or wait until time out * it will return, the caller will check compare result to verify * whether engine success. */ - if (!wait_us(10000, read32(&ch[chn].nao.testrpt) & 0x1)) - dramc_dbg("MEASURE_A timeout\n"); + while (wait_us(100, read32(&ch[chn].nao.testrpt) & status) != status) { + if (loop++ > 100) + dramc_dbg("MEASURE_A timeout\n"); + } +} + +static void dramc_engine2_compare(u8 chn, enum dram_te_op wr) +{ + u8 rank_status = ((read32(&ch[chn].ao.test2_3) & 0xf) == 1) ? 3 : 1; + + if (wr == TE_OP_WRITE_READ_CHECK) { + dramc_engine2_check_complete(chn, rank_status); + + clrbits_le32(&ch[chn].ao.test2_3, + (0x1 << TEST2_3_TEST2W_SHIFT) | + (0x1 << TEST2_3_TEST2R_SHIFT) | + (0x1 << TEST2_3_TEST1_SHIFT)); + udelay(1); + setbits_le32(&ch[chn].ao.test2_3, + (0x1 << TEST2_3_TEST2W_SHIFT)); + } + + dramc_engine2_check_complete(chn, rank_status); }
static u32 dramc_engine2_run(u8 chn, enum dram_te_op wr) @@ -478,26 +618,21 @@ if (wr == TE_OP_READ_CHECK) { clrbits_le32(&ch[chn].ao.test2_4, 0x1 << TEST2_4_TESTAUDMODE_SHIFT); + + clrsetbits_le32(&ch[chn].ao.test2_3, + (0x1 << TEST2_3_TEST2W_SHIFT) | + (0x1 << TEST2_3_TEST2R_SHIFT) | + (0x1 << TEST2_3_TEST1_SHIFT), + 0x1 << TEST2_3_TEST2R_SHIFT); } else if (wr == TE_OP_WRITE_READ_CHECK) { clrsetbits_le32(&ch[chn].ao.test2_3, + (0x1 << TEST2_3_TEST2W_SHIFT) | (0x1 << TEST2_3_TEST2R_SHIFT) | (0x1 << TEST2_3_TEST1_SHIFT), 0x1 << TEST2_3_TEST2W_SHIFT); - - dramc_engine2_check_complete(chn); - clrbits_le32(&ch[chn].ao.test2_3, - (0x1 << TEST2_3_TEST2W_SHIFT) | - (0x1 << TEST2_3_TEST2R_SHIFT) | - (0x1 << TEST2_3_TEST1_SHIFT)); - udelay(1); }
- /* Do read test */ - clrsetbits_le32(&ch[chn].ao.test2_3, - (0x1 << TEST2_3_TEST2W_SHIFT) | (0x1 << TEST2_3_TEST1_SHIFT), - 0x1 << TEST2_3_TEST2R_SHIFT); - - dramc_engine2_check_complete(chn); + dramc_engine2_compare(chn, wr);
udelay(1); result = read32(&ch[chn].nao.cmp_err); @@ -654,7 +789,8 @@
dramc_rx_dqs_isi_pulse_cg_switch(chn, true);
- write32(&ch[chn].ao.shu[0].rk[rank].selph_dqsg0, + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rank].selph_dqsg0, + 0x77777777, ((u32) best_coarse_tune2t[0] << SHURK_SELPH_DQSG0_TX_DLY_DQS0_GATED_SHIFT) | ((u32) best_coarse_tune2t[1] << @@ -663,7 +799,8 @@ SHURK_SELPH_DQSG0_TX_DLY_DQS0_GATED_P1_SHIFT) | ((u32) best_coarse_tune2t_p1[1] << SHURK_SELPH_DQSG0_TX_DLY_DQS1_GATED_P1_SHIFT)); - write32(&ch[chn].ao.shu[0].rk[rank].selph_dqsg1, + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rank].selph_dqsg1, + 0x77777777, ((u32) best_coarse_tune0p5t[0] << SHURK_SELPH_DQSG1_REG_DLY_DQS0_GATED_SHIFT) | ((u32) best_coarse_tune0p5t[1] << @@ -703,7 +840,8 @@ } }
- write32(&ch[chn].ao.shu[0].rk[rank].selph_odten0, + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rank].selph_odten0, + 0x77777777, ((u32) best_coarse_rodt[0] << SHURK_SELPH_ODTEN0_TXDLY_B0_RODTEN_SHIFT) | ((u32) best_coarse_rodt[1] << @@ -712,7 +850,8 @@ SHURK_SELPH_ODTEN0_TXDLY_B0_RODTEN_P1_SHIFT) | ((u32) best_coarse_rodt_p1[1] << SHURK_SELPH_ODTEN0_TXDLY_B1_RODTEN_P1_SHIFT)); - write32(&ch[chn].ao.shu[0].rk[rank].selph_odten1, + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rank].selph_odten1, + 0x77777777, ((u32) best_coarse_0p5t_rodt[0] << SHURK_SELPH_ODTEN1_DLY_B0_RODTEN_SHIFT) | ((u32) best_coarse_0p5t_rodt[1] << @@ -726,10 +865,12 @@ best_fine_tune[0] | (best_fine_tune[1] << 8)); }
-static void dramc_rx_dqs_gating_cal(u8 chn, u8 rank) +extern u8 MR01Value[FSP_MAX]; +static void dramc_rx_dqs_gating_cal(u8 chn, u8 rank, u32 freq_group) { u8 dqs; - const u8 mr1_value = 0x56; + u32 fsp = ( (freq_group == LP4X_DDR1600) ? FSP_0: FSP_1); + const u8 mr1_value = MR01Value[fsp]; u8 pass_begin[DQS_NUMBER] = {0}, pass_count[DQS_NUMBER] = {0}; u8 min_coarse_tune2t[DQS_NUMBER], min_coarse_tune0p5t[DQS_NUMBER], min_fine_tune[DQS_NUMBER]; @@ -760,8 +901,16 @@ dramc_rx_dqs_gating_cal_pre(chn, rank);
u32 dummy_rd_backup = read32(&ch[chn].ao.dummy_rd); - dramc_engine2_init(chn, rank, 0x23, true); + dramc_engine2_init(chn, rank, TEST2_1_CAL, 0xaa000023, true);
+ if (freq_group == LP4X_DDR1600) + coarse_start = 18; + else if (freq_group == LP4X_DDR3200) + coarse_start = 25; + else if (freq_group == LP4X_DDR3600) + coarse_start = 21; + + coarse_end = coarse_start + 12; dramc_dbg("[Gating]\n"); for (u32 coarse_tune = coarse_start; coarse_tune < coarse_end; coarse_tune += DQS_GW_COARSE_STEP) { @@ -787,42 +936,46 @@ value - (dly_coarse_large_rodt_p1 << 3); }
- write32(&ch[chn].ao.shu[0].rk[rank].selph_dqsg0, - ((u32) dly_coarse_large << - SHURK_SELPH_DQSG0_TX_DLY_DQS0_GATED_SHIFT) | - ((u32) dly_coarse_large << - SHURK_SELPH_DQSG0_TX_DLY_DQS1_GATED_SHIFT) | - (dly_coarse_large_p1 << - SHURK_SELPH_DQSG0_TX_DLY_DQS0_GATED_P1_SHIFT) | - (dly_coarse_large_p1 << - SHURK_SELPH_DQSG0_TX_DLY_DQS1_GATED_P1_SHIFT)); - write32(&ch[chn].ao.shu[0].rk[rank].selph_dqsg1, - ((u32) dly_coarse_0p5t << - SHURK_SELPH_DQSG1_REG_DLY_DQS0_GATED_SHIFT) | - ((u32) dly_coarse_0p5t << - SHURK_SELPH_DQSG1_REG_DLY_DQS1_GATED_SHIFT) | - (dly_coarse_0p5t_p1 << - SHURK_SELPH_DQSG1_REG_DLY_DQS0_GATED_P1_SHIFT) | - (dly_coarse_0p5t_p1 << - SHURK_SELPH_DQSG1_REG_DLY_DQS1_GATED_P1_SHIFT)); - write32(&ch[chn].ao.shu[0].rk[rank].selph_odten0, - (dly_coarse_large_rodt << - SHURK_SELPH_ODTEN0_TXDLY_B0_RODTEN_SHIFT) | - (dly_coarse_large_rodt << - SHURK_SELPH_ODTEN0_TXDLY_B1_RODTEN_SHIFT) | - (dly_coarse_large_rodt_p1 << - SHURK_SELPH_ODTEN0_TXDLY_B0_RODTEN_P1_SHIFT) | - (dly_coarse_large_rodt_p1 << - SHURK_SELPH_ODTEN0_TXDLY_B1_RODTEN_P1_SHIFT)); - write32(&ch[chn].ao.shu[0].rk[rank].selph_odten1, - (dly_coarse_0p5t_rodt << - SHURK_SELPH_ODTEN1_DLY_B0_RODTEN_SHIFT) | - (dly_coarse_0p5t_rodt << - SHURK_SELPH_ODTEN1_DLY_B1_RODTEN_SHIFT) | - (dly_coarse_0p5t_rodt_p1 << - SHURK_SELPH_ODTEN1_DLY_B0_RODTEN_P1_SHIFT) | - (dly_coarse_0p5t_rodt_p1 << - SHURK_SELPH_ODTEN1_DLY_B1_RODTEN_P1_SHIFT)); + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rank].selph_dqsg0, + 0x77777777, + ((u32) dly_coarse_large << 0) | + ((u32) dly_coarse_large << 8) | + ((u32) dly_coarse_large << 16) | + ((u32) dly_coarse_large << 24) | + (dly_coarse_large_p1 << 4) | + (dly_coarse_large_p1 << 12) | + (dly_coarse_large_p1 << 20) | + (dly_coarse_large_p1 << 28)); + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rank].selph_dqsg1, + 0x77777777, + ((u32) dly_coarse_0p5t << 0) | + ((u32) dly_coarse_0p5t << 8) | + ((u32) dly_coarse_0p5t << 16) | + ((u32) dly_coarse_0p5t << 24) | + (dly_coarse_0p5t_p1 << 4) | + (dly_coarse_0p5t_p1 << 12) | + (dly_coarse_0p5t_p1 << 20) | + (dly_coarse_0p5t_p1 << 28)); + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rank].selph_odten0, + 0x77777777, + (dly_coarse_large_rodt << 0) | + (dly_coarse_large_rodt << 8) | + (dly_coarse_large_rodt << 16) | + (dly_coarse_large_rodt << 24) | + (dly_coarse_large_rodt_p1 << 4) | + (dly_coarse_large_rodt_p1 << 12) | + (dly_coarse_large_rodt_p1 << 20) | + (dly_coarse_large_rodt_p1 << 28)); + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rank].selph_odten1, + 0x77777777, + (dly_coarse_0p5t_rodt << 0) | + (dly_coarse_0p5t_rodt << 8) | + (dly_coarse_0p5t_rodt << 16) | + (dly_coarse_0p5t_rodt << 24) | + (dly_coarse_0p5t_rodt_p1 << 4) | + (dly_coarse_0p5t_rodt_p1 << 12) | + (dly_coarse_0p5t_rodt_p1 << 20) | + (dly_coarse_0p5t_rodt_p1 << 28));
for (u8 dly_fine_xt = DQS_GW_FINE_START; dly_fine_xt < DQS_GW_FINE_END; @@ -933,8 +1086,7 @@ u16 temp_value = 0;
for (size_t b = 0; b < 2; b++) - clrbits_le32(&ch[chn].phy.shu[0].b[b].dq[7], - 0x1 << SHU1_BX_DQ7_R_DMDQMDBI_SHIFT); + clrbits_le32(&ch[chn].phy.shu[0].b[b].dq[7], 0x1 << 7);
clrsetbits_le32(&ch[chn].ao.mrs, MRS_MRSRK_MASK, rank << MRS_MRSRK_SHIFT); @@ -951,14 +1103,17 @@ (mr15_golden_value << 8) | mr20_golden_value); }
-static u32 dramc_rd_dqc_run(u8 chn) +static u32 dramc_rx_rd_dqc_run(u8 chn) { + u32 loop = 0; setbits_le32(&ch[chn].ao.spcmdctrl, 1 << SPCMDCTRL_RDDQCDIS_SHIFT); setbits_le32(&ch[chn].ao.spcmd, 1 << SPCMD_RDDQCEN_SHIFT);
- if (!wait_us(100, read32(&ch[chn].nao.spcmdresp) & - (0x1 << SPCMDRESP_RDDQC_RESPONSE_SHIFT))) - dramc_dbg("[RDDQC] resp fail (time out)\n"); + while (!wait_us(10, read32(&ch[chn].nao.spcmdresp) & + (0x1 << SPCMDRESP_RDDQC_RESPONSE_SHIFT))) { + if (loop++ > 10) + dramc_dbg("[RDDQC] resp fail (time out)\n"); + }
u32 result = read32(&ch[chn].nao.rdqc_cmp); clrbits_le32(&ch[chn].ao.spcmd, 1 << SPCMD_RDDQCEN_SHIFT); @@ -974,18 +1129,16 @@
static void dramc_rx_vref_enable(u8 chn) { - setbits_le32(&ch[chn].phy.b[0].dq[5], - 0x1 << B0_DQ5_RG_RX_ARDQ_VREF_EN_B0_SHIFT); - setbits_le32(&ch[chn].phy.b[1].dq[5], - 0x1 << B1_DQ5_RG_RX_ARDQ_VREF_EN_B1_SHIFT); + setbits_le32(&ch[chn].phy.b[0].dq[5], 0x1 << 16); + setbits_le32(&ch[chn].phy.b[1].dq[5], 0x1 << 16); }
static void dramc_set_rx_vref(u8 chn, u8 value) { for (size_t b = 0; b < 2; b++) clrsetbits_le32(&ch[chn].phy.shu[0].b[b].dq[5], - SHU1_BX_DQ5_RG_RX_ARDQ_VREF_SEL_B0_MASK, - value << SHU1_BX_DQ5_RG_RX_ARDQ_VREF_SEL_B0_SHIFT); + 0x3f, value << 0); + dramc_dbg("set rx vref :%d\n", value); }
static void dramc_set_tx_vref(u8 chn, u8 rank, u8 value) @@ -1004,17 +1157,18 @@ static void dramc_transfer_dly_tune( u8 chn, u32 dly, struct tx_dly_tune *dly_tune) { - u16 tmp_val; + u8 tune = 3; + u16 tmp;
dly_tune->fine_tune = dly & (TX_DQ_COARSE_TUNE_TO_FINE_TUNE_TAP - 1);
- tmp_val = (dly / TX_DQ_COARSE_TUNE_TO_FINE_TUNE_TAP) << 1; - dly_tune->coarse_tune_small = tmp_val - ((tmp_val >> 3) << 3); - dly_tune->coarse_tune_large = tmp_val >> 3; + tmp = (dly / TX_DQ_COARSE_TUNE_TO_FINE_TUNE_TAP) << 1; + dly_tune->coarse_tune_small = tmp - ((tmp >> tune) << tune); + dly_tune->coarse_tune_large = tmp >> tune;
- tmp_val -= 4; - dly_tune->coarse_tune_small_oen = tmp_val - ((tmp_val >> 3) << 3); - dly_tune->coarse_tune_large_oen = tmp_val >> 3; + tmp -= 4; + dly_tune->coarse_tune_small_oen = tmp - ((tmp >> tune) << tune); + dly_tune->coarse_tune_large_oen = tmp >> tune; }
static void dramc_set_rx_dly_factor(u8 chn, u8 rank, enum RX_TYPE type, u32 val) @@ -1052,48 +1206,53 @@ } }
-static void dramc_set_tx_dly_factor(u8 chn, u8 rank, - enum CAL_TYPE type, u32 val) +static void dramc_set_tx_dly_factor(u8 chn, u8 rk, + enum CAL_TYPE type, u32 dly) { struct tx_dly_tune dly_tune = {0}; - u32 coarse_tune_large = 0, coarse_tune_large_oen = 0; - u32 coarse_tune_small = 0, coarse_tune_small_oen = 0; + u32 dly_large = 0, dly_large_oen = 0, dly_small = 0, dly_small_oen = 0; + u32 tmp = 0xff;
- dramc_transfer_dly_tune(chn, val, &dly_tune); + dramc_transfer_dly_tune(chn, dly, &dly_tune);
for (u8 i = 0; i < 4; i++) { - coarse_tune_large += dly_tune.coarse_tune_large << (i * 4); - coarse_tune_large_oen += - dly_tune.coarse_tune_large_oen << (i * 4); - coarse_tune_small += dly_tune.coarse_tune_small << (i * 4); - coarse_tune_small_oen += - dly_tune.coarse_tune_small_oen << (i * 4); + dly_large += dly_tune.coarse_tune_large << (i * 4); + dly_large_oen += dly_tune.coarse_tune_large_oen << (i * 4); + dly_small += dly_tune.coarse_tune_small << (i * 4); + dly_small_oen += dly_tune.coarse_tune_small_oen << (i * 4); } + if (type == TX_WIN_DQ_DQM) dramc_dbg("%3d |%d %d %2d | [0]", - val, dly_tune.coarse_tune_large, + dly, dly_tune.coarse_tune_large, dly_tune.coarse_tune_small, dly_tune.fine_tune);
- if (type != TX_WIN_DQ_DQM && type != TX_WIN_DQ_ONLY) - return; + if (tmp != dly_large) { + if (type == TX_WIN_DQ_DQM || type == TX_WIN_DQ_ONLY) { + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rk].selph_dq[0], + 0x77777777, dly_large | (dly_large_oen << 16)); + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rk].selph_dq[2], + 0x77777777, dly_small | (dly_small_oen << 16)); + }
- write32(&ch[chn].ao.shu[0].rk[rank].selph_dq[0], - (coarse_tune_large_oen << 16) | coarse_tune_large); - write32(&ch[chn].ao.shu[0].rk[rank].selph_dq[2], - (coarse_tune_small_oen << 16) | coarse_tune_small); - for (size_t b = 0; b < 2; b++) - clrsetbits_le32(&ch[chn].phy.shu[0].rk[rank].b[b].dq[7], - FINE_TUNE_DQ_MASK, dly_tune.fine_tune << 8); + if (type == TX_WIN_DQ_DQM) { + /* Large coarse_tune setting */ + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rk].selph_dq[1], + 0x77777777, dly_large | (dly_large_oen << 16)); + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rk].selph_dq[3], + 0x77777777, dly_small | (dly_small_oen << 16)); + } + tmp = dly_large; + }
- if (type == TX_WIN_DQ_DQM) { - /* Large coarse_tune setting */ - write32(&ch[chn].ao.shu[0].rk[rank].selph_dq[1], - (coarse_tune_large_oen << 16) | coarse_tune_large); - write32(&ch[chn].ao.shu[0].rk[rank].selph_dq[3], - (coarse_tune_small_oen << 16) | coarse_tune_small); - /* Fine_tune delay setting */ + if (type == TX_WIN_DQ_DQM || type == TX_WIN_DQ_ONLY) { for (size_t b = 0; b < 2; b++) - clrsetbits_le32(&ch[chn].phy.shu[0].rk[rank].b[b].dq[7], + clrsetbits_le32(&ch[chn].phy.shu[0].rk[rk].b[b].dq[7], + FINE_TUNE_DQ_MASK, dly_tune.fine_tune << 8); + } + if (type == TX_WIN_DQ_DQM) { + for (size_t b = 0; b < 2; b++) + clrsetbits_le32(&ch[chn].phy.shu[0].rk[rk].b[b].dq[7], FINE_TUNE_DQM_MASK, dly_tune.fine_tune << 16); } } @@ -1101,22 +1260,33 @@ static u32 dramc_get_smallest_dqs_dly( u8 chn, u8 rank, const struct sdram_params *params) { - u32 min_dly = 0xffff; + u8 mck = 3; + u32 min_dly = 0xffff, virtual_delay = 0; + u32 tx_dly = read32(&ch[chn].ao.shu[0].selph_dqs0); + u32 dly = read32(&ch[chn].ao.shu[0].selph_dqs1);
- for (size_t i = 0; i < DQS_NUMBER; i++) - min_dly = MIN(min_dly, params->wr_level[chn][rank][i]); + for (size_t dqs = 0; dqs < DQS_NUMBER; dqs++) { + virtual_delay = (((((tx_dly >> (dqs << 2)) & 0x7) << mck) + ((dly >> (dqs << 2)) & 0x7)) << 5) + + params->wr_level[chn][rank][dqs]; + min_dly = MIN(min_dly, virtual_delay); + }
- return DQS_DELAY + min_dly + 40; + return min_dly; }
static void dramc_get_dly_range(u8 chn, u8 rank, enum CAL_TYPE type, - u16 *pre_cal, s16 *begin, s16 *end, + u32 freq_group, u16 *pre_cal, s16 *begin, s16 *end, const struct sdram_params *params) { u16 pre_dq_dly; switch (type) { case RX_WIN_RD_DQC: - *begin = FIRST_DQS_DELAY; + if (freq_group == LP4X_DDR1600) + *begin = -48; + else if (freq_group >= LP4X_DDR3200) + *begin = -26; + else + *begin = -64; *end = MAX_RX_DQDLY_TAPS; break;
@@ -1138,22 +1308,22 @@ break; } } -static int dramc_check_dqdqs_win( +static int dramc_check_rx_dqdqs_win( struct dqdqs_perbit_dly *p, s16 dly_pass, s16 last_step, bool fail, bool is_dq) { s16 best_pass_win; - struct perbit_dly *dly = is_dq ? &p->dqdly : &p->dqsdly; + struct perbit_dly *dly = (is_dq ? &p->dqdly : &p->dqsdly);
- if (!fail && dly->first == -1) + if (!fail && dly->first == PASS_RANGE_NA) dly->first = dly_pass;
- if (!fail && dly->last == -2 && dly_pass == last_step) + if (!fail && dly->last == PASS_RANGE_NA && dly_pass == last_step) dly->last = dly_pass; - else if (fail && dly->first != -1 && dly->last == -2) + else if (fail && dly->first != PASS_RANGE_NA && dly->last == PASS_RANGE_NA) dly->last = dly_pass - 1;
- if (dly->last == -2) + if (dly->last == PASS_RANGE_NA) return 0;
int pass_win = dly->last - dly->first; @@ -1163,8 +1333,8 @@ dly->best_first = dly->first; } /* Clear to find the next pass range if it has */ - dly->first = -1; - dly->last = -2; + dly->first = PASS_RANGE_NA; + dly->last = PASS_RANGE_NA;
return pass_win; } @@ -1210,7 +1380,7 @@ return true;
break; - case TX_DQ_DQS_MOVE_DQ_ONLY: + case RX_WIN_RD_DQC: for (size_t bit = 0; bit < DQ_DATA_WIDTH; bit++) { win_size = delay[bit].dqdly.best_last - delay[bit].dqdly.best_first + 1; @@ -1218,8 +1388,10 @@ win_size_sum += win_size; }
- if (win_size_sum > vref_dly->max_win - && vref_dly->min_win >= min_win_size_vref) { + dramc_dbg(" %s win_size_sum:%d, max_win:%d, vref_dly->min_win :%d, min_win_size_vref:%d \n", + __func__, win_size_sum, vref_dly->max_win, vref_dly->min_win, min_win_size_vref); + if ((win_size_sum > vref_dly->max_win) + && (vref_dly->min_win >= min_win_size_vref)) { min_win_size_vref = vref_dly->min_win; dramc_set_vref_dly(vref_dly, vref, win_size_sum, delay); } @@ -1246,7 +1418,7 @@ byte_delay_prop->max_center = win_center; }
-static void dramc_set_rx_dly(u8 chn, u8 rank, s32 dly) +static void dramc_set_rx_dqdqs_dly(u8 chn, u8 rank, s32 dly) { if (dly <= 0) { /* Hold time calibration */ @@ -1262,12 +1434,10 @@ }
static void dramc_set_tx_best_dly_factor(u8 chn, u8 rank_start, - struct per_byte_dly *tx_perbyte_dly, u16 dq_precal_result[]) + struct per_byte_dly *tx_perbyte_dly, u16 dq_precal_dly[]) { - u32 coarse_tune_large = 0; - u32 coarse_tune_large_oen = 0; - u32 coarse_tune_small = 0; - u32 coarse_tune_small_oen = 0; + u32 dq_large = 0, dq_large_oen = 0, dq_small = 0, dq_small_oen = 0; + u32 dqm_large = 0, dqm_large_oen = 0, dqm_small = 0, dqm_small_oen = 0; u16 dq_oen[DQS_NUMBER] = {0}, dqm_oen[DQS_NUMBER] = {0}; struct tx_dly_tune dqdly_tune[DQS_NUMBER] = {0}; struct tx_dly_tune dqmdly_tune[DQS_NUMBER] = {0}; @@ -1275,15 +1445,18 @@ for (size_t i = 0; i < DQS_NUMBER; i++) { dramc_transfer_dly_tune(chn, tx_perbyte_dly[i].final_dly, &dqdly_tune[i]); - dramc_transfer_dly_tune(chn, dq_precal_result[i], + dramc_transfer_dly_tune(chn, dq_precal_dly[i], &dqmdly_tune[i]);
- coarse_tune_large += dqdly_tune[i].coarse_tune_large << (i * 4); - coarse_tune_large_oen += - dqdly_tune[i].coarse_tune_large_oen << (i * 4); - coarse_tune_small += dqdly_tune[i].coarse_tune_small << (i * 4); - coarse_tune_small_oen += - dqdly_tune[i].coarse_tune_small_oen << (i * 4); + dq_large += dqdly_tune[i].coarse_tune_large << (i * 4); + dq_large_oen += dqdly_tune[i].coarse_tune_large_oen << (i * 4); + dq_small += dqdly_tune[i].coarse_tune_small << (i * 4); + dq_small_oen += dqdly_tune[i].coarse_tune_small_oen << (i * 4); + + dqm_large += dqmdly_tune[i].coarse_tune_large << (i * 4); + dqm_large_oen += dqmdly_tune[i].coarse_tune_large_oen << (i * 4); + dqm_small += dqmdly_tune[i].coarse_tune_small << (i * 4); + dqm_small_oen += dqmdly_tune[i].coarse_tune_small_oen << (i * 4);
dq_oen[i] = (dqdly_tune[i].coarse_tune_large_oen << 3) + (dqdly_tune[i].coarse_tune_small_oen << 5) + @@ -1294,24 +1467,21 @@ }
for (size_t rank = rank_start; rank < RANK_MAX; rank++) { - write32(&ch[chn].ao.shu[0].rk[rank].selph_dq[0], - (coarse_tune_large_oen << 16) | coarse_tune_large); - write32(&ch[chn].ao.shu[0].rk[rank].selph_dq[2], - (coarse_tune_small_oen << 16) | coarse_tune_small); - write32(&ch[chn].ao.shu[0].rk[rank].selph_dq[1], - (coarse_tune_large_oen << 16) | coarse_tune_large); - write32(&ch[chn].ao.shu[0].rk[rank].selph_dq[3], - (coarse_tune_small_oen << 16) | coarse_tune_small); - } + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rank].selph_dq[0], + 0x77777777, dq_large | (dq_large_oen << 16)); + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rank].selph_dq[2], + 0x77777777, dq_small| (dq_small_oen << 16)); + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rank].selph_dq[1], + 0x77777777, dqm_large | (dqm_large_oen << 16)); + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rank].selph_dq[3], + 0x77777777, dqm_small | (dqm_small_oen << 16));
- for (size_t rank = rank_start; rank < RANK_MAX; rank++) for (size_t b = 0; b < 2; b++) clrsetbits_le32(&ch[chn].phy.shu[0].rk[rank].b[b].dq[7], FINE_TUNE_DQ_MASK | FINE_TUNE_DQM_MASK, - (dqdly_tune[b].fine_tune << - FINE_TUNE_DQ_SHIFT) | - (dqmdly_tune[b].fine_tune << - FINE_TUNE_DQM_SHIFT)); + (dqdly_tune[b].fine_tune << 8) | + (dqmdly_tune[b].fine_tune << 16)); + } }
static void dramc_set_rx_best_dly_factor(u8 chn, u8 rank, @@ -1344,8 +1514,8 @@ { u8 fail = 0, hold, setup;
- hold = p->dqsdly.best_last - p->dqsdly.best_first + 1; setup = p->dqdly.best_last - p->dqdly.best_first + 1; + hold = p->dqsdly.best_last - p->dqsdly.best_first + 1;
if (hold > setup) { p->dqdly.best = 0; @@ -1370,8 +1540,8 @@ } }
- dramc_dbg("bit#%d : dq =%d dqs=%d win=%d (%d, %d)\n", bit, setup, - hold, setup + hold, p->dqdly.best, p->dqsdly.best); + dramc_dbg("bit#%d: dq win=%d, dqs win=%d total win=%d (%d~%d)\n", + bit, setup, hold, setup + hold, p->dqdly.best_first, p->dqdly.best_last);
return fail; } @@ -1379,7 +1549,7 @@ static void dramc_set_dqdqs_dly(u8 chn, u8 rank, enum CAL_TYPE type, s32 dly) { if ((type == RX_WIN_RD_DQC) || (type == RX_WIN_TEST_ENG)) - dramc_set_rx_dly(chn, rank, dly); + dramc_set_rx_dqdqs_dly(chn, rank, dly); else dramc_set_tx_dly_factor(chn, rank, type, dly); } @@ -1490,40 +1660,19 @@ *vref_end = TX_VREF_END; } else { *vref_scan_en = 0; + *vref_begin = 0; + *vref_end = 1; } }
-static void dramc_engine2_setpat(u8 chn, bool test_pat) -{ - clrbits_le32(&ch[chn].ao.test2_4, - (0x1 << TEST2_4_TESTXTALKPAT_SHIFT) | - (0x1 << TEST2_4_TESTAUDMODE_SHIFT) | - (0x1 << TEST2_4_TESTAUDBITINV_SHIFT)); - - if (!test_pat) { - setbits_le32(&ch[chn].ao.perfctl0, 1 << PERFCTL0_RWOFOEN_SHIFT); - - clrbits_le32(&ch[chn].ao.test2_4, - (0x1 << TEST2_4_TEST_REQ_LEN1_SHIFT) | - (0x1 << TEST2_4_TESTSSOPAT_SHIFT) | - (0x1 << TEST2_4_TESTSSOXTALKPAT_SHIFT) | - (0x1 << TEST2_4_TESTXTALKPAT_SHIFT)); - } else { - clrsetbits_le32(&ch[chn].ao.test2_4, - TEST2_4_TESTAUDINIT_MASK | TEST2_4_TESTAUDINC_MASK, - (0x11 << 8) | (0xd << 0) | (0x1 << 14)); - } - clrsetbits_le32(&ch[chn].ao.test2_3, - (0x1 << TEST2_3_TESTAUDPAT_SHIFT) | TEST2_3_TESTCNT_MASK, - (test_pat ? 1 : 0) << TEST2_3_TESTAUDPAT_SHIFT); -} - static u32 dram_k_perbit(u8 chn, enum CAL_TYPE type) { u32 err_value;
if (type == RX_WIN_RD_DQC) { - err_value = dramc_rd_dqc_run(chn); + err_value = dramc_rx_rd_dqc_run(chn); + } else if (type == RX_WIN_TEST_ENG) { + err_value = dramc_engine2_run(chn, TE_OP_WRITE_READ_CHECK); } else { dramc_engine2_setpat(chn, true); err_value = dramc_engine2_run(chn, TE_OP_WRITE_READ_CHECK); @@ -1533,7 +1682,7 @@ return err_value; }
-static u8 dramc_window_perbit_cal(u8 chn, u8 rank, +static u8 dramc_window_perbit_cal(u8 chn, u8 rank, u32 freq_group, enum CAL_TYPE type, const struct sdram_params *params) { u8 vref = 0, vref_begin = 0, vref_end = 1, vref_step = 1; @@ -1570,7 +1719,7 @@ dramc_rd_dqc_init(chn, rank); } else { dummy_rd_backup = read32(&ch[chn].ao.dummy_rd); - dramc_engine2_init(chn, rank, 0x400, false); + dramc_engine2_init(chn, rank, TEST2_1_CAL, TEST2_2_CAL, false); }
vref_dly.max_win = 0; @@ -1599,7 +1748,7 @@ RX_DQ, FIRST_DQ_DELAY); }
- dramc_get_dly_range(chn, rank, type, dq_precal_result, + dramc_get_dly_range(chn, rank, type, freq_group, dq_precal_result, &dly_begin, &dly_end, params); for (dly = dly_begin; dly < dly_end; dly += dly_step) { dramc_set_dqdqs_dly(chn, rank, type, dly); @@ -1624,7 +1773,7 @@
/* pass window bigger than 7, consider as real pass window */ - if (dramc_check_dqdqs_win(&(dq_perbit_dly[bit]), + if (dramc_check_rx_dqdqs_win(&(dq_perbit_dly[bit]), dly_pass, last_step, fail, flag) > 7) finish_bit |= (1 << bit); @@ -1643,9 +1792,11 @@ }
for (size_t bit = 0; bit < DQ_DATA_WIDTH; bit++) - dramc_dbg("Dq[%zd] win(%d ~ %d)\n", bit, + dramc_dbg("Dq[%zd] win width %d(%d ~ %d)\n", bit, + dq_perbit_dly[bit].dqdly.best_last - dq_perbit_dly[bit].dqdly.best_first, dq_perbit_dly[bit].dqdly.best_first, dq_perbit_dly[bit].dqdly.best_last); + dramc_dbg(" \n");
if (dramk_calc_best_vref(type, vref, &vref_dly, dq_perbit_dly)) break; @@ -1696,7 +1847,7 @@ chn, rank, best_step);
u32 dummy_rd_backup = read32(&ch[chn].ao.dummy_rd); - dramc_engine2_init(chn, rank, 0x400, false); + dramc_engine2_init(chn, rank, TEST2_1_CAL, TEST2_2_CAL, false);
for (datlat = 12; datlat < DATLAT_TAP_NUMBER; datlat++) { dramc_dle_factor_handler(chn, datlat); @@ -1801,7 +1952,8 @@ best_coarse_tune2t_p1[rank][dqs]); }
- write32(&ch[chn].ao.shu[0].rk[rank].selph_dqsg0, + clrsetbits_le32(&ch[chn].ao.shu[0].rk[rank].selph_dqsg0, + 0x77777777, (best_coarse_tune2t[rank][0] << 0) | (best_coarse_tune2t[rank][1] << 8) | (best_coarse_tune2t_p1[rank][0] << 4) | @@ -1837,7 +1989,7 @@ read_dqsinctl, rankinctl_root, xrtr2r); }
-void dramc_calibrate_all_channels(const struct sdram_params *pams) +void dramc_calibrate_all_channels(const struct sdram_params *pams, u32 freq_group) { u8 rx_datlat[RANK_MAX] = {0}; for (u8 chn = 0; chn < CHANNEL_MAX; chn++) { @@ -1847,12 +1999,12 @@ dramc_cmd_bus_training(chn, rk, pams); dramc_write_leveling(chn, rk, pams->wr_level); dramc_auto_refresh_switch(chn, true); - dramc_rx_dqs_gating_cal(chn, rk); - dramc_window_perbit_cal(chn, rk, RX_WIN_RD_DQC, pams); - dramc_window_perbit_cal(chn, rk, TX_WIN_DQ_DQM, pams); - dramc_window_perbit_cal(chn, rk, TX_WIN_DQ_ONLY, pams); + dramc_rx_dqs_gating_cal(chn, rk, freq_group); + dramc_window_perbit_cal(chn, rk, freq_group, RX_WIN_RD_DQC, pams); + dramc_window_perbit_cal(chn, rk, freq_group, TX_WIN_DQ_DQM, pams); + dramc_window_perbit_cal(chn, rk, freq_group, TX_WIN_DQ_ONLY, pams); rx_datlat[rk] = dramc_rx_datlat_cal(chn, rk); - dramc_window_perbit_cal(chn, rk, RX_WIN_TEST_ENG, pams); + dramc_window_perbit_cal(chn, rk, freq_group, RX_WIN_TEST_ENG, pams); }
dramc_rx_dqs_gating_post_process(chn); diff --git a/src/soc/mediatek/mt8183/emi.c b/src/soc/mediatek/mt8183/emi.c index 937d06d..27d80e8 100644 --- a/src/soc/mediatek/mt8183/emi.c +++ b/src/soc/mediatek/mt8183/emi.c @@ -19,6 +19,8 @@ #include <soc/dramc_pi_api.h> #include <soc/dramc_register.h>
+u32 freqTbl[LP4X_DDRFREQ_MAX] = {DDR_FREQ_1600, DDR_FREQ_3200, DDR_FREQ_3600}; + struct emi_regs *emi_regs = (void *)EMI_BASE; const u8 phy_mapping[CHANNEL_MAX][16] = { [CHANNEL_A] = { @@ -268,18 +270,34 @@ setbits_le32(&ch[0].phy.misc_ctrl1, 0x1 << 31); }
-static void dramc_ac_timing_optimize(void) +typedef struct { + u8 u1TRFC : 8; + u8 u1TRFRC_05T : 1; + u16 u2TXREFCNT : 10; +} optimizeACTime; + +static void dramc_ac_timing_optimize(u32 freq_group) +{ + optimizeACTime tRFCab_Opt[LP4X_DDRFREQ_MAX] = + { + {.u1TRFC = 44, .u1TRFRC_05T = 0, .u2TXREFCNT = 62}, //DDR1600 + {.u1TRFC = 100, .u1TRFRC_05T = 0, .u2TXREFCNT = 119}, //DDR3200 + {.u1TRFC = 118, .u1TRFRC_05T = 1, .u2TXREFCNT = 138}, //DDR3600 + }; + dramc_dbg("%s with freq:%d: u1TRFC %d, u2TXREFCNT:%d\n", __func__, freq_group, + tRFCab_Opt[freq_group].u1TRFC, tRFCab_Opt[freq_group].u2TXREFCNT); + for (size_t chn = 0; chn < CHANNEL_MAX; chn++) { clrsetbits_le32(&ch[chn].ao.shu[0].actim[3], - 0xff << 16, 0x64 << 16); + 0xff << 16, tRFCab_Opt[freq_group].u1TRFC << 16); clrbits_le32(&ch[chn].ao.shu[0].ac_time_05t, 0x1 << 2); clrsetbits_le32(&ch[chn].ao.shu[0].actim[4], - 0x3ff << 0, 0x77 << 0); + 0x3ff << 0, tRFCab_Opt[freq_group].u2TXREFCNT << 0); } }
-static void init_dram(const struct sdram_params *params) +static void init_dram(const struct sdram_params *params, u32 freq_group) { global_option_init(params); emi_init(params); @@ -288,7 +306,8 @@ dramc_init_pre_settings(); dramc_sw_impedance(params);
- dramc_init(); + dramc_init(params, freq_group); + dramc_apply_config_before_calibration(); emi_init2(params); }
@@ -301,17 +320,27 @@ clrbits_le32(&ch[chn].emi.chn_conb, 0xff << 24); }
-static void do_calib(const struct sdram_params *params) +static void do_calib(const struct sdram_params *params, u32 freq_group) { - dramc_apply_config_before_calibration(); - dramc_calibrate_all_channels(params); - dramc_ac_timing_optimize(); + dramc_show("Start K freq group:%d\n", freqTbl[freq_group]); + dramc_calibrate_all_channels(params, freq_group); + dramc_ac_timing_optimize(freq_group); + dramc_show("%s K freq group:%d finish!\n", __func__, freqTbl[freq_group]); +} + +static void after_calib(void) +{ dramc_apply_config_after_calibration(); dramc_runtime_config(); }
void mt_set_emi(const struct sdram_params *params) { - init_dram(params); - do_calib(params); + u32 freq_group = LP4X_DDR3600; + dramc_show("%s with: freq_sel %d,\n", __func__, freq_group); + + init_dram(params, freq_group); + + do_calib(params, freq_group); + after_calib(); } diff --git a/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h b/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h index 23b5cf0..815d586 100644 --- a/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h +++ b/src/soc/mediatek/mt8183/include/soc/dramc_pi_api.h @@ -38,6 +38,21 @@ #define IMP_DRVN_LP4X_UNTERM_VREF_SEL 0x16 #define IMP_TRACK_LP4X_UNTERM_VREF_SEL 0x1a
+enum +{ + LP4X_DDR1600, + LP4X_DDR3200, + LP4X_DDR3600, + LP4X_DDRFREQ_MAX, +}; + +enum +{ + DDR_FREQ_1600 = 1600, + DDR_FREQ_3200 = 3200, + DDR_FREQ_3600 = 3600, +}; + enum dram_te_op { TE_OP_WRITE_READ_CHECK = 0, TE_OP_READ_CHECK @@ -114,19 +129,21 @@ SELPH_DQS1 = (DQS_DELAY_0P5T << 0) | (DQS_DELAY_0P5T << 4) | (DQS_DELAY_0P5T << 8) | (DQS_DELAY_0P5T << 12) | (DQS_OEN_DELAY_0P5T << 16) | (DQS_OEN_DELAY_0P5T << 20) | - (DQS_OEN_DELAY_0P5T << 24) | (DQS_OEN_DELAY_0P5T << 28) + (DQS_OEN_DELAY_0P5T << 24) | (DQS_OEN_DELAY_0P5T << 28), };
void dramc_get_rank_size(u64 *dram_rank_size); void dramc_runtime_config(void); void dramc_set_broadcast(u32 onoff); u32 dramc_get_broadcast(void); -void dramc_init(void); +void dramc_init(const struct sdram_params *params, u32 freq_group); void dramc_sw_impedance(const struct sdram_params *params); void dramc_apply_config_before_calibration(void); void dramc_apply_config_after_calibration(void); -void dramc_calibrate_all_channels(const struct sdram_params *params); +void dramc_calibrate_all_channels(const struct sdram_params *pams, u32 freq_group); void dramc_hw_gating_onoff(u8 chn, bool onoff); void dramc_enable_phy_dcm(bool bEn); +void dramc_mode_reg_write(u8 chn, u8 mr_idx, u8 value); +void dramc_cke_fix_onoff(u8 chn, bool fix_on, bool fix_off);
#endif /* _DRAMC_PI_API_MT8183_H */ diff --git a/src/soc/mediatek/mt8183/include/soc/dramc_register.h b/src/soc/mediatek/mt8183/include/soc/dramc_register.h index f0720a7..40138e8 100644 --- a/src/soc/mediatek/mt8183/include/soc/dramc_register.h +++ b/src/soc/mediatek/mt8183/include/soc/dramc_register.h @@ -945,12 +945,15 @@ };
enum { + MISC_STATUSA_SREF_STATE = 16, MISC_STATUSA_REFRESH_QUEUE_CNT_SHIFT = 24, MISC_STATUSA_REFRESH_QUEUE_CNT_MASK = 0x0f000000, };
enum { SPCMDRESP_RDDQC_RESPONSE_SHIFT = 7, + SPCMDRESP_ZQLAT_RESPONSE_SHIFT = 6, + SPCMDRESP_ZQC_RESPONSE_SHIFT = 4, };
enum { @@ -974,6 +977,8 @@ };
enum { + MRS_MPCRK_SHIFT = 28, + MRS_MPCRK_MASK = 0x30000000, MRS_MRSRK_SHIFT = 24, MRS_MRSRK_MASK = 0x03000000, MRS_MRSMA_SHIFT = 8, @@ -986,6 +991,8 @@ SPCMD_DQSGCNTRST_SHIFT = 9, SPCMD_DQSGCNTEN_SHIFT = 8, SPCMD_RDDQCEN_SHIFT = 7, + SPCMD_ZQLATEN_SHIFT = 6, + SPCMD_ZQCEN_SHIFT = 4, SPCMD_MRWEN_SHIFT = 0, };