From 11dc5b049b83994603dc7eae3b921a0781cd934d Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Thu, 20 Apr 2023 18:35:56 +0800 Subject: [PATCH 1/4] Working clam shell topology --- litex/soc/software/liblitedram/sdram.c | 46 ++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/litex/soc/software/liblitedram/sdram.c b/litex/soc/software/liblitedram/sdram.c index 51805d11e..cdae0ae13 100644 --- a/litex/soc/software/liblitedram/sdram.c +++ b/litex/soc/software/liblitedram/sdram.c @@ -254,10 +254,28 @@ void sdram_software_control_off(void) { /* Mode Register */ /*-----------------------------------------------------------------------*/ +int swap_bit(int num, int a, int b) { + if (((num >> a) & 1) != ((num >> b) & 1)) { + num ^= (1 << a); + num ^= (1 << b); + } + return num; +} + void sdram_mode_register_write(char reg, int value) { sdram_dfii_pi0_address_write(value); sdram_dfii_pi0_baddress_write(reg); - command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS_TOP); + + value = swap_bit(value, 3, 4); + value = swap_bit(value, 5, 6); + value = swap_bit(value, 7, 8); + value = swap_bit(value, 11, 13); + reg = swap_bit(reg, 0, 1); + + sdram_dfii_pi0_address_write(value); + sdram_dfii_pi0_baddress_write(reg); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS_BOTTOM); } #ifdef CSR_DDRPHY_BASE @@ -543,7 +561,18 @@ static void sdram_write_leveling_on(void) { // Flip write leveling bit in the Mode Register, as it is disabled by default sdram_dfii_pi0_address_write(DDRX_MR_WRLVL_RESET ^ (1 << DDRX_MR_WRLVL_BIT)); sdram_dfii_pi0_baddress_write(DDRX_MR_WRLVL_ADDRESS); - command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS_TOP); + + int addr = DDRX_MR_WRLVL_RESET ^ (1 << DDRX_MR_WRLVL_BIT); + int baddr = DDRX_MR_WRLVL_ADDRESS; + addr = swap_bit(addr, 3, 4); + addr = swap_bit(addr, 5, 6); + addr = swap_bit(addr, 7, 8); + addr = swap_bit(addr, 11, 13); + baddr = swap_bit(baddr, 0, 1); + sdram_dfii_pi0_address_write(addr); + sdram_dfii_pi0_baddress_write(baddr); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS_BOTTOM); #ifdef SDRAM_PHY_DDR4_RDIMM sdram_dfii_pi0_address_write((DDRX_MR_WRLVL_RESET ^ (1 << DDRX_MR_WRLVL_BIT)) ^ 0x2BF8) ; @@ -557,7 +586,18 @@ static void sdram_write_leveling_on(void) { static void sdram_write_leveling_off(void) { sdram_dfii_pi0_address_write(DDRX_MR_WRLVL_RESET); sdram_dfii_pi0_baddress_write(DDRX_MR_WRLVL_ADDRESS); - command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS_TOP); + + int addr = DDRX_MR_WRLVL_RESET; + int baddr = DDRX_MR_WRLVL_ADDRESS; + addr = swap_bit(addr, 3, 4); + addr = swap_bit(addr, 5, 6); + addr = swap_bit(addr, 7, 8); + addr = swap_bit(addr, 11, 13); + baddr = swap_bit(baddr, 0, 1); + sdram_dfii_pi0_address_write(addr); + sdram_dfii_pi0_baddress_write(baddr); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS_BOTTOM); #ifdef SDRAM_PHY_DDR4_RDIMM sdram_dfii_pi0_address_write(DDRX_MR_WRLVL_RESET ^ 0x2BF8); From 89396c758616f551a359c42977a1fdbb1960992b Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Thu, 20 Apr 2023 18:45:12 +0800 Subject: [PATCH 2/4] Add SDRAM_PHY_CLAM_SHELL guard --- litex/soc/software/liblitedram/sdram.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/litex/soc/software/liblitedram/sdram.c b/litex/soc/software/liblitedram/sdram.c index cdae0ae13..f4ea33fe3 100644 --- a/litex/soc/software/liblitedram/sdram.c +++ b/litex/soc/software/liblitedram/sdram.c @@ -263,6 +263,11 @@ int swap_bit(int num, int a, int b) { } void sdram_mode_register_write(char reg, int value) { +#ifndef SDRAM_PHY_CLAM_SHELL + sdram_dfii_pi0_address_write(value); + sdram_dfii_pi0_baddress_write(reg); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS); +#else sdram_dfii_pi0_address_write(value); sdram_dfii_pi0_baddress_write(reg); command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS_TOP); @@ -276,6 +281,7 @@ void sdram_mode_register_write(char reg, int value) { sdram_dfii_pi0_address_write(value); sdram_dfii_pi0_baddress_write(reg); command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS_BOTTOM); +#endif } #ifdef CSR_DDRPHY_BASE @@ -559,6 +565,11 @@ int _sdram_write_leveling_cdly_range_end = -1; static void sdram_write_leveling_on(void) { // Flip write leveling bit in the Mode Register, as it is disabled by default +#ifndef SDRAM_PHY_CLAM_SHELL + sdram_dfii_pi0_address_write(DDRX_MR_WRLVL_RESET ^ (1 << DDRX_MR_WRLVL_BIT)); + sdram_dfii_pi0_baddress_write(DDRX_MR_WRLVL_ADDRESS); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS); +#else sdram_dfii_pi0_address_write(DDRX_MR_WRLVL_RESET ^ (1 << DDRX_MR_WRLVL_BIT)); sdram_dfii_pi0_baddress_write(DDRX_MR_WRLVL_ADDRESS); command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS_TOP); @@ -573,6 +584,7 @@ static void sdram_write_leveling_on(void) { sdram_dfii_pi0_address_write(addr); sdram_dfii_pi0_baddress_write(baddr); command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS_BOTTOM); +#endif #ifdef SDRAM_PHY_DDR4_RDIMM sdram_dfii_pi0_address_write((DDRX_MR_WRLVL_RESET ^ (1 << DDRX_MR_WRLVL_BIT)) ^ 0x2BF8) ; From 4731aa65220d361ed85fa691f53b46839a8b65ed Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Thu, 20 Apr 2023 18:46:50 +0800 Subject: [PATCH 3/4] Add missing ifdef check --- litex/soc/software/liblitedram/sdram.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/litex/soc/software/liblitedram/sdram.c b/litex/soc/software/liblitedram/sdram.c index f4ea33fe3..ad583bb4e 100644 --- a/litex/soc/software/liblitedram/sdram.c +++ b/litex/soc/software/liblitedram/sdram.c @@ -596,6 +596,11 @@ static void sdram_write_leveling_on(void) { } static void sdram_write_leveling_off(void) { +#ifndef SDRAM_PHY_CLAM_SHELL + sdram_dfii_pi0_address_write(DDRX_MR_WRLVL_RESET); + sdram_dfii_pi0_baddress_write(DDRX_MR_WRLVL_ADDRESS); + command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS); +#else sdram_dfii_pi0_address_write(DDRX_MR_WRLVL_RESET); sdram_dfii_pi0_baddress_write(DDRX_MR_WRLVL_ADDRESS); command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS_TOP); @@ -610,6 +615,7 @@ static void sdram_write_leveling_off(void) { sdram_dfii_pi0_address_write(addr); sdram_dfii_pi0_baddress_write(baddr); command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS_BOTTOM); +#endif #ifdef SDRAM_PHY_DDR4_RDIMM sdram_dfii_pi0_address_write(DDRX_MR_WRLVL_RESET ^ 0x2BF8); From 0976c5aa54a45101d8036209969710f92b33da4f Mon Sep 17 00:00:00 2001 From: Jiajie Chen Date: Thu, 20 Apr 2023 19:00:26 +0800 Subject: [PATCH 4/4] Refactor code --- litex/soc/software/liblitedram/sdram.c | 42 ++------------------------ 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/litex/soc/software/liblitedram/sdram.c b/litex/soc/software/liblitedram/sdram.c index ad583bb4e..0a00ed5fa 100644 --- a/litex/soc/software/liblitedram/sdram.c +++ b/litex/soc/software/liblitedram/sdram.c @@ -565,26 +565,7 @@ int _sdram_write_leveling_cdly_range_end = -1; static void sdram_write_leveling_on(void) { // Flip write leveling bit in the Mode Register, as it is disabled by default -#ifndef SDRAM_PHY_CLAM_SHELL - sdram_dfii_pi0_address_write(DDRX_MR_WRLVL_RESET ^ (1 << DDRX_MR_WRLVL_BIT)); - sdram_dfii_pi0_baddress_write(DDRX_MR_WRLVL_ADDRESS); - command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS); -#else - sdram_dfii_pi0_address_write(DDRX_MR_WRLVL_RESET ^ (1 << DDRX_MR_WRLVL_BIT)); - sdram_dfii_pi0_baddress_write(DDRX_MR_WRLVL_ADDRESS); - command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS_TOP); - - int addr = DDRX_MR_WRLVL_RESET ^ (1 << DDRX_MR_WRLVL_BIT); - int baddr = DDRX_MR_WRLVL_ADDRESS; - addr = swap_bit(addr, 3, 4); - addr = swap_bit(addr, 5, 6); - addr = swap_bit(addr, 7, 8); - addr = swap_bit(addr, 11, 13); - baddr = swap_bit(baddr, 0, 1); - sdram_dfii_pi0_address_write(addr); - sdram_dfii_pi0_baddress_write(baddr); - command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS_BOTTOM); -#endif + sdram_mode_register_write(DDRX_MR_WRLVL_ADDRESS, DDRX_MR_WRLVL_RESET ^ (1 << DDRX_MR_WRLVL_BIT)); #ifdef SDRAM_PHY_DDR4_RDIMM sdram_dfii_pi0_address_write((DDRX_MR_WRLVL_RESET ^ (1 << DDRX_MR_WRLVL_BIT)) ^ 0x2BF8) ; @@ -596,26 +577,7 @@ static void sdram_write_leveling_on(void) { } static void sdram_write_leveling_off(void) { -#ifndef SDRAM_PHY_CLAM_SHELL - sdram_dfii_pi0_address_write(DDRX_MR_WRLVL_RESET); - sdram_dfii_pi0_baddress_write(DDRX_MR_WRLVL_ADDRESS); - command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS); -#else - sdram_dfii_pi0_address_write(DDRX_MR_WRLVL_RESET); - sdram_dfii_pi0_baddress_write(DDRX_MR_WRLVL_ADDRESS); - command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS_TOP); - - int addr = DDRX_MR_WRLVL_RESET; - int baddr = DDRX_MR_WRLVL_ADDRESS; - addr = swap_bit(addr, 3, 4); - addr = swap_bit(addr, 5, 6); - addr = swap_bit(addr, 7, 8); - addr = swap_bit(addr, 11, 13); - baddr = swap_bit(baddr, 0, 1); - sdram_dfii_pi0_address_write(addr); - sdram_dfii_pi0_baddress_write(baddr); - command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS_BOTTOM); -#endif + sdram_mode_register_write(DDRX_MR_WRLVL_ADDRESS, DDRX_MR_WRLVL_RESET); #ifdef SDRAM_PHY_DDR4_RDIMM sdram_dfii_pi0_address_write(DDRX_MR_WRLVL_RESET ^ 0x2BF8);